mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Merge branch 'main' into fix/remove-operator-hud-layout
This commit is contained in:
19 files changed
+6715
-20
No files matched your search
@@ -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,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).
|
||||||
@@ -3789,7 +3789,7 @@ test:track` 43 tracking invariants · headless QA harnesses under
|
|||||||
|
|
||||||
### Interface localization (October 2026)
|
### Interface localization (October 2026)
|
||||||
|
|
||||||
Shipped locales: **en** (source and fallback), **es**, **ru**, **zh-CN** and **zh-Hant**. The code lives in
|
Shipped locales: **en** (source and fallback), **es**, **it**, **ru**, **uk**, **zh-CN** and **zh-Hant**. The code lives in
|
||||||
`src/i18n/`. How to mark UI text: [`docs/I18N.md`](./I18N.md); translator workflow:
|
`src/i18n/`. How to mark UI text: [`docs/I18N.md`](./I18N.md); translator workflow:
|
||||||
[`docs/TRANSLATORS.md`](./TRANSLATORS.md).
|
[`docs/TRANSLATORS.md`](./TRANSLATORS.md).
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
# Translating God's Eye View
|
# Translating God's Eye View
|
||||||
|
|
||||||
Shipped languages: **English** (source and fallback), **Spanish** (`es`), **Russian** (`ru`), **Simplified Chinese** (`zh-CN`) and **Traditional Chinese** (`zh-Hant`).
|
Shipped languages: **English** (source and fallback), **Spanish** (`es`), **Italian** (`it`), **Russian** (`ru`), **Ukrainian** (`uk`), **Simplified Chinese** (`zh-CN`) and **Traditional Chinese** (`zh-Hant`).
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
@@ -63,4 +63,4 @@ These are contracts, not copy: layer ids and registry keys, status enums and oth
|
|||||||
|
|
||||||
## Language notes
|
## Language notes
|
||||||
|
|
||||||
Each language keeps its glossary, plural forms, units and style in its own file, `docs/translations/<code>.md`: [Spanish](./translations/es.md), [Russian](./translations/ru.md), [Simplified Chinese](./translations/zh-CN.md), [Traditional Chinese](./translations/zh-Hant.md). Read it before translating, and add a term there when you settle on one.
|
Each language keeps its glossary, plural forms, units and style in its own file, `docs/translations/<code>.md`: [Spanish](./translations/es.md), [Italian](./translations/it.md), [Russian](./translations/ru.md), [Ukrainian](./translations/uk.md), [Simplified Chinese](./translations/zh-CN.md), [Traditional Chinese](./translations/zh-Hant.md). Read it before translating, and add a term there when you settle on one.
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# Italian (`it`)
|
||||||
|
|
||||||
|
Catalog: `src/i18n/locales/it.json`. General rules: [TRANSLATORS.md](../TRANSLATORS.md).
|
||||||
|
|
||||||
|
Translation source: abiyeenzo (#912).
|
||||||
|
|
||||||
|
## Style
|
||||||
|
|
||||||
|
- Standard Italian as in Italian software UIs. Address the user with informal "tu" imperatives: «Aggiungi», «Attiva», «Scegli», «Incolla», «Riprova». Tooltips that name an action use the same imperative: «Espandi il pannello», «Ripristina la camera».
|
||||||
|
- Sentence case, not Title Case: "Live Flights" → «Voli live», "Space Missions" → «Missioni spaziali». UPPERCASE English stays UPPERCASE: «LIVE», «NON DISPONIBILE».
|
||||||
|
- Quotes inside Italian text are straight double quotes: «Eliminare lo scatto "{shot}"?». Use the accented capitals (È, À) in UPPERCASE text: «VELOCITÀ», «CITTÀ».
|
||||||
|
- Errors read as a statement, not a past participle on its own: "Search failed" → «Ricerca non riuscita»; "Could not …" → «Impossibile …». A dash that joins a cause and a hint becomes a colon: «Chiave API rifiutata: controlla AISSTREAM_API_KEY». The same goes for a label and its hint in a tooltip: «Direzione (bussola °): clic per digitare».
|
||||||
|
- Short labels, chips and HUD readouts stay short. A standard abbreviation with a period beats a wrapped line: REGOLAZ., RILEV., INCL., ALT., VEL., STIM., PROIEZ., ESP.; PREC / SUCC for PREV / NEXT and PREVIOUS / NEXT.
|
||||||
|
- The HUD codes HDG, BRG, CRS, FOV and DEST stay in English, as in cockpit avionics. RANGE is «PORTATA». Words used in a sentence are translated: heading → «prua» (aircraft, ships) or «direzione» (camera, buses, trams, trains), course → «rotta».
|
||||||
|
- Keyboard keys stay in English: Space, Enter, Esc, Tab, Shift, Backspace, H, 1–9 («Tieni premuto Space per parlare», «Premi Enter per riprovare»).
|
||||||
|
- Decimal comma in numbers written in the text, magnitudes included: «28,2710° N», «M5,2». Numbers formatted by the code follow `Intl` and need nothing.
|
||||||
|
- Amounts: thousands, millions and billions are written out or abbreviated in Italian, not with K/M/B: «{amount} mila $», «{amount} mln $», «{amount} mld $».
|
||||||
|
- Units: km, m, km/h, m/s, kn (knots), ft (feet), h, min, s; in UPPERCASE text KM, KM/S, KT, FT, MIN, H. "m" is always metres, so minutes are «min» («5 min fa»). MW stays MW. `°` and `%` stay.
|
||||||
|
- "ago" goes after the time: «{count} min fa». When a placeholder already holds a localized "ago" text (`{age}`, `{ago}`), do not add «fa» again.
|
||||||
|
- A feature name used as a sentence subject gets a head noun so the verb agrees: «La modalità Missioni spaziali isola…», «Il pannello Impostazioni provider è disattivato…», «Il livello {layer} è attivo…», «Lo strumento {name} è attivo…». A short card title with a placeholder name puts the state after a colon: «{label}: attivato». The same goes for a placeholder list of names: «Attivazione recente: {layers}». A count in a plain `t()` entry (no plural forms) that can be 1 goes after a label, so nothing has to agree with it: «Record accettati: {accepted} su {raw}».
|
||||||
|
- English loanwords that Italian UIs use as they are stay in English: feed, live, cockpit, briefing, preset, overlay, layout, snapshot, tile, provider, timeout, payload, bloom, scope.
|
||||||
|
|
||||||
|
## Plurals
|
||||||
|
|
||||||
|
A `tn()` entry needs three forms. `Intl.PluralRules('it')` picks:
|
||||||
|
|
||||||
|
| Form | Counts | Example |
|
||||||
|
| ------- | -------------------------------------- | ----------------------- |
|
||||||
|
| `one` | 1 | 1 telecamera |
|
||||||
|
| `many` | 1 000 000, 2 000 000… (exact millions) | 1 000 000 di telecamere |
|
||||||
|
| `other` | everything else: 0, 2–999 999, 1,5… | 3 telecamere |
|
||||||
|
|
||||||
|
The `many` form is the `other` text with «di» after the number when a noun follows: «{count} di telecamere caricate», «{count} DI CHIAVI IN ATTESA». When no noun follows the number («{count} vicine», «{count} RICEVUTI»), `many` repeats `other`. Nouns that do not change in the plural keep one form for all three (`{count} file`, `{count} data center`), with «di» in `many`.
|
||||||
|
|
||||||
|
## Glossary
|
||||||
|
|
||||||
|
| English | Italiano |
|
||||||
|
| --------------------------------------------- | ------------------------------------------------------------ |
|
||||||
|
| layer / data layer | livello / livello dati |
|
||||||
|
| feed / source / data source | feed / fonte / fonte dati |
|
||||||
|
| LIVE (status) / live data / live (feed state) | LIVE / dati live / live |
|
||||||
|
| SIMULATED | SIMULATO |
|
||||||
|
| stale / degraded / unavailable | obsoleto / degradato / non disponibile |
|
||||||
|
| retry / retrying | riprova / nuovo tentativo |
|
||||||
|
| rate limited | limite di richieste (raggiunto) |
|
||||||
|
| key (API key) / POWER UP / POWERED UP | chiave / ACCENDI / ACCESO |
|
||||||
|
| Provider Settings | Impostazioni provider |
|
||||||
|
| ON / OFF (state chips) | ON / OFF |
|
||||||
|
| enable / disable | attivare / disattivare |
|
||||||
|
| globe / map / map source / map stack | globo / mappa / fonte mappa / stack mappa |
|
||||||
|
| basemap / box (Recent Imagery area) | mappa di base / riquadro |
|
||||||
|
| aircraft, plane / flight / military flights | aereo / volo / voli militari |
|
||||||
|
| vessel, ship | nave |
|
||||||
|
| satellite / shell (Starlink) / DENSE | satellite / shell / DENSO |
|
||||||
|
| SPARSE / BALANCED / DENSE (detection modes) | RADO / BILANCIATO / DENSO (agree with «overlay») |
|
||||||
|
| broadband (Starlink shell) | a banda larga |
|
||||||
|
| VISUAL (CelesTrak group) | VISIBILI |
|
||||||
|
| launch (rocket) / launch site / space mission | lancio / sito di lancio / missione spaziale |
|
||||||
|
| ascent / replay / payload / stage | salita / replay / payload / stadio |
|
||||||
|
| contact / tracking | contatto / tracciamento |
|
||||||
|
| installation / site | installazione / sito |
|
||||||
|
| mapped / observed | mappato / osservato |
|
||||||
|
| camera (view) / camera, CCTV camera | camera / telecamera, telecamera CCTV |
|
||||||
|
| earthquake / active fire / fire perimeter | terremoto / incendio attivo / perimetro dell'incendio |
|
||||||
|
| lightning strike / cloud (cover, %) | fulmine / nuvole («non singoli fulmini», «20% di nuvole») |
|
||||||
|
| incident (wildfire, Type N) / scene incident | evento (Evento di tipo N, Incendio senza nome) / evento |
|
||||||
|
| trigger record (USGS card) / OPEN SOURCE link | scheda / APRI LA FONTE |
|
||||||
|
| advisory (NHC/CPHC cyclone) / cone | bollettino / cono di incertezza |
|
||||||
|
| forecast lead hours (cyclone points) | scadenze di previsione in ore |
|
||||||
|
| AIR / SEA (radio category) / ground station | ARIA / MARE / stazione di terra |
|
||||||
|
| radio station / broadcaster | stazione radio / emittente |
|
||||||
|
| CH (radio channel readout) | CH (unchanged) |
|
||||||
|
| road / flow (traffic) | strada / flusso |
|
||||||
|
| transit / bike share | trasporto pubblico / bike sharing |
|
||||||
|
| last report (vehicle position) | ultima segnalazione |
|
||||||
|
| scene / shot / scene recipe | scena / scatto / ricetta della scena |
|
||||||
|
| anchor / data pack / bundle (scene) | ancora / pacchetto dati / pacchetto |
|
||||||
|
| story beat | tappa del racconto |
|
||||||
|
| briefing / panel / dock | briefing / pannello / dock |
|
||||||
|
| cockpit | cockpit |
|
||||||
|
| preset / visual preset | preset / preset visivo |
|
||||||
|
| Tactical / Operator / Minimal / Cyber | Tattico / Operatore / Minimale / Cyber |
|
||||||
|
| Scope (circular viewport mask) / keyhole | scope / foro |
|
||||||
|
| feather / fade | sfumatura / dissolvenza |
|
||||||
|
| detection overlay | overlay di rilevamento |
|
||||||
|
| pin (Draw tool) / mark | segnaposto / segno |
|
||||||
|
| pin (Recent Imagery) | fissare |
|
||||||
|
| Draw / Directions (tools) | Disegno / Indicazioni |
|
||||||
|
| Street Level (layer) / Street View (Google) | Vista stradale / Street View |
|
||||||
|
| Recent Imagery | Immagini recenti |
|
||||||
|
| Global Context / Context (panel) | Contesto globale / Contesto |
|
||||||
|
| heading, course / altitude / ground speed | prua, rotta / altitudine / velocità al suolo (VEL. AL SUOLO) |
|
||||||
|
| altitude in short HUD captions / Alt unknown | QUOTA (QUOTA · FT) / Quota sconosciuta |
|
||||||
|
| fallback (FALLBACK, Street View fallback) | riserva / di riserva (SUPERFICIE DI RISERVA) |
|
||||||
|
| forecast track / advisory center (cyclones) | traccia prevista / centro del ciclone da bollettino |
|
||||||
|
| witness source / authored (scene) | fonte testimoniale / predefinito, definito dall'autore |
|
||||||
|
| explore manually | esplora manualmente |
|
||||||
|
| HDG / BRG / CRS / FOV / DEST | HDG / BRG / CRS / FOV / DEST (unchanged) |
|
||||||
|
| RANGE / PITCH / HGT (CCTV calibration) | PORTATA / INCL. / ALT. |
|
||||||
|
| PREV / NEXT | PREC / SUCC |
|
||||||
|
| Previous / Next (button text) | Precedente / Successivo |
|
||||||
|
| Focus {target} (action, aria label) | Inquadra {target} (the FOCUS button stays FOCUS) |
|
||||||
|
| L / R (relative bearing) | S / D |
|
||||||
|
| SIG / NEWS / LOCAL (briefing tabs) | SIG / NOTIZIE / LOCALE |
|
||||||
|
| compass points (N, NNE, …, W, NW) | N, NNE, …, O, NO (west is «O», ovest) |
|
||||||
|
| NOT AN ALL-CLEAR | NON È UN VIA LIBERA |
|
||||||
|
| weather field / model / valid / issued | campo / modello / valida / emessa |
|
||||||
|
| click / click to … | fai clic / clic per … |
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
# Ukrainian (`uk`)
|
||||||
|
|
||||||
|
Catalog: `src/i18n/locales/uk.json`. General rules: [TRANSLATORS.md](../TRANSLATORS.md).
|
||||||
|
|
||||||
|
Translation source: meirm (#312).
|
||||||
|
|
||||||
|
## Style
|
||||||
|
|
||||||
|
- Address the user with polite imperatives: «Натисніть», «Увімкніть», «Спробуйте ще раз».
|
||||||
|
- Sentence case, not Title Case: "Live Flights" → «Рейси онлайн».
|
||||||
|
- Ukrainian norms, not Russian calques: «у радіусі», «за посиланням», «надто довгий», «потім», «вигляд» (a camera view: «вигляд згори»), «стеження» (tracking); prepositions alternate у/в and і/й by euphony.
|
||||||
|
- The apostrophe is always ʼ (U+02BC): обʼєкт, звʼязок, памʼять. Not ' or ’.
|
||||||
|
- Quotes inside Ukrainian text are «ялинки»; a button or layer name inside a sentence goes in them: Увімкніть «Вуличні знімки».
|
||||||
|
- In short labels, a standard abbreviation with a period beats a wrapped line: ПОПЕР., ДАЛЬН., КАЛІБР.
|
||||||
|
- Units: км, м, км/год, м/с, вуз (knots), фт (feet), год, хв, с, МГц, дБ, гПа; in UPPERCASE text КМ, М, КМ/С, ВУЗ, ФТ. MW is МВт in any case. `°` and `%` stay. Decimal comma in coordinates written as text: 28,2710° пн. ш.
|
||||||
|
- Coordinates: пн. ш. / пд. ш. / сх. д. / зх. д.; the HUD hemisphere letters are Пн, Пд, Сх, Зх.
|
||||||
|
|
||||||
|
## Plurals
|
||||||
|
|
||||||
|
A `tn()` entry needs four forms. `Intl.PluralRules('uk')` picks:
|
||||||
|
|
||||||
|
| Form | Counts | Example |
|
||||||
|
| ------- | ------------------------ | ---------- |
|
||||||
|
| `one` | 1, 21, 31, 101… | 1 камера |
|
||||||
|
| `few` | 2–4, 22–24, 32–34… | 3 камери |
|
||||||
|
| `many` | 0, 5–20, 25–30, 111–114… | 5 камер |
|
||||||
|
| `other` | fractions: 1.5, 2.25… | 1,5 камери |
|
||||||
|
|
||||||
|
`other` takes the genitive singular: 1,5 кадру, 1,5 літака, 1,5 ключа. When a word next to a number cannot agree in every form, move the number after a colon instead: «поруч: {count}», «відповідей: {responses}». The same trick keeps place names and tool names out of a preposition's case: «звідки: {origin}», «Активно: {name}».
|
||||||
|
|
||||||
|
## Glossary
|
||||||
|
|
||||||
|
| English | Українська |
|
||||||
|
| ----------------------------------------------- | ---------------------------------------------------------------- |
|
||||||
|
| layer / data layer | шар / шар даних |
|
||||||
|
| feed | потік даних (short: потік) |
|
||||||
|
| source / data source | джерело / джерело даних |
|
||||||
|
| LIVE (status) / live data | ОНЛАЙН / у реальному часі (status chip: ДАНІ ОНЛАЙН) |
|
||||||
|
| SIMULATED / SYNTHETIC | ІМІТАЦІЯ |
|
||||||
|
| stale / degraded / unavailable | застарів / з перебоями (chip: ПЕРЕБОЇ) / недоступний |
|
||||||
|
| retry | повтор |
|
||||||
|
| key (API key) / POWER UP | ключ / ЗАПУСК |
|
||||||
|
| Provider Settings / provider | Налаштування постачальників / постачальник |
|
||||||
|
| globe / map / map source / basemap | глобус / карта / джерело карти / підкладка |
|
||||||
|
| aircraft / flight / military flights | літак (short HUD: борт) / рейс / військові рейси |
|
||||||
|
| vessel, ship / vessels | судно / судна (gen. pl. суден) |
|
||||||
|
| satellite | супутник |
|
||||||
|
| launch (rocket) / space mission | запуск / космічна місія |
|
||||||
|
| ascent (rocket) / booster FLIGHT {n} | виведення / ПОЛІТ {n} (not рейс) |
|
||||||
|
| contact / tracking | контакт / стеження |
|
||||||
|
| installation, site / mapped | обʼєкт / нанесений (обʼєкт, контакт) |
|
||||||
|
| camera / CCTV camera | камера / камера CCTV |
|
||||||
|
| earthquake / active fire / fire perimeter | землетрус / активна пожежа / контур пожежі |
|
||||||
|
| advisory (NHC/CPHC cyclone) | зведення |
|
||||||
|
| scene / shot / scene recipe | сцена / кадр / рецепт сцени |
|
||||||
|
| briefing / panel / dock | брифінг / панель / док |
|
||||||
|
| preset / visual preset | пресет / візуальний пресет |
|
||||||
|
| Scope, keyhole (circular viewport mask) | приціл |
|
||||||
|
| overlay (detection overlay) / world overlay | накладка / накладка на глобусі |
|
||||||
|
| heading / altitude / ground speed | курс / висота / шляхова швидкість |
|
||||||
|
| map bearing, map heading | азимут карти |
|
||||||
|
| HDG / BRG / CRS, TRK / FOV / DEST / SPD / RANGE | КУРС / ПЕЛ. / ШК (шляховий кут) / ОГЛЯД / ПРИЗН. / ШВИД / ДАЛЬН. |
|
||||||
|
| Street View (Google) | Перегляд вулиць (as in Ukrainian Google Maps) |
|
||||||
|
| Street Level (layer) | Вуличні знімки |
|
||||||
|
| imagery / recent imagery | знімки / свіжі знімки |
|
||||||
|
| radar reflectivity / lightning density | радіолокаційна відбивність / щільність блискавок |
|
||||||
|
| infrared | інфрачервоний (short: ІЧ) |
|
||||||
|
| receiver / gain / decoder | приймач / підсилення / декодер |
|
||||||
|
| broadcaster | мовник |
|
||||||
|
| CONUS, WHOT/BHOT, Ironbow, CRT, NVG, FLIR | без перекладу |
|
||||||
|
| PREV / NEXT (HUD) / Previous / Next | ПОПЕР. / ДАЛІ / Попередній / Наступний |
|
||||||
|
| anchor / data pack / bundle (scene) | якір / пакет даних / архів |
|
||||||
|
| box (Recent Imagery area) | область |
|
||||||
|
| camera move | переліт |
|
||||||
|
| SIG / NEWS / LOCAL (briefing tabs) | СИГН. / НОВИНИ / МІСЦ. |
|
||||||
|
| compass points (N, NNE, NE, …) | Пн, ПнПнСх, ПнСх, … |
|
||||||
|
| L / R (relative bearing) | Л / П |
|
||||||
|
| click / tap | клацнути / натиснути |
|
||||||
|
| session (voice, OAuth) | сеанс |
|
||||||
|
| sequence (street-level photos) | послідовність |
|
||||||
|
| search (place search) | пошук місця |
|
||||||
|
| pitch (CCTV camera pose) | нахил |
|
||||||
|
| traffic (road traffic layer) | дорожній рух |
|
||||||
|
| phosphor (CRT) | люмінофор |
|
||||||
|
| view (map extent) / view centre / in view | видима область (карти) / центр карти / у кадрі |
|
||||||
|
| select (verb) / selected | вибрати / вибраний (not обрати) |
|
||||||
|
| ping (cockpit proximity contacts) | контакт |
|
||||||
|
| merge (turn-by-turn) / on ramp | влитися в потік / вʼїзд (off ramp: зʼїзд) |
|
||||||
|
| watch (Earth/Orbital Watch) | спостереження |
|
||||||
|
| timeout | тайм-аут |
|
||||||
|
| icon | значок (not іконка) |
|
||||||
|
| run (scene playback) / RUN LOG | відтворення / ЖУРНАЛ ВІДТВОРЕННЯ (запуск is a rocket launch) |
|
||||||
|
| Preview (voice panel replies) | відповіді |
|
||||||
|
| Marine (radio tag) / pleasure craft | море (not флот) / прогулянкове судно |
|
||||||
|
| emergency (ADS-B) / Emergency (radio tag) | аварійний стан / надзвичайні ситуації |
|
||||||
|
| confidence (FIRMS fire detection) | достовірність (short: достов.) |
|
||||||
|
| thermal (FLIR-style imaging) | тепловий (not термальний) |
|
||||||
|
| map stack | набір карт |
|
||||||
|
| stage (rocket) re-entry / recovery | вхід ступеня в атмосферу / повернення |
|
||||||
|
| ON / OFF (toggle chips) | УВІМК. / ВИМК. |
|
||||||
|
| Clean UI / EXIT CLEAN VIEW | чистий інтерфейс / ПОВЕРНУТИ ІНТЕРФЕЙС |
|
||||||
|
| full globe view | вигляд всього глобуса |
|
||||||
|
| inputs (cockpit context chip) | потоки (not вхідні дані) |
|
||||||
|
| downrange (rocket stage) | дальність |
|
||||||
|
| resolution (spatial) | роздільна здатність (not роздільність) |
|
||||||
|
| shared follow expired | посилання на стеження застаріло |
|
||||||
@@ -440,7 +440,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -480,7 +482,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -510,7 +514,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -532,7 +538,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -549,7 +557,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -569,7 +579,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -596,7 +608,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/layerNames.js"
|
"src/ui/layerNames.js"
|
||||||
@@ -631,7 +645,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -648,7 +664,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -807,7 +825,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -929,7 +949,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -997,7 +1019,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -1046,7 +1070,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1109,7 +1135,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1139,7 +1167,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -1170,7 +1200,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1201,7 +1233,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -1235,7 +1269,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1278,7 +1314,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/layers/installations/classLabel.js"
|
"src/layers/installations/classLabel.js"
|
||||||
@@ -1315,7 +1353,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -1366,7 +1406,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1396,7 +1438,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1445,7 +1489,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1509,7 +1555,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/layers/streetLevel/providers/mapillary/policy.js"
|
"src/layers/streetLevel/providers/mapillary/policy.js"
|
||||||
@@ -1539,7 +1587,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1580,7 +1630,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1603,7 +1655,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1660,7 +1714,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -1723,7 +1779,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/statusText.js",
|
"src/ui/statusText.js",
|
||||||
@@ -2607,7 +2665,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -3192,7 +3252,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js",
|
"src/ui/unitLabels.js",
|
||||||
@@ -3303,7 +3365,9 @@
|
|||||||
"src/data/cameraArrival.js",
|
"src/data/cameraArrival.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/i18n/index.js"
|
"src/i18n/index.js"
|
||||||
@@ -3327,7 +3391,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -3364,7 +3430,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/scopeMaskPolicy.js",
|
"src/scopeMaskPolicy.js",
|
||||||
@@ -3391,7 +3459,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -3483,7 +3553,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/unitLabels.js"
|
"src/ui/unitLabels.js"
|
||||||
@@ -3539,7 +3611,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/statusText.js",
|
"src/ui/statusText.js",
|
||||||
@@ -3794,7 +3868,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -3838,7 +3914,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -3892,7 +3970,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json"
|
"src/i18n/locales/zh-Hant.json"
|
||||||
],
|
],
|
||||||
@@ -3909,7 +3989,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/statusText.js",
|
"src/ui/statusText.js",
|
||||||
@@ -3969,7 +4051,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/data/geoImportImages.js",
|
"src/data/geoImportImages.js",
|
||||||
@@ -4166,7 +4250,9 @@
|
|||||||
"src/i18n/index.js",
|
"src/i18n/index.js",
|
||||||
"src/i18n/locale.js",
|
"src/i18n/locale.js",
|
||||||
"src/i18n/locales/es.json",
|
"src/i18n/locales/es.json",
|
||||||
|
"src/i18n/locales/it.json",
|
||||||
"src/i18n/locales/ru.json",
|
"src/i18n/locales/ru.json",
|
||||||
|
"src/i18n/locales/uk.json",
|
||||||
"src/i18n/locales/zh-CN.json",
|
"src/i18n/locales/zh-CN.json",
|
||||||
"src/i18n/locales/zh-Hant.json",
|
"src/i18n/locales/zh-Hant.json",
|
||||||
"src/ui/statusText.js",
|
"src/ui/statusText.js",
|
||||||
|
|||||||
@@ -33,8 +33,12 @@ function memoryStorage(initial = {}) {
|
|||||||
test('normalizeLocale folds regional variants and rejects unshipped tags', () => {
|
test('normalizeLocale folds regional variants and rejects unshipped tags', () => {
|
||||||
assert.equal(normalizeLocale('ru-RU'), 'ru');
|
assert.equal(normalizeLocale('ru-RU'), 'ru');
|
||||||
assert.equal(normalizeLocale(' RU '), 'ru');
|
assert.equal(normalizeLocale(' RU '), 'ru');
|
||||||
|
assert.equal(normalizeLocale('uk'), 'uk');
|
||||||
|
assert.equal(normalizeLocale('uk-UA'), 'uk');
|
||||||
assert.equal(normalizeLocale('en_GB'), 'en');
|
assert.equal(normalizeLocale('en_GB'), 'en');
|
||||||
assert.equal(normalizeLocale('xx'), null);
|
assert.equal(normalizeLocale('xx'), null);
|
||||||
|
assert.equal(normalizeLocale('it-IT'), 'it');
|
||||||
|
assert.equal(normalizeLocale('it_CH'), 'it');
|
||||||
// Explicit script tags take precedence over regional defaults.
|
// Explicit script tags take precedence over regional defaults.
|
||||||
assert.equal(normalizeLocale('zh'), 'zh-CN');
|
assert.equal(normalizeLocale('zh'), 'zh-CN');
|
||||||
assert.equal(normalizeLocale('zh-CN'), 'zh-CN');
|
assert.equal(normalizeLocale('zh-CN'), 'zh-CN');
|
||||||
@@ -142,6 +146,22 @@ test('tn() picks English and Russian plural forms', () => {
|
|||||||
assert.match(label(21), / 21 КЛЮЧ(?![А-ЯЁ])/);
|
assert.match(label(21), / 21 КЛЮЧ(?![А-ЯЁ])/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('tn() picks the four Ukrainian plural forms', () => {
|
||||||
|
const label = (count) =>
|
||||||
|
tn(
|
||||||
|
count,
|
||||||
|
'POWER UP · {count} KEY WAITING',
|
||||||
|
'POWER UP · {count} KEYS WAITING',
|
||||||
|
);
|
||||||
|
setLocale('uk');
|
||||||
|
assert.match(label(1), / 1 КЛЮЧ(?![А-ЯҐЄІЇ])/);
|
||||||
|
assert.match(label(3), / 3 КЛЮЧІ(?![А-ЯҐЄІЇ])/);
|
||||||
|
assert.match(label(5), / 5 КЛЮЧІВ(?![А-ЯҐЄІЇ])/);
|
||||||
|
assert.match(label(11), / 11 КЛЮЧІВ(?![А-ЯҐЄІЇ])/);
|
||||||
|
assert.match(label(21), / 21 КЛЮЧ(?![А-ЯҐЄІЇ])/);
|
||||||
|
assert.match(label(1.5), / 1\.5 КЛЮЧА(?![А-ЯҐЄІЇ])/);
|
||||||
|
});
|
||||||
|
|
||||||
test('t() context separates identical English with different meanings', () => {
|
test('t() context separates identical English with different meanings', () => {
|
||||||
assert.equal(t('CLEAR', { context: 'action' }), 'CLEAR');
|
assert.equal(t('CLEAR', { context: 'action' }), 'CLEAR');
|
||||||
setLocale('ru');
|
setLocale('ru');
|
||||||
|
|||||||
+10
-1
@@ -17,11 +17,20 @@ import {
|
|||||||
writeStoredLocale,
|
writeStoredLocale,
|
||||||
} from './locale.js';
|
} from './locale.js';
|
||||||
import es from './locales/es.json' with { type: 'json' };
|
import es from './locales/es.json' with { type: 'json' };
|
||||||
|
import it from './locales/it.json' with { type: 'json' };
|
||||||
import ru from './locales/ru.json' with { type: 'json' };
|
import ru from './locales/ru.json' with { type: 'json' };
|
||||||
|
import uk from './locales/uk.json' with { type: 'json' };
|
||||||
import zhCN from './locales/zh-CN.json' with { type: 'json' };
|
import zhCN from './locales/zh-CN.json' with { type: 'json' };
|
||||||
import zhHant from './locales/zh-Hant.json' with { type: 'json' };
|
import zhHant from './locales/zh-Hant.json' with { type: 'json' };
|
||||||
|
|
||||||
const CATALOGS = Object.freeze({ es, ru, 'zh-CN': zhCN, 'zh-Hant': zhHant });
|
const CATALOGS = Object.freeze({
|
||||||
|
es,
|
||||||
|
it,
|
||||||
|
ru,
|
||||||
|
uk,
|
||||||
|
'zh-CN': zhCN,
|
||||||
|
'zh-Hant': zhHant,
|
||||||
|
});
|
||||||
|
|
||||||
let currentLocale = DEFAULT_LOCALE;
|
let currentLocale = DEFAULT_LOCALE;
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -8,13 +8,23 @@ export const LOCALE_STORAGE_KEY = 'gev:locale:v1';
|
|||||||
export const DEFAULT_LOCALE = 'en';
|
export const DEFAULT_LOCALE = 'en';
|
||||||
|
|
||||||
/** Shipped locales; order does not matter. Adding one: docs/TRANSLATORS.md. */
|
/** Shipped locales; order does not matter. Adding one: docs/TRANSLATORS.md. */
|
||||||
export const LOCALES = Object.freeze(['en', 'es', 'ru', 'zh-CN', 'zh-Hant']);
|
export const LOCALES = Object.freeze([
|
||||||
|
'en',
|
||||||
|
'es',
|
||||||
|
'it',
|
||||||
|
'ru',
|
||||||
|
'uk',
|
||||||
|
'zh-CN',
|
||||||
|
'zh-Hant',
|
||||||
|
]);
|
||||||
|
|
||||||
/** Each locale named in its own language, for the selector. */
|
/** Each locale named in its own language, for the selector. */
|
||||||
export const LOCALE_NAMES = Object.freeze({
|
export const LOCALE_NAMES = Object.freeze({
|
||||||
en: 'English',
|
en: 'English',
|
||||||
es: 'Español',
|
es: 'Español',
|
||||||
|
it: 'Italiano',
|
||||||
ru: 'Русский',
|
ru: 'Русский',
|
||||||
|
uk: 'Українська',
|
||||||
'zh-CN': '中文(简体)',
|
'zh-CN': '中文(简体)',
|
||||||
'zh-Hant': '中文(繁體)',
|
'zh-Hant': '中文(繁體)',
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -124,6 +124,175 @@
|
|||||||
"ΔN",
|
"ΔN",
|
||||||
"▲ {frp} MW"
|
"▲ {frp} MW"
|
||||||
],
|
],
|
||||||
|
"it": [
|
||||||
|
"1090 MHz",
|
||||||
|
"978 MHz UAT",
|
||||||
|
"AFRICA",
|
||||||
|
"AIS: --",
|
||||||
|
"AIS: {name}",
|
||||||
|
"ALT {altitude} FT · GS {speed} KT · TRK {track}",
|
||||||
|
"ANIME",
|
||||||
|
"ASIA",
|
||||||
|
"AUTO",
|
||||||
|
"AUTO HOP OFF",
|
||||||
|
"AUTO HOP ON",
|
||||||
|
"Alternative",
|
||||||
|
"Ambient",
|
||||||
|
"Anime",
|
||||||
|
"Area",
|
||||||
|
"Austin",
|
||||||
|
"BRG {value}°",
|
||||||
|
"BRG —",
|
||||||
|
"Bloom",
|
||||||
|
"Blues",
|
||||||
|
"Business jet",
|
||||||
|
"CAL {value}",
|
||||||
|
"CAL · {badge}",
|
||||||
|
"CARGO",
|
||||||
|
"CCTV",
|
||||||
|
"CCTV OFF",
|
||||||
|
"CCTV ON",
|
||||||
|
"CH {index} / {total}",
|
||||||
|
"COCKPIT",
|
||||||
|
"CRS {value}°",
|
||||||
|
"CRT",
|
||||||
|
"Country",
|
||||||
|
"Cyber",
|
||||||
|
"DEST ---°",
|
||||||
|
"DEST {bearing}",
|
||||||
|
"DISPLAY",
|
||||||
|
"Dance",
|
||||||
|
"Drone",
|
||||||
|
"Dubai",
|
||||||
|
"ENE",
|
||||||
|
"ESE",
|
||||||
|
"FLIR",
|
||||||
|
"FM MHZ",
|
||||||
|
"FOCUS",
|
||||||
|
"FOV",
|
||||||
|
"FOV {value}°",
|
||||||
|
"FT",
|
||||||
|
"Folk",
|
||||||
|
"Funk",
|
||||||
|
"GEO",
|
||||||
|
"GOOGLE STREET VIEW",
|
||||||
|
"Google Street View",
|
||||||
|
"HDG",
|
||||||
|
"HDG {value}°",
|
||||||
|
"Hip-Hop",
|
||||||
|
"House",
|
||||||
|
"Indie",
|
||||||
|
"Ironbow",
|
||||||
|
"Jazz",
|
||||||
|
"KTS",
|
||||||
|
"LIVE",
|
||||||
|
"Landsat 8/9",
|
||||||
|
"Layout",
|
||||||
|
"Los Angeles",
|
||||||
|
"MIC",
|
||||||
|
"MIL",
|
||||||
|
"MINI",
|
||||||
|
"MM",
|
||||||
|
"MONITOR",
|
||||||
|
"MSG/S",
|
||||||
|
"Metal",
|
||||||
|
"NASA FIRMS · LIVE",
|
||||||
|
"NAV",
|
||||||
|
"NE",
|
||||||
|
"NNE",
|
||||||
|
"NOIR",
|
||||||
|
"NVG",
|
||||||
|
"New York",
|
||||||
|
"Noir",
|
||||||
|
"OCEANIA",
|
||||||
|
"OFF",
|
||||||
|
"OK",
|
||||||
|
"ON",
|
||||||
|
"ON/OFF",
|
||||||
|
"Oldies",
|
||||||
|
"PAYLOAD",
|
||||||
|
"PLAY",
|
||||||
|
"POS: LIVE",
|
||||||
|
"POS: {time}Z",
|
||||||
|
"PRECIP",
|
||||||
|
"Pop",
|
||||||
|
"Punk",
|
||||||
|
"RADIO",
|
||||||
|
"REC",
|
||||||
|
"RESET",
|
||||||
|
"RESET CAL",
|
||||||
|
"Radio",
|
||||||
|
"Reggae",
|
||||||
|
"Rock",
|
||||||
|
"S2 GhostMaps",
|
||||||
|
"SAR",
|
||||||
|
"SE",
|
||||||
|
"SIG",
|
||||||
|
"SNAPSHOT",
|
||||||
|
"SQUAWK {code} · {status}",
|
||||||
|
"SSE",
|
||||||
|
"STANDARD",
|
||||||
|
"STD",
|
||||||
|
"STOP",
|
||||||
|
"SYNC",
|
||||||
|
"San Francisco",
|
||||||
|
"Scope",
|
||||||
|
"Sentinel-2",
|
||||||
|
"Sonar",
|
||||||
|
"Soul",
|
||||||
|
"TEMP",
|
||||||
|
"TIMEOUT",
|
||||||
|
"Talk",
|
||||||
|
"Tallinn",
|
||||||
|
"Techno",
|
||||||
|
"Tokyo",
|
||||||
|
"Tram",
|
||||||
|
"Trance",
|
||||||
|
"UPSTREAM",
|
||||||
|
"USB {rate} msg/s",
|
||||||
|
"Upstream HTTP {status}",
|
||||||
|
"V/S {rate} FPM",
|
||||||
|
"VIEWSHED",
|
||||||
|
"VIEWSHED ON",
|
||||||
|
"VOLUME",
|
||||||
|
"VS",
|
||||||
|
"WHOT/BHOT",
|
||||||
|
"Washington DC",
|
||||||
|
"World",
|
||||||
|
"audio {state}",
|
||||||
|
"dB",
|
||||||
|
"feed status|live",
|
||||||
|
"ft",
|
||||||
|
"hPa",
|
||||||
|
"installation class|BASE",
|
||||||
|
"km",
|
||||||
|
"km/h",
|
||||||
|
"max {value} MW",
|
||||||
|
"min",
|
||||||
|
"mini",
|
||||||
|
"mph",
|
||||||
|
"radio|TALK",
|
||||||
|
"satellite",
|
||||||
|
"standard",
|
||||||
|
"view band|METRO",
|
||||||
|
"voice|OFF",
|
||||||
|
"{count} MSGS",
|
||||||
|
"{count} feeds live",
|
||||||
|
"{count} scenes",
|
||||||
|
"{rate} msg/s",
|
||||||
|
"{scene} / {pack}: {status}. File: {path}. {attribution} · {license}",
|
||||||
|
"{source} HTTP {status}",
|
||||||
|
"{speed} kn",
|
||||||
|
"{speed}KT",
|
||||||
|
"{value} KM",
|
||||||
|
"{value} KM DOWNRANGE",
|
||||||
|
"{value} KM/H",
|
||||||
|
"{value} KM/S",
|
||||||
|
"{value} conf",
|
||||||
|
"ΔE",
|
||||||
|
"ΔN",
|
||||||
|
"▲ {frp} MW"
|
||||||
|
],
|
||||||
"ru": [
|
"ru": [
|
||||||
"AIS: --",
|
"AIS: --",
|
||||||
"AIS: {name}",
|
"AIS: {name}",
|
||||||
@@ -142,6 +311,19 @@
|
|||||||
"VS",
|
"VS",
|
||||||
"WHOT/BHOT"
|
"WHOT/BHOT"
|
||||||
],
|
],
|
||||||
|
"uk": [
|
||||||
|
"AIS: --",
|
||||||
|
"AIS: {name}",
|
||||||
|
"CCTV",
|
||||||
|
"CRT",
|
||||||
|
"FLIR",
|
||||||
|
"Ironbow",
|
||||||
|
"Landsat 8/9",
|
||||||
|
"NVG",
|
||||||
|
"REC",
|
||||||
|
"S2 GhostMaps",
|
||||||
|
"WHOT/BHOT"
|
||||||
|
],
|
||||||
"zh-CN": [
|
"zh-CN": [
|
||||||
"1090 MHz",
|
"1090 MHz",
|
||||||
"978 MHz UAT",
|
"978 MHz UAT",
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { SCENE_RECIPES, displayShotTitle } from './recipes.js';
|
||||||
|
import { setLocale } from '../i18n/index.js';
|
||||||
|
|
||||||
|
test('an operator-typed title in the built-in Nepal scene stays as typed', () => {
|
||||||
|
const scene = SCENE_RECIPES.find((r) => r.id === 'bhote-koshi-nepal-scene');
|
||||||
|
assert.ok(scene, 'built-in bootstrap scene exists');
|
||||||
|
for (const locale of ['ru', 'es', 'it', 'zh-CN', 'zh-Hant']) {
|
||||||
|
setLocale(locale);
|
||||||
|
const title = 'Global Incident Context';
|
||||||
|
// A shot captured by the operator: no sourcePackId, renamed to this title.
|
||||||
|
const shown = displayShotTitle(
|
||||||
|
title,
|
||||||
|
{ id: 'shot-user', title },
|
||||||
|
{ id: scene.id },
|
||||||
|
);
|
||||||
|
assert.equal(shown, title, `${locale}: got ${shown}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -712,6 +712,10 @@ test('a legacy three-shot Nepal browser project bootstraps to the current 25-sho
|
|||||||
assert.deepEqual(scene.shots.slice(0, 3).map(({ camera }) => camera), originalCameras);
|
assert.deepEqual(scene.shots.slice(0, 3).map(({ camera }) => camera), originalCameras);
|
||||||
assert.equal(scene.appliedShotPacks[0].id, 'bhote-koshi-nepal-evidence-pack');
|
assert.equal(scene.appliedShotPacks[0].id, 'bhote-koshi-nepal-evidence-pack');
|
||||||
assert.equal(scene.appliedShotPacks[0].version, 18);
|
assert.equal(scene.appliedShotPacks[0].version, 18);
|
||||||
|
// displayShotTitle trusts these bindings to localize the bootstrap shots.
|
||||||
|
for (const shot of scene.shots.slice(0, 8)) {
|
||||||
|
assert.equal(scene.appliedShotPacks[0].shotBindings[shot.title], shot.id);
|
||||||
|
}
|
||||||
assert.equal(director._selectedSceneId, scene.id);
|
assert.equal(director._selectedSceneId, scene.id);
|
||||||
assert.equal(director._selectedShotId, scene.shots[0].id);
|
assert.equal(director._selectedShotId, scene.shots[0].id);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
+28
-9
@@ -1061,25 +1061,44 @@ export function displaySceneTitle(scene) {
|
|||||||
* (`sourcePackId`), so a typed title that matches a built-in one stays as
|
* (`sourcePackId`), so a typed title that matches a built-in one stays as
|
||||||
* typed. Without `shot`, the title alone decides.
|
* typed. Without `shot`, the title alone decides.
|
||||||
* @param {string} title
|
* @param {string} title
|
||||||
* @param {{sourcePackId?: string}} [shot]
|
* @param {{id?: string, sourcePackId?: string}} [shot]
|
||||||
* @param {{id?: string}} [scene] The shot's scene, for projects saved before
|
* @param {{id?: string, appliedShotPacks?: Array<{id?: string, shotBindings?: Object<string, string>}>}} [scene]
|
||||||
* shots recorded their source pack.
|
* The shot's scene, for projects saved before shots recorded their source
|
||||||
|
* pack.
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function displayShotTitle(title, shot = undefined, scene = undefined) {
|
export function displayShotTitle(title, shot = undefined, scene = undefined) {
|
||||||
const text = typeof title === 'string' ? title : '';
|
const text = typeof title === 'string' ? title : '';
|
||||||
const fromRecipe = shot
|
const fromRecipe = shot
|
||||||
? Boolean(shot.sourcePackId) || recipeDeclaresShotTitle(scene?.id, text)
|
? Boolean(shot.sourcePackId) || recipeDeclaresShotTitle(scene, shot, text)
|
||||||
: true;
|
: true;
|
||||||
if (fromRecipe && BUILTIN_SHOT_TITLES.has(text)) return t(text);
|
if (fromRecipe && BUILTIN_SHOT_TITLES.has(text)) return t(text);
|
||||||
const numbered = /^Shot ([1-9]\d*)$/.exec(text);
|
const numbered = /^Shot ([1-9]\d*)$/.exec(text);
|
||||||
return numbered ? t('Shot {n}', { n: numbered[1] }) : text;
|
return numbered ? t('Shot {n}', { n: numbered[1] }) : text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether the built-in recipe behind a scene declares a shot with this title. */
|
/** Whether the built-in recipe behind a scene declares this shot's title. */
|
||||||
function recipeDeclaresShotTitle(sceneId, title) {
|
function recipeDeclaresShotTitle(scene, shot, title) {
|
||||||
const recipe = sceneId ? getSceneRecipeById(sceneId) : null;
|
const recipe = scene?.id ? getSceneRecipeById(scene.id) : null;
|
||||||
return Boolean(
|
if (!recipe) return false;
|
||||||
recipe?.cameraPath?.some((keyframe) => keyframe?.title === title),
|
const declares = (path) =>
|
||||||
|
Array.isArray(path) && path.some((keyframe) => keyframe?.title === title);
|
||||||
|
if (declares(recipe.cameraPath)) return true;
|
||||||
|
// A bootstrap recipe seeds legacy "Shot N" keyframes; the upgrade replaces
|
||||||
|
// them with the append recipe's bootstrap shots, which carry no source pack.
|
||||||
|
// The pack marker binds each of those titles to its shot id, so a shot the
|
||||||
|
// operator later gave the same title stays as typed.
|
||||||
|
return SCENE_APPEND_RECIPES.some(
|
||||||
|
(append) =>
|
||||||
|
append.legacySceneBootstrap?.targetSceneTitle === recipe.title &&
|
||||||
|
declares(append.legacySceneBootstrap.cameraPath) &&
|
||||||
|
Boolean(shot?.id) &&
|
||||||
|
(Array.isArray(scene.appliedShotPacks)
|
||||||
|
? scene.appliedShotPacks
|
||||||
|
: []
|
||||||
|
).some(
|
||||||
|
(marker) =>
|
||||||
|
marker?.id === append.id && marker.shotBindings?.[title] === shot.id,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import {
|
import {
|
||||||
|
SCENE_APPEND_RECIPES,
|
||||||
SCENE_RECIPES,
|
SCENE_RECIPES,
|
||||||
displaySceneTitle,
|
displaySceneTitle,
|
||||||
displayShotTitle,
|
displayShotTitle,
|
||||||
@@ -141,3 +142,40 @@ test('the scene context of a shot carries its display title by provenance', asyn
|
|||||||
title,
|
title,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('bootstrap shots of a built-in scene localize without a source pack', () => {
|
||||||
|
setLocale('ru');
|
||||||
|
const append = SCENE_APPEND_RECIPES.find(
|
||||||
|
(recipe) => recipe.legacySceneBootstrap?.cameraPath?.length,
|
||||||
|
);
|
||||||
|
if (!append) return;
|
||||||
|
const bootstrap = append.legacySceneBootstrap;
|
||||||
|
const scene = SCENE_RECIPES.find(
|
||||||
|
(recipe) => recipe.title === bootstrap.targetSceneTitle,
|
||||||
|
);
|
||||||
|
if (!scene) return;
|
||||||
|
for (const { title } of bootstrap.cameraPath) {
|
||||||
|
// The upgrade copies these keyframes into the scene without sourcePackId
|
||||||
|
// and binds each title to its shot in the pack marker.
|
||||||
|
const upgraded = {
|
||||||
|
id: scene.id,
|
||||||
|
appliedShotPacks: [
|
||||||
|
{ id: append.id, version: 1, shotBindings: { [title]: 'shot-old' } },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
assert.equal(
|
||||||
|
displayShotTitle(title, { id: 'shot-old', title }, upgraded),
|
||||||
|
displayShotTitle(title),
|
||||||
|
);
|
||||||
|
// Another shot the operator gave the same title stays as typed.
|
||||||
|
assert.equal(
|
||||||
|
displayShotTitle(title, { id: 'shot-user', title }, upgraded),
|
||||||
|
title,
|
||||||
|
);
|
||||||
|
// The same title in an operator's own scene stays as typed.
|
||||||
|
assert.equal(
|
||||||
|
displayShotTitle(title, { id: 'shot-user', title }, { id: 'scene-user' }),
|
||||||
|
title,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -40,7 +40,7 @@ test('the current language comes first, the rest by their own names', () => {
|
|||||||
nativeNames: LOCALE_NAMES,
|
nativeNames: LOCALE_NAMES,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
['ru', 'en', 'es', 'zh-CN', 'zh-Hant'],
|
['ru', 'uk', 'en', 'es', 'it', 'zh-CN', 'zh-Hant'],
|
||||||
);
|
);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
codes(
|
codes(
|
||||||
@@ -50,7 +50,7 @@ test('the current language comes first, the rest by their own names', () => {
|
|||||||
nativeNames: LOCALE_NAMES,
|
nativeNames: LOCALE_NAMES,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
['es', 'en', 'ru', 'zh-CN', 'zh-Hant'],
|
['es', 'en', 'it', 'ru', 'uk', 'zh-CN', 'zh-Hant'],
|
||||||
);
|
);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
codes(
|
codes(
|
||||||
@@ -60,7 +60,7 @@ test('the current language comes first, the rest by their own names', () => {
|
|||||||
nativeNames: LOCALE_NAMES,
|
nativeNames: LOCALE_NAMES,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
['en', 'es', 'ru', 'zh-CN', 'zh-Hant'],
|
['en', 'es', 'it', 'ru', 'uk', 'zh-CN', 'zh-Hant'],
|
||||||
);
|
);
|
||||||
const rows = buildLocaleOptions({
|
const rows = buildLocaleOptions({
|
||||||
locales: MANY,
|
locales: MANY,
|
||||||
@@ -261,7 +261,8 @@ test('keyboard model: open on the current language, move, choose, close', () =>
|
|||||||
model.openList();
|
model.openList();
|
||||||
assert.equal(model.activeOption.code, 'ru');
|
assert.equal(model.activeOption.code, 'ru');
|
||||||
assert.deepEqual(model.keydown({ key: 'ArrowDown' }), { handled: true });
|
assert.deepEqual(model.keydown({ key: 'ArrowDown' }), { handled: true });
|
||||||
assert.equal(model.activeOption.code, 'en');
|
// Russian collation puts the other Cyrillic name next.
|
||||||
|
assert.equal(model.activeOption.code, 'uk');
|
||||||
model.keydown({ key: 'End' });
|
model.keydown({ key: 'End' });
|
||||||
assert.equal(model.activeOption.code, 'zh-Hant');
|
assert.equal(model.activeOption.code, 'zh-Hant');
|
||||||
model.keydown({ key: 'Home' });
|
model.keydown({ key: 'Home' });
|
||||||
@@ -275,7 +276,7 @@ test('keyboard model: open on the current language, move, choose, close', () =>
|
|||||||
model.keydown({ key: 'ArrowDown' });
|
model.keydown({ key: 'ArrowDown' });
|
||||||
assert.deepEqual(model.keydown({ key: ' ' }), {
|
assert.deepEqual(model.keydown({ key: ' ' }), {
|
||||||
handled: true,
|
handled: true,
|
||||||
choose: 'en',
|
choose: 'uk',
|
||||||
});
|
});
|
||||||
assert.deepEqual(model.keydown({ key: 'Escape' }), {
|
assert.deepEqual(model.keydown({ key: 'Escape' }), {
|
||||||
handled: true,
|
handled: true,
|
||||||
|
|||||||
@@ -730,7 +730,8 @@ html:not([lang='en']) .cockpit-roll-token.is-separator {
|
|||||||
}
|
}
|
||||||
.cockpit-vision-controls {
|
.cockpit-vision-controls {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 48px 58px 48px;
|
/* The current style grows for a long translated name (ЗВИЧАЙНИЙ). */
|
||||||
|
grid-template-columns: 48px minmax(58px, max-content) 48px;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
|||||||
Reference in new issue
Block a user