Omnigraph
그래프 엔진으로 컨텍스트를 조립하고, 객체 저장소 기반에서 에이전트가 코드처럼 그래프 데이터를 분기·타입·검토·병합·감사·거버넌스합니다
Urban digital twins of Raleigh, NC and Nagpur, Maharashtra: real OpenStreetMap city models with a cascade-intelligence layer that simulates how floods, grid faults, toxic releases and crowds propagate
데이터JavaScript · CSSGitHub @shreyascoder2006온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Urban digital twins of Raleigh, NC and Nagpur, Maharashtra: real OpenStreetMap city models with a cascade-intelligence layer that simulates how floods, grid faults, toxic releases and crowds propagate through drainage, roads, power, telecom and hospitals up to 72 hours ahead.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Urban digital twins of Raleigh, North Carolina and Nagpur, Maharashtra, with a crisis-cascade layer that predicts how a flood, a grid fault, a toxic release or a crowd propagates through drainage, roads, power, telecom, emergency response and hospitals up to 72 hours ahead. The city models are real: OpenStreetMap buildings, streets, rivers and facilities rendered in 3D. The cascade intelligence is one analytical layer on top of them, the way production CIM and digital-twin platforms are structured.
| Facility inspector | Inferred dependency graph |
|---|---|
python3 -m http.server 8000 # from the repository root
# open http://localhost:8000 (Nagpur, the default city)
# open http://localhost:8000/#/?city=raleigh
Any static file server works. Opening index.html straight from disk (file://) also works, but
browsers block local fetch there, so the map falls back to live OpenFreeMap tiles.
Everything you see is a simulation. The city (facilities, streets, creeks, buildings) is real OpenStreetMap data; the hazard, every sensor reading, citizen report and outcome are generated by a modeled scenario. The interface says so: a Simulation badge, a Now / Replay time mode instead of "live", the clock marked as scenario time, scenarios tagged modeled or reconstruction, and the inspector's feed and physical readings (stage, occupancy, speed…) marked as illustrative, since they are derived from the risk index rather than measured. A reconstruction (Nagpur's 23 Sep 2023 cloudburst) takes the rainfall's timing and totals from reported figures for the real event; its sensor streams, citizen reports and outcomes are still simulated.
The city is part of the link (city=nagpur or city=raleigh) and the selector sits next to the
scenario. A link without a city opens Nagpur. Each city brings its own data file (src/js/data/geodata*.js), time zone (EDT, IST),
systems and scenarios:
| Raleigh | Nagpur | |
|---|---|---|
| Monitored facilities | 44: drainage gauges, a pumping station, junctions, substations, hospitals and EMS, weather | 57: the same systems plus telecom (a telephone exchange and four mobile-site clusters) |
| Scenarios | Tropical remnant rainfall, convective flash flood, heat wave, grid fault and telecom blackout (all modeled) | Monsoon cloudburst · 23 Sep 2023 (reconstruction), chlorine release at the Seminary Hills water treatment plant, immersion-day crowds and an evening storm (modeled, Nagpur only), plus the four generic ones |
| Interventions | A hand-written catalogue for Raleigh's facilities | Generated from the dependency graph: the facilities that feed the most consequential links get the remedies |
| Modeled population | 1,412 cells, about 454,000 residents | 1,790 cells, about 2.94 million residents |
The Nagpur data, its scenarios, the population grid, telecom, the generated intervention catalogue and the crisis analytics were ported from vizsh/72_hours_CASCADE (at 9bc9058) with the owner's permission; this site's interface and renderer are its own.
The site is a set of pages in one document, addressed by the URL hash, so each engine and the 3D city are built once and shared, and every view can be linked to.
Six features sit in a permanent sidebar on the left, present on every view including the 3D twin, grouped as Operations and Public. Each row carries a chip computed from the engine at the issue time (the city's state, the crisis count, the plan's reduction), so scrubbing the clock moves the sidebar with the rest of the site. It collapses to an icon rail, and below 960 px becomes an overlay.
| Page | Path | What it shows |
|---|---|---|
| Situation | #/ | The briefing view of the same 3D twin (same map, timeline and inspector; no second renderer). The asset inventory gives way to an outlook panel with the city's state, a computed briefing, measures (critical now, forecast critical within 24 h, Cascade-R, modeled residents in high-risk areas now and in 24 h), risk by system with the next forecast CRITICAL crossing, and a prioritised list of crises and upcoming crossings. A strip above the map shows the next crossings in predicted order (observed solid, forecast dashed with probability), or "No cascade currently forecast". The camera frames the leading hazard; crisis footprints are on. Selecting an event selects the facility, moves the clock to it, pauses playback and opens the inspector, which links to the crisis, City twin and Response. Collapsible panels (predicted course, population exposure, highest-risk facilities, traffic and access, sensor evidence, the Chronos benchmark) appear only when the engine has data for them. |
| Crises | #/crises | A board of linked views, independent of the 3D twin (no map, no renderer): Cascade-R with direct-hazard against through-link stress per system; the learned dependency network between systems or facilities (confirmed, candidate and pruned links, plus direct hazard forcing) with an inspector; a 72 h timeline (Cascade-R, or the selected facility's risk with its forecast 10–90% band, and the predicted threshold crossings); the registry, a system impact matrix (stress flowing now along learned links, system to system, derived from the facility links), critical facilities and recent sensor evidence. One selection drives every view; clicking the timeline moves the shared time; the selected crisis stays in the link (c=) for City twin and Response. |
| Crisis | #/crises/<id> | One crisis: how it began, its members and what drives each now, the order in which they cross HIGH RISK and CRITICAL (observed, then forecast with probability), the residents near its members (modeled), its history, and links to the board, City twin and Response. |
| City twin | #/twin | Free investigation in the same app: the full asset inventory, layers and alerts (collapsed until opened), the system cascade strip and the legend. The 3D operations room, with its own drawers for the learned dependency graph, the intervention planner and replay validation. With c=<crisis id> it draws every crisis footprint, frames the camera on that one and shows it in the breadcrumb. |
| Response | #/plan | The action catalogue with what each action is worth alone, a crew budget, the planner's recommendation, a before/after ledger (critical facility-hours, hospital and EMS hours, P(a hospital goes critical), facilities reaching critical), what the plan costs elsewhere, and the . |
The decision deadline is what a dashboard cannot show. interventions.deadline(k, ids)
re-runs the plan with the crews starting 0, 2, 4 … 24 h later, still deciding at k on
information up to k. Nagpur's chlorine release decided at T+31 is worth 55% fewer
critical facility-hours if the crews move now, 36% after two hours and nothing after six;
the monsoon plan decided at T+37 keeps 80% of its value until T+47. Same engine, same
page, opposite decisions.
Segment counts in the warnings are the same kind of honesty. GSM 03.38 packs 160 characters into one SMS; Devanagari forces UCS-2 and 70, so the Nagpur flood warning is one message in English, two in Marathi and three in Hindi.
The shared context travels in the query (src/js/site/store.js):
| Parameter | Meaning | Example |
|---|---|---|
city | raleigh or nagpur; absent = the city in use (Nagpur on a fresh load) | city=raleigh |
s | scenario id; absent = the city's first scenario | s=flash |
t | view time in hours from T+0; absent = follow the simulated now | t=40 |
m | replay for replay mode; absent = now | m=replay |
a | selected facility id | a=HSP-WMR |
c | crisis shown on the twin | c=CR-RAL-4573 |
area | neighbourhood shown on My area | area=Dharampeth |
For example http://localhost:8000/#/twin?city=raleigh&s=flash&t=40&a=HSP-WMR opens Raleigh's
flash-flood scenario at T+40 with WakeMed selected, and
http://localhost:8000/#/crises/CR-NAG-5627?city=nagpur&s=monsoon2023&t=37 opens the Nagpur flood
crisis as issued at T+37. Selecting a facility, switching mode, scenario or page adds a history
entry (back/forward replay them); scrubbing time updates the current one. Unknown scenarios or
facilities are dropped from the link, and unknown pages fall back to the overview with a note.
The pages read what was known at the issue time: a link with a time after the simulated now shows the now. While another page is in front the twin is paused (its clock and render loop hold still), and its time, selection and crisis follow the context when you come back. A city switch on the twin reloads the page (map bounds, tiles and meshes are per city); the other pages switch in place.
python3 tools/build_dist.py produces dist/index.html, a single page with all CSS and JavaScript
inlined, plus dist/data/bundles/: the tiles and glyphs packed as base64 JSON for hosts that only
serve text and web media types, and dist/data/models/: the hero models as base64 JSON with their
texture images. It runs under a strict Content-Security-Policy (connect-src 'self', scripts only
from cdnjs and cdn.jsdelivr.net) and is what the published artifact is built from.
The map code is written against the Mapbox GL JS API (Map, Marker, fill-extrusion, flyTo,
addSource/addLayer, canvas sources, custom layers).
data/tiles through a twin://
protocol, so the twin works offline and inside sandboxed frames that block third-party requests.
This is the path the realism work below was built and tested on.mapboxToken in config.js to a Mapbox public token. The twin then
loads the Mapbox Standard style with Mapbox's own 3D buildings, landmarks and trees, pulls its
palette toward the dark command-center look (setConfigProperty on the basemap import) and
switches its light preset (dawn, day, dusk, night) as the timeline is scrubbed. The hero models
go into Standard's middle slot and the dependency arcs and radar into top. If the token is
rejected or the style does not load within 15 s, the failed map is removed and the app falls
back to MapLibre.
Untested: no valid token was available while this was built. Only the fallback has run (an
invalid token gets a 401 on the style and the app comes up on MapLibre); Standard itself, the
setConfigProperty keys, the light preset switching and the slot placement have not.
Known limitation: Standard's buildings come from Mapbox's own tiles and cannot be clipped,
so at a hero site the Mapbox building and the hero model overlap. The OSM footprint swap
described below only works on MapLibre.The city is drawn in three layers that share one sun, computed from the simulation clock
(core.sunPosition, NOAA low-precision ephemeris). T+0 is Sat 24 Oct 2026 00:00 local time and
the scenario's now is T+34.5, unless the scenario has its own clock: the Nagpur cloudburst
reconstruction starts at Thu 21 Sep 2023 06:00 IST with its now at T+37.
Scrubbing the timeline moves the sun, the sky, the haze and every shadow.
src/js/map/buildings.js): a WebGL2 custom layer that decodes the building
layer of every z13+ tile MapLibre loads and meshes it: walls and flat roofs from the footprint
(earcut), gable roofs fitted to the oriented bounding box of small houses. A procedural shader
draws facades in world metres per building class (punched windows, ribbon glazing, curtain
walls, storefronts, ribbed industrial cladding), roofing (shingle courses, membrane, rooftop
plant), sky reflections and sun glints in glass, and lit windows at night that fade to a dim
average once they are smaller than a couple of pixels. Each wall carries its direction in its
vertex data, so the window grid stays exact up close. A sun shadow map (4096², 2048² on
software rasterisers) is re-rendered only when the sun, the shadow region or the drawn tiles
change, and shades the buildings and a ground quad. Without WebGL2 or local tiles, or if the
driver rejects its shaders, it steps aside and the style's fill-extrusions show.src/js/map/heroes.js): a Three.js layer ([email protected], imported from
cdn.jsdelivr.net on first use) that shows a detailed glTF model of the selected facility, with a
ground ring and halo in its risk colour, sun-matched lighting and its own shadows. The OSM
footprints under each hero site are lifted out of the tiles (geodata.sites) and hidden while
the model stands there, in both the city-building layer and the fill-extrusion fallback. Models
exist for hospitals, EMS stations, the pumping station, substations, traffic sites and the
weather station (on its roof at 13.5 m); stream and culvert gauges keep their marker only.src/js/map/style.js): the dark CIM palette, a sky and horizon haze per
day phase, and the MapLibre light following the sun.Configuration (config.js): cityBuildings: false keeps the fill-extrusions, buildingShadows: false drops the shadow map, shadowSize overrides its size.
Frame times downtown (1600×900, zoom 16.4, pitch 60, about 250k triangles; node tools/test/perf.js <url> [gpu]; medians over several runs on a laptop, so the ranges are mostly machine load):
| City buildings + shadows | City buildings, no shadows | Fill-extrusion fallback | |
|---|---|---|---|
| Intel integrated GPU (D3D11) | 25–55 ms | 25–45 ms | 16–36 ms |
| SwiftShader (headless, software) | 0.84–1.15 s | 0.82–1.0 s | 0.49–0.81 s |
On a GPU the shadow pass costs little: it runs once per camera move or sun step (0 times across
static frames, stats.shadowPasses), not every frame.
tools/enrich_buildings.py classifies each
building by the OSM land-use polygon its centroid falls in and, where OSM has no height tag (most
of both cities), infers one from footprint area and class (inferred = 1 in the tiles). Explicit
OSM heights are kept. Facade style, window rhythm and roof shape follow from those estimates, not
from surveys or imagery.tools/models/facility_models.js). They are representative of each facility
type, not replicas of the real buildings. Two sites overlap a neighbouring OSM building that was
not lifted out of the tiles: the north edge of the Duke Raleigh Hospital model and one corner of
the Lake Boone pumping station yard.gen_*.png
decals (helipad, emergency and EMS signs, chain-link) are drawn by the build page.node tools/models/export_models.js preview/ # needs Playwright + Chromium and cdn.jsdelivr.net
It opens tools/models/build.html in headless Chromium, builds each model with three.js, writes
data/models/*.glb (and optional preview renders), then externalize.py points the glTF images at
the shared files in data/models/textures/. tools/build_dist.py wraps them as base64 JSON for
single-page builds (modelBundles).
| Real (OpenStreetMap, ODbL) | Modeled for the simulation |
|---|---|
| Buildings with heights, streets, creeks, ponds, parks: 170 vector tiles, z10–14 | Storm scenarios and the hidden "ground truth" run |
| Hospitals (WakeMed Raleigh, 628 beds; Duke Raleigh, 186; WakeMed North, 61; UNC Rex) | Risk indices, capacities, sensor IDs and readings |
| 31 Duke Energy substations with OSM voltages; their Voronoi service areas | Dependency weights in the ground-truth run |
| Wake County EMS stations, the Lake Boone pumping station | Injected sensor faults and false citizen reports |
| Gauges at exact creek × road crossings (e.g. Crabtree Creek at Glenwood Ave) | UNC Rex bed count (not tagged in OSM) |
| Every dependency route: Dijkstra on the real street graph or down the real waterway graph | Rain gauge sites |
| Nagpur: buildings, streets and the Nag, Pili and Pohara rivers (vector tiles z10–14) | Bed counts of all six Nagpur hospitals; base loads and thresholds (not MSEDCL, NMC or hospital records) |
| Nagpur: Government Medical College, Mayo, Wockhardt and other hospitals, substations and fire stations at their OSM features | Lake spillway gauges, mobile-site clusters, the Gandhi Sagar outfall pumps and the rain-gauge network |
| Nagpur: gauges at named river × road crossings, junction sensors at OSM squares | The cloudburst's sensor streams and outcomes (rain timing and totals follow reported figures) |
| Residents per 450 m cell: street length and building area in the tiles, scaled to each city's population |
| Requirement | Implementation |
|---|---|
| Multi-horizon forecasting | 200-member ensemble. Each facility gets P(critical) and a fan chart at +1/6/12/24/48 h, plus time-to-critical with p10–p90. Forecasts are perturbation forecasts anchored to the current analysis. |
| Dependency discovery | No structure is given. 71 candidate links (7 deliberately spurious) are learned online by sparse Bayesian regression (ARD) on the sensor streams, then confirmed, pruned or left as awaiting evidence. By T+72 h on the tropical storm: 32 confirmed, 12 pruned. A separate raw-stream screen (lagged correlation, weather partialled out by distributed-lag regression) checks the structure at system level. |
| Cascade prediction | Lagged propagation with feedback loops: hospital → EMS → hospital, diversion between hospitals, load transfer between substations. The timeline, cascade strip and graph show the stage-by-stage sequence, observed and forecast, numbered in propagation order. |
| Concurrent crises | analytics.js (ported from vizsh/72_hours_CASCADE with permission) groups stressed facilities into crises over the learned dependency graph: each gets an ID, hazard family, lifecycle stage (precursor, emerging, escalating, active, recovering), member systems and districts, the next facility forecast to go critical, and coupling or contention with other crises. Cascade-R compares the stress arriving through dependencies with the stress the hazard applies directly; above 1 the cascade is feeding itself. Both are computed now and as forecasts. The Crises pages show the registry, each crisis and its history; the twin draws their footprints (650 m around each member). Residents in a footprint come from the modeled population grid (population.js: each cell counts toward its nearest monitored facility within 1.5 km), the same model the twin's population layer uses. |
| Online learning under drift | A localized particle filter with forgetting (about a 23 h memory) and adaptive tempering keeps the effective sample size at or above 12%. Recursive estimators update every 30 minutes without retraining. "Trigger cascade" replays the streams from T+0 so you can watch this happen. |
| Uncertainty and adversity | Sensor trust comes from spread-normalized residuals and flatline detection. Suspect channels are quarantined, meaning their past evidence is forgotten quickly. In the tropical run the frozen gauge, offline camera and biased rain gauge are flagged with no false flags. Planted false citizen reports score 12–16% corroboration; genuine ones score 84–96%. |
Replay validation (24 h warning rule: P(critical within 24 h) ≥ 60%):
| City | Scenario | Brier | Skill vs climatology | Detection | False alarms | Median lead |
|---|---|---|---|---|---|---|
| Raleigh | Tropical remnant rainfall | 0.076 | +0.59 | 82% | 25% | 19.0 h |
| Raleigh | Convective flash flood | 0.070 | +0.63 | 77% | 5% | 16.5 h |
| Raleigh | Heat wave and grid stress | 0.019 | +0.81 | 77% | 0% | 23.0 h |
| Raleigh | Grid fault and telecom blackout | 0.017 | +0.77 | 88% | 11% | 16.5 h |
| Nagpur | Monsoon cloudburst · 23 Sep 2023 | 0.040 | +0.81 | 85% | 0% | 22.5 h |
| Nagpur | Immersion-day crowds and an evening storm | 0.021 | +0.40 | 33% (2 of 6) | 0% | 22.5 h |
| Nagpur | Tropical remnant rainfall | 0.060 | +0.74 | 96% | 13% | 20.5 h |
| Nagpur | Convective flash flood | 0.079 | +0.67 | 75% | 0% | 16.0 h |
| Nagpur | Heat wave and grid stress | 0.023 | +0.80 | 94% | 0% | 18.5 h |
| Nagpur | Grid fault and telecom blackout | 0.017 | +0.68 | 50% | 0% | 21.5 h |
In the Nagpur chlorine release no facility reaches CRITICAL in the ground truth, so there is nothing to detect and no skill score.
These numbers come from a synthetic ground truth generated by the same family of models. They show that the pipeline works end to end and is honestly isolated from future data. They are not evidence of real-world skill.
Two pretrained models sit beside the engine. Neither changes it: the engine's output is byte-identical with or without them.
A second opinion on every forecast: Chronos-Bolt (amazon/chronos-bolt-small, Apache-2.0). A
time-series foundation model pretrained on public data, used zero-shot: it has never been trained
on these cities. Offline, tools/ml/chronos_forecast.py gives it each facility's sensor stream as
observed up to every hourly issue time (with the planted noise, frozen gauges and dropouts, and
nothing after the issue time). It forecasts the next 24 h as nine quantiles. P(CRITICAL within h)
is the largest per-step probability of the stream reaching CRITICAL, read from those quantiles.
The results ship as src/js/data/chronos.js (250 KB, every scenario of both cities).
src/js/engine/second.js sets it beside the ensemble. It recomputes the ensemble's probability
exactly as engine.validation() does (second_probe.js checks the two agree in every run) and
scores both with the same code on the same cases. The Situation page shows where the two disagree
now, with the replay scores. The crisis page lists both probabilities for every member.
| Scenario | Brier, ensemble | Brier, Chronos | Warned in time (ens / Chronos) | False warnings (ens / Chronos) | Median lead (ens / Chronos) |
|---|---|---|---|---|---|
| Raleigh · tropical | 0.077 | 0.127 | 14 / 13 of 17 | 4 / 6 | 18.5 h / 1 h |
| Raleigh · flash flood | 0.071 | 0.143 | 17 / 12 of 22 | 1 / 6 | 15.5 h / 0.5 h |
| Raleigh · heat wave | 0.019 | 0.071 | 10 / 12 of 13 | 0 / 3 | 22.5 h / 1 h |
| Raleigh · grid fault | 0.017 | 0.053 | 7 / 2 of 8 | 1 / 3 | 16.5 h / 0 h |
| Nagpur · monsoon 2023 | 0.041 | 0.154 | 29 / 23 of 34 | 0 / 7 | 22 h / 0.5 h |
| Nagpur · tropical | 0.060 | 0.146 | 25 / 22 of 27 | 4 / 8 | 20.5 h / 1 h |
| Nagpur · flash flood | 0.079 | 0.161 | 24 / 14 of 32 | 0 / 2 | 15 h / 0 h |
| Nagpur · heat wave | 0.023 | 0.088 | 17 / 15 of 18 | 0 / 5 | 18 h / 0 h |
| Nagpur · grid fault | 0.017 | 0.039 | 4 / 6 of 8 | 0 / 5 | 21 h / 5 h |
| Nagpur · festival crowds | 0.022 | 0.040 | 2 / 6 of 6 | 0 / 17 | 22 h / 0.5 h |
Scored hourly from T+1 on every facility, for CRITICAL within 6, 12 and 24 h (8,700 cases on the Nagpur cloudburst). A warning is P(CRITICAL within 24 h) of 60% or more. In the chlorine release nothing reaches CRITICAL. The ensemble wins every run, and the lead times say why. Chronos sees only each facility's own stream, not the weather forecast or the dependency links, so it can follow a rise but not see one coming. Where it catches more events (heat, grid fault, crowds), it does so by warning often and late. Like the table above, these scores use simulated ground truth.
Search by meaning: all-MiniLM-L6-v2 (Xenova/all-MiniLM-L6-v2 through Transformers.js 3.0.2,
Apache-2.0, about 23 MB). The field at the top of the sidebar (/ to focus) embeds the query and
every page, facility, area, scenario and current crisis, then ranks them by cosine similarity. "Where
will the power go out" finds the substations and the grid-fault scenario; "chemical leak" finds the
chlorine release. The model downloads from Hugging Face on the first search and is cached by the
browser. Until then, or where it cannot load (offline, or the single-page build, whose
content-security policy only allows its own origin), results come from word overlap and say so
(src/js/site/search.js).
pip install chronos-forecasting # CPU is enough: all 11 runs take a few minutes
node tools/ml/export_streams.js # sensor streams → tools/ml/cache/ (git-ignored)
python tools/ml/chronos_forecast.py # → src/js/data/chronos.js
node tools/test/second_probe.js [--city nagpur] # exactness check and the scores above
index.html, config.js page shell and runtime configuration
src/css/ tokens, layout, panels, map chrome
src/js/core.js risk vocabulary, seeded RNG, geo helpers
src/js/engine/ scenarios, ensemble + assimilation + learning, interventions
(with decision deadlines), analytics (Cascade-R and the crisis
registry), population, comms (SITREP, CAP 1.2, SMS)
src/js/map/ basemap style, layers, hex markers, radar, renderer bootstrap
src/js/ui/ sidebar, inspector, timeline, drawers, sensor feed, app orchestrator
src/js/site/ engine access for every page (services.js), shared context in the URL
(store.js), the page router (router.js), the left sidebar and what
the site is (nav.js), page header, links and the SVG city map
(pages.js)
src/js/views/ pages: twin.js (Situation at #/ and City twin at #/twin, one app),
board.js (#/crises), crises.js (#/crises/<id>), plan.js (#/plan),
warnings.js (#/warnings), area.js (#/area), whatif.js (#/whatif)
src/js/ui/outlook.js Situation's outlook panel and its analytical panels
src/js/data/geodata*.js generated per city: facilities, routes, networks, population (from OSM)
data/tiles, data/fonts baked OpenMapTiles vector tiles and label glyphs
tools/ data pipeline (MVT decoder, spec, builders) and tests
python3 tools/fetch_tiles.py data/tiles # OpenFreeMap tiles for the extent (already committed)
python3 tools/build_data.py # decode tiles → src/js/data/geodata.js
python3 tools/build_data.py --city nagpur # → src/js/data/geodata_nagpur.js
python3 tools/enrich_buildings.py --city nagpur # building classes, heights, hero-site lifting
python3 tools/build_places.py # neighbourhoods, schools, colleges, pharmacies → src/js/data/places.js
tools/spec.py (Raleigh) and tools/spec_nagpur.py are the authored knowledge bases: which
facilities are monitored, which links engineers consider possible, the city's time zone and
overview camera, and the sensor faults planted in its streams. tools/mvt.py is a dependency-free vector-tile decoder.
build_data.py places gauges at exact creek × road crossings, routes links on the street and
waterway graphs, chunks the corridor and drainage networks, and computes the substation service
areas.
build_places.py reads the place and poi layers of the same tiles for My area: Nagpur has 88
named neighbourhoods and suburbs (plus the 30 monitored districts), 83 schools, 37 colleges and 45
pharmacies; Raleigh 35, 120, 26 and 22. They live apart from the geodata, so the engine never sees
them.
sh tools/test/regress.sh baseline/ check # every probe above, diffed against a stored baseline
node tools/test/engine_probe.js tropical # engine timeline, learning, validation
node tools/test/plan_probe.js --city nagpur # decision deadlines and the ghost-city delta
node tools/test/comms_probe.js --city nagpur # CAP, SMS segments and the situation report
node tools/test/interventions_probe.js # counterfactual planner
node tools/test/second_probe.js # Chronos-Bolt against the ensemble, same cases
node tools/test/analytics_probe.js [--city nagpur] # Cascade-R and the crisis registry per scenario
node tools/test/smoke.js http://localhost:8000/ out/ # headless browser run of the twin (Playwright)
node tools/test/routes.js http://localhost:8000/ # pages, deep links, back/forward, cities, labels
node tools/test/phone.js http://localhost:8000/ out/ # phone width: twin, drawer, overview, crises
node tools/test/heroes.js http://localhost:8000/ out/ # each hero model, plus dawn/noon/dusk/night
node tools/test/shot.js http://localhost:8000/ out/ '[{"time":37},{"shot":"noon"}]' # scripted views
node tools/test/perf.js http://localhost:8000/ gpu # frame times downtown
python3 tools/test/csp_server.py 8766 # serve dist/ under a strict CSP
The browser tests launch Chromium on SwiftShader (software GL), where a frame of the city takes
close to a second; interactions.js can time out on its phone step there, with or without the
city-building renderer. On a machine with a GPU, drop the SwiftShader flags. On Windows,
python -m http.server occasionally refuses one of the page's parallel script requests (its
listen backlog is 5), which leaves the page on its loading screen; reload or use another server.
The twin tests (smoke, interactions, phone, heroes, perf, shot) are written against Raleigh's
facilities and open #/twin?city=raleigh when the URL has no hash. In Git Bash, set MSYS_NO_PATHCONV=1 before
passing a URL that contains #/…, or the shell rewrites it as a Windows path.
Map data © OpenStreetMap contributors (ODbL) · tiles © OpenMapTiles, served by OpenFreeMap · rendering by MapLibre GL JS (BSD-3) and three.js (MIT) · earcut (ISC) · textures by Poly Haven (CC0) · Chronos-Bolt by Amazon (Apache-2.0) · all-MiniLM-L6-v2 by sentence-transformers (Apache-2.0), run with Transformers.js by Hugging Face (Apache-2.0).
| Warnings | #/warnings | A plain-text situation report, an OASIS CAP 1.2 alert per crisis with one info block per city language, and the public cell-broadcast text as a handset receives it, with its GSM-7 / UCS-2 encoding and segment count. Everything is marked EXERCISE. |
| What-if | #/whatif | Pick a place, an event (heavy rain, earthquake, hospital outbreak, heat wave, toxic gas release, grid failure, crowd surge) and its size; the page draws the chain of effects as a knowledge graph, stage by stage, with each effect's typical onset, likelihood, causes, what helps, and the real facilities, schools and pharmacies nearest the place. Built from a fixed knowledge base (src/js/engine/whatif.js) scaled by severity bands (IMD rainfall and heat-wave categories, USGS magnitude classes; the rest are the tool's own); template reasoning, not an engine forecast. It links to the engine's full scenario where one exists. |
| My area | #/area | The forecast for one neighbourhood, phone-first. Search 120+ neighbourhood names or use the phone's location. You get a plain verdict with the rain now against the rain coming; how it reaches you (the hazard → drains → roads → power → phones → ambulance → hospital chain for the facilities that serve you, each with its time, likelihood and the learned link that carries it); nearby schools, colleges and pharmacies with whether their access is forecast to be cut; what to do and by when in the city's languages, with a message to share; today's real weather from Open-Meteo; the next 36 h per system; and roads to avoid. |
| Causal explainability | Every risk value decomposes into baseline, hazard and each upstream link (posterior weight ± sd, lag, mechanism, upstream sensor reading and trust). The strongest chain back to the hazard is shown, e.g. Rainfall → Pigeon House Branch → Capital Blvd → EMS Station 2 → WakeMed. |
| Constrained counterfactuals | 7 actions with crew costs and side effects (an evacuation loads I-440; a detour loads Wake Forest Rd). They are re-simulated from the decision time on the most probable members, and a greedy planner chooses within the budget. At T+34.5 h with 5 crews it picks pumps, EMS staging and an early Capital Blvd closure: −13% critical facility-hours, −30% hospital/EMS critical hours. |
| Generalization | Seven scenarios across two cities run through the same engine without retuning: tropical rainfall, a convective flash flood, a heat wave with a derecho and a grid fault with a telecom blackout in either city, and in Nagpur a monsoon cloudburst reconstruction, a chlorine release (Gaussian plume) and immersion-day crowds. The learned structure changes with them. |
| Temporal validation | Historical mode replays the window. Every forecast uses only data up to its time stamp and is scored against the hidden truth. |