Commit Graph
664 Commits
Author SHA1 Message Date
manjunath 578ebdc030 merge main f13c60c into feat/voice-outlines
reconcile voice outlines with main f13c60c, retaining German/Japanese,
Operator HUD retirement and Context/Radio cleanup, named-building
containment, courtyard-hole, non-Latin identity, attribution, cancellation
and antimeridian repairs

keep outline callouts above the open voice preview when an above-panel
slot fits without colliding with another callout,
and clip the compact dock location label on narrow screens
2026-10-30 19:02:47 +05:30
German Khokhlov 5ed86200e5 Bring back the tuner-release and connecting-label Radio fixes
Restore the two fixes the previous commit moved out:

- A tuner release onto a station the directory dropped mid-drag stops the
  stream the drag paused, publishing one state with the gesture's origin,
  so the button reads PLAY and a voice handoff is cancelled.
- The transport buttons offer Pause while a stream connects, matching
  what a click does.

Their tests now use the shared Radio layer harness.
2026-10-30 16:44:15 +04:00
German Khokhlov a55450e2e7 Trim the Radio Next/Previous change to the HAL-722 scope
- Selections take the playback fallback as a `playFallback` option and
  set it after releasing a stale stream, instead of callers arming state
  that the release then had to save and restore.
- Move the tuner `station-unavailable` release and the Pause label while
  a stream connects out of this branch: both were wrong on main already
  and go in a separate change.
- Share the Radio layer test setup in src/testSupport/radioLayerHarness.mjs
  and fold overlapping Next/Previous tests (13 to 7).
- One-line comments and a two-line changelog entry.
2026-10-30 16:37:36 +04:00
German Khokhlov fa840ae3c3 Translate the Radio privacy note into the new locales
main added de, fr, it, ja and pt with the old "after you press play"
note; give them the updated wording. main also removed the compact
Context Radio player, so the Next/Previous tests stop checking its
button.
2026-10-30 14:26:58 +04:00
German Khokhlov a7c16a701c Merge remote-tracking branch 'origin/main' into fix/hal-722-radio-next-no-autoplay 2026-10-30 14:23:09 +04:00
German Khokhlov 4dd5a313b3 Keep Radio playback state consistent after a silent Next
Review follow-ups for HAL-722. A Next or Previous that only selects a
station now leaves nothing of the previous stream behind:

- Selecting another station without playing stops a paused or failed
  stream, so the panel, Stop, voice summaries and the audio element agree
  on "stopped". A fallback the caller armed for the new selection is kept.
- A silent UI step arms no broadcaster fallback, and a user Play of the
  selected station drops one left by a cancelled voice step. Voice steps
  pass `fallback: true` because voice starts the prepared playback later.
- A user step to another station emits a `select` playback control, and
  the realtime voice handoff treats it like Pause and Stop.
- A tuner release onto a station the directory no longer has stops the
  stream the drag paused, publishing one state with the gesture's origin,
  so the button reads PLAY and a voice handoff is cancelled.
- The transport buttons offer Pause while a stream connects, matching
  what a click does.
- The privacy note names every action that connects to a broadcaster
  (play, finishing tuning, choosing a station on the globe) in all
  locales.

The Next/Previous layer tests live in src/data/radioNextState.test.mjs.
2026-10-30 13:44:48 +04:00
German Khokhlov f967218a04 fix(hud): lead with the state tag, keep feedState in get_hud_caption
Review fixes for the HUD summary language change:

- The translated feed-state tag now leads the one-line summary and the
  fallback line, so the readout's ellipsis cannot hide it.
- get_hud_caption checks the reply's feedState, returns it and appends the
  state tag; a reply naming another state keeps only the place.
- The model gets the layer names the user sees (localizeLayerName).
- Japanese and Chinese summaries are capped at 20 characters; pt, zh-CN and
  zh-Hant get explicit language names.
- A partial view is narrated as incomplete coverage, not as not live.
- provenanceTag and hudSummaryMatchesProvenance move to layerSnapshot.js so
  the tools package can use them without browser globals.
- docs/CURRENT-STATE.md, changelog and comments updated; redundant tests
  trimmed.
2026-10-30 13:06:53 +04:00
German Khokhlov 563df3bad9 fix(hud): AI summary in the UI language, canonical feed state, partial aggregation
The HUD sends its locale with the summary context; the proxy names that
language in the instructions and the input, English when missing or
unsupported. The model returns {summary, feedState}; the HUD shows the
summary only when feedState matches its own state for a view that is not
nominal, and appends its own translated state tag.

partial joins the shared feed-state table between fallback and nominal,
so one partial layer no longer reads off and partial plus nominal no
longer reads nominal.
2026-10-30 12:37:43 +04:00
Matt Van Horn 4a74420e7b Merge remote-tracking branch 'upstream/main' into fix/drone-airspace
# Conflicts:
#	src/i18n/locales/uk.json
2026-10-30 00:14:42 -07:00
Sameh Khamis 93942d0dbe Show only the CCTV cameras in view, thinned to one per ground cell when zoomed out
The CCTV layer kept every loaded camera live: each view change touched every
icon, every notification rebuilt every camera's state, and the picker listed
the whole catalog. With the default 4,000 cameras, a continental drag ran at
152-179 fps with 18-24 frames over 30 ms (worst 112 ms). It now runs at
235 fps with none. The layer now:

- shows icons only on or near the screen, and when zoomed out keeps one camera
  per world-anchored cell (healthy feeds first), so panning keeps the same
  cameras;
- grounds and draws coverage only for the cameras in view, the active camera
  and its coverage neighbours, retrying a camera at most twice per view regime;
- reruns the view pass while the camera moves, paced by its own cost, and
  projects with one matrix per pass instead of a Cesium call per camera;
- keeps the billboard buffer-usage hint fixed, so showing or hiding a few
  icons no longer rewrites the vertex data of every billboard;
- lists the cameras in view (active camera first) in the picker, closing with
  the count of cameras outside the view, and builds the full camera list in
  the UI state only when it is read.
2026-10-29 21:31:59 -07:00
German Khokhlov 188a6086b8 Merge remote-tracking branch 'origin/main' into german/hal-644-ar
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/hudLocalityFormat.js
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/layers/cctv/presentation.js
#	src/scenes/recipes.js
#	src/ui/localePicker.test.mjs
#	src/ui/unitLabels.js
2026-10-29 20:05:03 +04:00
German Khokhlov 812308d0ee Merge remote-tracking branch 'origin/main' into german/hal-642-ja
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/layers/cctv/presentation.js
#	src/ui/localePicker.test.mjs
2026-10-29 19:47:54 +04:00
German Khokhlov 56ca340258 i18n: keep Upper Trishuli as a place name; drop duplicate cyclone keys 2026-10-29 19:36:02 +04:00
German Khokhlov a092933ad6 Merge remote-tracking branch 'origin/main' into german/hal-639-de
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/layers/cyclones/source.js
#	src/scenes/recipes.js
#	src/scenes/sceneTitleDisplay.test.mjs
#	src/ui/localePicker.test.mjs
2026-10-29 19:00:19 +04:00
Matt Van Horn f01393c41d Merge remote-tracking branch 'upstream/main' into fix/drone-airspace
# Conflicts:
#	src/i18n/locales/es.json
#	src/i18n/locales/ru.json
#	src/i18n/locales/zh-CN.json
2026-10-29 06:19:47 -07:00
Said Turksever 39a60b4034 Remove the Snow visual preset
Snow is no longer offered anywhere a style can be chosen: the Visual
Presets tray, keyboard shortcut 7, the Cockpit vision carousel, and the
set_visual_style voice action. The shader and its labels go with it;
weather snowfall and the SNOW weather condition are unaffected.

Share links keep working. Snow's enum code (6) stays reserved, so a
compact or long-form link that names it opens on Normal and drops the
Snow shader parameters without reporting them as unknown. A Scene
Director shot saved with Snow plays on Normal too. Snow's frozen share
defaults matched Normal's apart from those parameters, so no other
setting in an old link changes meaning.

The legacy voice-schema pins restore Snow before hashing, so the
unchanged pins still prove nothing else moved; the complete Realtime
payload digest is re-derived.
2026-10-29 11:20:49 +00:00
German KhokhlovandClaude Opus 5.5 04481ef202 i18n(ar): address code review findings
Mirror the dock trays and their pin, the compact Radio window and the
phone top-bar actions in right-to-left; keep the Cyber cockpit's Data
Layers stack on the left edge. Isolate the Space Missions counter,
landing coordinates and CCTV summary parts, format their numbers with
the locale's numerals, decide pack shot titles by the marker binding,
and place Bhote Koshi media cards between the panels on either side.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 15:20:47 +04:00
German KhokhlovandClaude Opus 5.5 8f8e6776bc Merge remote-tracking branch 'origin/main' into german/hal-644-ar
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:24:27 +04:00
German KhokhlovandClaude Opus 5.5 2f12cbf5c8 Merge remote-tracking branch 'origin/main' into german/hal-639-de
Conflicts in es, ru, zh-CN and zh-Hant catalogs: both sides appended keys
at the end (cyclone errors from this branch, routing refusals from main);
kept both.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:12:08 +04:00
German KhokhlovandClaude Opus 5.5 c493eb0126 Merge remote-tracking branch 'origin/main' into german/hal-642-ja
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:11:56 +04:00
quanticsoul4772andClaude Opus 5.5 692e99729c Merge branch 'main' into upstream/terrain-partial-heights
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 19:58:22 -07:00
Said Turksever 1c0a30adaf Merge branch 'main' into perf/vessels-idle-render 2026-10-29 01:18:39 +00:00
German KhokhlovandClaude Opus 5.5 8540535817 i18n(ar): apply review round 2
Catalog: refresh/updates wording, received SDR aircraft, playing states,
move-start button, impersonal layer note, live-data descriptions,
arrival steps, retry timing, tracking spelling, military chip, dollar
amounts, label: value statuses, upstream source, globe map, stage
recovery, comparison signs as words, ellipses and earlier round-2 fixes.

Code: FIRMS cell cards use the plural entry for their count (FIRES
pruned), translated locator pin titles are isolated in RTL, legend
stops keep their sign, voice timeout minutes agree with the number,
CCTV badges are translated, first-run and referenced-item alignment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 22:55:24 +04:00
German KhokhlovandClaude Opus 5.5 bceeb37836 i18n(de): apply review round 3
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 22:44:25 +04:00
quanticsoul4772andClaude Opus 5.5 19b4a7a7e0 fix(terrain): keep known heights when a terrain request fails
A request with any point the proxy cannot answer gets 502, and the page
used to put every point of that chunk on its geoid, including the ones the
proxy had real (cached or stale) heights for. During an upstream 429 pause
that drops cached ground under every chunk that also holds a new point.

The 502 body now carries `partial`: the request's real heights in order,
null for points without one, left out when there are none. The terrain
request service attaches it to the error it throws, and the page caches
those heights and uses its geoid only for the rest. `get_terrain_height`
still reports the failure as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 10:10:50 -07:00
quanticsoul4772 9d75376307 Merge branch 'main' into upstream/traffic-layer-stale 2026-10-28 09:41:49 -07:00
quanticsoul4772 3e5edff884 Merge branch 'main' into upstream/terrain-429-pause 2026-10-28 09:05:56 -07:00
quanticsoul4772 065314c07c Merge branch 'main' into upstream/traffic-layer-stale 2026-10-28 09:05:08 -07:00
Said Turksever db2744ca3b Merge remote-tracking branch 'upstream/main' into pr1405-fix 2026-10-28 15:39:16 +00:00
Said Turksever f5e65fbf9e Merge remote-tracking branch 'upstream/main' into pr871-fix 2026-10-28 15:32:26 +00:00
Said Turksever 4bbe175ba3 Merge branch 'codex/fix-seek-layer-state' of https://github.com/oneill9/gods-eye-view into pr1374-fix 2026-10-28 15:18:26 +00:00
Said Turksever 87133e8dbf Merge remote-tracking branch 'upstream/main' into pr871-fix
# Conflicts:
#	CHANGELOG.md
2026-10-28 15:15:50 +00:00
Said Turksever d57bc0af3c test(locator): give the Stop test double the seek-generation helper
stopScene now supersedes seeks through _bumpSceneSeekGeneration; the
bhoteKoshiLocator Stop test calls stopScene on a plain object, so it
needs the method too. Without it four tests throw at the PR head.
2026-10-28 14:30:45 +00:00
Said Turksever c1820aea49 fix(terrain): end retries early on a long Retry-After; cover the 429 pause
A Retry-After longer than the 10 s retry budget used to sleep the whole
budget out and then give up, so the proxy's 429 pause started 10 s late
and every new-point poll in that window still went upstream and logged.
The retry loop now stops at once in that case.

Tests: the retry loop no longer sleeps for an unreachable Retry-After;
fully cached points, including stale ones, are served during the pause
with no upstream call; a 503 does not pause; a shorter concurrent
Retry-After never cuts the pause short. CURRENT-STATE now says which
requests are still served and which log.
2026-10-28 14:09:12 +00:00
Said Turksever 11aad05dc9 Merge remote-tracking branch 'upstream/main' into pr1209-merge 2026-10-28 14:05:40 +00:00
German KhokhlovandClaude Opus 5.5 1eb9e06c49 i18n(de): apply review round 1
- Meaning fixes: playback connects to the broadcaster when it starts, browser
  keys are restricted at the provider, clearing data layers switches them off
  (ausschalten, not löschen), cockpit inputs are Quellen, Electronic is
  Elektronische Musik, AIS types name vessels (SEGLER, LOTSENBOOT,
  SANITÄTSDIENST, SCHNELLSCHIFF), contiguous US excludes Alaska/Hawaii,
  wind and weather readings are model values, nearest frames are nearest in
  time, cloud imagery and the brightness filter say what they are.
- NHC/CPHC advisories are Lageberichte, not Warnungen; cyclone strings use
  Wirbelsturm throughout. Glossary updated.
- Grammar: " oder " keeps its space as a join separator, "{x} konnte nicht
  sauber beendet werden", Then: no longer doubles Dann, scene save reasons
  continue the sentence in lower case, neutral "Warten auf".
- Spacing between numbers and units in the remaining nine readouts.
- Reroute tooltip: German mode nouns keep their capital (Auto, Fahrrad).
- Built-in Nepal shot titles localize in every language: the legacy scene
  upgrade rebuilds its base shots without sourcePackId, so the pack's own
  shots in the scene now vouch for them.
- Layout: the layer status column no longer shrinks under a wide chip, and
  a mixed-case compound (ALPR-Kameras) may break at its hyphen; only capital
  codes (ADS-B, RTL-SDR) stay unbroken. WIRD AKTIVIERT overlapped the name.
  The Bhote step meta line may take a third line.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 17:30:21 +04:00
Aditya 6364817b5b fix(directions): show a 9.96 km route as 10 km, not 10.0 km
routeDistanceText picked one decimal while the raw kilometres were under
10, then rounded them for display, so 9.95 km or more read "10.0 km".
It now picks the unit from the rounded tenth, as it already does at the
metre/kilometre boundary.
2026-10-28 15:16:45 +05:30
Aditya f73cd5935b fix(missions): run the full T-10 replay countdown after the tile hold
Replay Ascent schedules liftoff 15 s out: a 5 s tile-preparation hold,
then a 10 s countdown. The hold ended 5 s before liftoff instead of 10,
so the replay sat on the pad for 10 s and the countdown began at T-5.
The hold now ends at T-10, and the countdown runs T-10 to T-1.
2026-10-28 15:13:13 +05:30
German KhokhlovandClaude Opus 5.5 ed40201481 i18n(ja): ship Japanese
- Register ja: CATALOGS, LOCALES, LOCALE_NAMES (日本語) and the package
  boundaries; ja and ja-JP tags select it.
- Japanese unit words follow the number directly, as in the catalog:
  formatQuantity writes 5分 and 1時間5分 (km and kt keep the space), and
  formatRelativeTime drops the space CLDR puts in 5 分前.
- Tests: locale tags, picker order, Intl output, durations and the
  ramp/exit/lane wording in Japanese.
- docs/translations/ja.md: style, units, plurals and glossary; ja added to
  TRANSLATORS.md and CURRENT-STATE.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 12:59:32 +04:00
quanticsoul4772 eef64cfb4f Merge branch 'main' into upstream/traffic-layer-stale 2026-10-27 16:51:08 -07:00
quanticsoul4772 0ba59112f9 Merge branch 'main' into upstream/terrain-429-pause 2026-10-27 16:51:00 -07:00
manjunath d4434aa6d7 feat(outlines): restore voice outlines without public Overpass
use bundled place boundaries and shared OpenFreeMap tiles before a guarded Nominatim fallback

preserve multipart shapes, holes and cancellation,
and keep pending annotations visible while ground sampling finishes across frames

keep non-Latin name distinctions when selecting provider results,
and retain an outline anchor only when it lies in filled geometry
2026-10-27 13:24:02 +00:00
Matt Van Horn f2e722c4bf Merge remote-tracking branch 'upstream/main' into fix/houston-cctv-pack
# Conflicts:
#	.env.example
#	README.md
#	docs/CURRENT-STATE.md
#	server/providers/cctv/catalog.js
#	server/providers/cctv/normalize.js
#	server/providers/cctv/sources.js
#	src/data/dataCredits.js
2026-10-27 05:09:29 -07:00
Matt Van Horn 4c2159a70a Merge upstream/main into fix/drone-airspace
Move the share-link token to 6 (3 is gnss-integrity), build altitude
ranges from LOWER/UPPER VAL, UOM and CODE, mark card and legend strings
for translation, rename the layer to Prohibited & Restricted Airspace,
move the changelog entry to changelog.d, and keep the layer voice-off
while the Realtime prompt is at its budget.
2026-10-27 05:06:05 -07:00
Aditya 83c4388e64 fix(awareness): show a 999.6 m contact marker as 1.0 km, not 1000 m
The on-globe Contacts markers picked metres before rounding, so a contact
999.5 m or more away read "1000 m" while the Contacts panel read
"1.0 km". The marker label now rounds first, as the panel does.
2026-10-27 15:55:30 +05:30
Aditya d58199a214 fix(vessels): show a 359.7° course as 0°, not 360°
Vessel cards and the AIS HUD rounded the direction without wrapping, so
a vessel reporting no heading and a course over ground of 359.5° or more
read "360°" on its cards and "HDG: 360DEG" in the HUD. The rounded
direction now wraps to 0°.
2026-10-27 15:54:28 +05:30
Sameh Khamis da02fd8645 feat(share): short /share/<code> links with a compact versioned view format (#1418)
* feat(share): add compact versioned share-view codec

Add a standalone codec for `#s=<base64url>` share links: a version byte
followed by protobuf-style tag-length-value fields. Settings equal to
their default are omitted and refilled from the same table on decode;
unknown fields are skipped by wire type, so new fields never break
older apps. Views are a place (camera) or a thing (an aircraft,
military aircraft, vessel or satellite to follow, with camera offset
and last-known fix); an unknown kind falls back to the camera.

The decoder bounds its input and rejects malformed payloads with a
reason instead of throwing. A converter maps the long form's parsed
state to and from the codec state; the long form is unchanged.

* fix(share): tighten codec decoding after review

Unknown detection mode and allocation names now fall back to their
defaults instead of reaching the lenient long-form migration. Future
panel values and style-parameter tokens are skipped rather than applied
or rejected, and layer options are accepted only under their owner
layer. Wrap longitudes before scaling, normalize negative zero, reuse
the layer-state tracking ID grammar, and align the format doc with the
decoder.

* feat(share): let a host share the link its own way

ShareLinkManager.buildLink() returns the current share link without
copying it, and copyLink() now copies exactly that. The share button
passes the link to an optional services.shareLink(url), which resolves
to 'shared', 'copied', 'cancelled' or false; 'cancelled' shows no toast
and 'shared' shows the new "Link shared" (es, ru, zh-CN). Without the
service the button copies as before.

* feat(share): open and make short /share/<code> links

The share button now makes `<app>/share/<code>` links with the compact
share-view code, and the app opens them at start-up through the same
restore pipeline as long links. Once the app next writes the address, the
share path is replaced (no new history entry) by the app's own address and
the live long-form hash, so a reload follows the live view. A host can pass
the code as `initialShareCode` instead. A code that fails to decode restores
nothing and shows "This share link can't be opened".

The code gains a trailing CRC-8 check byte, so any single mistyped
character is rejected instead of opening a different view. Thing views no
longer store a camera: it is derived from the entity's last-known fix and
the follow offset on a sphere, the entity kind is implied by the id's
field, and the followed entity's layer bit is implied; an aircraft followed
from the app's own camera is a 42-character code. The `#s=` hash form is
gone.

While the camera follows an aircraft, military aircraft or satellite, the
link is a thing view with the camera's offset and the entity's position.
Opening one turns the layer on and follows the entity through the existing
shared-follow restore, then swings the camera round to the shared offset; a
vessel view selects the vessel once the vessel feed has it. If the entity
is not reporting within its window, the view stays at its last-known fix
and says so. The panel and style-parameter tables now come from the codec,
and a host share hook that returns a plain value or throws still gets a
toast.

* fix(share): encode style settings against the style's own look

Settings a style applies when selected (bloom, sharpen, HUD, detection,
celestial ring and the style's shader parameters) now default, per field,
to what that style applies in a fresh session, read from the tables the
app applies (the first-load baseline, the style presets and the shader
defaults). The encoder compares against the view's style and the decoder
fills omitted settings from the decoded style, so a view that keeps its
style's look costs only its camera and style. The previous defaults did not
match a fresh session (sharpen, HUD and detection were off), so every link
paid for them, and a style's own shader parameters were always written.

A test pins the per-style defaults as frozen v1 meanings. A followed
aircraft in Noir is now 44 characters and the real long-link example 39.

* docs: changelog for #1418
2026-10-26 15:31:51 -07:00
Sameh Khamis fefd5cdcf1 fix(layers): make Clear All clear the saved and shared layer selection (#1417)
* fix(layers): make Clear All clear the saved and shared layer selection

After Clear All every layer control was off, but the share URL could keep
listing layers (for example l=e.f) and a reload switched them back on.

The URL and local preferences are written from the committed layer
state, which only explicit visibility changes update. Clear All issued an
explicit OFF only for layers it found on at the start of the batch and
whose turn was not superseded. A layer already off for a passive reason
(isolated by Contacts or another context mode, or released by Contacts'
own teardown while the batch ran) never received one, so it stayed in the
committed state. Clear All also discards the context snapshot that would
have restored those layers, leaving the screen and the URL out of step.

Clear All now publishes the set of layers still on once its batch
settles, and the layer-state coordinator commits that selection: every
saved layer not in it is dropped and its passive restore is cancelled,
while a layer a newer explicit request turned back on is kept. A context
restore interrupted by Clear All no longer brings its snapshot back after
Contacts settles.

* docs: changelog for #1417
2026-10-26 14:07:58 -07:00
Sameh Khamis b7ece1d4d1 fix(share): restore a share link opened in an already-open tab (#1416)
* fix(share): restore a share link opened by hash navigation

Opening a different share link in an already-open tab (pasting it into
the address bar, following a link, or Back/Forward) changed the URL but
left the camera, visual style, map, panels and layers on the old view
until a reload.

The share manager now listens for hashchange and popstate. A new hash
that parses as a share and differs from the last hash the app read or
wrote runs the start-up restore pipeline: lane authority is reserved, URL
writes are held (including a pending debounced write of the old view),
the camera restore takes a new navigation generation, and the layer
coordinator replaces any in-flight layer restore with the new share's
layers through the passive share origin. A newer navigation supersedes an
older restore end to end; only the newest one releases URL writes. The
app's own replaceState writes never restore. Listeners are removed on
destroy.

Returning to the Normal style and resetting an already-active preset now
also apply when a share is restored after start-up, so the result matches
a fresh load of the same link.

* docs: changelog for #1416
2026-10-26 13:56:19 -07:00
Mazeyar Moeini Feizabadi 4da002bd42 Merge current main into S2 GhostMaps and preserve updated import and voice behavior 2026-10-26 16:25:49 +01:00