Public data ships without working notes; unused data files stay out of the drop-in
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions

- data/ tables and the people-groups file: meta blocks reduced to provenance (source, url,
  downloaded, rows, grain, attribution); the link-verification table keeps only state and detail
  per link; generators write the same shape
- dropin.exclude in the build config: people_groups.csv, open-doors.json, platform-reachability.json
  and tables/index.json are not shipped (nothing loads them); sync-dropin honours it
- public-hygiene --strict flags note-style meta keys in shipped data
- Rebuilt bundles and gallery
This commit is contained in:
swift-river542 2026-09-16 20:16:08 -05:00
parent 8aa3848bdc
commit b7d91e9aca
70 changed files with 3736 additions and 241 deletions

View file

@ -148,7 +148,7 @@ const languages = computed(() => {
const meta = computed(() => tables.value.resources?.meta || {})
const checkedPools = computed(() => (meta.value.sources || []).map((s) => s.name).join(', ') || 'unknown')
const uncheckedPools = computed(() => (meta.value.unchecked || [])
const uncheckedPools = computed(() => (meta.value.not_included || meta.value.unchecked || [])
.map((s) => `${s.name} (${s.covers})`).join('; ') || 'unknown')
// The caveat block every chart carries — the pools, and what a missing value means.

View file

@ -39,25 +39,25 @@
"id": "grn",
"name": "Global Recordings Network",
"covers": "audio (37,697 recordings)",
"blocked": "API key required (see BLOCKER-grn-api-key.md)"
"status": "not included: requires an API key"
},
{
"id": "api_bible",
"name": "API.Bible (bible.com ecosystem)",
"covers": "scripture",
"blocked": "HTTP 401 — key required"
"status": "not included: requires an API key"
},
{
"id": "dbl",
"name": "Digital Bible Library",
"covers": "scripture",
"blocked": "not yet evaluated"
"status": "not included: not evaluated"
},
{
"id": "progress_bible",
"name": "progress.bible",
"covers": "translation status",
"blocked": "HTTP 403 to programmatic access"
"status": "not included: no programmatic access"
}
],
"boundary": "Resource AVAILABILITY per language only. Contains no church, believer or meeting-point data, and must not gain any."

View file

@ -235,34 +235,22 @@ async function main() {
film: { checked: fRes.length, ...tally(fRes) },
}
// The shipped file carries exactly what the map reads — one state and one detail line per
// URL — plus the run's summary. Controls, methods and response hashes are this script's own
// log (printed above), not data for a visitor.
const out = {
meta: {
title: 'Gospel resource link verification',
generated: new Date().toISOString(),
grain: 'one entry per DISTINCT resource URL',
states: {
verified: 'the link resolves to the language the row claims (see method)',
broken: 'the target does not exist, or holds nothing to open',
mismatch: 'the link resolves, but to a DIFFERENT language than the row joined on',
unknown: 'could not be checked — never read as either working or broken',
},
methods: {
'ebible-http': 'HTTP GET of the eBible page. eBible returns a real 404 for a bogus code and distinct bodies for valid ones, so status is meaningful here.',
'arclight-api': 'The languageId is looked up in the Arclight catalogue (core.arclight.org/v2/media-languages), asserting it exists, its iso3 equals the code the row joined on, and it lists at least one film. jesusfilm.org is NOT fetched: it is a client-rendered SPA that returns a byte-identical HTTP 200 for a bogus languageId, so fetching it could only produce a false green.',
},
limits: [
'A film "verified" is a CATALOGUE check, not an independent one: it confirms the link points at the language claimed, not that Arclight itself is correct.',
'Nothing here was rendered in a browser. A verified link is a link that resolves — not a promise about what a visitor sees.',
'"unknown" means not checked or not checkable. It is never evidence that a resource is absent.',
],
controls: {
negative: ['eBible bogus code zzz9999', 'Arclight bogus languageId 99999999', 'Arclight valid languageId 13562 asserted against wrong iso "zzz"'],
positive: ['eBible eng-web', 'Arclight languageId 13562 vs iso "apd"'],
note: 'All five ran and behaved before any result below was written; the script exits non-zero without writing if any misbehaves.',
},
summary,
},
links,
links: Object.fromEntries(Object.entries(links).map(([u, r]) => [u, { state: r.state, detail: r.detail }])),
}
writeFileSync(OUT, JSON.stringify(out, null, 0))

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@
"grain": "one row per people group",
"the_question": "Can this group reach the gospel today — in their heart language, or through a bridge language of their country that already carries a resource?",
"opportunity_meaning": "No resource in the heart language, but a language spoken by MULTIPLE groups in the same country DOES have one. Reachable now with what already exists.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. Brief: \"opportunities exist in many places where resources and environment are all aligned for the gospel work to happen.\" These are the highest-leverage rows here.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. These are the highest-leverage rows here.",
"gap_meaning": "Nothing found in the heart language AND no in-country bridge language carries anything, in the pools checked.",
"bridge_strength_note": "MEASURED: 24% of aligned rows rest on a bridge shared by only 2-3 groups. bridge_strength grades this (strong >=8 groups, moderate >=4, weak <4). A WEAK bridge is a hypothesis, not a route — e.g. \"Gawri\" was offered as the bridge for 10.3M Pakistanis where the real lingua franca is Urdu, which no unengaged group here claims as primary and which this method therefore cannot see. Filter on bridge_strength before acting.",
"bridge_caveat": "A bridge candidate is measured from THIS corpus (a language primary to >1 DX group in the country). It is NOT proof the group speaks it, and it is NOT a national trade language — a lingua franca no unengaged group claims as primary is invisible here.",

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"generated": "2026-08-01",
"method": "IEMV \u2014 extraction by the fetch/derive scripts, MODELING + VALIDATION here",
"method": "Derived from the source tables in this folder.",
"tables": [
{
"name": "people-group-resources",
@ -60,8 +60,7 @@
},
{
"name": "gaps-and-opportunities",
"rows": 2106,
"producer": "build-trade-languages.mjs"
"rows": 2106
}
]
}

View file

@ -3,7 +3,7 @@
"title": "Key Cities under Admin-N",
"grain": "one row per NAMED location cluster, with its sub-country admin unit",
"derivation": "key_tier is a band over PIN DENSITY computed from this corpus: key-high >= 4 groups (top decile), key >= 3 (top quartile), else candidate.",
"HARD_LIMIT": "VERIFICATION IS SINGLE-SOURCE. Every name comes from Nominatim/OSM and NOTHING here is cross-referenced against a second gazetteer. verification_tier says exactly what was established. A \"verified key-cities list\" in the full sense needs a second independent source — NOT yet done.",
"verification_limit": "Place names are single-source: Nominatim/OSM, not cross-checked against a second gazetteer. verification_tier says exactly what was established.",
"admin_n_note": "admin_n is the sub-country unit OSM reports (276 of 277 named places have one, 81 distinct values). What that level is CALLED varies by country — geoBoundaries boundaryCanonical gives the native term (State/Union Territory, Province, Wilayat, Region...). Not mislabelled \"province\" for everyone.",
"rendering": "No city polygons are shipped; every row renders as a STAR pin, visually distinct from people-group pins.",
"source": "Nominatim/OpenStreetMap (ODbL 1.0) for names; people-group counts from the DX spine."

View file

@ -9,7 +9,7 @@
"generated": "2026-08-01",
"definition": "A BRIDGE CANDIDATE is a language that is the primary language of MORE THAN ONE distinct DX people group in that country — measured from the corpus, not asserted from a list.",
"honest_limit": "This is NOT the same as a national trade language. It finds languages widely used AMONG THE UNENGAGED GROUPS TRACKED HERE, and will MISS a lingua franca that no unengaged group claims as primary (e.g. Hindi in India). Named bridge_candidates, not trade_languages, for that reason.",
"why_not_a_list": "restcountries v3.1 is DEPRECATED (returns an error body); Ethnologue is paywalled; Glottolog has no lingua-franca field. Hand-typing 175 national languages from memory is exactly where a confident error would enter."
"why_not_a_list": "No open machine-readable list of national trade languages was available; bridge candidates are derived from this corpus."
}
},
"columns": [

View file

@ -3,7 +3,7 @@
"title": "Open Doors — where the path is clear, and where it is not",
"grain": "one row per people group x country",
"the_question": "Every other table answers SUPPLY (does a resource exist, is there internet). This answers ROUTE: could a person here reach the gospel in their own language today?",
"THE_BOUNDARY": "There is a FOURTH leg — is anyone there — deliberately ABSENT and it must stay absent (NEVER-DO #6). This table pins resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open NEVER means the gospel has arrived.",
"boundary": "This table records resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open never means the gospel has arrived.",
"verdicts": "channel-open-no-resource (highest translation leverage) · resource-exists-channel-shut (a DISTRIBUTION problem, not a translation one) · no-resource-and-no-channel · resource-and-channel-but-network-poor · channel-UNMEASURED (no probe coverage — an UNKNOWN, never read as censorship) · path-open.",
"honesty": "not-measured platforms are counted SEPARATELY and never as open or shut. Rows carry channels_not_measured + a confidence_note so a verdict resting on partial data says so.",
"derived_from": "gospel-access-vs-growth + platform-reachability + connectivity-by-country. NO new research — a join over already-verified tables."

View file

@ -20,30 +20,30 @@
"note": "public API, no key required — carries iso3 per language, so the join is exact"
}
],
"unchecked": [
"not_included": [
{
"id": "grn",
"name": "Global Recordings Network",
"covers": "audio (37,697 recordings)",
"blocked": "API key required (see BLOCKER-grn-api-key.md)"
"status": "not included: requires an API key"
},
{
"id": "api_bible",
"name": "API.Bible (bible.com ecosystem)",
"covers": "scripture",
"blocked": "HTTP 401 — key required"
"status": "not included: requires an API key"
},
{
"id": "dbl",
"name": "Digital Bible Library",
"covers": "scripture",
"blocked": "not yet evaluated"
"status": "not included: not evaluated"
},
{
"id": "progress_bible",
"name": "progress.bible",
"covers": "translation status",
"blocked": "HTTP 403 to programmatic access"
"status": "not included: no programmatic access"
}
],
"absence_meaning": "FALSE means NOT FOUND in the pools checked — never proof that no resource exists.",

View file

@ -22,6 +22,11 @@
* page), assets/ (data) and <tree>/ (the bundle folders + manifest.json). Every other
* root entry — a shell's nav.js, external/, _headers … — is a FINDING under --strict
* ("outside the drop-in contract"); without --strict it is a warning
* meta — working notes shipped as data: a JSON under assets/ whose top-level "meta" carries
* a key named like a to-do or an internal rule (unchecked, blocked, todo, HARD_LIMIT,
* THE_BOUNDARY, robots, NEVER) or a value quoting one ("Brief:", "not yet", "TODO",
* "NEVER-DO"). A served data file carries provenance, not notes — a FINDING under
* --strict, a warning otherwise
* Also prints an inventory (bundles, leaf pages, staging pages, assets by folder, total size).
*
* Usage: node internal/public-hygiene-check.mjs [<dir> | --root <dir>] [--tree doxa-maps] [--strict] [--json out.json]
@ -69,6 +74,23 @@ for (const f of files) {
if (/sourceMappingURL=/.test(t)) hit(warnings, 'debug', f.rel, 'sourceMappingURL comment (map file absent → harmless, but points at a missing map)')
if (ext === '.js' && /console\.(log|debug)\(/.test(t)) hit(warnings, 'debug', f.rel, 'console.log/debug in a shipped bundle')
}
// working notes in data: a JSON under assets/ whose top-level "meta" carries a key named like a
// to-do or an internal rule, or a value that quotes one. Provenance ships; notes do not.
const META_KEY = /unchecked|blocked|todo|hard_limit|the_boundary|robots|never/i
const META_VALUE = [[/Brief:/, '"Brief:"'], [/\bnot yet\b/i, '"not yet"'], [/\bTODO\b/, '"TODO"'], [/NEVER-DO/, '"NEVER-DO"']]
for (const f of files) {
if (!f.rel.startsWith('assets/') || extname(f.rel).toLowerCase() !== '.json' || f.size > 40 * 1024 * 1024) continue
let doc; try { doc = JSON.parse(readFileSync(f.abs, 'utf8')) } catch { continue }
const meta = doc && typeof doc === 'object' && !Array.isArray(doc) ? doc.meta : null
if (!meta || typeof meta !== 'object') continue
const notes = new Set()
;(function scan(node, path) {
if (Array.isArray(node)) { node.forEach((v, i) => scan(v, `${path}[${i}]`)); return }
if (node && typeof node === 'object') { for (const [k, v] of Object.entries(node)) { const p = `${path}.${k}`; if (META_KEY.test(k)) notes.add(`key ${p} reads as a working note`); scan(v, p) }; return }
if (typeof node === 'string') for (const [re, why] of META_VALUE) if (re.test(node)) notes.add(`${path} contains ${why}`)
})(meta, 'meta')
for (const d of notes) hit(STRICT ? findings : warnings, 'meta', f.rel, d)
}
// staging surfaces: <tree>/index.html and <tree>/<bundle>/index.html (leaf pages are deeper)
const staging = files.filter(f => f.rel === `${TREE}/index.html` || /^[^/]+\/[^/]+\/index\.html$/.test(f.rel) && f.rel.startsWith(`${TREE}/`)).map(f => f.rel)
for (const s of staging) hit(STRICT ? findings : warnings, 'staging', s, 'preview/staging page (internal surface) — exclude from a public mirror or accept knowingly')

View file

@ -18,7 +18,11 @@
* are internal surfaces; partners embed the LEAF pages one level deeper (--keep-staging to
* opt back in);
* · host-owned files can be PROTECTED with --protect (none by default) — never overwritten,
* never deleted.
* never deleted;
* · built data that no page fetches is NOT shipped — "dropin.exclude" in the build-config (path
* prefixes relative to public/, inside the allowlist; internal scripts still read them here).
* Honoured with --from-config; counted as "excluded (not shipped)"; a copy already in <dest>
* is removed like any other stale file.
*
* THE DROP-IN CONTRACT (allowlist): a host does not need the whole web-root. The website takes
* ONLY the bundles it embeds, declared ONCE in vite.doxa-maps-build-config.json under
@ -38,7 +42,8 @@
* [--only a,b | --from-config] [--prune] [--protect a.txt,other] [--dry-run]
* e.g. node internal/sync-dropin.mjs ../doxa-life/public/embed/doxa-maps-build --from-config --prune
* Prints: copied · unchanged · deleted (stale inside the allowlist) · pruned (outside it) ·
* excluded (credentials/docs/staging), then the destination's top-level tree after the sync.
* excluded (credentials/docs/staging) · excluded (not shipped: dropin.exclude), then the
* destination's top-level tree after the sync.
* Exit: 0 synced (or dry-run printed) · 1 bad arguments / dest missing / no allowlist in config
* Review the result with `git -C <host> status` — the host repo is the restore point.
*/
@ -71,7 +76,12 @@ const isDoc = (f) => /\.(md|markdown|txt)$/i.test(f)
const TREE = String(argOf('--tree', 'doxa-maps')).replace(/\/+$/, '')
const KEEP_STAGING = args.includes('--keep-staging')
const isStaging = (f) => !KEEP_STAGING && (f === `${TREE}/index.html` || new RegExp(`^${TREE.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/[^/]+/index\\.html$`).test(f))
const excluded = (f) => EXCLUDE.has(f) || isDoc(f) || isStaging(f)
// Built data nothing shipped fetches: "dropin.exclude" in the build-config (read with --from-config,
// below) — path prefixes relative to public/. Internal scripts still read them in this repo.
let NOT_SHIPPED = []
const isNotShipped = (f) => NOT_SHIPPED.some(p => f === p || f.startsWith(p + '/'))
const excludedInternal = (f) => EXCLUDE.has(f) || isDoc(f) || isStaging(f)
const excluded = (f) => excludedInternal(f) || isNotShipped(f)
const usage = 'usage: node internal/sync-dropin.mjs [<dest>] [--from public] [--only a,b | --from-config] [--prune] [--protect a,b] [--dry-run] (<dest> defaults to $DOXA_DROPIN_DEST, then dropin.dest in vite.doxa-maps-build-config.json)'
if (!DEST) { console.error(`[sync-dropin] ${usage}`); process.exit(1) }
@ -93,6 +103,10 @@ if (args.includes('--only')) {
if (!Array.isArray(inc) || !inc.length || !inc.every(s => typeof s === 'string')) { console.error(`[sync-dropin] --from-config: ${norm(relative(ROOT, CONFIG))} declares no "dropin": { "include": [ …path prefixes relative to public/… ] }`); process.exit(1) }
ALLOW = inc.map(normPrefix).filter(Boolean)
ALLOW_FROM = `${norm(relative(ROOT, CONFIG))} · dropin.include`
const exc = cfg?.dropin?.exclude
if (exc !== undefined && (!Array.isArray(exc) || !exc.every(s => typeof s === 'string'))) { console.error(`[sync-dropin] --from-config: "dropin.exclude" must be an array of path prefixes relative to public/`); process.exit(1) }
NOT_SHIPPED = (exc || []).map(normPrefix).filter(Boolean)
if (NOT_SHIPPED.some(p => p.split('/').includes('..'))) { console.error(`[sync-dropin] dropin.exclude climbs out of ${norm(relative(ROOT, FROM))}/: ${JSON.stringify(NOT_SHIPPED)}`); process.exit(1) }
}
if (ALLOW && (!ALLOW.length || ALLOW.some(p => p.split('/').includes('..')))) { console.error(`[sync-dropin] allowlist is empty or climbs out of ${norm(relative(ROOT, FROM))}/: ${JSON.stringify(ALLOW)}`); process.exit(1) }
const allowed = f => !ALLOW || ALLOW.some(p => f === p || f.startsWith(p + '/'))
@ -111,9 +125,10 @@ const destReal = realpathSync(dest)
const insideDest = f => { try { return realpathSync(join(dest, f)).startsWith(destReal + sep) } catch { return false } }
const allSrc = walk(FROM)
const excludedCount = allSrc.filter(excluded).length
const excludedCount = allSrc.filter(excludedInternal).length
const notShippedCount = allSrc.filter(f => !excludedInternal(f) && isNotShipped(f)).length
const src = allSrc.filter(f => !excluded(f) && allowed(f))
const outsideSrc = allSrc.length - excludedCount - src.length // built, but not part of the contract
const outsideSrc = allSrc.length - excludedCount - notShippedCount - src.length // built, but not part of the contract
const have = new Set(walk(dest))
const result = new Set() // what <dest> holds after the sync
let copied = 0, unchanged = 0, deleted = 0, pruned = 0, kept = 0, protectedSkips = 0, refused = 0
@ -162,6 +177,7 @@ function renderTree(paths, depth = 2) {
console.log(`[sync-dropin] ${DRY ? 'DRY RUN — ' : ''}${norm(relative(ROOT, FROM))}/ → ${dest}`)
if (ALLOW) console.log(`[sync-dropin] allowlist (${ALLOW_FROM}): ${ALLOW.join(', ')} — ${PRUNE ? '--prune: everything else in the destination is removed' : 'no --prune: destination files outside it are left alone'}`)
else if (PRUNE) console.log('[sync-dropin] --prune has no effect without an allowlist (--only or --from-config) — full mirror as usual')
console.log(`[sync-dropin] copied ${copied} · unchanged ${unchanged} · deleted ${deleted} · pruned ${pruned} · protected ${protectedSkips}${PROTECT.size ? ` (${[...PROTECT].join(', ')})` : ''} · excluded ${excludedCount} (credentials/docs/staging)${ALLOW ? ` · outside allowlist: ${outsideSrc} built file(s) not shipped${kept ? `, ${kept} destination file(s) left` : ''}` : ''}${refused ? ` · refused ${refused} (resolve outside the destination)` : ''}`)
if (NOT_SHIPPED.length) console.log(`[sync-dropin] not shipped (dropin.exclude): ${NOT_SHIPPED.join(', ')}`)
console.log(`[sync-dropin] copied ${copied} · unchanged ${unchanged} · deleted ${deleted} · pruned ${pruned} · protected ${protectedSkips}${PROTECT.size ? ` (${[...PROTECT].join(', ')})` : ''} · excluded ${excludedCount} (credentials/docs/staging)${NOT_SHIPPED.length ? ` · excluded (not shipped) ${notShippedCount} (dropin.exclude)` : ''}${ALLOW ? ` · outside allowlist: ${outsideSrc} built file(s) not shipped${kept ? `, ${kept} destination file(s) left` : ''}` : ''}${refused ? ` · refused ${refused} (resolve outside the destination)` : ''}`)
console.log(`[sync-dropin] destination${DRY ? ' (as it would be)' : ''}: ${result.size} file(s)`)
renderTree([...result])

View file

@ -63,12 +63,12 @@ const POOLS = [{
accessed: '2026-08-01',
note: 'public API, no key required — carries iso3 per language, so the join is exact',
}];
// Pools NOT yet checked — named so the gaps are legible rather than implied-complete.
// Pools not included — named so the gaps are legible rather than implied-complete.
const UNCHECKED = [
{ id: 'grn', name: 'Global Recordings Network', covers: 'audio (37,697 recordings)', blocked: 'API key required (see BLOCKER-grn-api-key.md)' },
{ id: 'api_bible', name: 'API.Bible (bible.com ecosystem)', covers: 'scripture', blocked: 'HTTP 401 — key required' },
{ id: 'dbl', name: 'Digital Bible Library', covers: 'scripture', blocked: 'not yet evaluated' },
{ id: 'progress_bible', name: 'progress.bible', covers: 'translation status', blocked: 'HTTP 403 to programmatic access' },
{ id: 'grn', name: 'Global Recordings Network', covers: 'audio (37,697 recordings)', status: 'not included: requires an API key' },
{ id: 'api_bible', name: 'API.Bible (bible.com ecosystem)', covers: 'scripture', status: 'not included: requires an API key' },
{ id: 'dbl', name: 'Digital Bible Library', covers: 'scripture', status: 'not included: not evaluated' },
{ id: 'progress_bible', name: 'progress.bible', covers: 'translation status', status: 'not included: no programmatic access' },
];
// ── eBible CSV ───────────────────────────────────────────────────────────────

View file

@ -175,7 +175,7 @@ const obsFor = (iso) => {
title: 'People Groups × Gospel Resources',
grain: 'one row per people group',
sources: src.stats.pools_checked,
unchecked: src.stats.pools_unchecked,
not_included: src.stats.pools_unchecked,
absence_meaning: 'FALSE means NOT FOUND in the pools checked — never proof that no resource exists.',
unmatchable_note: '33 of 862 DX language codes are OUTSIDE the ISO 639-3 registry (31 private-use q*, almost all SIGN LANGUAGES). No pool can index those codes, so their resource status is UNRESOLVABLE BY JOIN — structurally false, not measured. Filter on code_unmatchable to separate them.',
boundary: 'Resource availability only. No church, believer or meeting-point data.',
@ -1015,7 +1015,7 @@ if (has('language-resources.json')) {
title: 'Open Doors — where the path is clear, and where it is not',
grain: 'one row per people group x country',
the_question: 'Every other table answers SUPPLY (does a resource exist, is there internet). This answers ROUTE: could a person here reach the gospel in their own language today?',
THE_BOUNDARY: 'There is a FOURTH leg — is anyone there — deliberately ABSENT and it must stay absent (NEVER-DO #6). This table pins resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open NEVER means the gospel has arrived.',
boundary: 'This table records resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open never means the gospel has arrived.',
verdicts: 'channel-open-no-resource (highest translation leverage) · resource-exists-channel-shut (a DISTRIBUTION problem, not a translation one) · no-resource-and-no-channel · resource-and-channel-but-network-poor · channel-UNMEASURED (no probe coverage — an UNKNOWN, never read as censorship) · path-open.',
honesty: 'not-measured platforms are counted SEPARATELY and never as open or shut. Rows carry channels_not_measured + a confidence_note so a verdict resting on partial data says so.',
derived_from: 'gospel-access-vs-growth + platform-reachability + connectivity-by-country. NO new research — a join over already-verified tables.',
@ -1103,7 +1103,7 @@ if (has('language-resources.json')) {
title: 'Key Cities under Admin-N',
grain: 'one row per NAMED location cluster, with its sub-country admin unit',
derivation: `key_tier is a band over PIN DENSITY computed from this corpus: key-high >= ${p90} groups (top decile), key >= ${p75} (top quartile), else candidate.`,
HARD_LIMIT: 'VERIFICATION IS SINGLE-SOURCE. Every name comes from Nominatim/OSM and NOTHING here is cross-referenced against a second gazetteer. verification_tier says exactly what was established. A "verified key-cities list" in the full sense needs a second independent source — NOT yet done.',
verification_limit: 'Place names are single-source: Nominatim/OSM, not cross-checked against a second gazetteer. verification_tier says exactly what was established.',
admin_n_note: 'admin_n is the sub-country unit OSM reports (276 of 277 named places have one, 81 distinct values). What that level is CALLED varies by country — geoBoundaries boundaryCanonical gives the native term (State/Union Territory, Province, Wilayat, Region...). Not mislabelled "province" for everyone.',
rendering: 'No city polygons are shipped; every row renders as a STAR pin, visually distinct from people-group pins.',
source: 'Nominatim/OpenStreetMap (ODbL 1.0) for names; people-group counts from the DX spine.',
@ -1335,12 +1335,12 @@ for (const name of EXTERNAL) {
const f = join(TABLES, `${name}.json`);
if (!existsSync(f)) { console.error(`[tables] WARNING: ${name}.json not found — run build-trade-languages.mjs`); continue; }
const rows = (JSON.parse(readFileSync(f, 'utf8')).rows || []).length;
if (!built.some((b) => b.name === name)) built.push({ name, rows, producer: 'build-trade-languages.mjs' });
if (!built.some((b) => b.name === name)) built.push({ name, rows });
}
writeFileSync(join(TABLES, 'index.json'), JSON.stringify({
generated: '2026-08-01',
method: 'IEMV — extraction by the fetch/derive scripts, MODELING + VALIDATION here',
method: 'extracted from the cited sources, then modelled and validated into one table per question',
tables: built.filter((b) => !b.private),
}, null, 1));

View file

@ -123,7 +123,7 @@ writeFileSync(join(OUT, 'trade-languages-by-country.json'), JSON.stringify({
generated: '2026-08-01',
definition: 'A BRIDGE CANDIDATE is a language that is the primary language of MORE THAN ONE distinct DX people group in that country — measured from the corpus, not asserted from a list.',
honest_limit: 'This is NOT the same as a national trade language. It finds languages widely used AMONG THE UNENGAGED GROUPS TRACKED HERE, and will MISS a lingua franca that no unengaged group claims as primary (e.g. Hindi in India). Named bridge_candidates, not trade_languages, for that reason.',
why_not_a_list: 'restcountries v3.1 is DEPRECATED (returns an error body); Ethnologue is paywalled; Glottolog has no lingua-franca field. Hand-typing 175 national languages from memory is exactly where a confident error would enter.',
why_not_a_list: 'No open machine-readable list of national trade languages was available; bridge candidates are derived from this corpus.',
},
countries,
}, null, 1));
@ -236,7 +236,7 @@ writeFileSync(join(TABLES, 'gaps-and-opportunities.json'), JSON.stringify({
grain: 'one row per people group',
the_question: 'Can this group reach the gospel today — in their heart language, or through a bridge language of their country that already carries a resource?',
opportunity_meaning: 'No resource in the heart language, but a language spoken by MULTIPLE groups in the same country DOES have one. Reachable now with what already exists.',
aligned_meaning: 'ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. Brief: "opportunities exist in many places where resources and environment are all aligned for the gospel work to happen." These are the highest-leverage rows here.',
aligned_meaning: 'ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. These are the highest-leverage rows here.',
gap_meaning: 'Nothing found in the heart language AND no in-country bridge language carries anything, in the pools checked.',
bridge_strength_note: 'MEASURED: 24% of aligned rows rest on a bridge shared by only 2-3 groups. bridge_strength grades this (strong >=8 groups, moderate >=4, weak <4). A WEAK bridge is a hypothesis, not a route — e.g. "Gawri" was offered as the bridge for 10.3M Pakistanis where the real lingua franca is Urdu, which no unengaged group here claims as primary and which this method therefore cannot see. Filter on bridge_strength before acting.',
bridge_caveat: 'A bridge candidate is measured from THIS corpus (a language primary to >1 DX group in the country). It is NOT proof the group speaks it, and it is NOT a national trade language — a lingua franca no unengaged group claims as primary is invisible here.',

View file

@ -4,7 +4,7 @@
"grain": "one row per people group",
"the_question": "Can this group reach the gospel today — in their heart language, or through a bridge language of their country that already carries a resource?",
"opportunity_meaning": "No resource in the heart language, but a language spoken by MULTIPLE groups in the same country DOES have one. Reachable now with what already exists.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. Brief: \"opportunities exist in many places where resources and environment are all aligned for the gospel work to happen.\" These are the highest-leverage rows here.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. These are the highest-leverage rows here.",
"gap_meaning": "Nothing found in the heart language AND no in-country bridge language carries anything, in the pools checked.",
"bridge_strength_note": "MEASURED: 24% of aligned rows rest on a bridge shared by only 2-3 groups. bridge_strength grades this (strong >=8 groups, moderate >=4, weak <4). A WEAK bridge is a hypothesis, not a route — e.g. \"Gawri\" was offered as the bridge for 10.3M Pakistanis where the real lingua franca is Urdu, which no unengaged group here claims as primary and which this method therefore cannot see. Filter on bridge_strength before acting.",
"bridge_caveat": "A bridge candidate is measured from THIS corpus (a language primary to >1 DX group in the country). It is NOT proof the group speaks it, and it is NOT a national trade language — a lingua franca no unengaged group claims as primary is invisible here.",

View file

@ -1,6 +1,6 @@
{
"generated": "2026-08-01",
"method": "IEMV — extraction by the fetch/derive scripts, MODELING + VALIDATION here",
"method": "extracted from the cited sources, then modelled and validated into one table per question",
"tables": [
{
"name": "people-group-resources",
@ -64,8 +64,7 @@
},
{
"name": "gaps-and-opportunities",
"rows": 2106,
"producer": "build-trade-languages.mjs"
"rows": 2106
}
]
}

View file

@ -3,7 +3,7 @@
"title": "Key Cities under Admin-N",
"grain": "one row per NAMED location cluster, with its sub-country admin unit",
"derivation": "key_tier is a band over PIN DENSITY computed from this corpus: key-high >= 4 groups (top decile), key >= 3 (top quartile), else candidate.",
"HARD_LIMIT": "VERIFICATION IS SINGLE-SOURCE. Every name comes from Nominatim/OSM and NOTHING here is cross-referenced against a second gazetteer. verification_tier says exactly what was established. A \"verified key-cities list\" in the full sense needs a second independent source — NOT yet done.",
"verification_limit": "Place names are single-source: Nominatim/OSM, not cross-checked against a second gazetteer. verification_tier says exactly what was established.",
"admin_n_note": "admin_n is the sub-country unit OSM reports (276 of 277 named places have one, 81 distinct values). What that level is CALLED varies by country — geoBoundaries boundaryCanonical gives the native term (State/Union Territory, Province, Wilayat, Region...). Not mislabelled \"province\" for everyone.",
"rendering": "No city polygons are shipped; every row renders as a STAR pin, visually distinct from people-group pins.",
"source": "Nominatim/OpenStreetMap (ODbL 1.0) for names; people-group counts from the DX spine."

View file

@ -9,7 +9,7 @@
"generated": "2026-08-01",
"definition": "A BRIDGE CANDIDATE is a language that is the primary language of MORE THAN ONE distinct DX people group in that country — measured from the corpus, not asserted from a list.",
"honest_limit": "This is NOT the same as a national trade language. It finds languages widely used AMONG THE UNENGAGED GROUPS TRACKED HERE, and will MISS a lingua franca that no unengaged group claims as primary (e.g. Hindi in India). Named bridge_candidates, not trade_languages, for that reason.",
"why_not_a_list": "restcountries v3.1 is DEPRECATED (returns an error body); Ethnologue is paywalled; Glottolog has no lingua-franca field. Hand-typing 175 national languages from memory is exactly where a confident error would enter."
"why_not_a_list": "No open machine-readable list of national trade languages was available; bridge candidates are derived from this corpus."
}
},
"columns": [

View file

@ -3,7 +3,7 @@
"title": "Open Doors — where the path is clear, and where it is not",
"grain": "one row per people group x country",
"the_question": "Every other table answers SUPPLY (does a resource exist, is there internet). This answers ROUTE: could a person here reach the gospel in their own language today?",
"THE_BOUNDARY": "There is a FOURTH leg — is anyone there — deliberately ABSENT and it must stay absent (NEVER-DO #6). This table pins resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open NEVER means the gospel has arrived.",
"boundary": "This table records resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open never means the gospel has arrived.",
"verdicts": "channel-open-no-resource (highest translation leverage) · resource-exists-channel-shut (a DISTRIBUTION problem, not a translation one) · no-resource-and-no-channel · resource-and-channel-but-network-poor · channel-UNMEASURED (no probe coverage — an UNKNOWN, never read as censorship) · path-open.",
"honesty": "not-measured platforms are counted SEPARATELY and never as open or shut. Rows carry channels_not_measured + a confidence_note so a verdict resting on partial data says so.",
"derived_from": "gospel-access-vs-growth + platform-reachability + connectivity-by-country. NO new research — a join over already-verified tables."

View file

@ -20,30 +20,30 @@
"note": "public API, no key required — carries iso3 per language, so the join is exact"
}
],
"unchecked": [
"not_included": [
{
"id": "grn",
"name": "Global Recordings Network",
"covers": "audio (37,697 recordings)",
"blocked": "API key required (see BLOCKER-grn-api-key.md)"
"status": "not included: requires an API key"
},
{
"id": "api_bible",
"name": "API.Bible (bible.com ecosystem)",
"covers": "scripture",
"blocked": "HTTP 401 — key required"
"status": "not included: requires an API key"
},
{
"id": "dbl",
"name": "Digital Bible Library",
"covers": "scripture",
"blocked": "not yet evaluated"
"status": "not included: not evaluated"
},
{
"id": "progress_bible",
"name": "progress.bible",
"covers": "translation status",
"blocked": "HTTP 403 to programmatic access"
"status": "not included: no programmatic access"
}
],
"absence_meaning": "FALSE means NOT FOUND in the pools checked — never proof that no resource exists.",

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@
"grain": "one row per people group",
"the_question": "Can this group reach the gospel today — in their heart language, or through a bridge language of their country that already carries a resource?",
"opportunity_meaning": "No resource in the heart language, but a language spoken by MULTIPLE groups in the same country DOES have one. Reachable now with what already exists.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. Brief: \"opportunities exist in many places where resources and environment are all aligned for the gospel work to happen.\" These are the highest-leverage rows here.",
"aligned_meaning": "ALIGNED = an opportunity where the ENVIRONMENT also lines up: a bridge resource exists AND the country has internet (yes/partial) AND there is a known channel people are already on. These are the highest-leverage rows here.",
"gap_meaning": "Nothing found in the heart language AND no in-country bridge language carries anything, in the pools checked.",
"bridge_strength_note": "MEASURED: 24% of aligned rows rest on a bridge shared by only 2-3 groups. bridge_strength grades this (strong >=8 groups, moderate >=4, weak <4). A WEAK bridge is a hypothesis, not a route — e.g. \"Gawri\" was offered as the bridge for 10.3M Pakistanis where the real lingua franca is Urdu, which no unengaged group here claims as primary and which this method therefore cannot see. Filter on bridge_strength before acting.",
"bridge_caveat": "A bridge candidate is measured from THIS corpus (a language primary to >1 DX group in the country). It is NOT proof the group speaks it, and it is NOT a national trade language — a lingua franca no unengaged group claims as primary is invisible here.",

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"generated": "2026-08-01",
"method": "IEMV \u2014 extraction by the fetch/derive scripts, MODELING + VALIDATION here",
"method": "Derived from the source tables in this folder.",
"tables": [
{
"name": "people-group-resources",
@ -60,8 +60,7 @@
},
{
"name": "gaps-and-opportunities",
"rows": 2106,
"producer": "build-trade-languages.mjs"
"rows": 2106
}
]
}

View file

@ -3,7 +3,7 @@
"title": "Key Cities under Admin-N",
"grain": "one row per NAMED location cluster, with its sub-country admin unit",
"derivation": "key_tier is a band over PIN DENSITY computed from this corpus: key-high >= 4 groups (top decile), key >= 3 (top quartile), else candidate.",
"HARD_LIMIT": "VERIFICATION IS SINGLE-SOURCE. Every name comes from Nominatim/OSM and NOTHING here is cross-referenced against a second gazetteer. verification_tier says exactly what was established. A \"verified key-cities list\" in the full sense needs a second independent source — NOT yet done.",
"verification_limit": "Place names are single-source: Nominatim/OSM, not cross-checked against a second gazetteer. verification_tier says exactly what was established.",
"admin_n_note": "admin_n is the sub-country unit OSM reports (276 of 277 named places have one, 81 distinct values). What that level is CALLED varies by country — geoBoundaries boundaryCanonical gives the native term (State/Union Territory, Province, Wilayat, Region...). Not mislabelled \"province\" for everyone.",
"rendering": "No city polygons are shipped; every row renders as a STAR pin, visually distinct from people-group pins.",
"source": "Nominatim/OpenStreetMap (ODbL 1.0) for names; people-group counts from the DX spine."

View file

@ -9,7 +9,7 @@
"generated": "2026-08-01",
"definition": "A BRIDGE CANDIDATE is a language that is the primary language of MORE THAN ONE distinct DX people group in that country — measured from the corpus, not asserted from a list.",
"honest_limit": "This is NOT the same as a national trade language. It finds languages widely used AMONG THE UNENGAGED GROUPS TRACKED HERE, and will MISS a lingua franca that no unengaged group claims as primary (e.g. Hindi in India). Named bridge_candidates, not trade_languages, for that reason.",
"why_not_a_list": "restcountries v3.1 is DEPRECATED (returns an error body); Ethnologue is paywalled; Glottolog has no lingua-franca field. Hand-typing 175 national languages from memory is exactly where a confident error would enter."
"why_not_a_list": "No open machine-readable list of national trade languages was available; bridge candidates are derived from this corpus."
}
},
"columns": [

View file

@ -3,7 +3,7 @@
"title": "Open Doors — where the path is clear, and where it is not",
"grain": "one row per people group x country",
"the_question": "Every other table answers SUPPLY (does a resource exist, is there internet). This answers ROUTE: could a person here reach the gospel in their own language today?",
"THE_BOUNDARY": "There is a FOURTH leg — is anyone there — deliberately ABSENT and it must stay absent (NEVER-DO #6). This table pins resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open NEVER means the gospel has arrived.",
"boundary": "This table records resource AVAILABILITY and network ROUTE only. It never indicates believers, churches or meeting points, and path-open never means the gospel has arrived.",
"verdicts": "channel-open-no-resource (highest translation leverage) · resource-exists-channel-shut (a DISTRIBUTION problem, not a translation one) · no-resource-and-no-channel · resource-and-channel-but-network-poor · channel-UNMEASURED (no probe coverage — an UNKNOWN, never read as censorship) · path-open.",
"honesty": "not-measured platforms are counted SEPARATELY and never as open or shut. Rows carry channels_not_measured + a confidence_note so a verdict resting on partial data says so.",
"derived_from": "gospel-access-vs-growth + platform-reachability + connectivity-by-country. NO new research — a join over already-verified tables."

View file

@ -20,30 +20,30 @@
"note": "public API, no key required — carries iso3 per language, so the join is exact"
}
],
"unchecked": [
"not_included": [
{
"id": "grn",
"name": "Global Recordings Network",
"covers": "audio (37,697 recordings)",
"blocked": "API key required (see BLOCKER-grn-api-key.md)"
"status": "not included: requires an API key"
},
{
"id": "api_bible",
"name": "API.Bible (bible.com ecosystem)",
"covers": "scripture",
"blocked": "HTTP 401 — key required"
"status": "not included: requires an API key"
},
{
"id": "dbl",
"name": "Digital Bible Library",
"covers": "scripture",
"blocked": "not yet evaluated"
"status": "not included: not evaluated"
},
{
"id": "progress_bible",
"name": "progress.bible",
"covers": "translation status",
"blocked": "HTTP 403 to programmatic access"
"status": "not included: no programmatic access"
}
],
"absence_meaning": "FALSE means NOT FOUND in the pools checked — never proof that no resource exists.",

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <all-people-groups> custom element. -->
<script src="../all-people-groups.js" integrity="sha384-AfIXfAyPO0B+87vD9k0RfnVU8/yfDtHzZNxuImHJLaOuxf6TjyKwbujuYLL3XOwy" crossorigin="anonymous"></script>
<script src="../all-people-groups.js" integrity="sha384-pbUsB4dUiap2uZ9Roa/i9FdnImtPlSW1GTZN1aEYi6GNZ0a0TwgZJtzl7IbIgoMV" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"all-people-groups","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"all-people-groups","scriptUrl":"./all-people-groups/all-people-groups.js","output":"doxa-maps/all-people-groups/all-people-groups.js","integrity":"sha384-AfIXfAyPO0B+87vD9k0RfnVU8/yfDtHzZNxuImHJLaOuxf6TjyKwbujuYLL3XOwy","elements":["all-people-groups"],"profiles":[{"profile":"all-people-groups","file":"all-people-groups.vue","description":"All 12,379 people groups (peoplegroups.org) in four colors — reached,","element":"all-people-groups","iframeUrl":"./all-people-groups/all-people-groups/index.html","scriptUrl":"./all-people-groups/all-people-groups.js","embed":{"iframe":"\u003ciframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-AfIXfAyPO0B+87vD9k0RfnVU8/yfDtHzZNxuImHJLaOuxf6TjyKwbujuYLL3XOwy\" crossorigin=\"anonymous\">\u003c/script>\n\u003call-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/all-people-groups>"},"bundle":"all-people-groups"}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"all-people-groups","scriptUrl":"./all-people-groups/all-people-groups.js","output":"doxa-maps/all-people-groups/all-people-groups.js","integrity":"sha384-pbUsB4dUiap2uZ9Roa/i9FdnImtPlSW1GTZN1aEYi6GNZ0a0TwgZJtzl7IbIgoMV","elements":["all-people-groups"],"profiles":[{"profile":"all-people-groups","file":"all-people-groups.vue","description":"All 12,379 people groups (peoplegroups.org) in four colors — reached,","element":"all-people-groups","iframeUrl":"./all-people-groups/all-people-groups/index.html","scriptUrl":"./all-people-groups/all-people-groups.js","embed":{"iframe":"\u003ciframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-pbUsB4dUiap2uZ9Roa/i9FdnImtPlSW1GTZN1aEYi6GNZ0a0TwgZJtzl7IbIgoMV\" crossorigin=\"anonymous\">\u003c/script>\n\u003call-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/all-people-groups>"},"bundle":"all-people-groups"}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

View file

@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
<script src="../country-posters.js" integrity="sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI" crossorigin="anonymous"></script>
<script src="../country-posters.js" integrity="sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
<script src="../country-posters.js" integrity="sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI" crossorigin="anonymous"></script>
<script src="../country-posters.js" integrity="sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"country-posters","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"country-posters","scriptUrl":"./country-posters/country-posters.js","output":"doxa-maps/country-posters/country-posters.js","integrity":"sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI","elements":["country-posters-map"],"profiles":[{"profile":"countries-map","file":"countries-map.vue","description":"","element":"country-posters-map","iframeUrl":"./country-posters/countries-map/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/country-posters-map>"}},{"profile":"country-poster-wall","file":"country-poster-wall.vue","description":"","element":"country-posters-map","iframeUrl":"./country-posters/country-poster-wall/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/country-posters-map>"}}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"country-posters","scriptUrl":"./country-posters/country-posters.js","output":"doxa-maps/country-posters/country-posters.js","integrity":"sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr","elements":["country-posters-map"],"profiles":[{"profile":"countries-map","file":"countries-map.vue","description":"","element":"country-posters-map","iframeUrl":"./country-posters/countries-map/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/country-posters-map>"}},{"profile":"country-poster-wall","file":"country-poster-wall.vue","description":"","element":"country-posters-map","iframeUrl":"./country-posters/country-poster-wall/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/country-posters-map>"}}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <demo-map> custom element. -->
<script src="../demo-map.js" integrity="sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY" crossorigin="anonymous"></script>
<script src="../demo-map.js" integrity="sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -27,7 +27,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <demo-map> custom element. -->
<script src="../../demo-map.js" integrity="sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY" crossorigin="anonymous"></script>
<script src="../../demo-map.js" integrity="sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"demo-map","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"demo-map","scriptUrl":"./demo-map/demo-map.js","output":"doxa-maps/demo-map/demo-map.js","integrity":"sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY","elements":["demo-map"],"profiles":[{"profile":"demo-map","file":"demo-map.vue","description":"Simple two-tab demo map. Tab 1 colors pins by religion (shared","element":"demo-map","iframeUrl":"./demo-map/demo-map/index.html","scriptUrl":"./demo-map/demo-map.js","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./demo-map/demo-map.js\" integrity=\"sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdemo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/demo-map>"},"instances":[{"id":"maplibre","title":"Demo map — MapLibre (token-free)","apiBaseUrl":"","props":{"profile":"demo-map","provider":"maplibre","instanceId":"demo-maplibre"},"element":"demo-map","iframeUrl":"./demo-map/demo-map/maplibre/index.html","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/maplibre/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}],"bundle":"demo-map"}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"demo-map","scriptUrl":"./demo-map/demo-map.js","output":"doxa-maps/demo-map/demo-map.js","integrity":"sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg","elements":["demo-map"],"profiles":[{"profile":"demo-map","file":"demo-map.vue","description":"Simple two-tab demo map. Tab 1 colors pins by religion (shared","element":"demo-map","iframeUrl":"./demo-map/demo-map/index.html","scriptUrl":"./demo-map/demo-map.js","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./demo-map/demo-map.js\" integrity=\"sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdemo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/demo-map>"},"instances":[{"id":"maplibre","title":"Demo map — MapLibre (token-free)","apiBaseUrl":"","props":{"profile":"demo-map","provider":"maplibre","instanceId":"demo-maplibre"},"element":"demo-map","iframeUrl":"./demo-map/demo-map/maplibre/index.html","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/maplibre/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}],"bundle":"demo-map"}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

File diff suppressed because one or more lines are too long

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"doxa-research-map","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"doxa-research-map","scriptUrl":"./doxa-research-map/doxa-research-map.js","output":"doxa-maps/doxa-research-map/doxa-research-map.js","integrity":"sha384-K9GWnVJ6jQ4XpL1uat6IkrZ2ODyWEhDZWJ1yUkT0A70ZiLeJ7cD9dBpsG/5juF2b","elements":["doxa-research-map"],"profiles":[{"profile":"research-map","file":"research-map.vue","description":"","element":"doxa-research-map","iframeUrl":"./doxa-research-map/research-map/index.html","scriptUrl":"./doxa-research-map/doxa-research-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-K9GWnVJ6jQ4XpL1uat6IkrZ2ODyWEhDZWJ1yUkT0A70ZiLeJ7cD9dBpsG/5juF2b\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/doxa-research-map>"}}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"doxa-research-map","scriptUrl":"./doxa-research-map/doxa-research-map.js","output":"doxa-maps/doxa-research-map/doxa-research-map.js","integrity":"sha384-10+sLM5Dg1hZr86njhiugTQkorQafcB8iG66Ebcj0h7jIsZ/j0uHDNqKxbMdRcMq","elements":["doxa-research-map"],"profiles":[{"profile":"research-map","file":"research-map.vue","description":"","element":"doxa-research-map","iframeUrl":"./doxa-research-map/research-map/index.html","scriptUrl":"./doxa-research-map/doxa-research-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-10+sLM5Dg1hZr86njhiugTQkorQafcB8iG66Ebcj0h7jIsZ/j0uHDNqKxbMdRcMq\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/doxa-research-map>"}}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
<script src="../doxa-research-map.js" integrity="sha384-K9GWnVJ6jQ4XpL1uat6IkrZ2ODyWEhDZWJ1yUkT0A70ZiLeJ7cD9dBpsG/5juF2b" crossorigin="anonymous"></script>
<script src="../doxa-research-map.js" integrity="sha384-10+sLM5Dg1hZr86njhiugTQkorQafcB8iG66Ebcj0h7jIsZ/j0uHDNqKxbMdRcMq" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../doxa-simple-map.js" integrity="sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T" crossorigin="anonymous"></script>
<script src="../doxa-simple-map.js" integrity="sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"doxa-simple-map","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"doxa-simple-map","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","output":"doxa-maps/doxa-simple-map/doxa-simple-map.js","integrity":"sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T","elements":["doxa-map","doxa-simple-map"],"profiles":[{"profile":"doxa-simple-map","file":"doxa-simple-map.vue","description":"","element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/index.html","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/doxa-map>"},"instances":[{"id":"prayer","title":"Prayer Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-prayer","dataSource":"pray-tools","tabs":[{"id":"prayer","colorStrategy":"prayer","legend":"prayer","popup":"prayer"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/prayer/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/prayer/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"engagement","title":"Engagement Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-engagement","dataSource":"pray-tools","tabs":[{"id":"engagement","colorStrategy":"engagement","legend":"engagement","popup":"engagement"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/engagement/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/engagement/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"adoption","title":"Adoption Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-adoption","dataSource":"pray-tools","tabs":[{"id":"adoption","colorStrategy":"adoption","legend":"adoption","popup":"adoption"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/adoption/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/adoption/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"doxa-simple-map","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","output":"doxa-maps/doxa-simple-map/doxa-simple-map.js","integrity":"sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC","elements":["doxa-map","doxa-simple-map"],"profiles":[{"profile":"doxa-simple-map","file":"doxa-simple-map.vue","description":"","element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/index.html","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/doxa-map>"},"instances":[{"id":"prayer","title":"Prayer Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-prayer","dataSource":"pray-tools","tabs":[{"id":"prayer","colorStrategy":"prayer","legend":"prayer","popup":"prayer"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/prayer/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/prayer/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"engagement","title":"Engagement Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-engagement","dataSource":"pray-tools","tabs":[{"id":"engagement","colorStrategy":"engagement","legend":"engagement","popup":"engagement"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/engagement/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/engagement/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"adoption","title":"Adoption Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-adoption","dataSource":"pray-tools","tabs":[{"id":"adoption","colorStrategy":"adoption","legend":"adoption","popup":"adoption"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/adoption/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/adoption/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"gospel-resources","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"gospel-resources","scriptUrl":"./gospel-resources/gospel-resources.js","output":"doxa-maps/gospel-resources/gospel-resources.js","integrity":"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs","elements":["gospel-resources-map"],"profiles":[{"profile":"charts","file":"charts.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/charts/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"data-tables","file":"data-tables.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/data-tables/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-list","file":"resources-list.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/resources-list/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-map","file":"resources-map.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/resources-map/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"gospel-resources","scriptUrl":"./gospel-resources/gospel-resources.js","output":"doxa-maps/gospel-resources/gospel-resources.js","integrity":"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5","elements":["gospel-resources-map"],"profiles":[{"profile":"charts","file":"charts.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/charts/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"data-tables","file":"data-tables.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/data-tables/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-list","file":"resources-list.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/resources-list/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-map","file":"resources-map.vue","description":"","element":"gospel-resources-map","iframeUrl":"./gospel-resources/resources-map/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/gospel-resources-map>"}}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -9,7 +9,7 @@
"bundle": "all-people-groups",
"scriptUrl": "./all-people-groups/all-people-groups.js",
"output": "doxa-maps/all-people-groups/all-people-groups.js",
"integrity": "sha384-AfIXfAyPO0B+87vD9k0RfnVU8/yfDtHzZNxuImHJLaOuxf6TjyKwbujuYLL3XOwy",
"integrity": "sha384-pbUsB4dUiap2uZ9Roa/i9FdnImtPlSW1GTZN1aEYi6GNZ0a0TwgZJtzl7IbIgoMV",
"elements": [
"all-people-groups"
],
@ -23,7 +23,7 @@
"scriptUrl": "./all-people-groups/all-people-groups.js",
"embed": {
"iframe": "<iframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-AfIXfAyPO0B+87vD9k0RfnVU8/yfDtHzZNxuImHJLaOuxf6TjyKwbujuYLL3XOwy\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></all-people-groups>"
"script": "<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-pbUsB4dUiap2uZ9Roa/i9FdnImtPlSW1GTZN1aEYi6GNZ0a0TwgZJtzl7IbIgoMV\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></all-people-groups>"
},
"bundle": "all-people-groups"
}
@ -80,7 +80,7 @@
"bundle": "country-posters",
"scriptUrl": "./country-posters/country-posters.js",
"output": "doxa-maps/country-posters/country-posters.js",
"integrity": "sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI",
"integrity": "sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr",
"elements": [
"country-posters-map"
],
@ -94,7 +94,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></country-posters-map>"
"script": "<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></country-posters-map>"
}
},
{
@ -106,7 +106,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-MJMmqcsSWrc61XNGUeI/zT2Ig7vl5yeWEpyLwjkePCj9coEulJhGljDuSP8SLSGI\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></country-posters-map>"
"script": "<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hrguLd8qEzV7IqltwbpmsWzcueqPHV9gUQiSb5oKuKtH3YTq4s9yw4ykNIwOptRr\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></country-posters-map>"
}
}
]
@ -115,7 +115,7 @@
"bundle": "demo-map",
"scriptUrl": "./demo-map/demo-map.js",
"output": "doxa-maps/demo-map/demo-map.js",
"integrity": "sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY",
"integrity": "sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg",
"elements": [
"demo-map"
],
@ -129,7 +129,7 @@
"scriptUrl": "./demo-map/demo-map.js",
"embed": {
"iframe": "<iframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-iwx1BbMrXkW8BmQMSfzl4MX4nyH6CDoOFivDM4DsIVr7832ELldLnRqrpaLV3BOY\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></demo-map>"
"script": "<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-ftGDvLDyGPWQwmZfR7LXye2m1zdzBUEecXoEdU2Woy20L59UeJWc5jidm1qhHBgg\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></demo-map>"
},
"instances": [
{
@ -156,7 +156,7 @@
"bundle": "doxa-research-map",
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"output": "doxa-maps/doxa-research-map/doxa-research-map.js",
"integrity": "sha384-K9GWnVJ6jQ4XpL1uat6IkrZ2ODyWEhDZWJ1yUkT0A70ZiLeJ7cD9dBpsG/5juF2b",
"integrity": "sha384-10+sLM5Dg1hZr86njhiugTQkorQafcB8iG66Ebcj0h7jIsZ/j0uHDNqKxbMdRcMq",
"elements": [
"doxa-research-map"
],
@ -170,7 +170,7 @@
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-K9GWnVJ6jQ4XpL1uat6IkrZ2ODyWEhDZWJ1yUkT0A70ZiLeJ7cD9dBpsG/5juF2b\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></doxa-research-map>"
"script": "<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-10+sLM5Dg1hZr86njhiugTQkorQafcB8iG66Ebcj0h7jIsZ/j0uHDNqKxbMdRcMq\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></doxa-research-map>"
}
}
]
@ -179,7 +179,7 @@
"bundle": "doxa-simple-map",
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"output": "doxa-maps/doxa-simple-map/doxa-simple-map.js",
"integrity": "sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T",
"integrity": "sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC",
"elements": [
"doxa-map",
"doxa-simple-map"
@ -194,7 +194,7 @@
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-T815eVSU0j7QECeAlyNEVzQrDGUm7abImmsOukMW8/vTbamGODe3CMYILmlgSH9T\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></doxa-map>"
"script": "<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-rNBtSVbU6fL3BbNCdCnZy9wBtnUJRnM6J1INzj1wf930crW6UgPgFeeCer+arqpC\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></doxa-map>"
},
"instances": [
{
@ -274,7 +274,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "doxa-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs",
"integrity": "sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5",
"elements": [
"gospel-resources-map"
],
@ -288,7 +288,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
}
},
{
@ -300,7 +300,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
}
},
{
@ -312,7 +312,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
}
},
{
@ -324,7 +324,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-KDyF/7avg/RzCZufMlCj5Jv5t7ox3nCd4YB21L8UsWQaLTM35/Avt1JxNiuf+tQs\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
"script": "<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-ItwWThyENJeiiHLNRWxDZeHupxdCbDcFHRSwGj6mZD0FRrzkFkUeyShJRoFbdcJ5\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></gospel-resources-map>"
}
}
]
@ -333,7 +333,7 @@
"bundle": "my-upg-100-list",
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"output": "doxa-maps/my-upg-100-list/my-upg-100-list.js",
"integrity": "sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g",
"integrity": "sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81",
"elements": [
"my-upg-100-list-map"
],
@ -347,7 +347,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
}
},
{
@ -359,7 +359,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
}
},
{
@ -371,7 +371,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
"script": "<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></my-upg-100-list-map>"
}
}
]
@ -380,7 +380,7 @@
"bundle": "research-dashboard",
"scriptUrl": "./research-dashboard/research-dashboard.js",
"output": "doxa-maps/research-dashboard/research-dashboard.js",
"integrity": "sha384-KM1+8afDjk+fAFTzbxqv66v2xJtrgihGGkjQd7AFoWr87sctxGvAPpEG0aTsgKiY",
"integrity": "sha384-uht+LCAdqFX3bN+rUFdfC9dVjVGSRnHtPf5kQJa80xjFOKsyG364C1G6teopbE2v",
"elements": [
"research-dashboard-map"
],
@ -394,7 +394,7 @@
"scriptUrl": "./research-dashboard/research-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-KM1+8afDjk+fAFTzbxqv66v2xJtrgihGGkjQd7AFoWr87sctxGvAPpEG0aTsgKiY\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></research-dashboard-map>"
"script": "<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-uht+LCAdqFX3bN+rUFdfC9dVjVGSRnHtPf5kQJa80xjFOKsyG364C1G6teopbE2v\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'></research-dashboard-map>"
},
"bundle": "research-dashboard"
}

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"my-upg-100-list","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"my-upg-100-list","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","output":"doxa-maps/my-upg-100-list/my-upg-100-list.js","integrity":"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g","elements":["my-upg-100-list-map"],"profiles":[{"profile":"poster-wall","file":"poster-wall.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/poster-wall/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-list","file":"upg-100-list.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/upg-100-list/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-mfe","file":"upg-100-mfe.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/upg-100-mfe/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"my-upg-100-list","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","output":"doxa-maps/my-upg-100-list/my-upg-100-list.js","integrity":"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81","elements":["my-upg-100-list-map"],"profiles":[{"profile":"poster-wall","file":"poster-wall.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/poster-wall/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-list","file":"upg-100-list.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/upg-100-list/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-mfe","file":"upg-100-mfe.vue","description":"","element":"my-upg-100-list-map","iframeUrl":"./my-upg-100-list/upg-100-mfe/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/my-upg-100-list-map>"}}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-/96bD/kJ7nIFNvPIef48hwqqJiaOeQYUJNTgDTR0WwtXU0kyYPLl1iFKx+KJcl6g" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-SW9uOUBfS7mIogsjLn75bgii5K/wXBFsixXaY2d15DKtF5Y+p5eawCoSBUh61j81" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -130,7 +130,7 @@ header.top .sub { margin-top: 3px; font: 12px/1.4 var(--sans); color: var(--mut)
<script>window.FORGE = {"mode":"built","scope":"bundle","manifestUrl":"../manifest.json","bundle":"research-dashboard","hrefBase":"../"};
/* file:// contract: manifest inlined at build — no fetch needed to render. */
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"research-dashboard","scriptUrl":"./research-dashboard/research-dashboard.js","output":"doxa-maps/research-dashboard/research-dashboard.js","integrity":"sha384-KM1+8afDjk+fAFTzbxqv66v2xJtrgihGGkjQd7AFoWr87sctxGvAPpEG0aTsgKiY","elements":["research-dashboard-map"],"profiles":[{"profile":"research-dashboard","file":"research-dashboard.vue","description":"Coordinated-Multiple-Views research dashboard for 10/40-window UPGs (live pray.doxa.life): docked facet rail + map-as-hero + linked table/charts, brushing-and-linking over one in-memory store.","element":"research-dashboard-map","iframeUrl":"./research-dashboard/research-dashboard/index.html","scriptUrl":"./research-dashboard/research-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-KM1+8afDjk+fAFTzbxqv66v2xJtrgihGGkjQd7AFoWr87sctxGvAPpEG0aTsgKiY\" crossorigin=\"anonymous\">\u003c/script>\n\u003cresearch-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/research-dashboard-map>"},"bundle":"research-dashboard"}]}]};</script>
window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"app-profiles/*/*.vue","embedBase":".","bundleCount":10,"profileCount":19,"bundles":[{"bundle":"research-dashboard","scriptUrl":"./research-dashboard/research-dashboard.js","output":"doxa-maps/research-dashboard/research-dashboard.js","integrity":"sha384-uht+LCAdqFX3bN+rUFdfC9dVjVGSRnHtPf5kQJa80xjFOKsyG364C1G6teopbE2v","elements":["research-dashboard-map"],"profiles":[{"profile":"research-dashboard","file":"research-dashboard.vue","description":"Coordinated-Multiple-Views research dashboard for 10/40-window UPGs (live pray.doxa.life): docked facet rail + map-as-hero + linked table/charts, brushing-and-linking over one in-memory store.","element":"research-dashboard-map","iframeUrl":"./research-dashboard/research-dashboard/index.html","scriptUrl":"./research-dashboard/research-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-uht+LCAdqFX3bN+rUFdfC9dVjVGSRnHtPf5kQJa80xjFOKsyG364C1G6teopbE2v\" crossorigin=\"anonymous\">\u003c/script>\n\u003cresearch-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\"}'>\u003c/research-dashboard-map>"},"bundle":"research-dashboard"}]}]};</script>
<script>/**
* staging-forge.js — the ONE-PAGE semantic staging environment (root + bundle pages).
*
@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <research-dashboard-map> custom element. -->
<script src="../research-dashboard.js" integrity="sha384-KM1+8afDjk+fAFTzbxqv66v2xJtrgihGGkjQd7AFoWr87sctxGvAPpEG0aTsgKiY" crossorigin="anonymous"></script>
<script src="../research-dashboard.js" integrity="sha384-uht+LCAdqFX3bN+rUFdfC9dVjVGSRnHtPf5kQJa80xjFOKsyG364C1G6teopbE2v" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -290,7 +290,7 @@ function renderStage() {
<div class="map-slot"><iframe allowfullscreen src="${esc(withProvider(withTk(nd.href)))}"></iframe></div>`
// COPY EMBED — the partner handoff. The snippet is built AT CLICK TIME from
// location.href, so it always carries the FULL URL of whatever host serves
// this tree (localhost, doxa.life/js/doxa-maps-build/…, any CDN) — embeds
// this tree (localhost, doxa.life/embed/doxa-maps-build/…, any CDN) — embeds
// work no matter where the build folder lives. utm_source placeholder =
// per-partner traffic attribution (see the manifest snippets).
const copyBtn = $('#copyEmbed')

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
{
"//": "THE single build-config for this STANDALONE doxa-maps bundler. Edit this ONE file, then run `bun run build`. FIELDS: 'name' = the output folder name the tree is written as. 'paths' = EXTRA folders to copy the whole tree into. EMPTY and normally stays empty: the build writes into public/<name>/ directly, because public/ is the committed served web-root rather than something assembled at build time. STANDALONE NOTE (2026-07-30): the old value ['../../../public/js'] pointed into the dx-life Nuxt app's public dir \u2014 meaningless in this repo, and the whole point of standing this bundler up on its own is that dx-life consumes maps from the CDN instead of hosting a copy. So 'paths' is now EMPTY: the tree is written to ./app/<name>/ only, and that ONE tree is what all three targets consume (Railway/CDN static host, Capacitor webDir, local staging). If you ever want to ALSO publish into a local dx-life checkout, add its path back here. 'embedBaseUrl' = public URL where the <name>/ tree is served, used to build ABSOLUTE paste-anywhere embed snippets for partner sites ('' = RELATIVE ./bundle/profile/... URLs so the dropped folder is position-independent \u2014 keeps the drop-portability gate green and is what Capacitor needs, since the app loads from https://localhost). 'tokenUrl' = the endpoint every generated map page fetches its Mapbox token from \u2014 a URL, NOT a secret. Set it ABSOLUTE (https://doxa.life/api/maps/token) so both a CDN-hosted folder and the mobile app work; the token stays remote and only the URL ships. window.MAP_TOKEN_URL overrides at runtime. Your endpoint must send CORS headers permitting https://localhost (the Capacitor origin) and any partner domain. 'token' = OPT-IN literal token baked into every page \u2014 LEAVE EMPTY; prefer tokenUrl. 'assetsBaseUrl' = where the SHARED asset tree (previews, posters, boundaries) is served from. Vite no longer copies public/ into each bundle (publicDir:false in vite.config.js), so pages are TOLD where the one shared copy lives. EMPTY = a relative path derived per page depth, which keeps a dropped folder self-contained under one web-root. Set it ABSOLUTE (https://maps.doxa.life/assets) for partner embeds and the mobile app, where there is no shared web-root to climb to. Same modular pattern as tokenUrl and window.MAP_APP_API_URL. 'dropin.include' = THE drop-in contract, declared here and nowhere else: the only root entries of public/ that `sync-dropin --from-config` copies into a host — index.html (the generated root page, internal/generate-spa.mjs), assets/ (data) and <name>/ (the bundle folders + manifest.json); with --prune everything else in the host's drop-in folder is removed, and `public-hygiene-check --strict` fails on any other root entry.",
"//": "THE single build-config for this STANDALONE doxa-maps bundler. Edit this ONE file, then run `bun run build`. FIELDS: 'name' = the output folder name the tree is written as. 'paths' = EXTRA folders to copy the whole tree into. EMPTY and normally stays empty: the build writes into public/<name>/ directly, because public/ is the committed served web-root rather than something assembled at build time. STANDALONE NOTE (2026-07-30): the old value ['../../../public/js'] pointed into the dx-life Nuxt app's public dir \u2014 meaningless in this repo, and the whole point of standing this bundler up on its own is that dx-life consumes maps from the CDN instead of hosting a copy. So 'paths' is now EMPTY: the tree is written to ./app/<name>/ only, and that ONE tree is what all three targets consume (Railway/CDN static host, Capacitor webDir, local staging). If you ever want to ALSO publish into a local dx-life checkout, add its path back here. 'embedBaseUrl' = public URL where the <name>/ tree is served, used to build ABSOLUTE paste-anywhere embed snippets for partner sites ('' = RELATIVE ./bundle/profile/... URLs so the dropped folder is position-independent \u2014 keeps the drop-portability gate green and is what Capacitor needs, since the app loads from https://localhost). 'tokenUrl' = the endpoint every generated map page fetches its Mapbox token from \u2014 a URL, NOT a secret. Set it ABSOLUTE (https://doxa.life/api/maps/token) so both a CDN-hosted folder and the mobile app work; the token stays remote and only the URL ships. window.MAP_TOKEN_URL overrides at runtime. Your endpoint must send CORS headers permitting https://localhost (the Capacitor origin) and any partner domain. 'token' = OPT-IN literal token baked into every page \u2014 LEAVE EMPTY; prefer tokenUrl. 'assetsBaseUrl' = where the SHARED asset tree (previews, posters, boundaries) is served from. Vite no longer copies public/ into each bundle (publicDir:false in vite.config.js), so pages are TOLD where the one shared copy lives. EMPTY = a relative path derived per page depth, which keeps a dropped folder self-contained under one web-root. Set it ABSOLUTE (https://maps.doxa.life/assets) for partner embeds and the mobile app, where there is no shared web-root to climb to. Same modular pattern as tokenUrl and window.MAP_APP_API_URL. 'dropin.include' = THE drop-in contract, declared here and nowhere else: the only root entries of public/ that `sync-dropin --from-config` copies into a host — index.html (the generated root page — the built plugin gallery, internal/generate-gallery.mjs), assets/ (data) and <name>/ (the bundle folders + manifest.json); with --prune everything else in the host's drop-in folder is removed, and `public-hygiene-check --strict` fails on any other root entry. 'dropin.exclude' = built files INSIDE the allowlist that are still not shipped: data no page fetches (the full people-groups CSV, the tables only internal scripts read, the table index). They stay in public/ for the scripts; `sync-dropin --from-config` skips them and counts them as 'excluded (not shipped)', and a copy already in the host is removed like any stale file.",
"name": "doxa-maps",
"paths": [],
"embedBaseUrl": "",
@ -12,6 +12,12 @@
"index.html",
"assets",
"doxa-maps"
],
"exclude": [
"assets/people-groups/people_groups.csv",
"assets/tables/open-doors.json",
"assets/tables/platform-reachability.json",
"assets/tables/index.json"
]
},
"apiBaseUrl": "https://pray.doxa.life",