Merge branch 'main' into fix/e-route-distance-ten-km

This commit is contained in:
Sameh Khamis committed 2026-11-01 22:22:22 -08:00
commit 941a7a392e
779 files changed
+69864 -21453

No files matched your search

@@ -0,0 +1,4 @@
- Director clock listeners, interaction observers and scene release failures
no longer leave the director inconsistent: each scene is released once, and
a phase error is kept (with the release failure logged) when cleanup also
fails (deepeshbind, #1014).
+4
View File
@@ -0,0 +1,4 @@
- FIRMS fire data loads on hosts where IPv6 is unreachable and IPv4 is slow to
connect: a request whose every address fails to connect retries once over
IPv4, and FIRMS warnings name the underlying connection errors instead of
only `fetch failed` (jeffblakely, #1078).
@@ -0,0 +1,5 @@
- Keep Directions route errors, the Local ADS-B receiver error and Global
Context cohort reasons English in layer data; the Layers panel, Radio card
and awareness panel still show them in the interface language. The route
proxy's "routing busy" and "route proxy error" refusals are now translated
too (daikaginza, #1209).
@@ -0,0 +1,4 @@
- Pause the HUD's camera readout while the page is hidden, as polled layers
already do. An app embedded inline in a panel keeps both updating, because the
panel's host can report the page as hidden while it is on screen (nu-stats,
#1344).
@@ -0,0 +1,4 @@
- Restore a shot's declared layer visibility when seeking within it after manual
layer changes, including toggles still in flight. Only changed layers are
reconciled; refused restoration reports a failed seek and keeps the last
position, while undeclared operator layers are preserved (@oneill9, #1374).
+2
View File
@@ -0,0 +1,2 @@
- A "place, region" search such as "Paris, Texas" now lands on the place in
that region instead of a namesake elsewhere (quanticsoul4772, #1401).
+5
View File
@@ -0,0 +1,5 @@
- The terrain proxy stops asking the upstream for a while after a 429
(its Retry-After, at most 10 minutes, or 60 s) instead of retrying on every
page request, and a Retry-After longer than its 10 s retry budget now ends
the retries at once instead of sleeping the budget out (quanticsoul4772,
#1402).
+3
View File
@@ -0,0 +1,3 @@
- Fire Perimeters and `get_fire_perimeters` say when WFIGS is unreachable and
the last snapshot is being shown (STALE, its age, "data may be stale"), and
that snapshot is served for at most 24 hours (quanticsoul4772, #1404).
+3
View File
@@ -0,0 +1,3 @@
- The Traffic layer reads STALE instead of LIVE when the TomTom proxy serves
cached flow tiles (budget spent or TomTom failing), and the row dates them by
the oldest cached tile (quanticsoul4772, #1405).
+3
View File
@@ -0,0 +1,3 @@
- Show a vessel course of 359.5° or more as 0°. Vessel cards and the AIS HUD
rounded the course without wrapping, so a ship with no reported heading on
a 359.7° course read "360°" and "HDG: 360DEG" (Aditya, @Rohilalala, #1432).
+3
View File
@@ -0,0 +1,3 @@
- Show a CCTV camera facing 359.5° or more as HDG 0°. The HUD heading token
and the camera panel rounded the bearing without wrapping, so a camera
facing 359.6° read "HDG 360°" (Aditya, @Rohilalala, #1441).
+3
View File
@@ -0,0 +1,3 @@
- Show a drawn area of 9,999.5 m² or more as 1.0 ha, and of 999,500 m² or
more as 1.00 km². The draw hint picked the unit before rounding, so it read
"10000 m²" and "100.0 ha" (Aditya, @Rohilalala, #1446).
+2
View File
@@ -0,0 +1,2 @@
- Show an ALPR camera's mapped bearing of 359.5° or more as DIRECTION 0°
rather than DIRECTION 360° (Aditya, @Rohilalala, #1451).
@@ -0,0 +1,3 @@
- Show a transit vehicle's reported bearing of 359.5° or more as 0°. The
selected-vehicle card rounded it without wrapping, so a bus heading 359.6°
read "reported hdg 360°" (Aditya, @Rohilalala, #1452).
@@ -0,0 +1,5 @@
- Describe a selected flight or military contact on 359.5° or more to the
voice assistant as heading 0°, not 360° (Aditya, @Rohilalala, #1454).
- Heading and bearing readouts share one rounding helper, so the Cockpit's
TRACK ACQUIRED course no longer reads 360°, and a negative bearing wraps
instead of printing a minus sign (#1454).
+5
View File
@@ -0,0 +1,5 @@
- Cut the Google requests the HUD's AI summary makes on its own. It no longer
looks up place names when no OpenAI key is configured, reverse-geocodes at
most two points instead of up to four, and looks up again only once the view
shows a different area, not after every small pan, so a small pan no longer
asks OpenAI for a new summary either (samehkhamis, #0000).
+4
View File
@@ -0,0 +1,4 @@
- Update the development tools to Vite 6.4.4 and Puppeteer 25.16.0, which
clears the open npm advisories for the dev server and the browser test
tooling, and remove the unused local screenshot helper `scripts/shot-sink.mjs`
(samehkhamis, #1463).
@@ -0,0 +1,5 @@
- Give the side panels one look. Every panel title now uses the command dock's
label type in a brighter colour; a panel's edge and title light up on hover,
as the dock's trays do; and in the default theme each collapse button sits
19px from its panel's edge (plus the scrollbar's width in an open, scrolling
panel where the system always shows scrollbars) (asturksever, #1466).
@@ -0,0 +1,3 @@
- Remove the Operator HUD layout. Display > HUD > Layout and the HUD voice
action now offer Tactical, Minimal and Cyber; share links, scenes and saved
views that name Operator open in Tactical (asturksever, #1467).
+4
View File
@@ -0,0 +1,4 @@
- Remove the Snow visual preset. Visual Presets, keyboard shortcuts, the
Cockpit vision carousel and the visual-style voice action now offer Normal,
CRT, NVG, FLIR, Anime and Noir; share links and scene shots that name Snow
open on Normal (asturksever, #1468).
+3
View File
@@ -0,0 +1,3 @@
- Add Ukrainian (uk) to the language picker: the whole interface in Ukrainian,
with its four plural forms and Cyrillic HUD units. Based on the Ukrainian
translation by @meirm (#312) (German, @gekh, #1470).
@@ -0,0 +1,7 @@
- Remove the Radio icon from the Context panel header, along with the compact
Radio player it opened; Radio stays in Context as its own section, and
Cockpit's compact Radio is unchanged. Context is also easier to read: the
Contacts / Space Missions modes are one segmented control, labels and
guidance are larger and higher contrast, the standby hint is plain text
instead of a dashed box, and the panel draws no glow halo. Cyber keeps its
own framed buttons and red titles (asturksever, #1471).
+4
View File
@@ -0,0 +1,4 @@
- Rename the Scenes panel to Authoring and lay it out in steps (Scene, Shots,
Preview, Save & share) with larger, higher-contrast text, numbered shots, a
tooltip on every action and buttons that are disabled when they would do
nothing (asturksever, #1472).
+3
View File
@@ -0,0 +1,3 @@
- Add Italian (it) to the language picker: the whole interface in Italian,
with Italian plural forms and labels shortened to fit the panels. Based on
the translation by @abiyeenzo (#912) (German, @gekh, #1473).
+4
View File
@@ -0,0 +1,4 @@
- Add Brazilian Portuguese (pt) to the language picker, with every screen
translated and Portuguese plural forms. The CCTV summary line now names its
calibration, source and view in the page language. Based on translations by
@abiyeenzo (#909) (German, @gekh, #1475).
+4
View File
@@ -0,0 +1,4 @@
- Add French (fr) to the language picker, with French typography and plural
forms. With nine languages the picker now shows its search field. Based on
the translation by @abiyeenzo (#907), checked against @meirm's French
catalog (#312) (German, @gekh, #1476).
+3
View File
@@ -0,0 +1,3 @@
- Add German (de) to the language picker, with a full translation of the
interface and a German style guide in docs/translations/de.md. Based on
translations by @abiyeenzo (#908) (German, @gekh, #1477).
+4
View File
@@ -0,0 +1,4 @@
- Add Japanese (ja) to the language picker, with year-first dates, Japanese
counters, unit words joined to their numbers (5分前, 1時間5分) and CJK label
rules for Japanese text. Based on translations by @abiyeenzo (#913)
(German, @gekh, #1478).
+5
View File
@@ -0,0 +1,5 @@
- Add Arabic (ar), the first right-to-left language: the title, rails, dock and
corner row mirror, numbers keep Western digits, and plurals use all six
Arabic forms. FIRMS cards and Space Missions landing labels are now
translated in every language. Based on translations by @abiyeenzo (#915)
(German, @gekh, #1479).
+4
View File
@@ -0,0 +1,4 @@
- Draw only the CCTV cameras in view, and thin them to one per ground cell when
zoomed out. Dragging the globe with the default 4,000-camera catalog no
longer stalls, and the camera picker lists the cameras in view with a count
of the ones outside it (samehkhamis, #1485).
+3
View File
@@ -0,0 +1,3 @@
- Let a GNSS integrity source set the layer's evidence window (`windowMs`). A
missing or invalid value keeps the 30-minute default, and the layer row now
names the window in use instead of a fixed "30 min" (samehkhamis, #1491).
@@ -0,0 +1,4 @@
- Let a weather source describe its own products through an optional
`display` object in each manifest (source, credit, units, coverage, info,
legend and extent). Each valid field replaces the built-in value, and
manifests without it render as before (samehkhamis, #1494).
+205
View File
@@ -0,0 +1,205 @@
- The language picker switches language in place instead of reloading the
page. Views re-render; code that publishes translated text words it again
through `onLocaleChange` (`src/i18n/index.js`), and `<html lang>`/`dir` and
the page's `data-i18n` markup follow. `persistLocale` replaces
`persistLocaleAndReload`, and `registerUnsavedWork` and the switch's
unsaved-work prompt are removed, since a switch no longer loses anything
(samehkhamis, #1499).
- A map source's `unavailableReason` may be a function, read when the reason
is shown so it follows the locale; the sources from `createDefaultMapSources`
(`./maps/defaults`) give functions. `MapSourceController` reads either form
(samehkhamis, #1499).
- The application views translate their text with `t()` as they render,
so it follows the active locale; they no longer carry `data-i18n*`
attributes, and `npm run i18n` rejects those in a Vue template. The boot
pass (`applyDocumentTranslations`) still translates static page markup
such as the loading screen and a host's own markup (samehkhamis, #1499).
- The page's locale lives in a vue-i18n instance installed in every
application view, and `t()`, `tn()` and the Intl formatters read it from
there, so a view that translates while rendering renders again when the
locale changes. `bindLocale` (`src/i18n/index.js`) keeps the locale in a
given ref; Core's Vite config builds vue-i18n without its message
compiler. Catalogs, messages and call sites are unchanged
(samehkhamis, #1499).
- Cockpit's Display popover shows the Display panel's own HUD, Detection,
Parameters and 3D groups through Vue teleports: `CockpitDisplayPortal`
publishes the popover's slots (`publish`, with `afterRender` to lay out once
they have moved) instead of moving the groups itself (samehkhamis, #1499).
- The Cockpit utility strip's measured layout renders from the `gev-cockpit`
store: the layout pass publishes `utilityLayout` (the HUD's
`--cockpit-utility-*` lengths, `primaryOnly` and `hideCollapsed`), and a host
constructing `CockpitController` passes `publish.utilityLayout` beside its
other publishers (samehkhamis, #1499).
- The Cockpit Contact and briefing cards' collapse renders from the
`gev-cockpit` store: the controller publishes `contextCollapsed` and
`signalCollapsed` in its presence, and each card's `data-collapsed` and its
toggle's state, words and icon follow it (samehkhamis, #1499).
- The panels' own state classes (`collapsed`, `dock-pinned`, `dock-pinned-top`,
`layout-auto-collapsed`, `accordion-collapsed`) render from the
`gev-panel-chrome` store: the shell, the rails and the accordion present each
panel's state there instead of writing its classes. `layoutLeftPanelRail` and
`layoutRightPanelRail` (`./ui/layout`) now call
`onCollapse(panel, {collapsed, auto})` and leave drawing it to the host.
Without a shell to own the panels, the voice tools' `set_panel_open` now
reports that there is no panel to open instead of writing its classes
(samehkhamis, #1499).
- The shell's panel chrome no longer writes the panels' collapse buttons, the
dock tray toggles' names or the dock pins' pressed state: it presents each
panel's open and pinned state to the `gev-panel-chrome` store, and the
buttons, now views, call it there. `bindPanelDisclosure` (`./ui/panels`) binds
only a panel's Escape; it no longer takes `buttons` or `onChange`. `UiButton`
joins the component kit (samehkhamis, #1499).
- `SceneControls` (`./ui/scenes`) no longer takes `elements` or writes the Scene
panel's buttons, status, progress or runtime chip: it presents them to the
`gev-scenes` store and the panel's buttons call its actions there.
`sceneElements`, `presentSceneButtons`, `presentSceneProgress` and
`presentSceneRuntime` give way to `sceneButtonsDisabled` and `scenePercent`.
It no longer stands down when the page has no Scene panel: ESC still stops a
playing scene and the runtime chip still shows (samehkhamis, #1499).
- `initFirstRunExperience` (via `./application/chrome`) no longer writes the
launcher's classes, attributes or text, or removes the card: it presents them
to the welcome view's `gev-first-run` store (its new `store` option) and
connects the controls the view's buttons call (samehkhamis, #1499).
- `IntelHUD` (`./ui/hud`) no longer builds or writes `#intel-hud`: it hands its
readouts, visibility, layout variant and style colors to its `publish` option,
and Core's `intel-hud` view renders them. A page places that view with
`<div class="gev-view" data-gev-view="intel-hud">` instead of a bare
`#intel-hud` element. `./layers/vessels` shows the selected vessel's HUD
readout through `services.readouts.presentSelectedVessel()` instead of writing
`#hud-ais-vessel`; the application passes `src/hudReadouts.js`, which IntelHUD
follows (samehkhamis, #1499).
- `LocationControls` (`./ui/location`) no longer builds the city and landmark
pills or writes the mini status: it presents the tray, including the search
error (`setSearchError()`), and hands it to its `publish` option, and Core's
dock renders it and calls `chooseCity()` and `choosePoi()`. Its `elements` are
now only `search`: `resetButtons` and `searchToggle` are gone, and the reset
buttons and the search toggle call its new `reset()` and `toggleSearch()`. It
presents the search field's open and searching state too (`searchExpanded`,
`searching`; a `searchExpanded` option starts it open), set through
`setSearching()`, `settleSearch()` and `closeSearch()`, and a host renders the
field's `expanded` and `searching` classes from it; `LocationSearch` takes a
`setSearching` option in place of writing the field's class, and
`NavigationController` a `settleSearch` option in place of `searchInput`.
`createOrbitIndicator()` is replaced by `showOrbit(active)`, which adds the
ORBIT indicator to the presented tray as `orbit: { active }` (null until
offered) (samehkhamis, #1499).
- `createMapSourceControls()` (`./ui/maps`) no longer renders the map source
chips into a `container` or writes a `statusElement`: it presents the chip row
and status badge and hands them to its `publish` option, and Core's dock
renders them and calls `select()`. `renderMapStackChips`, `syncMapStackChips`
and `MAP_STACK_CHIP_CLASS` are removed (samehkhamis, #1499).
- `./layers/launches` no longer writes the Space Missions roster or the selected
mission panel into `#space-mission-panel-host`: the layer publishes both
through `subscribePanel(listener)` and Core's Space Missions views render
them, calling the layer's panel commands (`selectMissionAt`,
`selectPreviousMission`, `selectNextMission`, `deselectMission`,
`focusSelectedLaunchSite`, `startSelectedReplay`, `toggleReplayPause`,
`cancelReplay`, `setReplaySpeed` and the `roster*` preview inputs). The
`bindMissionRosterItemKeyboardPreview`, `captureMissionRosterFocus` and
`restoreMissionRosterFocus` helpers are gone; the roster keeps focus itself
(samehkhamis, #1499).
- `./layers/awareness` no longer writes the Contacts panel into
`#military-awareness-panel`: the layer publishes a plain panel view through
`subscribePanel(listener)` and Core's Contacts view renders it, calling the
layer's `navigatePrevious`, `focusCurrent`, `navigateNext` and `focusTarget`.
The `awarenessPanelControlKey`, `captureAwarenessPanelFocus` and
`restoreAwarenessPanelFocus` helpers are gone; the view keeps focus itself
(samehkhamis, #1499).
- `./ui/cctv` and `./ui/radio` import Vue and Pinia: their controllers publish
the panel's state to a store that the CCTV and Radio views render, instead of
writing the panel's markup themselves (samehkhamis, #1499).
- `./ui/display`'s `bindDisplayControls` is gone: the Display panel's controls
and the dock's style buttons call their owner through the display store's
`connect`/`act`, and its allocation and 3D model choices are the kit's
`UiSegmented`. `initDrawTool` takes `connect(actions)`, which returns their
disconnect, and no longer listens on the Draw controls; its view publishes
`color` and `label` too, and the shape choice is a `UiSegmented`.
`initGeoFileImport` takes `connect(actions)` the same way and no longer
listens on the Import button, picker or list, nor restores focus itself: the
`GeoImport` view does both, and its `publish` need not settle once the list
renders. Street Level's fit and panorama filters and Recent Imagery's mode are
`UiSegmented` too: the Street Level store's owner answers `setPano` and
`setRenderMode`, and `RecentImageryReadout` takes `onSetMode`. The Radio
panel's and Cockpit's internet radio controls and the tuner slider's events
call `RadioControls`, and the local RTL-SDR card's controls
`LocalSdrControls`, through the radio store's new `connect`/`act`; the card
labels its gain options itself. `act` returns what the answering action
returned. The Display, Radio, RTL-SDR, Cockpit, mission replay, style
parameter, rail card, observation timeline, imagery opacity, Street Level date
and Bhote Koshi sliders are the kit's `UiSlider`, a native range input that
emits numbers, and the pressed toggles are the kit's `UiButton`, which gains
`pressedClass`; so are the rail card chips, map source chips and location
pills (which now report `aria-pressed`), and the voice card's chips are the
kit's new `UiChip`. The selects are the kit's new `UiSelect`, the status
badges its new `UiBadge` and the one-line empty states its new `UiEmpty`. The
top-center clear, share, tilt, north-up and reset buttons, and the cockpit's
reset, call the shell through the new globe actions store, which also carries
the camera's tilt and compass heading. The recording safe frame renders what
`RecordingControls` publishes to the new recording store. `syncScopeControls`
(`./ui/display`), `shouldHideCollapsedRightPanels` (`./ui/layout`),
`bindClearLayersControl` (`./ui/layers`) and `createStyleParameters`
(`./ui/input`; the Display panel renders the style parameters VisualSettings
publishes to the display store) are deprecated: the Display view, the rail and
the globe actions view now own what they did. `./ui/input` imports Vue
(samehkhamis, #1499).
- `./scenes` presents the scene sharing dialogs and the EDIT DETAILS / SHARE
SCENE bar through a store that the scene panels view renders, so a page that
omits `layer-panels` shows neither (samehkhamis, #1499).
- `./voice/control`'s `createVoiceControl({ panel })` returns the voice
control's presenter instead of element handles: owners write it by part
(`update('detail', { text })`) and listen with `on('button', fn)`, and the
command dock renders it from a store. `createVoiceCommands`' `createControl`
and `VoiceCardControls` (`{ ui }` instead of `{ root }`) take the same
presenter; the `reset` option is gone, since a newer control replaces the
previous one (samehkhamis, #1499).
- Pages place each view with a `<div class="gev-view" data-gev-view="NAME">`
host and write their own loading screen; the `build/html` template expansion
and its `gev:template` markers are gone. `createApplication` takes `omitViews`
(for example `['provider-settings']`) for views an application leaves out
(samehkhamis, #1499).
- The page's panels, dock, cockpit and dialogs are Vue views with the same
markup as before. Hosts that do not initialize Core's locale pass
`localePicker: false` to `createApplicationControls` to drop the language
picker, and Node tests that import application modules register the component
loader with `--import=<core>/build/register-vue` (samehkhamis, #1499).
- The Data, Authoring, Weather, Recent Imagery, Context, CCTV, Street Level and
Radio panels are one component, `UiPanel` (`src/ui/kit/`), with the same
markup plus the kit's `ui-panel` classes, their titles translated by `t()`
rather than `data-i18n`; `RailPanel` binds it to the panel chrome store.
`PanelCollapseButton` drops its `initial` and `initialTitle` props and takes
`startCollapsed`, so before startup presents a panel its button already shows
that state's glyph, words and `aria-expanded` (samehkhamis, #1499).
- The Authoring, shot list and CCTV buttons and Street Level's nearest button
are the kit's `UiButton` (danger buttons in the `alert` tone, primary ones the
`primary` variant), keeping their classes; the CCTV on/off, coverage,
auto-hop, projection and adjust toggles now say their state with
`aria-pressed` (samehkhamis, #1499).
- Each desktop sidebar has an icon rail that lists every panel on that side and
opens one with a click. One panel is open per side in every HUD layout, so the
collapsed panel headers no longer take up the sidebars. Phones keep the bottom
tab bar. The rail is the first view built with Vue and Pinia, which now ship
with the app; see docs/VUE-MIGRATION.md (samehkhamis, #1499).
+4
View File
@@ -0,0 +1,4 @@
- `build/register-vue` loads components on the test thread and keeps compiled
components between test processes in a per-user cache directory, so Node
tests that import views run about twice as fast. `GEV_VUE_CACHE=0` compiles
every time (samehkhamis, #1500).
+7
View File
@@ -0,0 +1,7 @@
- Let the scene idle with AIS vessels enabled. Vessels no longer hold the
continuous render loop; they request frames for new data and selection, one
trailing frame after the camera stops, and hold the loop only while focus
emphasis animates or a vessel stays dimmed under a tracked target. A parked
vessels-only scene went from continuous rendering to 0 frames in 5 s. While
anything is tracked, the vessel focus pass skips hidden sprites at rest:
about 4 ms to 1.2 ms per pass over 12,000 vessels (waar19, #871).
+8
View File
@@ -0,0 +1,8 @@
- Add the Autostrada del Brennero (A22, Brenner–Modena) motorway webcams as a
CCTV pack, the first Italian cameras. The 13-camera list is one keyless
request to the Open Data Hub (NOI Techpark) tourism API, which republishes
Autobrennero's own list with coordinates; frames are the operator's stills,
refreshed about once a minute and pinned to each camera's own `km<N>.jpg`.
Each camera's ground elevation comes from a per-kilometre DEM table, since
the road climbs from the Po valley to the Brenner Pass. `CCTV_A22_ENABLED=0`
disables the pack (Jibran Tahir, @jibraaan, #956). Closes #155.