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]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-28 22:55:24 +04:00
1 parent 4f44a17b44
commit 8540535817
15 files changed
+253 -174

No files matched your search

+26 -10
View File
@@ -1,5 +1,5 @@
import { CCTV_AMBIENT_CARD_MAX } from '../../data/cctvLod.js';
import { t } from '../../i18n/index.js';
import { t, translateKnown } from '../../i18n/index.js';
import { ACTIVE_FRAME_REFRESH_MS, IDLE_FRAME_REFRESH_MS } from './policy.js';
import { headingHudToken, isHeadingEstimated } from './headingConfidence.js';
import {
@@ -8,6 +8,22 @@ import {
isDatasheetFov,
} from './modelSpecs.js';
/** The translated name of a camera view band (street, city, regional, global). */
function viewBandLabel(band) {
switch (band) {
case 'street':
return t('STREET', { context: 'view band' });
case 'city':
return t('CITY', { context: 'view band' });
case 'regional':
return t('REGIONAL', { context: 'view band' });
case 'global':
return t('GLOBAL', { context: 'view band' });
default:
return String(band).toUpperCase();
}
}
export function createPresentation({
state: layerState,
services,
@@ -73,16 +89,16 @@ export function createPresentation({
layerState._showProjection ? t('PROJ MONITOR') : t('PROJ OFF'),
layerState._coverageMode === 'viewshed' ? t('VIEWSHED') : null,
t('CAL {value}', {
value: calBadge.replace('-', ' ').toUpperCase(),
value: translateKnown(calBadge.replace('-', ' ').toUpperCase()),
}),
health?.sourceKind
? t('SRC {value}', {
value: String(health.sourceKind).toUpperCase(),
})
: t('SRC {value}', {
value: String(active.camera.feedType || 'image').toUpperCase(),
}),
t('{value} CONTEXT', { value: viewBand.toUpperCase() }),
t('SRC {value}', {
value: translateKnown(
String(
health?.sourceKind || active.camera.feedType || 'image',
).toUpperCase(),
),
}),
t('{value} CONTEXT', { value: viewBandLabel(viewBand) }),
// Identified hardware: append the model's datasheet specs + attribution.
active.camera.spec
? t('{spec} · SPECS: CCTV-DATABASE.COM', {
+7 -3
View File
@@ -1,5 +1,5 @@
import * as Cesium from 'cesium';
import { formatNumber, isolate, t } from '../../i18n/index.js';
import { formatNumber, getLocale, isolate, t, tn } from '../../i18n/index.js';
import {
satelliteShortName,
fireDetectionKey,
@@ -407,7 +407,6 @@ export function createModel({
function buildCellCard(candidate, nowMs) {
const cell = candidate.cell;
const noun = cell.count === 1 ? t('FIRE') : t('FIRES');
const parts = [t('max {value} MW', { value: formatFrpLabel(cell.maxFrp) })];
if (cell.newestAcqMs > 0) {
const age = formatAgeLabel(nowMs - cell.newestAcqMs);
@@ -419,7 +418,12 @@ export function createModel({
cullPosition: candidate.cullPosition || candidate.position,
gapPx: 10,
accent: candidate.accent || accentForSeverity('yellow'),
title: `${cell.count} ${noun}`,
// The count picks the plural form of the language ("حريقان (2)",
// "14 حريقًا", "14 ПОЖАРОВ"); the card shows it in capitals like the
// other card titles.
title: tn(cell.count, '{n} fire', '{n} fires', {
n: cell.count,
}).toLocaleUpperCase(getLocale()),
details: [parts.join(' · ')],
selected: false,
priority: Number(cell.maxFrp) || 0,