Ran the full-page comparison against a COUNTRY page, a surface whose localised strings had never been compared in any language. Six more divergences, all in regions.json and all verbatim in the clone, so all copied faithfully while the clone lagged live. Several are subtle and none would survive a glance in a language I do not read: ru "Загрузить еще" to "Загрузить ещё"; ru search placeholder "по именам" to "по названиям"; hi "पूर्ण प्रोफ़ाइल" to "पूरी प्रोफ़ाइल"; hi search placeholder ending "..।" to a real ellipsis "…"; ar "الملف الشخصي الكامل" to "الملف الكامل"; ar "إبحث" to "ابحث", an alif-hamza spelling fix. regions.json is now clean against live on BOTH the region page and the country page, in all seven upstream locales. Two more probe defects, both of which would have produced a false report: SUBJECT= sets an EMPTY STRING, and the probe read process.env.SUBJECT || 'africa'. Empty is falsy, so it silently re-ran the Africa region page while I believed I was measuring the list page -- the leaf count gave it away at 262, identical to the region run. Now ??, which respects an empty string. And the list page turns out not to be comparable by leaf index at all. Their region cards are sorted by LOCALISED name, so leaf i on /en is a different region's card than leaf i on /ru, and aligning by index would have paired the wrong regions' text. The alignment guard caught it and skipped six locales rather than guess, which is the behaviour I want from it. Worth recording that ours already matches theirs exactly here: en, ru, de and ar region-card orders are byte-identical to live, both sorted by the translated label. check:i18n-provenance now records 41 live-sourced keys, each beside the clone value it replaces. |
||
|---|---|---|
| .. | ||
| api | ||
| colors | ||
| components | ||
| composables | ||
| constants | ||
| data | ||
| i18n | ||
| layouts | ||
| maps | ||
| packet | ||
| scripts | ||
| stores | ||
| styles | ||
| utils | ||
| index.js | ||
| ProfileLoader.vue | ||
| README.md | ||
library/ (@map) — the shared map template
The other half of the architecture (see ../plugin-designs/README.md):
every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here.
Fix something here and every map benefits on the next build; break something here and every map
breaks — read components/WARNING.md before touching shared pieces.
| Folder | What lives there |
|---|---|
ProfileLoader.vue |
The root of every bundle: parses profile-config, loads the profile, provides the stores + config |
components/ |
Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README) |
composables/ |
Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming |
stores/ |
Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children |
api/ |
Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring |
colors/ |
Color sets maps opt into via profile-config.colorSet |
i18n/ |
The shared string catalogs (all maps speak the same languages) |
data/ |
Small shared datasets baked at build time (big served data lives in ../data/) |
constants/ |
Shared constants |
scripts/ |
Maintainer pipelines (posters, research) — not part of any bundle |
The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.