Compare commits
4 commits
main
...
upg100/ren
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48d623330e | ||
|
|
32d669deea | ||
|
|
1faf1c9d49 | ||
|
|
07b28e405e |
29 changed files with 474 additions and 293 deletions
|
|
@ -50,11 +50,14 @@ const ok = (cond, msg) => { if (!cond) fails.push(msg) }
|
|||
// directly (legend-tree's regionFor returns 'India' / 'China + Mongolia' / 'Other' without a helper call).
|
||||
const TABLES = [
|
||||
{
|
||||
file: 'plugin-designs/my-upg-100-list/poster-wall.vue',
|
||||
// the poster wall's region sections (and <dxm-poster-section type="upg100-list">): the table moved out of
|
||||
// poster-wall.vue into data/upg100-regions.js; regionOf RETURNS 'India' / 'China + Mongolia' / 'Other' directly
|
||||
file: 'plugin-designs/my-upg-100-list/data/upg100-regions.js',
|
||||
produces: 'REGION_OF',
|
||||
mapsFile: 'plugin-designs/my-upg-100-list/data/legend-tree.js',
|
||||
maps: 'REGION_KEY',
|
||||
via: 'regionLabel',
|
||||
via: 'regionTitle',
|
||||
producerReturns: 'regionOf',
|
||||
area: 'poster',
|
||||
},
|
||||
{
|
||||
|
|
@ -87,6 +90,13 @@ function producerLabels(src, fn) {
|
|||
const m = new RegExp(`const ${fn}\\s*=\\s*\\([^)]*\\)\\s*=>([\\s\\S]*?);\\n`).exec(src)
|
||||
return m ? [...m[1].matchAll(/[?:]\s*'([^']+)'/g)].map((x) => x[1]) : null
|
||||
}
|
||||
/** The labels a function declaration RETURNS as literals: `return 'India'`. */
|
||||
function returnedLabels(src, fn) {
|
||||
const at = src.search(new RegExp(`function ${fn}\\s*\\(`))
|
||||
if (at < 0) return null
|
||||
const body = src.slice(at, src.indexOf('\n}\n', at))
|
||||
return [...body.matchAll(/return\s+'([^']+)'/g)].map((x) => x[1])
|
||||
}
|
||||
/** Quoted values on the right of a colon — the English labels a table produces. */
|
||||
const valuesOf = (body) => new Set([...body.matchAll(/:\s*'([^']+)'/g)].map((m) => m[1]))
|
||||
/** Quoted keys on the left of a colon — the English labels a table covers. */
|
||||
|
|
@ -119,6 +129,11 @@ for (const t of TABLES) {
|
|||
if (!got || !got.length) { ok(false, `${t.file}: no \`const ${t.producerFn} = (…) =>\` returning labels — this gate has gone blind`); continue }
|
||||
fromFn = got
|
||||
}
|
||||
if (t.producerReturns) {
|
||||
const got = returnedLabels(src, t.producerReturns)
|
||||
if (!got || !got.length) { ok(false, `${t.file}: no \`function ${t.producerReturns}(…)\` returning labels — this gate has gone blind`); continue }
|
||||
fromFn = [...fromFn, ...got]
|
||||
}
|
||||
const produced = new Set([...fromTable, ...fromCalls, ...fromFn])
|
||||
const covered = keysOf(maps)
|
||||
|
||||
|
|
|
|||
84
internal/check-upg100-poster-type.mjs
Normal file
84
internal/check-upg100-poster-type.mjs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env node
|
||||
// check-upg100-poster-type — UPG-100's region sections are ONE section, whether the poster wall draws them or
|
||||
// <dxm-poster-section type="upg100-list" scope="…"> does. Headless. Asserts:
|
||||
// A. every zone the wall shows (clusters.json: lists + asia_lists + uncovered_lists) belongs to a NAMED region,
|
||||
// never 'Other', and the sections the wall promises exist (India, China + Mongolia, Africa, Middle East,
|
||||
// Central Asia, Southeast Asia + Oceania, Americas, Europe). NEGATIVE CONTROL: a planted unknown zone falls to
|
||||
// 'Other', so this check can fail;
|
||||
// B. each region's scope (its slug) is unique and round-trips from the English name, so a scope can't name two
|
||||
// sections;
|
||||
// C. each region's heading has its poster.region_* key in all 11 locales;
|
||||
// D. the wiring: the bundle registers the 'upg100-list' type and the element; the type's adapter has the four
|
||||
// parts a section reads; the wall groups through the SAME regionOf and draws the SAME zones (upg100Zones), and
|
||||
// its sections are collapsible.
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
|
||||
const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const P = (...a) => join(REPO, ...a)
|
||||
const PLUGIN = 'plugin-designs/my-upg-100-list'
|
||||
const fails = [], notes = []
|
||||
const ok = (cond, msg, note) => { if (!cond) fails.push(msg); else if (note) notes.push(` ok ${note}`) }
|
||||
const LANGS = ['en', 'es', 'fr', 'pt', 'de', 'it', 'ro', 'ru', 'ar', 'hi', 'zh']
|
||||
|
||||
let R, clusters, REGION_KEY
|
||||
try {
|
||||
R = await import(pathToFileURL(P(PLUGIN, 'data/upg100-regions.js')).href)
|
||||
clusters = JSON.parse(readFileSync(P(PLUGIN, 'data/clusters.json'), 'utf8'))
|
||||
// REGION_KEY is a plain table in legend-tree.js; read it from the source rather than importing the module (it
|
||||
// pulls JSON the node loader cannot take without import attributes).
|
||||
const src = readFileSync(P(PLUGIN, 'data/legend-tree.js'), 'utf8')
|
||||
REGION_KEY = Object.fromEntries([...src.slice(src.indexOf('export const REGION_KEY'), src.indexOf('};', src.indexOf('export const REGION_KEY'))).matchAll(/'([^']+)': '([^']+)'/g)].map((m) => [m[1], m[2]]))
|
||||
} catch (e) {
|
||||
console.error(`UPG100-POSTER-TYPE: NOT MEASURED (exit 75) — an input did not load: ${e.message}`)
|
||||
process.exit(75)
|
||||
}
|
||||
|
||||
// ── A ──
|
||||
const ids = [...(clusters.lists || []), ...(clusters.asia_lists || []), ...(clusters.uncovered_lists || [])].map((l) => l.id).filter(Boolean)
|
||||
const others = ids.filter((id) => R.regionOf(id) === 'Other')
|
||||
const used = new Set(ids.map((id) => R.regionOf(id)))
|
||||
const PROMISED = ['India', 'China + Mongolia', 'Africa', 'Middle East', 'Central Asia', 'Southeast Asia + Oceania', 'Americas', 'Europe']
|
||||
ok(R.regionOf('a-zone-nobody-placed') === 'Other', 'NEGATIVE CONTROL: an unknown zone did not fall to Other, so this check cannot see a missing region',
|
||||
'negative control: an unplaced zone falls to Other')
|
||||
ok(ids.length > 20 && !others.length && PROMISED.every((r) => used.has(r)),
|
||||
`zones without a region: ${others.join(', ') || '(none)'}; sections missing: ${PROMISED.filter((r) => !used.has(r)).join(', ') || '(none)'}`,
|
||||
`${ids.length} zones, every one in a named region; all ${PROMISED.length} sections present`)
|
||||
|
||||
// ── B ──
|
||||
const scopes = R.REGIONS.map(R.regionScope)
|
||||
ok(new Set(scopes).size === scopes.length && R.REGIONS.every((r) => R.regionScope(R.regionScope(r)) === R.regionScope(r)) && R.regionScope('Southeast Asia + Oceania') === 'southeast-asia-oceania',
|
||||
`scopes are not unique or do not round-trip: ${scopes.join(', ')}`, `scopes unique and stable: ${scopes.join(', ')}`)
|
||||
|
||||
// ── C ──
|
||||
const missingKeys = []
|
||||
for (const r of R.REGIONS) {
|
||||
const key = REGION_KEY[r]
|
||||
if (!key) { missingKeys.push(`${r}: no REGION_KEY`); continue }
|
||||
for (const l of LANGS) { const cat = JSON.parse(readFileSync(P('library/i18n/locales', l, 'poster.json'), 'utf8')); if (typeof cat[key] !== 'string' || !cat[key].trim()) missingKeys.push(`${l} poster.${key}`) }
|
||||
}
|
||||
ok(!missingKeys.length, `region headings missing: ${missingKeys.slice(0, 6).join(', ')}`, `every region heading exists in all ${LANGS.length} locales`)
|
||||
|
||||
// ── D ──
|
||||
const index = readFileSync(P(PLUGIN, 'index.js'), 'utf8')
|
||||
const type = readFileSync(P(PLUGIN, 'data/upg100-poster-type.js'), 'utf8')
|
||||
const wall = readFileSync(P(PLUGIN, 'poster-wall.vue'), 'utf8')
|
||||
const wired = {
|
||||
'the bundle registers the upg100-list type': /registerPosterType\('upg100-list', \(\) => import\('\.\/data\/upg100-poster-type\.js'\)\)/.test(index),
|
||||
'the bundle registers the element': /\nregisterPosterSectionElement\(\)/.test(index),
|
||||
'the adapter has scopes, items, title and actions': ['scopes:', 'items(scope, locale)', 'title(scope, t)', 'actions({'].every((s) => type.includes(s)),
|
||||
'the wall groups through the same regionOf': /const regionFor = \(id\) => regionTitle\(regionOf\(id\), t\)/.test(wall) && !/const REGION_OF = /.test(wall),
|
||||
'the wall draws the same zones': /return upg100Zones\(profileConfig, locale\)/.test(wall),
|
||||
'the wall sections are collapsible': /:collapsible="true"/.test(wall) && /:collapsed-by="allOpen"/.test(wall),
|
||||
}
|
||||
const missingWires = Object.entries(wired).filter(([, v]) => !v).map(([k]) => k)
|
||||
ok(!missingWires.length, `missing: ${missingWires.join('; ')}`, 'the wall and <dxm-poster-section type="upg100-list"> share one region table, one zone list and the collapsible section')
|
||||
|
||||
for (const n of notes) console.log(n)
|
||||
if (fails.length) {
|
||||
console.error('UPG100-POSTER-TYPE: FAIL')
|
||||
for (const f of fails) console.error(` ✗ ${f}`)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('UPG100-POSTER-TYPE: PASS — UPG-100\'s region sections are one section, on the wall and as <dxm-poster-section type="upg100-list">.')
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "نسخ",
|
||||
"exportCsv": "تصدير CSV",
|
||||
"copyNotRegroupable": "لا يمكن إعادة تجميعها معًا: انسخ ولايات أو مقاطعات بلد واحد، أو البلدان، كلًّا على حدة",
|
||||
"displayName": "ملصقات قائمة UPG 100",
|
||||
"wallHeading": "ملصقات قائمة UPG 100",
|
||||
"displayName": "ملصقات قائمة UPG-100",
|
||||
"wallHeading": "ملصقات قائمة UPG-100",
|
||||
"wallIntroA": "كيف تُطعم جمعًا من خمسة آلاف؟ أجلسهم يسوع جماعاتٍ من خمسين ومن مئة، فصار المستحيل قابلًا للمشاركة (لوقا ٩:١٤). فعلنا المثل مع {n} شعوب غير مبلَّغة: ٢٧ قائمة من نحو خمسين إلى مئة. تُطبع كل قائمة حزمةَ صلاة وملصقًا، ليحمل ٢٧ تلميذًا أو كنيسة أو قائدًا محليًا كلٌّ واحدة — مصلّين لأجلهم ",
|
||||
"peopleStillLoading": "لا تزال الشعوب قيد التحميل، حاول مرة أخرى بعد لحظة"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Kopieren",
|
||||
"exportCsv": "CSV exportieren",
|
||||
"copyNotRegroupable": "Nicht gemeinsam umgruppierbar: Bundesstaaten oder Provinzen eines Landes oder die Länder getrennt kopieren",
|
||||
"displayName": "Poster der UPG 100 Liste",
|
||||
"wallHeading": "Poster der UPG 100 Liste",
|
||||
"displayName": "Poster der UPG-100-Liste",
|
||||
"wallHeading": "Poster der UPG-100-Liste",
|
||||
"wallIntroA": "Wie würden Sie eine Menge von fünftausend speisen? Jesus ließ sie in Gruppen zu fünfzig und hundert lagern, und das Unmögliche wurde teilbar (Lukas 9,14). Dasselbe haben wir mit den {n} unerreichten Volksgruppen getan: 27 Listen von etwa fünfzig bis hundert. Jede Liste druckt als Gebetspaket und als Poster, damit 27 Jünger, Gemeinden oder einheimische Leiter je eine tragen können — und für sie beten ",
|
||||
"peopleStillLoading": "die Volksgruppen werden noch geladen; versuchen Sie es gleich noch einmal"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copy",
|
||||
"exportCsv": "Export CSV",
|
||||
"copyNotRegroupable": "Can't be regrouped together: copy one country's states or provinces, or the countries, separately",
|
||||
"displayName": "UPG 100 List Posters",
|
||||
"wallHeading": "UPG 100 List Posters",
|
||||
"displayName": "UPG-100 List Posters",
|
||||
"wallHeading": "UPG-100 List Posters",
|
||||
"wallIntroA": "How would you feed a crowd of five thousand? Jesus sat them down in groups of fifty and a hundred, and the impossible became shareable (Luke 9:14). We did the same with the {n} unreached people groups: 27 lists of about fifty to a hundred. Each list prints as a prayer packet and a poster, so 27 disciples, churches or local leaders can each carry one — praying for them ",
|
||||
"peopleStillLoading": "the people groups are still loading, try again in a moment"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copiar",
|
||||
"exportCsv": "Exportar CSV",
|
||||
"copyNotRegroupable": "No se pueden reagrupar juntos: copia por separado los estados o provincias de un solo país, o los países",
|
||||
"displayName": "Carteles de la lista UPG 100",
|
||||
"wallHeading": "Carteles de la lista UPG 100",
|
||||
"displayName": "Carteles de la lista UPG-100",
|
||||
"wallHeading": "Carteles de la lista UPG-100",
|
||||
"wallIntroA": "¿Cómo alimentarías a una multitud de cinco mil? Jesús los sentó en grupos de cincuenta y de cien, y lo imposible se volvió compartible (Lucas 9:14). Hicimos lo mismo con los {n} pueblos no alcanzados: 27 listas de unos cincuenta a cien. Cada lista se imprime como paquete de oración y cartel, para que 27 discípulos, iglesias o líderes locales lleven una cada uno — orando por ellos ",
|
||||
"peopleStillLoading": "los pueblos aún se están cargando; inténtalo de nuevo en un momento"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copier",
|
||||
"exportCsv": "Exporter en CSV",
|
||||
"copyNotRegroupable": "Impossible de les regrouper ensemble : copiez séparément les États ou provinces d’un seul pays, ou les pays",
|
||||
"displayName": "Affiches de la liste UPG 100",
|
||||
"wallHeading": "Affiches de la liste UPG 100",
|
||||
"displayName": "Affiches de la liste UPG-100",
|
||||
"wallHeading": "Affiches de la liste UPG-100",
|
||||
"wallIntroA": "Comment nourririez-vous une foule de cinq mille personnes ? Jésus les a fait asseoir par groupes de cinquante et de cent, et l’impossible est devenu partageable (Luc 9.14). Nous avons fait de même avec les {n} peuples non atteints : 27 listes d’environ cinquante à cent. Chaque liste s’imprime en dossier de prière et en affiche, pour que 27 disciples, Églises ou responsables locaux en portent chacun une — en priant pour eux ",
|
||||
"peopleStillLoading": "les peuples sont encore en cours de chargement ; réessayez dans un instant"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "कॉपी करें",
|
||||
"exportCsv": "CSV निर्यात करें",
|
||||
"copyNotRegroupable": "इन्हें एक साथ पुनर्समूहित नहीं किया जा सकता: एक देश के राज्य या प्रांत, या देश, अलग-अलग कॉपी करें",
|
||||
"displayName": "UPG 100 सूची पोस्टर",
|
||||
"wallHeading": "UPG 100 सूची पोस्टर",
|
||||
"displayName": "UPG-100 सूची पोस्टर",
|
||||
"wallHeading": "UPG-100 सूची पोस्टर",
|
||||
"wallIntroA": "पाँच हज़ार की भीड़ को आप कैसे खिलाते? यीशु ने उन्हें पचास-पचास और सौ-सौ के समूहों में बिठाया, और असंभव बाँटने योग्य हो गया (लूका 9:14). हमने {n} अनपहुँचे जनसमूहों के साथ वही किया: लगभग पचास से सौ तक की 27 सूचियाँ. हर सूची प्रार्थना पैकेट और पोस्टर के रूप में छपती है, ताकि 27 शिष्य, कलीसियाएँ या स्थानीय अगुवे एक-एक ले सकें — उनके लिए प्रार्थना करते हुए ",
|
||||
"peopleStillLoading": "जनसमूह अभी लोड हो रहे हैं, थोड़ी देर में फिर कोशिश करें"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copia",
|
||||
"exportCsv": "Esporta CSV",
|
||||
"copyNotRegroupable": "Non si possono raggruppare insieme: copia separatamente gli stati o le province di un solo paese, o i paesi",
|
||||
"displayName": "Poster della lista UPG 100",
|
||||
"wallHeading": "Poster della lista UPG 100",
|
||||
"displayName": "Poster della lista UPG-100",
|
||||
"wallHeading": "Poster della lista UPG-100",
|
||||
"wallIntroA": "Come sfameresti una folla di cinquemila? Gesù li fece sedere a gruppi di cinquanta e di cento, e l’impossibile divenne condivisibile (Luca 9:14). Abbiamo fatto lo stesso con i {n} popoli non raggiunti: 27 liste di circa cinquanta-cento. Ogni lista si stampa come pacchetto di preghiera e manifesto, così 27 discepoli, chiese o responsabili locali ne portano una ciascuno — pregando per loro ",
|
||||
"peopleStillLoading": "i popoli si stanno ancora caricando; riprova tra un momento"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copiar",
|
||||
"exportCsv": "Exportar CSV",
|
||||
"copyNotRegroupable": "Não podem ser reagrupados juntos: copie separadamente os estados ou províncias de um só país, ou os países",
|
||||
"displayName": "Cartazes da lista UPG 100",
|
||||
"wallHeading": "Cartazes da lista UPG 100",
|
||||
"displayName": "Cartazes da lista UPG-100",
|
||||
"wallHeading": "Cartazes da lista UPG-100",
|
||||
"wallIntroA": "Como você alimentaria uma multidão de cinco mil? Jesus os sentou em grupos de cinquenta e de cem, e o impossível tornou-se compartilhável (Lucas 9.14). Fizemos o mesmo com os {n} povos não alcançados: 27 listas de cerca de cinquenta a cem. Cada lista imprime como pacote de oração e cartaz, para que 27 discípulos, igrejas ou líderes locais levem uma cada um — orando por eles ",
|
||||
"peopleStillLoading": "os povos ainda estão carregando; tente de novo em um instante"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Copiază",
|
||||
"exportCsv": "Exportă CSV",
|
||||
"copyNotRegroupable": "Nu pot fi regrupate împreună: copiază separat statele sau provinciile unei singure țări, sau țările",
|
||||
"displayName": "Afișe din lista UPG 100",
|
||||
"wallHeading": "Afișe din lista UPG 100",
|
||||
"displayName": "Afișe din lista UPG-100",
|
||||
"wallHeading": "Afișe din lista UPG-100",
|
||||
"wallIntroA": "Cum ai hrăni o mulțime de cinci mii? Isus i-a așezat în grupuri de cincizeci și de o sută, iar imposibilul a devenit împărțibil (Luca 9:14). Am făcut la fel cu cele {n} popoare neatinse: 27 de liste de aproximativ cincizeci până la o sută. Fiecare listă se tipărește ca pachet de rugăciune și afiș, ca 27 de ucenici, biserici sau lideri locali să poarte fiecare câte una — rugându-se pentru ei ",
|
||||
"peopleStillLoading": "popoarele încă se încarcă; încearcă din nou peste o clipă"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "Копировать",
|
||||
"exportCsv": "Экспорт в CSV",
|
||||
"copyNotRegroupable": "Нельзя перегруппировать вместе: копируйте отдельно штаты или провинции одной страны либо страны",
|
||||
"displayName": "Плакаты списка UPG 100",
|
||||
"wallHeading": "Плакаты списка UPG 100",
|
||||
"displayName": "Плакаты списка UPG-100",
|
||||
"wallHeading": "Плакаты списка UPG-100",
|
||||
"wallIntroA": "Как накормить толпу в пять тысяч человек? Иисус рассадил их группами по пятьдесят и по сто, и невозможное стало посильным (Лк. 9:14). Мы поступили так же с {n} неохваченными народами: 27 списков примерно по пятьдесят-сто. Каждый список печатается как молитвенный пакет и плакат, чтобы 27 учеников, церквей или местных служителей взяли по одному — молясь о них ",
|
||||
"peopleStillLoading": "народы ещё загружаются; попробуйте ещё раз через мгновение"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"copySelection": "复制",
|
||||
"exportCsv": "导出 CSV",
|
||||
"copyNotRegroupable": "无法一起重新分组:请分别复制同一国家的邦或省,或各个国家",
|
||||
"displayName": "UPG 100 名单海报",
|
||||
"wallHeading": "UPG 100 名单海报",
|
||||
"displayName": "UPG-100 名单海报",
|
||||
"wallHeading": "UPG-100 名单海报",
|
||||
"wallIntroA": "你会怎样喂饱五千人的群众?耶稣让他们一排五十、一排一百地坐下,不可能的事就变得可以分担了(路加福音 9:14)。我们对 {n} 个未得之民做了同样的事:27 份名单,每份约五十到一百。每份名单都能印成祷告手册和海报,让 27 位门徒、教会或当地领袖各领一份 — 为他们祷告 ",
|
||||
"peopleStillLoading": "族群仍在加载中,请稍后再试"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@
|
|||
"check:list-pattern-doc": "node internal/check-list-pattern-doc.mjs",
|
||||
"check:pg-name-gate": "node internal/check-pg-name-gate.mjs",
|
||||
"check:pin-selection": "node internal/check-pin-selection.mjs",
|
||||
"check:upg100-poster-type": "node internal/check-upg100-poster-type.mjs",
|
||||
"check:poster-action-print": "node internal/check-poster-action-print.mjs",
|
||||
"check:popup-href-escaped": "node internal/check-popup-href-escaped.mjs",
|
||||
"check:popup-pan-controls": "node internal/check-popup-pan-clears-controls.mjs",
|
||||
|
|
@ -351,7 +352,7 @@
|
|||
"fix:sri": "node internal/fix-sri.mjs",
|
||||
"gallery": "node internal/generate-gallery.mjs",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-design-catalogue check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-design-catalogue check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:upg100-poster-type",
|
||||
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
||||
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
||||
"library-index": "node internal/generate-library-index.mjs",
|
||||
|
|
@ -589,6 +590,7 @@
|
|||
"check:popup-escaping": "the library's pin and region popups render hostile data (an <img onerror>, a <script>, a javascript: URL) as text, never markup: every field goes through escapeHtml/safeUrl (library/utils/html.js). Headless.",
|
||||
"check:ported-globals-identical": "the DX Life base/_globals.scss rules that shadow-root components used to copy now come from one module (library/styles/portedGlobals.js), and the CSS each component actually INJECTS must be byte-identical to the pre-refactor baseline: it runs each component's setup with stubbed imports and hashes the real useShadowStyles argument, not the source text. Deduplication with a proof that no pixel can change. Node only, no browser.",
|
||||
"check:pg-name-gate": "a people group's localized name (assets/pplr/pg-names.json) is shown only when it is a transliteration: library/utils/peopleGroupName.js falls back to English for EVERY locale of a row whose Latin-script names are far from the English one in two or more locales (bigram Dice < 0.5), because about a third were machine-translated as words (Balantak → 'Balance', Balo → 'Sac à dos'). A row with fewer than two Latin names cannot be checked and shows English too. Proved on the real table: the 4 known translated rows show English in 7 locales, Balangao Bontoc keeps its names, planted rows AT the threshold (exactly two far → English, one → kept, one Latin name → English), the whole-table fallback stays 30-45% (38.2%), and no file outside the helper reads or indexes pg-names rows (pplr-data-maps carded; the scanner is negative-controlled both ways). Headless.",
|
||||
"check:upg100-poster-type": "UPG-100's region sections are ONE section on the poster wall and as <dxm-poster-section type=\"upg100-list\">: every zone in clusters.json belongs to a named region (a planted unknown zone falls to Other: the negative control), the 8 promised sections exist, each scope slug is unique and round-trips, each heading has its poster.region_* key in all 11 locales, and the wiring holds (the bundle registers the type and the element; the wall groups through the same regionOf, draws the same zones and its sections are collapsible). Headless.",
|
||||
"check:pin-selection": "the shared source reader understands BOTH engines: mapbox-gl stores a GeoJSON source _data as the FeatureCollection, maplibre-gl wraps it as { geojson } (or { url } when remote). Reading only the Mapbox shape returned an EMPTY list on MapLibre — the keyless engine public builds use — which silently killed zoomToLegendRow camera fits on three maps and the research packet row selection, with no error because every caller no-ops on no features. Asserts both shapes, that a remote source returns [] AND warns, the serialize fallback, and that selectedPinIds agrees with the reader. Headless, no map. Exit 0 pass, 1 fail.",
|
||||
"check:popup-href-escaped": "a URL interpolated into an HTML string is escaped before it lands in href= or src=. Written for RegionCountryMap's popup, which escaped every value except its two link URLs -- both built from joinBase(hostAttribute, apiSlug), so a quote in either escaped the attribute. Data URLs, blob URLs, encodeURIComponent and safeUrl() are recognised as safe; anything else needs an href-escaped-ok: reason. 6 self-tests. Source-only, headless.",
|
||||
"check:poster-action-print": "a poster button opens the print dialog (the rule since 2026-09-28: never a direct download). Two arms: PosterWall's posterAction defaults to 'print' and any consumer opting into 'download' carries a posterAction-download: comment saying why; and no shipped file hand-rolls an <a download> for a poster IMAGE (svg/png/webp/pdf) without first attempting to print, which the prop arm cannot see. Data exports (csv/txt/json) are out of scope. 6 self-tests. Source-only, headless.",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Cities with Internet', 'sub.cities-internet': 'connectivity of key cities',
|
||||
'tab.gospel-resources': 'Gospel Resources', 'sub.gospel-resources': 'resources by place',
|
||||
'tab.regions-dashboard': 'Regions', 'sub.regions-dashboard': 'regions and their countries',
|
||||
'tab.upg-100': "UPG 100 List Posters", 'sub.upg-100': 'my unreached list + posters',
|
||||
'tab.upg-100': "UPG-100 List Posters", 'sub.upg-100': 'my unreached list + posters',
|
||||
navLabel: 'Research maps', meta: '{n} maps', loading: 'Loading {label}…', loadFailed: 'Could not load {label}.',
|
||||
manifestHint: 'This tab is composed from manifest.json — build the tree, or serve the built tree, to load it.',
|
||||
close: 'Close', help: 'About this map', desktopOnly: 'desktop only', lab: 'lab', experimentalSub: 'experimental bundle',
|
||||
|
|
@ -46,7 +46,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Ciudades con Internet', 'sub.cities-internet': 'conectividad de ciudades clave',
|
||||
'tab.gospel-resources': 'Recursos del Evangelio', 'sub.gospel-resources': 'recursos por lugar',
|
||||
'tab.regions-dashboard': 'Regiones', 'sub.regions-dashboard': 'regiones y sus países',
|
||||
'tab.upg-100': "Carteles de la lista UPG 100", 'sub.upg-100': 'mi lista de no alcanzados + carteles',
|
||||
'tab.upg-100': "Carteles de la lista UPG-100", 'sub.upg-100': 'mi lista de no alcanzados + carteles',
|
||||
navLabel: 'Mapas de investigación', meta: '{n} mapas', loading: 'Cargando {label}…', loadFailed: 'No se pudo cargar {label}.',
|
||||
manifestHint: 'Esta pestaña se compone a partir de manifest.json: compila el árbol o sirve el árbol compilado para cargarla.',
|
||||
close: 'Cerrar', help: 'Acerca de este mapa', desktopOnly: 'solo escritorio', lab: 'beta', experimentalSub: 'mapa experimental',
|
||||
|
|
@ -67,7 +67,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Villes avec Internet', 'sub.cities-internet': 'connectivité des villes clés',
|
||||
'tab.gospel-resources': "Ressources de l'Évangile", 'sub.gospel-resources': 'ressources par lieu',
|
||||
'tab.regions-dashboard': 'Régions', 'sub.regions-dashboard': 'régions et leurs pays',
|
||||
'tab.upg-100': "Affiches de la liste UPG 100", 'sub.upg-100': 'ma liste des non atteints + affiches',
|
||||
'tab.upg-100': "Affiches de la liste UPG-100", 'sub.upg-100': 'ma liste des non atteints + affiches',
|
||||
navLabel: 'Cartes de recherche', meta: '{n} cartes', loading: 'Chargement de {label}…', loadFailed: 'Impossible de charger {label}.',
|
||||
manifestHint: "Cet onglet est composé à partir de manifest.json : construisez l'arborescence ou servez l'arborescence construite pour le charger.",
|
||||
close: 'Fermer', help: 'À propos de cette carte', desktopOnly: 'ordinateur uniquement', lab: 'bêta', experimentalSub: 'carte expérimentale',
|
||||
|
|
@ -88,7 +88,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Städte mit Internet', 'sub.cities-internet': 'Konnektivität wichtiger Städte',
|
||||
'tab.gospel-resources': 'Evangeliumsressourcen', 'sub.gospel-resources': 'Ressourcen nach Ort',
|
||||
'tab.regions-dashboard': 'Regionen', 'sub.regions-dashboard': 'Regionen und ihre Länder',
|
||||
'tab.upg-100': "Poster der UPG 100 Liste", 'sub.upg-100': 'meine Liste der Unerreichten + Poster',
|
||||
'tab.upg-100': "Poster der UPG-100-Liste", 'sub.upg-100': 'meine Liste der Unerreichten + Poster',
|
||||
navLabel: 'Forschungskarten', meta: '{n} Karten', loading: '{label} wird geladen…', loadFailed: '{label} konnte nicht geladen werden.',
|
||||
manifestHint: 'Dieser Tab wird aus manifest.json zusammengesetzt – bauen Sie den Baum oder stellen Sie den gebauten Baum bereit, um ihn zu laden.',
|
||||
close: 'Schließen', help: 'Über diese Karte', desktopOnly: 'nur Desktop', lab: 'Beta', experimentalSub: 'experimentelle Karte',
|
||||
|
|
@ -109,7 +109,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Cidades com Internet', 'sub.cities-internet': 'conectividade das principais cidades',
|
||||
'tab.gospel-resources': 'Recursos do Evangelho', 'sub.gospel-resources': 'recursos por lugar',
|
||||
'tab.regions-dashboard': 'Regiões', 'sub.regions-dashboard': 'regiões e seus países',
|
||||
'tab.upg-100': "Cartazes da lista UPG 100", 'sub.upg-100': 'minha lista de não alcançados + cartazes',
|
||||
'tab.upg-100': "Cartazes da lista UPG-100", 'sub.upg-100': 'minha lista de não alcançados + cartazes',
|
||||
navLabel: 'Mapas de pesquisa', meta: '{n} mapas', loading: 'Carregando {label}…', loadFailed: 'Não foi possível carregar {label}.',
|
||||
manifestHint: 'Esta aba é composta a partir do manifest.json — compile a árvore ou sirva a árvore compilada para carregá-la.',
|
||||
close: 'Fechar', help: 'Sobre este mapa', desktopOnly: 'só no computador', lab: 'beta', experimentalSub: 'mapa experimental',
|
||||
|
|
@ -132,7 +132,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Città con Internet', 'sub.cities-internet': 'connettività delle città chiave',
|
||||
'tab.gospel-resources': 'Risorse del Vangelo', 'sub.gospel-resources': 'risorse per luogo',
|
||||
'tab.regions-dashboard': 'Regioni', 'sub.regions-dashboard': 'regioni e i loro paesi',
|
||||
'tab.upg-100': "Poster della lista UPG 100", 'sub.upg-100': 'la mia lista dei non raggiunti + poster',
|
||||
'tab.upg-100': "Poster della lista UPG-100", 'sub.upg-100': 'la mia lista dei non raggiunti + poster',
|
||||
navLabel: 'Mappe di ricerca', meta: '{n} mappe', loading: 'Caricamento di {label}…', loadFailed: 'Impossibile caricare {label}.',
|
||||
manifestHint: "Questa scheda è composta da manifest.json: compila l'albero o pubblica l'albero compilato per caricarla.",
|
||||
close: 'Chiudi', help: 'Informazioni su questa mappa', desktopOnly: 'solo desktop', lab: 'beta', experimentalSub: 'mappa sperimentale',
|
||||
|
|
@ -153,7 +153,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Orașe cu internet', 'sub.cities-internet': 'conectivitatea orașelor-cheie',
|
||||
'tab.gospel-resources': 'Resurse ale Evangheliei', 'sub.gospel-resources': 'resurse după loc',
|
||||
'tab.regions-dashboard': 'Regiuni', 'sub.regions-dashboard': 'regiunile și țările lor',
|
||||
'tab.upg-100': "Afișe din lista UPG 100", 'sub.upg-100': 'lista mea de neatinși + afișe',
|
||||
'tab.upg-100': "Afișe din lista UPG-100", 'sub.upg-100': 'lista mea de neatinși + afișe',
|
||||
navLabel: 'Hărți de cercetare', meta: '{n} hărți', loading: 'Se încarcă {label}…', loadFailed: '{label} nu a putut fi încărcat.',
|
||||
manifestHint: 'Această filă este compusă din manifest.json — construiți arborele sau serviți arborele construit pentru a o încărca.',
|
||||
close: 'Închide', help: 'Despre această hartă', desktopOnly: 'doar pe desktop', lab: 'beta', experimentalSub: 'hartă experimentală',
|
||||
|
|
@ -174,7 +174,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'Города с интернетом', 'sub.cities-internet': 'подключённость ключевых городов',
|
||||
'tab.gospel-resources': 'Евангельские ресурсы', 'sub.gospel-resources': 'ресурсы по местам',
|
||||
'tab.regions-dashboard': 'Регионы', 'sub.regions-dashboard': 'регионы и их страны',
|
||||
'tab.upg-100': "Плакаты списка UPG 100", 'sub.upg-100': 'мой список недостигнутых + плакаты',
|
||||
'tab.upg-100': "Плакаты списка UPG-100", 'sub.upg-100': 'мой список недостигнутых + плакаты',
|
||||
navLabel: 'Исследовательские карты', meta: 'Карт: {n}', loading: 'Загрузка: {label}…', loadFailed: 'Не удалось загрузить: {label}.',
|
||||
manifestHint: 'Эта вкладка собирается из manifest.json — соберите дерево или разместите собранное дерево, чтобы загрузить её.',
|
||||
close: 'Закрыть', help: 'Об этой карте', desktopOnly: 'только на компьютере', lab: 'бета', experimentalSub: 'экспериментальная карта',
|
||||
|
|
@ -195,7 +195,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'مدن متصلة بالإنترنت', 'sub.cities-internet': 'اتصال المدن الرئيسية',
|
||||
'tab.gospel-resources': 'موارد الإنجيل', 'sub.gospel-resources': 'الموارد حسب المكان',
|
||||
'tab.regions-dashboard': 'المناطق', 'sub.regions-dashboard': 'المناطق ودولها',
|
||||
'tab.upg-100': "ملصقات قائمة UPG 100", 'sub.upg-100': 'قائمتي لغير المُبشَّرين + ملصقات',
|
||||
'tab.upg-100': "ملصقات قائمة UPG-100", 'sub.upg-100': 'قائمتي لغير المُبشَّرين + ملصقات',
|
||||
navLabel: 'خرائط البحث', meta: 'عدد الخرائط: {n}', loading: 'جارٍ تحميل {label}…', loadFailed: 'تعذّر تحميل {label}.',
|
||||
manifestHint: 'تُبنى علامة التبويب هذه من manifest.json — ابنِ الشجرة أو قدّم الشجرة المبنية لتحميلها.',
|
||||
close: 'إغلاق', help: 'عن هذه الخريطة', desktopOnly: 'على الحاسوب فقط', lab: 'تجريبي', experimentalSub: 'خريطة تجريبية',
|
||||
|
|
@ -216,7 +216,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': 'इंटरनेट वाले शहर', 'sub.cities-internet': 'प्रमुख शहरों की कनेक्टिविटी',
|
||||
'tab.gospel-resources': 'सुसमाचार संसाधन', 'sub.gospel-resources': 'स्थान के अनुसार संसाधन',
|
||||
'tab.regions-dashboard': 'क्षेत्र', 'sub.regions-dashboard': 'क्षेत्र और उनके देश',
|
||||
'tab.upg-100': "UPG 100 सूची पोस्टर", 'sub.upg-100': 'मेरी अप्राप्त सूची + पोस्टर',
|
||||
'tab.upg-100': "UPG-100 सूची पोस्टर", 'sub.upg-100': 'मेरी अप्राप्त सूची + पोस्टर',
|
||||
navLabel: 'शोध मानचित्र', meta: '{n} मानचित्र', loading: '{label} लोड हो रहा है…', loadFailed: '{label} लोड नहीं हो सका।',
|
||||
manifestHint: 'यह टैब manifest.json से बनता है — इसे लोड करने के लिए ट्री बनाएँ या बना हुआ ट्री सर्व करें।',
|
||||
close: 'बंद करें', help: 'इस नक्शे के बारे में', desktopOnly: 'केवल डेस्कटॉप', lab: 'बीटा', experimentalSub: 'प्रायोगिक मानचित्र',
|
||||
|
|
@ -237,7 +237,7 @@ export const STRINGS = {
|
|||
'tab.cities-internet': '有互联网的城市', 'sub.cities-internet': '主要城市的网络连接',
|
||||
'tab.gospel-resources': '福音资源', 'sub.gospel-resources': '按地点划分的资源',
|
||||
'tab.regions-dashboard': '区域', 'sub.regions-dashboard': '区域及其国家',
|
||||
'tab.upg-100': "UPG 100 名单海报", 'sub.upg-100': '我的未得之民名单 + 海报',
|
||||
'tab.upg-100': "UPG-100 名单海报", 'sub.upg-100': '我的未得之民名单 + 海报',
|
||||
navLabel: '研究地图', meta: '{n} 张地图', loading: '正在加载{label}…', loadFailed: '无法加载{label}。',
|
||||
manifestHint: '此标签页由 manifest.json 组成——请构建目录树或提供已构建的目录树以加载它。',
|
||||
close: '关闭', help: '关于此地图', desktopOnly: '仅限桌面', lab: '测试版', experimentalSub: '实验性地图',
|
||||
|
|
|
|||
60
plugin-designs/my-upg-100-list/data/upg100-poster-type.js
vendored
Normal file
60
plugin-designs/my-upg-100-list/data/upg100-poster-type.js
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* The 'upg100-list' poster type: the UPG-100 zone posters, one section per region. Registered from this plugin
|
||||
* (index.js, registerPosterType), so <dxm-poster-section type="upg100-list" scope="africa"> draws exactly the section
|
||||
* the UPG-100 poster wall draws. The same zones (zonesForList, list-aware), the same region of each zone
|
||||
* (upg100-regions.js), the same headings (poster.region_*), and the same print path (the library's records provider
|
||||
* with this plugin's selector evaluator, and zone-sheet-print.js for the sheet).
|
||||
* scope = a region's key in either spelling: the slug ("southeast-asia-oceania") or the English name.
|
||||
*/
|
||||
import { zonesForList } from './zones-for-list.js'
|
||||
import { regionOf, regionScope, REGIONS } from './upg100-regions.js'
|
||||
import { REGION_KEY } from './legend-tree.js'
|
||||
import { zoneTitle } from './zone-title.js'
|
||||
import { evaluate as evaluateSelector } from './selector-evaluator.js'
|
||||
import { makeZoneSheet } from './zone-sheet-print.js'
|
||||
import { resolvePeopleGroupList } from '@map/lists/peopleGroupList.js'
|
||||
import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js'
|
||||
import { countryName } from '@map/utils/countryName.js'
|
||||
import { keyedError } from '@map/i18n/keyedError.js'
|
||||
|
||||
/**
|
||||
* Every zone the wall shows for the list in force, its card named in the reader's language. zoneTitle declines
|
||||
* (null) for a zone it cannot name, and that zone keeps its hand-written label, exactly as on the legend and the
|
||||
* packet.
|
||||
*/
|
||||
export function upg100Zones(profileConfig, locale) {
|
||||
const z = zonesForList(resolvePeopleGroupList(profileConfig))
|
||||
return [...(z.lists || []), ...(z.asia_lists || []), ...(z.uncovered_lists || [])]
|
||||
.filter((l) => l && l.id)
|
||||
.map((l) => { const title = zoneTitle(l, null, { countryName, locale }); return title ? { ...l, label: title } : l })
|
||||
}
|
||||
|
||||
/** A region's heading in the reader's language (poster.region_*, in all 11 locales); the English key if none. */
|
||||
export function regionTitle(english, t) {
|
||||
const key = REGION_KEY[english]
|
||||
if (!key) return english
|
||||
const v = t(`poster.${key}`)
|
||||
return v && v !== `poster.${key}` ? v : english
|
||||
}
|
||||
|
||||
const englishOf = (scope) => REGIONS.find((r) => regionScope(r) === regionScope(scope)) || null
|
||||
|
||||
export default {
|
||||
scopes: () => REGIONS.map(regionScope),
|
||||
items(scope, locale) {
|
||||
return upg100Zones(null, locale).filter((l) => regionScope(regionOf(l.id)) === regionScope(scope))
|
||||
},
|
||||
title(scope, t) {
|
||||
const english = englishOf(scope)
|
||||
return english ? regionTitle(english, t) : String(scope || '')
|
||||
},
|
||||
actions({ assetsBase, apiBase, lang, profileConfig }) {
|
||||
const recordsFor = createPeopleGroupRecords({ apiBase, lang, profileConfig, evaluate: (selector, records) => evaluateSelector(selector, records) })
|
||||
return {
|
||||
records: (list) => (apiBase() ? recordsFor(list.selector) : Promise.reject(keyedError('wall.hud.noApi', 'no people-groups service is configured'))),
|
||||
sheet: makeZoneSheet({ allRecords: () => recordsFor.all(), assetsBase, profileConfig }),
|
||||
unsupported: () => null,
|
||||
unit: 'UPG', itemCountKey: 'wall.listCount', eventName: 'doxa-upg-100-list:show-on-map', downloadPrefix: 'doxa-upg-100', cardStocks: true,
|
||||
}
|
||||
},
|
||||
}
|
||||
61
plugin-designs/my-upg-100-list/data/upg100-regions.js
vendored
Normal file
61
plugin-designs/my-upg-100-list/data/upg100-regions.js
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// upg100-regions.js — which REGION SECTION each UPG-100 zone belongs to, and that section's scope key. PURE (no
|
||||
// imports), so the poster wall, the 'upg100-list' poster type (upg100-poster-type.js) and the gate read ONE table.
|
||||
// Moved here verbatim from poster-wall.vue, which groups by it as before.
|
||||
// ─── REGIONAL SECTIONS ───────────────────────────────────────────────────────
|
||||
// clusters.json carries no region field, so the mapping lives here. It is keyed by
|
||||
// list id rather than derived from the selector: a selector can be a wagf_block, a
|
||||
// country_codes array or an explicit pg_slugs list, and none of those reliably
|
||||
// implies the continent a reader expects to browse by.
|
||||
//
|
||||
// SE Asia + Oceania are ONE section deliberately (the island chains read as a
|
||||
// single sweep), and the Americas gathers Brazil, the Andean/Caribbean list and the
|
||||
// US-bearing scatter list.
|
||||
export const REGION_OF = {
|
||||
// Africa
|
||||
'west-africa': 'Africa', 'sudan': 'Africa', 'east-africa': 'Africa',
|
||||
'central-africa': 'Africa', 'southern-africa-islands': 'Africa',
|
||||
// Middle East. Maghreb+Egypt is geographically North AFRICA but belongs here:
|
||||
// the region is read as a cultural/linguistic sweep.
|
||||
'maghreb-egypt': 'Middle East',
|
||||
'middle-east-core': 'Middle East',
|
||||
// CENTRAL ASIA is its own section: the 55-UPG Pakistan map belongs to Central
|
||||
// Asia, not the Middle East. It had been folded into the Middle
|
||||
// East as "the same sweep continuing east", but Pakistan, Afghanistan,
|
||||
// Uzbekistan, Tajikistan, Kyrgyzstan and Kazakhstan are Central/South Asia —
|
||||
// filing them under the Middle East misnames six countries to save a heading.
|
||||
'uncovered-nas-a': 'Central Asia',
|
||||
// Southeast Asia + Oceania
|
||||
'laos': 'Southeast Asia + Oceania', 'oceania-indonesia': 'Southeast Asia + Oceania',
|
||||
'mainland-se-asia-philippines': 'Southeast Asia + Oceania',
|
||||
// Americas
|
||||
'brazil': 'Americas', 'andean-caribbean': 'Americas', 'uncovered-scatter': 'Americas',
|
||||
// Europe
|
||||
'europe': 'Europe',
|
||||
// India and China are their OWN sections, not one lump called "Asia". Between
|
||||
// them they are 1,122 people groups across 12 lists — more than every other
|
||||
// section combined — so collapsing them hides the two largest prayer fields in
|
||||
// the dataset behind a single continental label. Matched by id prefix below.
|
||||
}
|
||||
|
||||
/** The section a zone belongs to, by its ENGLISH grouping key (REGION_OF, then the India / China id prefixes). */
|
||||
export function regionOf(id) {
|
||||
if (REGION_OF[id]) return REGION_OF[id]
|
||||
if (String(id).startsWith('asia-india-')) return 'India'
|
||||
// "China + Mongolia": the northern zone declares Mongolia as a member country (its land is drawn and highlighted),
|
||||
// so the section heading names both rather than folding a sovereign country under a China label.
|
||||
if (String(id).startsWith('asia-china-')) return 'China + Mongolia'
|
||||
return 'Other'
|
||||
}
|
||||
|
||||
/**
|
||||
* A section's SCOPE for <dxm-poster-section type="upg100-list" scope="…">: its English key slugified the way DX
|
||||
* Life's /regions does (no diacritics, lowercase, "&"/"+" → a dash, non-alphanumerics → "-"), so "Southeast Asia +
|
||||
* Oceania" is "southeast-asia-oceania" and the English name itself is accepted too.
|
||||
*/
|
||||
export const regionScope = (s) => String(s || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase()
|
||||
.replace(/['’.]/g, '').replace(/&/g, ' and ').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'other'
|
||||
|
||||
/** Every section's English key, in a stable order (the wall itself sorts its sections by size). */
|
||||
export const REGIONS = ['India', 'China + Mongolia', 'Africa', 'Middle East', 'Central Asia', 'Southeast Asia + Oceania', 'Americas', 'Europe', 'Other']
|
||||
|
||||
export default { REGION_OF, regionOf, regionScope, REGIONS }
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
import { defineMapElement } from '@map/elements/defineMapElement.js'
|
||||
import { registerPosterType } from '@map/components/poster/posterTypes.js'
|
||||
import { registerPosterSectionElement } from '@map/elements/posterSectionElement.js'
|
||||
/**
|
||||
* plugin-designs/my-upg-100-list/index.js
|
||||
*
|
||||
|
|
@ -64,4 +66,11 @@ if (typeof customElements !== 'undefined') {
|
|||
}
|
||||
}
|
||||
|
||||
// ★ THE 'upg100-list' POSTER TYPE, registered from this plugin (no plugin code in the library): one UPG-100 region
|
||||
// section as an element, <dxm-poster-section type="upg100-list" scope="africa">, drawing the same section the poster
|
||||
// wall draws (data/upg100-poster-type.js). The element is registered here too (a no-op when another bundle on the
|
||||
// page did it first), so a page that loads only this bundle can show it.
|
||||
registerPosterType('upg100-list', () => import('./data/upg100-poster-type.js'))
|
||||
registerPosterSectionElement()
|
||||
|
||||
export default Upg100ListMapElement
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"_comment": "The printable half of UPG-100: a wall of prayer-card posters, one per 100-list entry, with the three print paths. Declared so the Studio rail names it rather than falling back to a humanized id (check:studio-rail).",
|
||||
"label": "UPG 100 List Posters — Poster Wall"
|
||||
"label": "UPG-100 List Posters — Poster Wall"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* its records provider.
|
||||
*
|
||||
* WHAT COULD NOT BE SHARED, and why each is here rather than in the component:
|
||||
* REGION_OF / regionFor — the 100-list's own continental taxonomy, keyed by list id because a
|
||||
* regionFor (REGION_OF in data/upg100-regions.js) — the 100-list's own continental taxonomy, keyed by list id because a
|
||||
* selector can be a wagf_block, a country_codes array or an explicit
|
||||
* pg_slugs list and none of those implies a continent.
|
||||
* fetchListRecords — knows the people-groups API, the selector evaluator AND the pg_slugs
|
||||
|
|
@ -41,7 +41,6 @@
|
|||
import { computed, inject, ref } from 'vue'
|
||||
import { useOptionalT, useOptionalI18n } from '@map/composables/useOptionalT.js'
|
||||
// The page's people-group LIST (library/lists/): every people-group fetch below keeps only its groups.
|
||||
import { resolvePeopleGroupList } from '@map/lists/peopleGroupList.js'
|
||||
import PosterWall from '@map/components/poster/PosterWall.vue'
|
||||
import { resolveAssetsBase } from '@map/utils/embedBase.js'
|
||||
// The reader's language, for the DATA fetch below. Not for interface text — that goes through t().
|
||||
|
|
@ -49,18 +48,15 @@ import { getRuntimeLocale, detectLocale } from '@map/i18n/index.js'
|
|||
// The list's total for the intro, from the funnel (never a number written into a string; see data/upg-total.js).
|
||||
import visionFunnel from '../../data/people-groups/vision-funnel.json'
|
||||
import { upgTotal, countInSentence } from './data/upg-total.js'
|
||||
// Named imports: only the list arrays ship in the bundle; the file's bookkeeping fields stay out.
|
||||
import { zonesForList } from './data/zones-for-list.js'
|
||||
// The SAME normalize+evaluate pipeline the sibling map profile uses to turn the live
|
||||
// /people-groups/list payload + a list's `selector` into the exact rows that belong to it.
|
||||
import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js'
|
||||
import { makeZoneSheet } from './data/zone-sheet-print.js'
|
||||
import { REGION_KEY } from './data/legend-tree.js'
|
||||
import { regionOf } from './data/upg100-regions.js'
|
||||
// The zones (list-aware, each named in the reader's language) and each region's heading: the 'upg100-list' poster
|
||||
// type's own functions, so this wall and <dxm-poster-section type="upg100-list"> draw the same cards.
|
||||
import { upg100Zones, regionTitle } from './data/upg100-poster-type.js'
|
||||
import { keyedError } from '@map/i18n/keyedError.js'
|
||||
// A zone's title in the reader's language (tier A: its country; others keep their label) — the same
|
||||
// generator the map's legend and the packet use, so a card, its alt text and its print say one name.
|
||||
import { zoneTitle } from './data/zone-title.js'
|
||||
import { countryName } from '@map/utils/countryName.js'
|
||||
import { evaluate as evaluateSelector } from './data/selector-evaluator.js'
|
||||
|
||||
// The table the zone map sheets were generated from (generate.mjs labels each country with it), so a
|
||||
|
|
@ -82,41 +78,7 @@ const API_BASE = (typeof window !== 'undefined' && window.MAP_APP_API_URL)
|
|||
|| import.meta.env.VITE_API_BASE_URL
|
||||
|| ''
|
||||
|
||||
// ─── REGIONAL SECTIONS ───────────────────────────────────────────────────────
|
||||
// clusters.json carries no region field, so the mapping lives here. It is keyed by
|
||||
// list id rather than derived from the selector: a selector can be a wagf_block, a
|
||||
// country_codes array or an explicit pg_slugs list, and none of those reliably
|
||||
// implies the continent a reader expects to browse by.
|
||||
//
|
||||
// SE Asia + Oceania are ONE section deliberately (the island chains read as a
|
||||
// single sweep), and the Americas gathers Brazil, the Andean/Caribbean list and the
|
||||
// US-bearing scatter list.
|
||||
const REGION_OF = {
|
||||
// Africa
|
||||
'west-africa': 'Africa', 'sudan': 'Africa', 'east-africa': 'Africa',
|
||||
'central-africa': 'Africa', 'southern-africa-islands': 'Africa',
|
||||
// Middle East. Maghreb+Egypt is geographically North AFRICA but belongs here:
|
||||
// the region is read as a cultural/linguistic sweep.
|
||||
'maghreb-egypt': 'Middle East',
|
||||
'middle-east-core': 'Middle East',
|
||||
// CENTRAL ASIA is its own section: the 55-UPG Pakistan map belongs to Central
|
||||
// Asia, not the Middle East. It had been folded into the Middle
|
||||
// East as "the same sweep continuing east", but Pakistan, Afghanistan,
|
||||
// Uzbekistan, Tajikistan, Kyrgyzstan and Kazakhstan are Central/South Asia —
|
||||
// filing them under the Middle East misnames six countries to save a heading.
|
||||
'uncovered-nas-a': 'Central Asia',
|
||||
// Southeast Asia + Oceania
|
||||
'laos': 'Southeast Asia + Oceania', 'oceania-indonesia': 'Southeast Asia + Oceania',
|
||||
'mainland-se-asia-philippines': 'Southeast Asia + Oceania',
|
||||
// Americas
|
||||
'brazil': 'Americas', 'andean-caribbean': 'Americas', 'uncovered-scatter': 'Americas',
|
||||
// Europe
|
||||
'europe': 'Europe',
|
||||
// India and China are their OWN sections, not one lump called "Asia". Between
|
||||
// them they are 1,122 people groups across 12 lists — more than every other
|
||||
// section combined — so collapsing them hides the two largest prayer fields in
|
||||
// the dataset behind a single continental label. Matched by id prefix below.
|
||||
}
|
||||
// ─── REGIONAL SECTIONS: data/upg100-regions.js (moved there so the 'upg100-list' poster type reads the same table) ─
|
||||
// ⚠ TAKES AN ID, while the shared wall's groupBy takes the whole ITEM. The template
|
||||
// adapts it — `:group-by="(item) => regionFor(item.id)"` — rather than changing this
|
||||
// signature, because the id is what the taxonomy is keyed by and every prefix rule
|
||||
|
|
@ -128,19 +90,11 @@ const REGION_OF = {
|
|||
// grouping — and the heading a reader sees is resolved here, per locale, through REGION_KEY
|
||||
// (data/legend-tree.js), the one table the legend's region rows translate through as well. Every
|
||||
// heading has a poster.region_* key in all 11 locales, India and Other included.
|
||||
const regionLabel = (english) => {
|
||||
const key = REGION_KEY[english]
|
||||
return key ? t(`poster.${key}`) : english // no key yet -> the English heading, not a raw key
|
||||
}
|
||||
const regionFor = (id) => {
|
||||
if (REGION_OF[id]) return regionLabel(REGION_OF[id])
|
||||
if (id.startsWith('asia-india-')) return regionLabel('India')
|
||||
// "China + Mongolia": the northern zone declares Mongolia as a member country
|
||||
// (its land is drawn and highlighted), so the section heading names both rather
|
||||
// than folding a sovereign country under a China label.
|
||||
if (id.startsWith('asia-china-')) return regionLabel('China + Mongolia')
|
||||
return regionLabel('Other')
|
||||
}
|
||||
const regionFor = (id) => regionTitle(regionOf(id), t)
|
||||
// ★ COLLAPSIBLE, LIKE COUNTRY POSTERS (each region section is the shared PosterSection, through the wall). Every
|
||||
// section starts OPEN: a reader who knew the wall finds it as before, and can now fold away the regions they are
|
||||
// not praying for. (Country Posters starts its small regions shut; UPG-100's regions are all large.)
|
||||
const allOpen = () => false // no key yet -> the English heading, not a raw key
|
||||
// One flat list of the zones the map paints — for WHICHEVER list is showing.
|
||||
//
|
||||
// ★ THROUGH zonesForList, not a static clusters.json import (pattern work, 2026-09-27). This wall already
|
||||
|
|
@ -156,21 +110,15 @@ const regionFor = (id) => {
|
|||
// this list IS, and the old comment was describing the wrong thing.
|
||||
const { locale: wallLocale } = useOptionalI18n('')
|
||||
const items = computed(() => {
|
||||
const z = zonesForList(resolvePeopleGroupList(profileConfig))
|
||||
// The i18n locale REF, read here so this computed re-runs on a runtime language switch: getRuntimeLocale()
|
||||
// is a plain getter, and a computed that reads only it is resolved once and never again (a frozen label).
|
||||
const l = wallLocale && (wallLocale.value ?? wallLocale)
|
||||
const locale = (typeof l === 'string' && l) || getRuntimeLocale() || detectLocale()
|
||||
return [
|
||||
...(z.lists || []),
|
||||
...(z.asia_lists || []),
|
||||
...(z.uncovered_lists || []),
|
||||
].filter(l => l && l.id)
|
||||
// ★ THE CARD'S NAME IN THE READER'S LANGUAGE. item.label is the Show-on-map button's accessible
|
||||
// name, every poster's alt text and tooltip, the print HUD's title and the printed documents' title
|
||||
// — all five were English in every locale. zoneTitle declines (null) for a zone it cannot name, and
|
||||
// that zone keeps its hand-written label, exactly as on the legend and the packet.
|
||||
.map(l => { const title = zoneTitle(l, null, { countryName, locale }); return title ? { ...l, label: title } : l })
|
||||
// ★ THE CARD'S NAME IN THE READER'S LANGUAGE (item.label is the Show-on-map button's accessible name, every
|
||||
// poster's alt text and tooltip, the print HUD's title and the printed documents' title). The zones and their
|
||||
// names come from the 'upg100-list' poster type's own function, so this wall and <dxm-poster-section
|
||||
// type="upg100-list"> can never show different cards.
|
||||
return upg100Zones(profileConfig, locale)
|
||||
})
|
||||
|
||||
// ─── THE RECORDS PROVIDER — now the library's (lists/peopleGroupRecords.js) ─────────
|
||||
|
|
@ -292,6 +240,8 @@ const wallTag = computed(() => t('messages.upg100WallTag'))
|
|||
download-prefix="doxa-upg-100"
|
||||
:columns-control="true"
|
||||
:min-card-px="150"
|
||||
:collapsible="true"
|
||||
:collapsed-by="allOpen"
|
||||
/>
|
||||
<!-- min-card-px 150: "Posters per row: 2" now SHOWS two on a phone. The shared clamp (210px) forced one at
|
||||
390 and silently overrode the select, which read 2 (2026-09-30: work like the country posters,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"_comment": "The map half of UPG-100: the zoned list of unengaged people groups, with the semantic-tree legend and the packet/poster exports. Declared so the Studio rail names it rather than falling back to a humanized id (check:studio-rail).",
|
||||
"label": "UPG 100 List Posters — Zoned Map"
|
||||
"label": "UPG-100 List Posters — Zoned Map"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"stage": "production",
|
||||
"type": "nested-elements-mfe",
|
||||
"label": "UPG 100 List Posters",
|
||||
"label": "UPG-100 List Posters",
|
||||
"composes": ["my-upg-100-list/upg-100-list", "my-upg-100-list/poster-wall"],
|
||||
"note": "Composite MFE built on the pane-wrapper layout (imitates the shell's 'upg-100-list' panes: map at [0,0], Prayer Lists at [1,0]). Makes this bundle MFE-class (tier 1) in the plugin gallery. See eco-dx (internal): PS001-composition-model."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
export const STRINGS = {
|
||||
en: {
|
||||
'sec.posters': 'Posters', 'sec.experimental': 'Experimental',
|
||||
'tab.upg-100': 'UPG 100 List Posters', 'sub.upg-100': 'my unreached list + posters',
|
||||
'tab.upg-100': 'UPG-100 List Posters', 'sub.upg-100': 'my unreached list + posters',
|
||||
'tab.country-posters': 'Country Posters', 'sub.country-posters': 'a poster for every country',
|
||||
'tab.poster-design': 'Poster Design', 'sub.poster-design': 'every poster style and size',
|
||||
'tab.wall-of-people-groups': 'Wall of People Groups',
|
||||
|
|
@ -29,7 +29,7 @@ export const STRINGS = {
|
|||
},
|
||||
es: {
|
||||
'sec.posters': 'Carteles', 'sec.experimental': 'Experimental',
|
||||
'tab.upg-100': 'Carteles de la lista UPG 100', 'sub.upg-100': 'mi lista de no alcanzados + carteles',
|
||||
'tab.upg-100': 'Carteles de la lista UPG-100', 'sub.upg-100': 'mi lista de no alcanzados + carteles',
|
||||
'tab.country-posters': 'Carteles por país', 'sub.country-posters': 'un cartel para cada país',
|
||||
'tab.poster-design': 'Diseño de carteles', 'sub.poster-design': 'todos los estilos y tamaños de cartel',
|
||||
'tab.wall-of-people-groups': 'Muro de los pueblos',
|
||||
|
|
@ -43,7 +43,7 @@ export const STRINGS = {
|
|||
},
|
||||
fr: {
|
||||
'sec.posters': 'Affiches', 'sec.experimental': 'Expérimental',
|
||||
'tab.upg-100': 'Affiches de la liste UPG 100', 'sub.upg-100': 'ma liste des non atteints + affiches',
|
||||
'tab.upg-100': 'Affiches de la liste UPG-100', 'sub.upg-100': 'ma liste des non atteints + affiches',
|
||||
'tab.country-posters': 'Affiches par pays', 'sub.country-posters': 'une affiche pour chaque pays',
|
||||
'tab.poster-design': 'Conception d’affiches', 'sub.poster-design': 'tous les styles et formats d’affiche',
|
||||
'tab.wall-of-people-groups': 'Mur des peuples',
|
||||
|
|
@ -57,7 +57,7 @@ export const STRINGS = {
|
|||
},
|
||||
de: {
|
||||
'sec.posters': 'Poster', 'sec.experimental': 'Experimentell',
|
||||
'tab.upg-100': 'Poster der UPG 100 Liste', 'sub.upg-100': 'meine Liste der Unerreichten + Poster',
|
||||
'tab.upg-100': 'Poster der UPG-100-Liste', 'sub.upg-100': 'meine Liste der Unerreichten + Poster',
|
||||
'tab.country-posters': 'Länderposter', 'sub.country-posters': 'ein Poster für jedes Land',
|
||||
'tab.poster-design': 'Postergestaltung', 'sub.poster-design': 'alle Posterstile und -größen',
|
||||
'tab.wall-of-people-groups': 'Wand der Volksgruppen',
|
||||
|
|
@ -71,7 +71,7 @@ export const STRINGS = {
|
|||
},
|
||||
pt: {
|
||||
'sec.posters': 'Cartazes', 'sec.experimental': 'Experimental',
|
||||
'tab.upg-100': 'Cartazes da lista UPG 100', 'sub.upg-100': 'minha lista de não alcançados + cartazes',
|
||||
'tab.upg-100': 'Cartazes da lista UPG-100', 'sub.upg-100': 'minha lista de não alcançados + cartazes',
|
||||
'tab.country-posters': 'Cartazes por país', 'sub.country-posters': 'um cartaz para cada país',
|
||||
'tab.poster-design': 'Design de cartazes', 'sub.poster-design': 'todos os estilos e tamanhos de cartaz',
|
||||
'tab.wall-of-people-groups': 'Mural dos povos',
|
||||
|
|
@ -85,7 +85,7 @@ export const STRINGS = {
|
|||
},
|
||||
it: {
|
||||
'sec.posters': 'Poster', 'sec.experimental': 'Sperimentale',
|
||||
'tab.upg-100': 'Poster della lista UPG 100', 'sub.upg-100': 'la mia lista dei non raggiunti + poster',
|
||||
'tab.upg-100': 'Poster della lista UPG-100', 'sub.upg-100': 'la mia lista dei non raggiunti + poster',
|
||||
'tab.country-posters': 'Poster per paese', 'sub.country-posters': 'un poster per ogni paese',
|
||||
'tab.poster-design': 'Design dei poster', 'sub.poster-design': 'tutti gli stili e i formati dei poster',
|
||||
'tab.wall-of-people-groups': 'Muro dei popoli',
|
||||
|
|
@ -99,7 +99,7 @@ export const STRINGS = {
|
|||
},
|
||||
ro: {
|
||||
'sec.posters': 'Afișe', 'sec.experimental': 'Experimental',
|
||||
'tab.upg-100': 'Afișe din lista UPG 100', 'sub.upg-100': 'lista mea de neatinși + afișe',
|
||||
'tab.upg-100': 'Afișe din lista UPG-100', 'sub.upg-100': 'lista mea de neatinși + afișe',
|
||||
'tab.country-posters': 'Afișe pe țări', 'sub.country-posters': 'un afiș pentru fiecare țară',
|
||||
'tab.poster-design': 'Design de afișe', 'sub.poster-design': 'toate stilurile și dimensiunile de afiș',
|
||||
'tab.wall-of-people-groups': 'Zidul popoarelor',
|
||||
|
|
@ -113,7 +113,7 @@ export const STRINGS = {
|
|||
},
|
||||
ru: {
|
||||
'sec.posters': 'Плакаты', 'sec.experimental': 'Экспериментальное',
|
||||
'tab.upg-100': 'Плакаты списка UPG 100', 'sub.upg-100': 'мой список недостигнутых + плакаты',
|
||||
'tab.upg-100': 'Плакаты списка UPG-100', 'sub.upg-100': 'мой список недостигнутых + плакаты',
|
||||
'tab.country-posters': 'Плакаты по странам', 'sub.country-posters': 'плакат для каждой страны',
|
||||
'tab.poster-design': 'Дизайн плакатов', 'sub.poster-design': 'все стили и размеры плакатов',
|
||||
'tab.wall-of-people-groups': 'Стена народов',
|
||||
|
|
@ -127,7 +127,7 @@ export const STRINGS = {
|
|||
},
|
||||
ar: {
|
||||
'sec.posters': 'ملصقات', 'sec.experimental': 'تجريبي',
|
||||
'tab.upg-100': 'ملصقات قائمة UPG 100', 'sub.upg-100': 'قائمتي لغير المُبشَّرين + ملصقات',
|
||||
'tab.upg-100': 'ملصقات قائمة UPG-100', 'sub.upg-100': 'قائمتي لغير المُبشَّرين + ملصقات',
|
||||
'tab.country-posters': 'ملصقات الدول', 'sub.country-posters': 'ملصق لكل دولة',
|
||||
'tab.poster-design': 'تصميم الملصقات', 'sub.poster-design': 'كل أنماط الملصقات وأحجامها',
|
||||
'tab.wall-of-people-groups': 'جدار الشعوب',
|
||||
|
|
@ -141,7 +141,7 @@ export const STRINGS = {
|
|||
},
|
||||
hi: {
|
||||
'sec.posters': 'पोस्टर', 'sec.experimental': 'प्रायोगिक',
|
||||
'tab.upg-100': 'UPG 100 सूची पोस्टर', 'sub.upg-100': 'मेरी अप्राप्त सूची + पोस्टर',
|
||||
'tab.upg-100': 'UPG-100 सूची पोस्टर', 'sub.upg-100': 'मेरी अप्राप्त सूची + पोस्टर',
|
||||
'tab.country-posters': 'देश पोस्टर', 'sub.country-posters': 'हर देश के लिए एक पोस्टर',
|
||||
'tab.poster-design': 'पोस्टर डिज़ाइन', 'sub.poster-design': 'हर पोस्टर शैली और आकार',
|
||||
'tab.wall-of-people-groups': 'जनसमूहों की दीवार',
|
||||
|
|
@ -155,7 +155,7 @@ export const STRINGS = {
|
|||
},
|
||||
zh: {
|
||||
'sec.posters': '海报', 'sec.experimental': '实验性',
|
||||
'tab.upg-100': 'UPG 100 名单海报', 'sub.upg-100': '我的未得之民名单 + 海报',
|
||||
'tab.upg-100': 'UPG-100 名单海报', 'sub.upg-100': '我的未得之民名单 + 海报',
|
||||
'tab.country-posters': '国家海报', 'sub.country-posters': '每个国家一张海报',
|
||||
'tab.poster-design': '海报设计', 'sub.poster-design': '所有海报样式与尺寸',
|
||||
'tab.wall-of-people-groups': '民族之墙',
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@
|
|||
"bundle": "my-upg-100-list",
|
||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||
"integrity": "sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT",
|
||||
"integrity": "sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -952,7 +952,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>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -968,8 +968,8 @@
|
|||
"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": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -985,8 +985,8 @@
|
|||
"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": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@
|
|||
"bundle": "my-upg-100-list",
|
||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||
"integrity": "sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT",
|
||||
"integrity": "sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -952,7 +952,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>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -968,8 +968,8 @@
|
|||
"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": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -985,8 +985,8 @@
|
|||
"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": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,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-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,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-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,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-wqGkce90Mk4Dsb5HfOxpamV+vhIh2/W6vtzTTi/gqub5DeZgxKgHg+XzN+36RRRT" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-CUhGS9/Bdh0HwbbVKldAV7BC7Ljw8GRAWp+gOia5+mbPkTb5nK/mrlmbNX9JR12Q" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue