doxa-maps/library
doxa-maps-88655c70 cad85227d1 Arabic: take nine terms from the live site, which has revised them since our clone
Diffing the Arabic region page against live turned up three table headers
rendering differently from ours. Tracing them proved we had copied FAITHFULLY:
our values are verbatim in root-dx-life's i18n/locales/ar/common.json under
exactly those keys. The live site renders different strings, and none of the new
ones appears anywhere in that file. The read-only clone we are told to copy from
has fallen behind the site we are told to match.

So the two standing instructions disagreed, and the scope ruling settles it: a
change must MATCH what is on dx-life's /regions pages, and those pages are live.
Copying a string out of the live DOM still translates nothing, so the live
wording wins. dx-life has revised its Arabic terminology -- people groups from
بشرية to شعبية, engaged from منخرط to مخدومة, adopted from تم انتماؤه to متبنّاة.

Every value was mapped BY MEASUREMENT, never by reading Arabic, which I cannot
check: the table by its logical column order (Country, People Groups, 1+ People
Praying, Adopted, Engaged) against their /ar table; the three cards
heading-for-heading and line-for-line; and the two remaining labels by their own
class names, region-stat__label inside "region-stat | card" and
.color-brand-lighter, both present on their EN and their AR page.

Result: 60 of the 61 Arabic strings our page renders are now identical to live,
up from 51. The table headers match byte for byte. The one remainder is their
own map-note template, ours byte-identical to their file, which their page does
not display -- so there is no live evidence it changed and it is left alone.

Four other keys also contain مجموعة بشرية and are deliberately NOT touched: the
revision live may well be partial, and without a rendered string to measure
against there is nothing to copy.

Two of my own oracles were corrected on the way. The page-text diff filtered to
strings under 60 characters, which silently excluded every long goal sentence --
raised to 220, which is how the interpolated summary line surfaced at all. And
that diff marks a rendered string "clone lacks it" whenever the clone holds a
TEMPLATE with placeholders, so interpolated text can never match a raw value
set; that is a property of the oracle, not evidence of invention.

check:i18n-provenance now records these nine as taken from live, each beside the
value the clone still carries, so the decision stays auditable and a future clone
refresh can be checked against it. Any other locale and any other key still
fails, so a hand-translated string remains exactly as catchable as before.
Parity PASS, SRI PASS, and the RTL region-page diff still reports 0 differences.
2026-09-25 01:02:15 +00:00
..
api Add the Gospel Access filter, the ladder the binary flag was flattening 2026-09-23 13:19:22 +00:00
colors Adopt the research map's region colours, and pin the one unit that wasn't px 2026-09-24 20:48:27 +00:00
components poster cards: a blue outline on hover, and a gate that can see it 2026-09-24 23:17:42 +00:00
composables Merge commit '840830ebc47250b642d6d58ba1e584a30e74d47d' into bundler-1/work 2026-09-24 22:45:25 +00:00
constants doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
data Regions: expand a region to its country posters, reusing the shared wall 2026-09-24 04:26:29 +00:00
i18n Arabic: take nine terms from the live site, which has revised them since our clone 2026-09-25 01:02:15 +00:00
layouts Plugin studio: an Explorer tree for the rail, imitating VS Code 2026-09-24 21:40:48 +00:00
maps Load the RTL text plugin from one place, and in the composite too 2026-09-22 19:55:58 +00:00
packet packet: a partial translation renders 12 prayer points, not 3 2026-09-24 12:20:38 +00:00
scripts packets: fixtures at the PAGE BOUNDARY, which nothing had ever rendered 2026-09-24 23:53:07 +00:00
stores fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
styles Fiord: the MapLibre dark that actually looks like the map it replaces 2026-09-24 02:26:14 +00:00
utils Regions: one rollup, ported from theirs, instead of two copies 2026-09-24 04:01:34 +00:00
index.js Brand-neutral shared VerticalTabsLayout with lazy nested-element hosting; fix cap-5 prayer tab leaf path; neutralize library identifiers; add Forgejo CI build-gate workflow 2026-09-19 17:24:30 +00:00
ProfileLoader.vue One page, one map token — and the nested search bar comes back 2026-09-24 01:14:37 +00:00
README.md Complete app-profiles->plugin-designs sweep across comments/docs; build green; layouts kept at root (load-bearing) 2026-09-17 18:18:19 +00:00

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.