Commit Graph

10 Commits

Author SHA1 Message Date
type-two
30b1381a8b feat: Wave 6.2 — swap paywalled Windy for free 511-network road cams
Windy moved its Webcams API behind a paid tier (only the in-site Plugins
API is free), so the windycams layer is gone before ever going live. In
its place: roadcams — official public traffic cameras from keyless 511
APIs (a North-America-standard platform, one adapter covers many regions).
Launching with Alberta (367) + Ontario (946); more regions are one entry
in REGIONS + serve.py CAMS_REGIONS + an nginx location each (several 511s
just need free keys). InfoBox descriptions are CallbackProperties, so the
snapshot cache-buster is computed at click time — always-fresh images with
zero entity rebuilds. Verified: 1,302 cams, live Toronto snapshot in-app.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 15:01:19 +10:00
type-two
a435997a3d fix: hide SOLARGOD portal link off-localhost — it targets a dev server
The deep-link keeps working in local dev; on partly.party it would be a
dead localhost button until SOLARGOD has a public home.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:35:32 +10:00
type-two
f55d3202e0 feat: Wave 6.1 keyed layers — NASA FIRMS hotspots + Windy webcams
- firms (bespoke): raw VIIRS S-NPP fire detections, world, 24h. CSV via
  new serve.py proxy/firms (key from gitignored firmscredentials.json,
  injected server-side, 1h cache + stale-on-error). Points colored/sized
  by fire radiative power; click -> FRP/brightness/time/satellite overlay.
  Verified live: 1412 detections, hottest 88 MW seen 00:35 UTC today.
- windycams (bespoke): viewport-driven Windy Webcams v3 — nearest ~50 cams
  wherever the camera stops, entities with live preview img in InfoBox.
  proxy/windy validates nearby=lat,lon,km, injects x-windy-api-key header,
  10min coarsened cache. Degrades cleanly: 'key rejected' status until a
  real WEBCAMS-product key lands in windycredentials.json (re-read per
  request, no restart needed).
- key loader tolerant of JSON, brace-less fragments, or raw pasted tokens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:14:32 +10:00
type-two
7ccb2214f9 feat: Wave 6 OSINT4ALL sweep — TfL JamCams, InciWeb incidents, Radio Garden
Three new layers from the OSINT4ALL directory triage:

- jamcams (registry): ~800 live London traffic cameras via TfL open API
  (CORS-open, keyless). Click a cam dot -> live snapshot in the InfoBox,
  5-min cache-busted refresh. New collapsed 'Regional - London' category.
- inciweb (registry): named US wildfire incidents from InciWeb RSS. New
  spec.parse hook in the geojson-layer factory lets XML feeds supply their
  own parser; coordinates regex'd out of DMS text in <description>.
- radio (bespoke): ~12k live radio stations from Radio Garden pinned to
  their cities (PointPrimitiveCollection). Click -> station list + live
  audio player (audio streams direct; JSON via new allowlisted serve.py
  proxy/rg/ with 12h/1h caches, SSRF-tested). Keeps playing while you pan.

Deploy note: prod nginx needs a location for /godsigh/proxy/rg/ before
the radio layer works live (mirror of serve.py RG_PATH_RE allowlist).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 13:57:26 +10:00
type-two
b3499381bf feat: celestial layer — zodiac ring + Sun/Moon/planets in true sky positions
New 'Sky: zodiac · planets' layer (Space, default off). All computed, no data:
- 12 zodiac signs labeled around the ecliptic ring
- Sun & Moon from Cesium's Simon1994 model, 5 naked-eye planets from Schlyter's
  low-precision series — correct directions, verified (Sun sits in the right
  sign for the date, planets hug the ecliptic)
- placed in the INERTIAL frame (CallbackProperty × ICRF→Fixed each frame) so the
  sky stays star-locked while the globe rotates; distances compressed to one
  display ring beyond GEO so they're visible when zoomed out

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 10:19:21 +10:00
jing
60ceb4a261 wave3.1: ADS-B OSINT layers (emergency squawks, rare-type hunter, shadow, radius focus)
All FREE via adsb.lol. New generic pieces:
- serve.py proxy/adsb/<path>: regex-allowlisted (SSRF-safe) adsb.lol v2 proxy
  with per-path 120s cache + upstream call-spacing (adsb.lol 429s on bursts;
  reservation slots space call *starts* without serializing network time),
  12s fail-fast timeout, stale-on-error
- js/layers/adsb-layer.js: generic {ac:[...]} billboard factory (parallel
  allSettled fetch, live/scrub/visibility gating, optional client-side filter)
- js/adsb-registry.js: emergency (sqk 7700/7600/7500, default-on, alerts red),
  rare-type hunter (filters the shared mil feed by ICAO type — 1 cached call,
  no per-type rate-limit), shadow (LADD+PIA, purple/pink)
- js/layers/radius.js: camera-driven 'all traffic within 250nm of view'
- verified live: all four render, worst-case simultaneous-enable ok, 0 errors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 10:19:21 +10:00
monsterrobotparty
d06ebf07cb 🪐 portal: the orrery gets a door — 🪐 SOLARGOD button deep-links at GODSIGH's scrubbed moment
Reciprocal to SOLARGOD's Earth-card link into GODSIGH. A subtle HUD pill
(above the footer, styled to the mode-button family) opens the orrery in a
new tab. The href is rebuilt fresh at click time from viewer.clock.currentTime
via the shared `#t=@<unixMs>` convention, so scrubbing GODSIGH's clock carries
straight through to SOLARGOD's sim time.

- index.html: <a#solargod-link.portal-link> between #layers and footer
- css: .portal-link (matches .modes button; accent on hover)
- ui.js: wireSolargodLink(getMs) — rebuilds href on pointerdown+click
  (covers ⌘/middle-click new-tab); Cesium stays out of the DOM module
- main.js: wire it with a getMs closure over viewer.clock

Verified in-browser: button renders, zero console errors, all layers boot;
live click → href tracks the clock; scrub -3h → href exactly 3h behind now +
chip flips SCRUBBED + live layers pause; opening the link launches SOLARGOD
in SCRUBBED state at the passed epoch (its hash echoes the exact ms).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 09:45:48 +10:00
jing
3dde813d7d wave3: categorized collapsible HUD (Space/Air/Sea/Earth/Context/Regional)
12+ layers in a flat list was unusable. ui.js now groups rows into ordered,
collapsible category sections (scheme owned in ui.js so order is stable
regardless of registration order); Regional — Australia collapsed by default;
empty categories auto-hidden via :has(:empty). URL-state get/set layer APIs
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 00:29:49 +10:00
jing
2e061b2cdf wave2 phase 5: polish pack (military, ground tracks, URL state, screenshots)
1. Military callsigns (aircraft.js): callsigns matching CONFIG.aircraft.
   militaryPrefixes tint red regardless of altitude band and bump larger. New
   "Military filter" HUD row (default off) shows only military aircraft when on;
   status "N military of M". Pick overlay shows Military/Civil class.
2. Satellite ground track (satellites.js): selecting a satellite draws its
   sub-satellite path (height 0, ±half orbit around now) as a dashed polyline in
   the sat's colour; deselect hides it; one track at a time. Recomputed on
   demand from the satrec (no upfront precompute of 97 tracks).
3. Shareable URL state (main.js + ui.js): camera / mode / layer toggles / clock
   offset serialize to location.hash (replaceState, 1 s cadence, only on change)
   and are restored on boot; malformed hashes ignored silently.
4. Screenshot endpoint (serve.py): dev-only POST snap?name= writes a base64 PNG
   body to docs/<name>.png (name sanitized to [a-z0-9-], can't escape docs/).
   Captured docs/screenshot-data.png + screenshot-photo.png (render() called
   synchronously before toDataURL — the preserveDrawingBuffer pitfall).

README rewritten for Wave 2: quakes/fires layer rows (marked REAL), replay,
shared cache, shareable links, ground tracks, military, screenshots, updated
architecture + roadmap.

Verified in browser: 11 military of 6062 + filter; ground track 180 pts on
select / hidden on deselect; URL round-trips camera+mode+layers+clock; both
screenshots written as valid 1280x720 PNGs; subpath audit clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 16:53:05 +10:00
jing
7356d62381 phase 1: globe core — viewer, dual basemaps, clock, HUD, layer contract
- CesiumJS viewer (token-free, baseLayer:false), Carto dark + EOX Sentinel-2
- clock spans now +/-6h CLAMPED; built-in timeline/animation = the space-time slider
- HUD: brand, LIVE/SCRUBBED chip, Data/Photo mode toggle, layer rows, credits
- lighting is mode-aware: OFF in Data (high-contrast asset map), ON in Photo
  (realistic day/night terminator) — refines SPEC 6.1's global-lighting note
- main.js defines the layer-factory contract + dynamic loader; layers land next
- serve.py now forwards OpenSky X-Rate-Limit-* headers for the aircraft status line

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 12:06:05 +10:00