Merge meirm/i18n-spanish: upstream main (geocode proxy, radio mirror, CMR, terrain, tools)

Both sides had merged the same main features (cockpit emergencies, GNSS
integrity, geo file import) with their own i18n. Conflicts keep this
branch's reviewed version; the 7 catalog entries only the other side
used are pruned. Newer main commits come in unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-15 23:52:05 +04:00
commit 54f7513ef6
38 files changed
+1139 -118

No files matched your search

+48 -7
View File
@@ -101,6 +101,10 @@ lists at 25 rows by default. Voice offers the same queries next to its app
actions: the session lists them, and the browser runs them through the same
catalog, loaded on first use. See [tools and the MCP server](TOOLS.md).
Catalog calls check their cancellation signal immediately before executing a
tool. Already-cancelled queries do not start; cancellation after execution starts
continues to follow the existing tool and caller behavior.
## Cyber HUD — September 30, 2026
Display > HUD > Layout includes Cyber, also available through the HUD voice
@@ -1090,6 +1094,9 @@ collapse can still be undone.
## Surface keyboard lifecycle
Surface Tab cycling excludes controls with a negative tabindex, native disabled
state or inert ancestry; ordinary visible enabled controls retain their order.
`ui/surfaces` owns the capture-phase keyboard listener, Tab cycling and return
focus shared by the first-run launcher and Provider Settings. Each caller
activates it while open and deactivates it on dismissal; destruction releases
@@ -1173,7 +1180,9 @@ stalled downloads are cancelled. Development and preview use the same handler.
Overpass query validation, geometry simplification, disk caching and upstream
transport now have separate modules; military-installation search reuses that
transport. Regional briefing combines separate place, news and weather sources,
while weather effects uses only the weather source. Existing process-scoped
while weather effects uses only the weather source.
GDELT compact dates that do not name a real calendar instant keep the article
with an unknown publication time. Existing process-scoped
caches, rate limits, stale fallbacks and route ordering are preserved.
Local voice has separate HUD-summary, debug-log and Realtime-token handlers,
@@ -1202,13 +1211,21 @@ a browser key. Preview is for local build verification, not a production server.
## CCTV and radio provider modules
CCTV direction text resolves travel tokens first, then intercardinals, then
bare cardinals when enabled. Only conflicting headings within the highest
matching tier remain unknown; street quadrants and lower-tier words do not
cancel an explicit travel heading.
CCTV catalog acquisition, source normalization and frame/media delivery now live
in separate modules. Each CCTV factory owns its catalog and health state; its
`sourceRoot` option resolves relative source files against the application root.
Radio Browser station normalization, restricted outbound transport and directory
caching are separate modules. Node-only package entries expose both provider
factories. Routes, payloads, fallback behavior and existing dev/preview hook
registration are preserved; browser rendering is unchanged.
caching are separate modules. The pinned transport gives a mirror's 204, 205 or
304 reply an empty body and fails any reply outside 200–599 without throwing
outside its promise, so an unusual mirror status cannot crash the server.
Node-only package entries expose both provider factories. Routes, payloads,
fallback behavior and existing dev/preview hook registration are preserved;
browser rendering is unchanged.
## Terrain, traffic, fire and bike-share provider modules
@@ -1222,6 +1239,10 @@ The browser layers and their rendering remain in their existing modules.
## Terrain height cache bound
The terrain proxy parser rejects finite longitudes outside [-180, 180] and
latitudes outside [-90, 90] for every client before upstream resolution. One
out-of-range point rejects the whole batch; inclusive WGS84 bounds remain valid.
The client terrain-height resolver's in-memory cache is bounded at 20 000
entries (`DEFAULT_MAX_CACHE_ENTRIES`, overridable per instance through
`createTerrainHeights({ maxCacheEntries })`). Coordinate rounding makes repeated
@@ -1459,7 +1480,7 @@ accessible name remains "Don't show this again". Control behavior is unchanged.
## FIRMS source status
FIRMS ingestion and adaptation require explicit finite coordinates within WGS84 ranges; genuine zero coordinates remain valid and admitted detection indices stay sequential.
The FIRMS CSV parser rejects impossible acquisition calendar dates before the proxy filters records to the trailing 24 hours, while retaining valid UTC acquisition times.
The FIRMS proxy records source success after appending its rows. If aggregation
throws, that source reports failure without a contradictory success entry.
@@ -4162,7 +4183,8 @@ when its own signal aborts.
Configured endpoints have per-instance cooldowns for 406/429, honoring
Retry-After; absent delays back off from 30 seconds to five minutes. Empty
`elements` is a valid answer. Existing byte, query, concurrency and cache caps
remain. Consumer capability misses never schedule automatic retries.
remain. Malformed capability-probe responses remain unknown and are retried after the existing 30-second backoff; valid configured decisions remain memoized.
Consumer capability misses never schedule automatic retries.
Operator-configured Overpass area and focus-footprint queries use body-level
`out geom` (with `center` for focus), preserving relation member outlines.
@@ -4460,7 +4482,24 @@ Providers normalize coordinates, canonical name, label, place types and optional
bounds. Camera framing, nearby landmark recovery and footprint selection remain
in their consumers, including the Capitol identity/containment safeguards.
Radio keeps localized country names in labels rather than station filters.
Reverse geocoding and nearby/text-search endpoints retain their existing behavior.
Nearby/text-search endpoints retain their existing behavior.
**Google geocoding is a server route, not a browser call** (#363). Forward and
reverse lookups go to `/api/google/geocode` and `/api/google/reverse-geocode`,
which carry `GOOGLE_MAPS_SERVER_API_KEY` (falling back to `GOOGLE_MAPS_API_KEY`)
and share the Places routes' opt-in `GEV_RATELIMIT_GOOGLE_PER_MIN` throttle.
Google's Geocoding **web service** refuses referrer-restricted keys, so the
previous browser call forced the bundled browser key — visible in devtools by
design — to be left unrestricted; it now needs only the Map Tiles API and the
Maps JavaScript API (Street View). Both routes answer in Google's own
`status`/`results` shape rather than the Places routes' `places: []` contract,
because the browser adapters normalize that shape directly. The browser key still gates the provider client-side, so a keyless
session spends no request to learn it has no Google: the route's own keyless
answer reads as an unanswered provider, which would stop the chain caching the
negative Photon or Nominatim then produces. Its query is capped at 200
characters, its reverse coordinates are validated against WGS84 bounds before
the request is paid for, and a malformed viewport bias is dropped rather than
refused, since a bias only ranks results.
Only valid answers and definitive misses enter bounded caches; malformed replies,
HTTP refusals and outages remain retryable. Searches share a 12-second total
@@ -4557,6 +4596,8 @@ are omitted rather than framing the wrong part of the globe.
### Recent Imagery (September 2026)
CMR pagination counts raw rows when checking page completion and the record budget. A catalog is truncated when upstream hits exceed the rows examined or the record cap drops valid granules from the last page; discarded malformed rows do not imply unseen imagery.
Programmatic boxes passed to the exported `setBox` and `searchHls` operations
reject missing, blank or boolean edges instead of interpreting them as zero
coordinates. Valid finite numeric edges remain accepted; the app’s drag tool,