🌐

Site Overview

The ORCSGirls Play Lab is a collection of interactive educational tools for students. It runs across two servers:

ServerDomainContents
Play serverplay.orcsgirls.orgAll HTML/CSS/JS — the full student-facing site
Data serverdata.orcsgirls.orgPHP API + teacher admin UI (/showcase/)

Deployment is done by uploading two zip files produced at the end of each work session:

  • play-server.zip — extract to the play server web root
  • data-server.zip — extract to the data server web root (contains showcase/ subfolder and setup.sql)

⚠️ Always rm -f the old zip before rebuilding — zip -r updates rather than replaces, which can leave stale files from earlier sessions.

🗂️

Play Server File Structure

Root index.html ← Main hub (six section cards) style.css ← Global design tokens, layout, components theme-init.js ← Runs before first paint; sets data-theme from localStorage standalone.js ← Hides nav when ?mode=standalone is in the URL access.js ← Class code gate — runs in <head>, protects all pages common.js ← Shared Caesar/Vigenère cipher helpers cyber/ index.html ← Cybersecurity Hub wheel.html ← Cipher Wheel (Caesar rotation) vigenere.html ← Vigenère Square translator.html ← Bidirectional live Caesar translator password.html ← Password Strength Checker binary.html ← Binary Numbers Game data/ index.html ← Data & Electronics Hub terminal.html ← USB/BLE Serial Terminal plotter.html ← Real-time CSV Data Plotter js/ble-serial.js ← Shared BLE/USB module (window.BleSerial) fun/ index.html ← Fun Tools Hub drawing-pad.html ← Anaglyph 3D Drawing Pad dice.html ← Dice Roller js/DrawingPad.js ← Full anaglyph drawing engine js/Anaglyphs.js ← Legacy (unused — keep for stamp work) science/ index.html ← Science Lab Hub fourier-camera.html ← Fourier Transform Camera interference.html ← Wave Interference Simulator diffraction.html ← Diffraction Simulator js/FourierCamera.js, FastFourier2D.js, interference.js js/Fourdem.js ← Unknown purpose — audit and remove if unused web/ index.html ← Web Lab Hub editor.html ← Live Code Playground (Monaco editor, 3 tabs) showcase.html ← Student Web Showcase (date-filtered gallery) emoji.html ← Unicode/Emoji Explorer range.html ← Unicode Range Finder images/ Logo-White.png, Logo-Black.png LogoRound-Purple.png, LogoRound-White.png
🗄️

Data Server Files & API

showcase/api/ config.php ← DB credentials (reads from ../../credentials.php) _db.php ← PDO connection, CORS, content scanner, helpers submit.php ← POST: save submission, auto-hide if bad content submissions.php ← GET ?date=YYYY-MM-DD: list for showcase dates.php ← GET: distinct session dates with counts submission.php ← GET ?id=N: full HTML for one submission status.php ← GET: submissions open/closed state verify.php ← POST: validate a class code admin.php ← GET/POST: teacher admin (Basic Auth protected) .htaccess ← Blocks config.php and _db.php from HTTP access showcase/admin/ index.html ← Teacher admin UI (fully self-contained) .htaccess ← Apache Basic Auth setup.sql ← Run once to create all tables in ORCSPlay database

API Endpoints

EndpointMethodAuthPurpose
/showcase/api/submit.phpPOSTnoneSave submission; auto-hides bad content
/showcase/api/submissions.php?date=GETnoneList approved rows for a date
/showcase/api/dates.phpGETnoneDistinct session dates with counts
/showcase/api/submission.php?id=GETnoneFull HTML for one submission
/showcase/api/status.phpGETnoneSubmissions open/closed state
/showcase/api/verify.phpPOSTnoneValidate a class code
/showcase/api/admin.phpGET/POSTBasic AuthList all / toggle / delete; manage codes & submissions state

Database Tables (ORCSPlay)

web_submissions  (id, student_name, title, html, approved, submitted_at, ip)
site_settings    (setting_key PK, setting_val)          -- e.g. submissions_open=1
class_codes      (code PK, label, active, created_at)

CORS Allowed Origins

https://play.orcsgirls.org, http://localhost, http://localhost:80, http://localhost:8000, http://127.0.0.1

Access Gate (access.js)

All pages load access.js in <head>. Hides page immediately, then:

  • Fast path: session-verified (sessionStorage: orcs_code_ok) → show instantly
  • Stored code: calls verify.php async → show or show gate if revoked
  • No code: show gate overlay on DOMContentLoaded
  • Network error: fail open — never blocks a student because of a server blip

Gate: purple card, ORCSGirls logo, monospace input (auto-uppercase), shake on wrong, locks after 5 attempts. Includes contact hint: "Forgot your code? Contact contact@orcsgirls.org". On success: code → localStorage, flag → sessionStorage.

Submissions Gate

Teacher opens/closes submissions from admin page. State in site_settings. submit.php returns HTTP 423 when closed. Editor fetches status.php on load and shows "🔒 Submissions Closed" when disabled.

Content Scanner

containsBadContent() in _db.php — strips tags, lowercases, checks first 5000 chars against a wordlist (profanity, slurs, explicit terms, self-harm). Called at insert time (submit.php) and by admin.php for the Flags column.

📐

Key Design Patterns

Global Conventions

  • Script order in <head>: theme-init.jsstandalone.jsaccess.js
  • Dark/light mode: html[data-theme="dark"] selectors; persisted in localStorage as orcs_theme
  • ?mode=standalone hides the nav bar — used for embedding tools in class
  • Footer: © YEAR ORCSGirls — contact@orcsgirls.org on every page
  • Favicon: <link rel="icon" href="[../]images/LogoRound-Purple.png">
  • Tool pages: body > main.container { flex: 1 } fills height; footer always pinned

CSS Variables (style.css)

--primary-purple: #4a148c    --accent-teal:    #0097a7
--accent-green:   #00873c    --accent-magenta: #c2185b
--text-dark:      #1a1a2e    --text-muted:     #6b5f7a
--bg-light:       #f5f3f8    --radius:         10px

Panel Layout Pattern

.tool-split (flex row, align-items:stretch) contains .tool-side-controls (flex column, fixed width) and .tool-side-visual (flex:1). Inner .panel gets flex:1; overflow-y:auto so it matches the visual panel height.

Drawing Pad Anaglyph Rendering

DrawingPad.js uses getImageData/putImageData for per-pixel channel manipulation (R = left-eye, G+B = right-eye offset by depth slider). Cursor overlay is a separate <canvas id="dp-cursor-canvas"> with pointer-events:none. Critical: clear() resets globalCompositeOperation to source-over before filling — otherwise subsequent strokes are transparent.

Binary Game Progressive Difficulty

Challenge mode: starts 1–15 (4-bit), expands every 3 correct answers through 1–31, 1–63, 1–127, 1–255. LEVEL_MAXES = [0, 15, 31, 63, 127, 255]. Practice mode always uses full range.

Admin Page

Fully self-contained — all CSS inlined, no dependency on play server. Theme toggle wired via DOMContentLoaded listener. Flags column: ⚠ Content (PHP scan, immediate) and ⚠ JS Error (hidden iframe + postMessage, ~6s delay). Class Codes panel shows active codes as large monospace chips.

Completed This Chat Session

FeatureFiles
Drawing Pad: upload image with placement mode, scroll-to-resize, correct anaglyph renderingfun/js/DrawingPad.js, drawing-pad.html, fun.css
Drawing Pad: brush/eraser cursor overlay canvasDrawingPad.js, fun.css
Password Strength Checker with passphrase detectioncyber/password.html
Binary Numbers Game with progressive difficultycyber/binary.html
Student Web Showcase with date-filter pillsweb/showcase.html, data server API
Teacher Admin page (self-contained, Basic Auth, content + JS error flags)showcase/admin/index.html, admin.php
Content scanner — auto-hides inappropriate submissions_db.php, submit.php
Submissions open/close gatestatus.php, admin.php, editor.html, admin/index.html
Class code access gate — all pages protectedaccess.js, verify.php, setup.sql
Skid Steer Configurator card (external link)fun/index.html
Site-wide: standalone mode, compact footer, panel heights, full-height layoutstyle.css, standalone.js, all pages
Monaco editor height fix (flex instead of hardcoded calc)web/web.css, web/editor.html
Fourier Camera 1:1 aspect ratio via CSS aspect-ratiofourier-camera.html, science.css
Two-server CORS setup (play → data)_db.php
Logic Gate Simulator — full canvas circuit editor with AND/OR/XOR/NOT gates, drag-place, wire drawing, DAG evaluation, challenge mode (OR gate / half-adder / XOR from ANDs+NOTs)cyber/logic-gates.html, cyber/index.html
Logic Gate Simulator — polished IEEE gate symbols with wire stubs; toggle-switch INPUT; LED-in-box OUTPUT; no labels; panel layout; localStorage persistence; single-placement mode; help bar at top of canvascyber/logic-gates.html
Logic Gate Simulator — Challenge 4 Full Adder (3 inputs, 8 rows); INPUT/OUTPUT disabled in challenge mode; animated truth-table step-through with per-row pass/fail colouring; canvas top help barcyber/logic-gates.html
🚀

Future Work

⭐ Binary — Logic Gate Simulator

✓ Done

Completed April 2026. Full canvas circuit editor at cyber/logic-gates.html, card on cyber/index.html.

  • Gates: AND, OR, XOR, NOT — IEEE-style shapes with explicit wire stubs; no labels (students learn by shape)
  • I/O: SWITCH (iOS toggle in square box, click to flip 0↔1), LED (indicator in matching square box)
  • Interaction: click palette → place one gate → return to idle; drag body to move; drag output ○ → input ○ to wire; right-click to delete; ESC cancels; undo stack (50 deep)
  • Evaluation: topological DAG traversal on every change; active wires glow green; cycle detection prevents loops
  • Persistence: sandbox circuit auto-saved to localStorage and restored on reload; challenge circuits never saved
  • Challenge mode: Challenge 1 OR gate · Challenge 2 Half-Adder · Challenge 3 XOR from ANDs+NOTs · Challenge 4 Full Adder (3 inputs, 8-row truth table); INPUT/OUTPUT buttons disabled while a challenge is active; animated truth-table step-through with per-row pass/fail colouring; "▶ Test My Circuit" button
  • UI chrome: terminal-style panel (purple toolbar, rounded corners); frosted help bar rendered at canvas top; consistent dark/light theme

Logic Gate Simulator — Future Extensions

Ideas

Multi-select, group move & delete

Let students select several gates at once and move or delete the whole group — essential for tidying up large circuits without rebuilding them from scratch.

  • Selection rectangle: mousedown on empty canvas → drag to draw a rubber-band rect (dashed purple outline); any gate whose centre falls inside becomes selected. Add iState = 'selecting' to the FSM; on mouseup commit the set selectedIds.
  • Click-to-add / Shift-click: shift-click an individual gate to add or remove it from the current selection without clearing others.
  • Group drag: mousedown on any selected gate enters iState = 'dragging-group'; on mousemove apply the same delta to every gate in selectedIds. Wires follow automatically since they reference gate IDs.
  • Group delete: Delete / Backspace key removes all gates in selectedIds in one snapshot (single undo step).
  • Visual feedback: render a light-blue tinted highlight rect around each selected gate body; show a small "N selected" badge in the help bar.
  • Deselect: click on empty canvas (outside a gate) or press ESC to clear the selection.
  • Implementation note: extend the existing snap() / undo system — no structural changes needed; selectedIds is transient UI state and does not need to be snapshotted or persisted.

Grid snapping

An optional snap-to-grid makes circuits look neat without students needing to align gates manually — especially helpful on touchscreens.

  • Grid size: 28 px matches the existing dot grid exactly, so snapped gates sit on visible dot intersections. Consider a toolbar toggle (⊞ Snap) to turn it on/off; persist preference to localStorage.
  • Snap function: function snap(v){ return Math.round(v / GRID) * GRID; } — apply to x and y in addGate() and during drag (mouseup, not mousemove, so dragging still feels smooth).
  • Placement ghost: when snap is on, snap the ghost preview too so students see exactly where the gate will land.
  • Grid visual: the dot grid is already drawn; when snap is enabled, optionally brighten the dots slightly (opacity: 0.220.32) to make the grid more prominent as a visual affordance.
  • Challenge mode: snap the pre-placed locked inputs/outputs to grid coordinates so wires between them are more likely to align neatly.

Other ideas (lower priority)

  • Wire labels / annotations: click a wire to give it a name (e.g. "carry") displayed as a small label mid-wire — useful for teaching students to trace signal paths in complex circuits.
  • Export / import: serialize the circuit to JSON and offer a download button; reciprocally, allow dragging a JSON file onto the canvas to load a saved circuit — enables teachers to share starter circuits.
  • Additional gate types: NAND, NOR, XNOR are directly derivable (NOT + AND/OR/XOR) and would complete the standard gate set; add as palette buttons with their own IEEE shapes.
  • Challenge 5 — SR Latch: two NOR (or NAND) gates with cross-coupled feedback — introduces students to memory and state; requires first adding NOR to the gate set and handling the stable-state feedback loop in the evaluator (currently cycle-detection blocks it).

Internet of Things — Particle IoT Tools

Low Priority
  • Migrate existing Particle IoT tools into the site; owner will provide files
  • Suggested location: new iot/ section with hub page + new nav item on all pages

Cyber — Password Crack Time Visual Simulator

Pending

Standalone deeper companion to the existing Password Strength Checker.

  • Visual timeline of crack times at multiple attack speeds
  • Adjustable inputs: length, character pool (lower/upper/digits/symbols), entropy bits
  • Link between this and cyber/password.html

Fun Tools — Skid Steer Configurator

✓ Done

Card added to fun/index.html — opens https://play.orcsgirls.org/SkidSteerConfigurator/ in a new tab. Students pick colours for their 3D printed skid steer robot for maker camp.

Fun Tools — Additional Ideas

Ideas
  • Colour mixer showing how red + cyan combine into greyscale (anaglyph tie-in)
  • Oscilloscope / waveform viewer using the Web Audio API
  • Pixel art editor

Science — Fourier Camera Improvements

Pending
  • Mobile: Verify iOS file-picker branch (snapImageiOS) on current Safari
  • Error state: Show Retry button when camera permission is denied
  • Spectrum annotation: "Low frequency (shapes)" near centre, "High frequency (edges)" near corners
  • Download: Dedicated button below spectrum panel (currently buried in status bar)

Drawing Pad — Stamps

Pending
  • Create fun/stamps/ folder with paired red/cyan PNG files per stamp
  • Add stamps/manifest.jsonloadStamps() in DrawingPad.js fetches and populates dropdown
  • No base64 in JS source — that caused a syntax error previously

Drawing Pad — Mobile Touch

Pending
  • Test coordinate accuracy on iOS and Android
  • Verify scroll-to-resize in image placement mode on trackpads and touch screens

Web Showcase — Future Improvements

Ideas
  • Auto-refresh so the showcase updates live during a class without manual reload
  • Allow students to update their own submission (needs a one-time secret code returned at submit time)
🔧

Technical Debt

ItemFileStatusNotes
Anaglyphs.js in fun/ fun/js/Anaglyphs.js ⚠️ Unused Kept as scaffold for stamp work; remove once stamps are re-implemented
Fourdem.js science/js/Fourdem.js ⚠️ Unknown Audit and remove if unused
science.css consolidation science/science.css ⚠️ Pending Some Fourier Camera styles still in inline <style> in fourier-camera.html
Cookie-based camera preference science/js/FourierCamera.js ⚠️ Pending Uses setCookie/getCookie from Anaglyphs.js — replace with localStorage
Admin modal dark mode showcase/admin/index.html Minor .admin-modal background doesn't switch in dark mode