Merge origin/main into claude/hal-676-gev-fire-intensity-742bd1

Locale conflicts (es, ru, zh-CN): keep both sides' new keys. The new uk
and zh-Hant catalogs get the fire filter strings; zh-Hant keeps
"≥ {value} MW" as in English, like zh-CN.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-29 17:22:30 +04:00
commit 520cf4cb4f
237 files changed
+10805 -944

No files matched your search

+2
View File
@@ -1102,6 +1102,8 @@
"src/cameraGlobeRotation.test.mjs",
"src/voice/globeResetConfirmation.test.mjs",
"src/hudDms.test.mjs",
"src/hudSummaryGate.test.mjs",
"src/voice/hudPlaceLabels.test.mjs",
"src/voice/panel/preferences.test.mjs",
"src/voice/panel/host.test.mjs",
"src/voice/panel/manualPanel.test.mjs",
+107 -20
View File
@@ -441,7 +441,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -480,7 +482,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -511,7 +515,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/ui/keyGuidance.js",
"src/ui/statusText.js",
@@ -532,7 +538,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -548,7 +556,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -567,7 +577,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/ui/statusBadge.js"
],
@@ -593,7 +605,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/layerNames.js"
],
"external": []
@@ -627,7 +641,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium"]
@@ -643,7 +659,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": []
@@ -803,7 +821,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/ui/keyGuidance.js",
"src/ui/layerNames.js",
@@ -924,7 +944,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium"]
@@ -992,7 +1014,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium"]
@@ -1041,7 +1065,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1104,7 +1130,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1133,7 +1161,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/layers/recentImagery/display.js"
],
@@ -1164,7 +1194,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1194,7 +1226,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium", "satellite.js"]
@@ -1227,7 +1261,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1269,7 +1305,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/layers/installations/classLabel.js"
],
"external": ["cesium", "@mapbox/vector-tile", "pbf"]
@@ -1305,7 +1343,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium"]
@@ -1355,7 +1395,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium", "pbf", "@mapbox/vector-tile"]
},
@@ -1384,7 +1426,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1432,7 +1476,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["hls.js", "cesium"]
},
@@ -1495,7 +1541,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/layers/streetLevel/providers/mapillary/policy.js"
],
"external": ["cesium", "pbf", "@mapbox/vector-tile", "mapillary-js"]
@@ -1524,7 +1572,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium", "@mapbox/vector-tile", "pbf"]
},
@@ -1565,7 +1615,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1587,7 +1639,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1643,7 +1697,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -1705,7 +1761,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/statusText.js",
"src/voice/providerCommands.js",
"src/voice/providerCapabilities.js",
@@ -1934,6 +1992,7 @@
"src/hud.js",
"src/hudLocality.js",
"src/hudLocalityFormat.js",
"src/hudPlaceLookup.js",
"src/hudSummaryResponse.js",
"src/keySetup.js",
"src/keySetupCore.mjs",
@@ -2589,7 +2648,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/layers/recentImagery/display.js",
"src/ui/keyGuidance.js",
@@ -3174,7 +3235,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js",
"src/layers/recentImagery/display.js",
"src/layers/installations/classLabel.js",
@@ -3284,7 +3347,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/i18n/index.js"
],
"external": ["cesium"]
@@ -3308,7 +3373,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -3344,7 +3411,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/scopeMaskPolicy.js",
"src/ui/displayControls.js"
],
@@ -3370,7 +3439,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": []
},
@@ -3461,7 +3532,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/unitLabels.js"
],
"external": ["cesium"]
@@ -3516,7 +3589,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/statusText.js",
"src/voice/providerCapabilities.js"
],
@@ -3770,7 +3845,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium", "egm96-universal", "pbf"]
},
@@ -3813,7 +3890,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium", "pbf"]
},
@@ -3866,7 +3945,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/zh-CN.json"
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json"
],
"external": ["cesium"]
},
@@ -3882,7 +3963,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/statusText.js",
"src/ui/layerNames.js"
],
@@ -3942,7 +4025,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/data/geoImportImages.js",
"src/data/geoImportPins.js",
"src/layers/streetLevel/tileMath.js",
@@ -4141,7 +4226,9 @@
"src/i18n/locale.js",
"src/i18n/locales/es.json",
"src/i18n/locales/ru.json",
"src/i18n/locales/uk.json",
"src/i18n/locales/zh-CN.json",
"src/i18n/locales/zh-Hant.json",
"src/ui/statusText.js",
"src/ui/layerNames.js"
],
+64
View File
@@ -88,6 +88,70 @@ try {
};
});
for (const [name, passed] of Object.entries(result)) check(name, passed);
const visibilityRestored = await page.evaluate(async () => {
// QA layer registration exists only in Vite dev builds.
if (typeof window.__gevQaRegisterLayer !== 'function') return 'skipped';
const { sceneDirector: director, dataManager } = window.__godsEyeView;
const layerId = 'director-seek-visibility-qa';
window.__gevQaRegisterLayer(dataManager, {
id: layerId,
name: 'Director seek visibility QA',
updateInterval: -1,
init() {},
enable() {},
disable() {},
update() {},
destroy() {},
getStats: () => ({ count: 0 }),
});
const scene = {
id: 'visibility-qa',
title: 'Visibility QA',
shots: [
{
id: 'visibility-shot',
title: 'Visibility shot',
durationSec: 0.4,
holdSec: 0,
camera: director.styleManager.getCameraState(),
visual: director.styleManager.getVisualState(),
layers: { [layerId]: { enabled: true } },
},
],
};
director._project.scenes.push(scene);
try {
const loaded = await director.loadShot(scene.id, scene.shots[0].id, {
flyDuration: 0.2,
});
const disabled =
(await dataManager.setEnabled(layerId, false, { origin: 'user' })) &&
!dataManager.layers.get(layerId).enabled;
const sought = await director.seekScene(scene.id, 0.5);
return (
loaded?.started &&
disabled &&
sought &&
dataManager.layers.get(layerId).enabled
);
} finally {
director.stopScene();
director._project.scenes = director._project.scenes.filter(
({ id }) => id !== scene.id,
);
await window.__gevQaUnregisterLayer(dataManager, layerId);
}
});
if (visibilityRestored === 'skipped') {
console.log(
'[SKIP] same-shot seek visibility needs a Vite dev server (QA_BASE_URL)',
);
} else {
check(
'same-shot seek restores manually changed layer visibility',
visibilityRestored,
);
}
const content = await page.evaluate(async () => {
const d = window.__godsEyeView.sceneDirector;
const scene = d._project.scenes.find(({ title }) =>
-43
View File
@@ -1,43 +0,0 @@
#!/usr/bin/env node
// Minimal screenshot sink: the browser POSTs a data:image/... URL (grabbed from
// the real-GPU Cesium canvas) and this writes it to qa-shots/height-datum/<name>.
// Keeps large image payloads OUT of the agent's context — browser → sink → disk.
// Usage: node scripts/shot-sink.mjs (listens on :4399)
import http from 'node:http';
import { writeFileSync, mkdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
const OUT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'qa-shots', 'height-datum');
mkdirSync(OUT, { recursive: true });
const PORT = 4399;
const cors = (res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
};
http.createServer((req, res) => {
cors(res);
if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; }
const url = new URL(req.url, 'http://localhost');
if (req.method === 'POST' && url.pathname === '/save') {
const name = (url.searchParams.get('name') || 'shot').replace(/[^a-zA-Z0-9._-]/g, '_');
let body = '';
req.on('data', (c) => { body += c; });
req.on('end', () => {
try {
const m = /^data:image\/(png|jpeg);base64,(.+)$/s.exec(body.trim());
if (!m) { res.writeHead(400); res.end('bad dataurl'); return; }
const ext = m[1] === 'jpeg' ? 'jpg' : 'png';
const file = path.join(OUT, `${name}.${ext}`);
writeFileSync(file, Buffer.from(m[2], 'base64'));
res.writeHead(200); res.end(file);
console.log(`saved ${file} (${Math.round(m[2].length / 1024)} KB b64)`);
} catch (e) { res.writeHead(500); res.end(String(e)); }
});
return;
}
res.writeHead(404); res.end('nope');
}).listen(PORT, () => console.log(`shot-sink on http://localhost:${PORT} → ${OUT}`));