Gospel x Internet: translation readiness, from open data
For an AI or Bible-translation team choosing where a first New Testament draft is feasible: per language, five named open signals, each cited and licensed: Glottolog's most extensive description (CC BY 4.0), Scripture books found (eBible), a language Wikipedia (CC BY-SA 4.0), Common Voice validated speech hours (CC0) and FLORES+ (CC BY-SA 4.0). A dated snapshot the build reads; no live fetch. The board shows 'Open data (of 5)', a sortable column (with the signals in the CSV), a drawer section with each signal and its source, and a line on the tree card. It is a count of named facts, not a score. Codes that could not be mapped are listed (6 Wikipedia codes), and the 31 languages Glottolog lacks read as unknown, never none. Of the 736 languages with no New Testament found: 20 have 3+ signals.
This commit is contained in:
parent
4e818b7442
commit
71f524cd52
22 changed files with 5130 additions and 39 deletions
1
data/tables/gospel-internet-readiness.json
Normal file
1
data/tables/gospel-internet-readiness.json
Normal file
File diff suppressed because one or more lines are too long
4828
data/translation-readiness/snapshot.json
Normal file
4828
data/translation-readiness/snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,103 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* build-translation-readiness.mjs — per roster language, the OPEN data a translation team could start
|
||||||
|
* from, read from the committed snapshot (fetch-translation-readiness.mjs) and eBible's index. No live
|
||||||
|
* fetch, no invented score: five named signals, each with its value and source, and the COUNT of the
|
||||||
|
* five that are present (a count of named facts, not a weighting).
|
||||||
|
*
|
||||||
|
* grammar Glottolog MED: the most extensive description (grammar / sketch / text-or-dictionary);
|
||||||
|
* present when the level is better than "word list or less"
|
||||||
|
* scripture eBible: canonical books found (partial Scripture counts; a full NT is the board's green)
|
||||||
|
* wikipedia a language Wikipedia exists (open written text)
|
||||||
|
* speech Common Voice validated hours > 0 (open speech)
|
||||||
|
* benchmark the language is in FLORES+ (machine-translation evaluation)
|
||||||
|
*
|
||||||
|
* Mapping is explicit (ISO 639-3 <-> Glottocode via the tree snapshot; 639-1 via SIL in the fetcher), and
|
||||||
|
* the report counts, for the languages with no New Testament, how many could not be mapped to Glottolog
|
||||||
|
* (their grammar signal is then UNKNOWN, not "none").
|
||||||
|
* Outputs data/tables/gospel-internet-readiness.json (+ the public copy). `--check` compares.
|
||||||
|
*/
|
||||||
|
import { readFileSync, writeFileSync } from 'node:fs'
|
||||||
|
import { resolve, dirname } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const REPO = resolve(HERE, '../../..')
|
||||||
|
const T = (f) => JSON.parse(readFileSync(resolve(REPO, 'data/tables', f), 'utf8'))
|
||||||
|
const CHECK = process.argv.includes('--check')
|
||||||
|
|
||||||
|
const snap = JSON.parse(readFileSync(resolve(REPO, 'data/translation-readiness/snapshot.json'), 'utf8'))
|
||||||
|
const tree = T('gospel-internet-tree.json')
|
||||||
|
const gi = T('gospel-internet.json')
|
||||||
|
const ebible = T('ebible-index.json').codes || {}
|
||||||
|
const glotto = JSON.parse(readFileSync(resolve(REPO, 'data/glottolog/glottolog-subset.json'), 'utf8'))
|
||||||
|
const inGlottolog = new Set(glotto.languoids.filter((l) => l.iso).map((l) => l.iso))
|
||||||
|
|
||||||
|
const byIso = new Map()
|
||||||
|
for (const r of gi.rows) {
|
||||||
|
const e = byIso.get(r.iso639_3) || { iso: r.iso639_3, language: r.language, groups: 0, people: 0 }
|
||||||
|
e.groups++; e.people += Number(r.population) || 0
|
||||||
|
byIso.set(r.iso639_3, e)
|
||||||
|
}
|
||||||
|
const stOf = new Map(tree.nodes.filter((n) => n.iso && n.st).map((n) => [n.iso, n.st]))
|
||||||
|
|
||||||
|
const rows = []
|
||||||
|
for (const e of byIso.values()) {
|
||||||
|
const m = snap.med[e.iso]
|
||||||
|
const eb = ebible[e.iso]
|
||||||
|
const books = eb ? Number(eb.books) || 0 : 0
|
||||||
|
const row = {
|
||||||
|
iso: e.iso, language: e.language, groups: e.groups, people: e.people,
|
||||||
|
nt: stOf.get(e.iso) === 'g',
|
||||||
|
grammar_level: m ? m.level : null, // 0 long grammar .. 4 word list or less
|
||||||
|
grammar: m ? snap.med_codes[m.level] : (inGlottolog.has(e.iso) ? '' : null), // null = not in Glottolog: unknown
|
||||||
|
scripture_books: books,
|
||||||
|
wikipedia: snap.wikipedia[e.iso] || '',
|
||||||
|
speech_hours: snap.commonVoice[e.iso] || 0,
|
||||||
|
benchmark: (snap.flores[e.iso] || []).join(' '),
|
||||||
|
}
|
||||||
|
row.signals = [row.grammar_level !== null && row.grammar_level < 4, books > 0, !!row.wikipedia, row.speech_hours > 0, !!row.benchmark].filter(Boolean).length
|
||||||
|
rows.push(row)
|
||||||
|
}
|
||||||
|
rows.sort((a, b) => a.iso.localeCompare(b.iso))
|
||||||
|
|
||||||
|
const noNt = rows.filter((r) => !r.nt)
|
||||||
|
const count = (f) => noNt.filter(f).length
|
||||||
|
const coverage = {
|
||||||
|
languages: rows.length, without_new_testament: noNt.length,
|
||||||
|
not_in_glottolog: count((r) => r.grammar === null),
|
||||||
|
signal: { grammar: count((r) => r.grammar_level !== null && r.grammar_level < 4), scripture: count((r) => r.scripture_books > 0),
|
||||||
|
wikipedia: count((r) => !!r.wikipedia), speech: count((r) => r.speech_hours > 0), benchmark: count((r) => !!r.benchmark) },
|
||||||
|
by_signal_count: noNt.reduce((m, r) => { m[r.signals] = (m[r.signals] || 0) + 1; return m }, {}),
|
||||||
|
source_codes_unmapped: snap.unmapped,
|
||||||
|
}
|
||||||
|
const doc = {
|
||||||
|
meta: {
|
||||||
|
title: 'Translation readiness: the open data each language has, for a team starting a translation',
|
||||||
|
generated_by: 'plugin-designs/gospel-internet/scripts/build-translation-readiness.mjs',
|
||||||
|
snapshot: snap.fetched,
|
||||||
|
sources: { ...snap.sources, ebible: { name: 'eBible.org translation catalogue (books per language)', licence: 'per translation, as eBible lists it' } },
|
||||||
|
signals: {
|
||||||
|
grammar: 'Glottolog MED better than "word list or less" (a grammar, sketch, text or dictionary)',
|
||||||
|
scripture: 'eBible: at least one canonical book found (partial Scripture)',
|
||||||
|
wikipedia: 'an open language Wikipedia exists',
|
||||||
|
speech: 'Mozilla Common Voice: validated hours > 0',
|
||||||
|
benchmark: 'the language is in FLORES+ (MT evaluation)',
|
||||||
|
},
|
||||||
|
no_score: 'signals = how many of the five named facts are present. It is a count, not a weighting or a prediction.',
|
||||||
|
unknown: 'grammar is null where the language is not in Glottolog (IMB private codes): unknown, never "none"',
|
||||||
|
coverage,
|
||||||
|
},
|
||||||
|
rows,
|
||||||
|
}
|
||||||
|
const body = JSON.stringify(doc) + '\n'
|
||||||
|
const OUTS = ['data/tables', 'public/dx-maps/assets/tables'].map((d) => resolve(REPO, d, 'gospel-internet-readiness.json'))
|
||||||
|
if (CHECK) {
|
||||||
|
let same = true
|
||||||
|
for (const o of OUTS) { try { if (readFileSync(o, 'utf8') !== body) same = false } catch { same = false } }
|
||||||
|
console.log(same ? 'ok readiness table is current' : 'FAIL readiness table is stale: re-run the builder'); if (!same) process.exitCode = 1
|
||||||
|
} else {
|
||||||
|
for (const o of OUTS) writeFileSync(o, body)
|
||||||
|
console.log('ok wrote gospel-internet-readiness.json:', rows.length, 'languages')
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify(coverage))
|
||||||
|
|
@ -48,7 +48,7 @@ const get = (lc, key) => {
|
||||||
// SETTLED, not deferred: the correct word in that language IS the English spelling. Each is a decision,
|
// SETTLED, not deferred: the correct word in that language IS the English spelling. Each is a decision,
|
||||||
// listed by locale and key so a new identical string is still caught.
|
// listed by locale and key so a new identical string is still caught.
|
||||||
const SAME_ON_PURPOSE = new Set(['fr:res.source', 'fr:res.type', 'ro:tree.dialect', 'fr:facet.religion',
|
const SAME_ON_PURPOSE = new Set(['fr:res.source', 'fr:res.type', 'ro:tree.dialect', 'fr:facet.religion',
|
||||||
'de:facet.region', 'de:facet.religion', 'de:tree.poster', 'it:tree.poster', 'ro:tree.poster'])
|
'de:facet.region', 'de:facet.religion', 'de:tree.poster', 'it:tree.poster', 'ro:tree.poster', 'de:col.openWiki', 'es:col.openWiki', 'it:col.openWiki', 'ro:col.openWiki'])
|
||||||
|
|
||||||
let fails = 0
|
let fails = 0
|
||||||
if (keys.size < 100) { console.log(`NOT MEASURED: read only ${keys.size} keys (expected 100+); the parser is broken, not the bundle`); process.exitCode = 75 }
|
if (keys.size < 100) { console.log(`NOT MEASURED: read only ${keys.size} keys (expected 100+); the parser is broken, not the bundle`); process.exitCode = 75 }
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,19 @@ for (const n of ix.nodes) if (!n.p) { const x = scZero.get(n.id); gy += x.g + x.
|
||||||
ok(gy === 0, `with only zero-access groups in scope, no family counts a green or yellow language (${gy})`)
|
ok(gy === 0, `with only zero-access groups in scope, no family counts a green or yellow language (${gy})`)
|
||||||
bus.clearFilters()
|
bus.clearFilters()
|
||||||
|
|
||||||
|
// 11. translation readiness: current against its snapshot, every roster language present, the no-NT set is
|
||||||
|
// the tree's, the 31 codes Glottolog lacks read as UNKNOWN (null) not "none", and the signal count is a
|
||||||
|
// recount of the five named facts (no hidden weighting)
|
||||||
|
let rcur = true
|
||||||
|
try { execFileSync('node', [resolve(HERE, 'build-translation-readiness.mjs'), '--check'], { stdio: 'pipe' }) } catch { rcur = false }
|
||||||
|
ok(rcur, 'the readiness table is what its builder makes from the committed snapshot')
|
||||||
|
const rd = JSON.parse(readFileSync(resolve(REPO, 'data/tables/gospel-internet-readiness.json'), 'utf8'))
|
||||||
|
ok(rd.rows.length === langsOnBoard.size, `readiness covers every roster language (${rd.rows.length})`)
|
||||||
|
ok(rd.rows.filter((r) => !r.nt).length === tot.y + tot.r, `its no-New-Testament set is the tree's (${rd.rows.filter((r) => !r.nt).length} == ${tot.y + tot.r})`)
|
||||||
|
ok(rd.meta.coverage.not_in_glottolog === 31 && rd.rows.filter((r) => r.grammar === null).length === 31, 'the 31 codes Glottolog lacks read as unknown (null), never "none"')
|
||||||
|
const recount = (r) => [r.grammar_level !== null && r.grammar_level < 4, r.scripture_books > 0, !!r.wikipedia, r.speech_hours > 0, !!r.benchmark].filter(Boolean).length
|
||||||
|
ok(rd.rows.every((r) => r.signals === recount(r)) && !POISON, 'every signal count is a recount of the five named facts')
|
||||||
|
|
||||||
// 8. safety: no engagement / who-works-where field in the shipped data
|
// 8. safety: no engagement / who-works-where field in the shipped data
|
||||||
const cols = doc.meta.columns || []
|
const cols = doc.meta.columns || []
|
||||||
const banned = cols.filter((c) => /engage|worker|team|agenc|missionar/i.test(c))
|
const banned = cols.filter((c) => /engage|worker|team|agenc|missionar/i.test(c))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* fetch-translation-readiness.mjs — a DATED SNAPSHOT of the open language data an AI or Bible-translation
|
||||||
|
* team could start from, for the languages our people groups speak. Run by hand; the board and its
|
||||||
|
* builder read ONLY the committed snapshot (no live fetch at runtime). Card BUILD-TRANSLATION-READINESS-VIEW.
|
||||||
|
*
|
||||||
|
* Four open sources, each stored with its URL, licence and fetch date:
|
||||||
|
* Glottolog 5.x "most extensive description" (MED) per languoid CC BY 4.0
|
||||||
|
* Wikimedia the language Wikipedias (sitematrix), open editions CC BY-SA 4.0 (the text)
|
||||||
|
* Common Voice validated speech hours per locale (Mozilla) CC0 1.0
|
||||||
|
* FLORES+ the MT benchmark's languages (OLDI, Hugging Face) CC BY-SA 4.0
|
||||||
|
* plus SIL's ISO 639-3 code table, used ONLY to map 2-letter codes (ISO 639-1) to ISO 639-3.
|
||||||
|
* (Partial Scripture comes from eBible's index, already in data/tables, and is read by the builder.)
|
||||||
|
*
|
||||||
|
* Codes are mapped EXPLICITLY and every code that cannot be mapped is COUNTED and listed, never dropped
|
||||||
|
* silently (dx-shepherd's guard 3).
|
||||||
|
* Writes data/translation-readiness/snapshot.json. Refuses a much smaller snapshot than the last one.
|
||||||
|
*/
|
||||||
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
|
||||||
|
import { resolve, dirname } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const REPO = resolve(HERE, '../../..')
|
||||||
|
const OUT = resolve(REPO, 'data/translation-readiness/snapshot.json')
|
||||||
|
const today = new Date().toISOString().slice(0, 10)
|
||||||
|
|
||||||
|
const SRC = {
|
||||||
|
glottolog: { url: 'https://raw.githubusercontent.com/glottolog/glottolog-cldf/master/cldf/values.csv', licence: 'CC BY 4.0', name: 'Glottolog (CLDF): most extensive description (MED)' },
|
||||||
|
sil: { url: 'https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3.tab', licence: 'SIL ISO 639-3 code tables (free to use)', name: 'SIL ISO 639-3 code table' },
|
||||||
|
wikipedia: { url: 'https://meta.wikimedia.org/w/api.php?action=sitematrix&format=json&smtype=language&smlangprop=code|site', licence: 'CC BY-SA 4.0 (Wikipedia text)', name: 'Wikimedia sitematrix: language Wikipedias' },
|
||||||
|
commonVoice: { url: 'https://commonvoice.mozilla.org/api/v1/stats/languages', licence: 'CC0 1.0', name: 'Mozilla Common Voice: validated hours per locale' },
|
||||||
|
flores: { url: 'https://huggingface.co/api/datasets/openlanguagedata/flores_plus/tree/main/dev', licence: 'CC BY-SA 4.0', name: 'FLORES+ (OLDI) MT benchmark languages' },
|
||||||
|
}
|
||||||
|
const text = async (u) => { const r = await fetch(u, { headers: { 'User-Agent': 'dx-maps readiness snapshot (open data)' } }); if (!r.ok) throw new Error(`${u} HTTP ${r.status}`); return r.text() }
|
||||||
|
|
||||||
|
// our languoids: every roster ISO code and its Glottolog id (from the committed tree snapshot)
|
||||||
|
const glotto = JSON.parse(readFileSync(resolve(REPO, 'data/glottolog/glottolog-subset.json'), 'utf8'))
|
||||||
|
const ourIds = new Map(glotto.languoids.filter((l) => l.iso).map((l) => [l.id, l.iso]))
|
||||||
|
|
||||||
|
// 1. MED for our languoids only (values.csv is ~20 MB; the snapshot keeps a few hundred rows)
|
||||||
|
const med = {}
|
||||||
|
for (const line of (await text(SRC.glottolog.url)).split('\n')) {
|
||||||
|
if (!line.includes(',med,')) continue
|
||||||
|
const [, lang, param, value, code] = line.split(',')
|
||||||
|
if (param === 'med' && ourIds.has(lang)) med[ourIds.get(lang)] = { level: Number(value), code }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. SIL: ISO 639-1 -> ISO 639-3, and the set of valid 639-3 codes
|
||||||
|
const part1 = {}
|
||||||
|
const valid = new Set()
|
||||||
|
for (const row of (await text(SRC.sil.url)).split('\n').slice(1)) {
|
||||||
|
const c = row.split('\t')
|
||||||
|
if (!c[0]) continue
|
||||||
|
valid.add(c[0])
|
||||||
|
if (c[3]) part1[c[3]] = c[0]
|
||||||
|
}
|
||||||
|
const toIso3 = (code) => { const b = String(code || '').toLowerCase().split(/[-_]/)[0]; return valid.has(b) ? b : part1[b] || '' }
|
||||||
|
|
||||||
|
// 3. Wikipedia editions (open ones), mapped to ISO 639-3
|
||||||
|
const sm = JSON.parse(await text(SRC.wikipedia.url)).sitematrix || {}
|
||||||
|
const wikipedia = {}
|
||||||
|
const wikiUnmapped = []
|
||||||
|
for (const [k, v] of Object.entries(sm)) {
|
||||||
|
if (k === 'count' || !v || !v.site) continue
|
||||||
|
const wp = v.site.find((s) => s.code === 'wiki' && !('closed' in s))
|
||||||
|
if (!wp) continue
|
||||||
|
const iso = toIso3(v.code)
|
||||||
|
if (iso) wikipedia[iso] = v.code; else wikiUnmapped.push(v.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Common Voice validated hours, mapped to ISO 639-3
|
||||||
|
const commonVoice = {}
|
||||||
|
const cvUnmapped = []
|
||||||
|
for (const l of JSON.parse(await text(SRC.commonVoice.url))) {
|
||||||
|
if (!(l.validatedHours > 0)) continue
|
||||||
|
const iso = toIso3(l.locale)
|
||||||
|
if (iso) commonVoice[iso] = Math.max(commonVoice[iso] || 0, l.validatedHours); else cvUnmapped.push(l.locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. FLORES+ languages (lang_Script), ISO 639-3 is the first part
|
||||||
|
const flores = {}
|
||||||
|
for (const m of (await text(SRC.flores.url)).matchAll(/dev\/([a-z]{3})_([A-Z][a-z]{3})\.jsonl/g)) (flores[m[1]] ||= []).push(m[2])
|
||||||
|
|
||||||
|
const doc = {
|
||||||
|
fetched: today,
|
||||||
|
sources: Object.fromEntries(Object.entries(SRC).map(([k, v]) => [k, { ...v, fetched: today }])),
|
||||||
|
med_codes: { 0: 'long grammar (300+ pages)', 1: 'grammar', 2: 'grammar sketch', 3: 'text, phonology, dictionary or a New Testament', 4: 'word list or less' },
|
||||||
|
med, wikipedia, commonVoice, flores,
|
||||||
|
unmapped: { wikipedia: wikiUnmapped.sort(), commonVoice: cvUnmapped.sort() },
|
||||||
|
counts: { med: Object.keys(med).length, wikipedia: Object.keys(wikipedia).length, commonVoice: Object.keys(commonVoice).length, flores: Object.keys(flores).length,
|
||||||
|
wikipedia_unmapped: wikiUnmapped.length, commonVoice_unmapped: cvUnmapped.length },
|
||||||
|
}
|
||||||
|
if (existsSync(OUT)) {
|
||||||
|
const prev = JSON.parse(readFileSync(OUT, 'utf8'))
|
||||||
|
for (const k of ['med', 'wikipedia', 'commonVoice', 'flores']) {
|
||||||
|
if (doc.counts[k] < 0.9 * (prev.counts?.[k] || 0)) { console.error(`REFUSING: ${k} dropped from ${prev.counts[k]} to ${doc.counts[k]} (a bad fetch?)`); process.exit(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mkdirSync(dirname(OUT), { recursive: true })
|
||||||
|
writeFileSync(OUT, JSON.stringify(doc, null, 1) + '\n')
|
||||||
|
console.log('ok', OUT.replace(REPO + '/', ''), JSON.stringify(doc.counts))
|
||||||
|
|
@ -34,6 +34,14 @@ export function buildColumns(T) {
|
||||||
{ key: 'internet_band', header: 'internet_band', label: T('gospelInternet.col.band', 'Internet band'), w: 115, show: (r) => band(r.internet_band), swatch: true },
|
{ key: 'internet_band', header: 'internet_band', label: T('gospelInternet.col.band', 'Internet band'), w: 115, show: (r) => band(r.internet_band), swatch: true },
|
||||||
{ key: 'state_internet_women', header: 'state_internet_women_pct', label: T('gospelInternet.col.stateWomen', 'State online: women'), w: 130, num: true, hidden: true, show: (r) => pct(r.state_internet_women) },
|
{ key: 'state_internet_women', header: 'state_internet_women_pct', label: T('gospelInternet.col.stateWomen', 'State online: women'), w: 130, num: true, hidden: true, show: (r) => pct(r.state_internet_women) },
|
||||||
{ key: 'state_internet_men', header: 'state_internet_men_pct', label: T('gospelInternet.col.stateMen', 'State online: men'), w: 130, num: true, hidden: true, show: (r) => pct(r.state_internet_men) },
|
{ key: 'state_internet_men', header: 'state_internet_men_pct', label: T('gospelInternet.col.stateMen', 'State online: men'), w: 130, num: true, hidden: true, show: (r) => pct(r.state_internet_men) },
|
||||||
|
// translation readiness: how many of five named OPEN data signals the language has (a count, not a score)
|
||||||
|
{ key: 'open_data', header: 'open_data_signals_of_5', label: T('gospelInternet.col.openData', 'Open data (of 5)'), w: 120, num: true,
|
||||||
|
show: (r) => (r.open_data == null ? '' : r.open_data.toLocaleString()) },
|
||||||
|
{ key: 'open_grammar', header: 'grammar_glottolog_med', label: T('gospelInternet.col.openGrammar', 'Grammar (Glottolog)'), w: 170, hidden: true },
|
||||||
|
{ key: 'open_scripture_books', header: 'scripture_books_ebible', label: T('gospelInternet.col.openBooks', 'Scripture books (eBible)'), w: 130, num: true, hidden: true },
|
||||||
|
{ key: 'open_wikipedia', header: 'wikipedia_edition', label: T('gospelInternet.col.openWiki', 'Wikipedia'), w: 100, hidden: true },
|
||||||
|
{ key: 'open_speech_hours', header: 'speech_hours_common_voice', label: T('gospelInternet.col.openSpeech', 'Speech hours (Common Voice)'), w: 150, num: true, hidden: true },
|
||||||
|
{ key: 'open_benchmark', header: 'mt_benchmark_flores', label: T('gospelInternet.col.openBench', 'MT benchmark (FLORES+)'), w: 150, hidden: true },
|
||||||
{ key: 'top_messaging_app', header: 'top_messaging_app_country_ios', label: T('gospelInternet.col.messaging', 'Top messaging app (country, iOS)'), w: 170 },
|
{ key: 'top_messaging_app', header: 'top_messaging_app_country_ios', label: T('gospelInternet.col.messaging', 'Top messaging app (country, iOS)'), w: 170 },
|
||||||
{ key: 'top_platform', header: 'top_social_platform_country', label: T('gospelInternet.col.platform', 'Top platform (country)'), w: 140 },
|
{ key: 'top_platform', header: 'top_social_platform_country', label: T('gospelInternet.col.platform', 'Top platform (country)'), w: 140 },
|
||||||
{ key: 'mobile_per_100', header: 'mobile_subscriptions_per_100', label: T('gospelInternet.col.mobile', 'Mobile per 100'), w: 110, num: true, hidden: true },
|
{ key: 'mobile_per_100', header: 'mobile_subscriptions_per_100', label: T('gospelInternet.col.mobile', 'Mobile per 100'), w: 110, num: true, hidden: true },
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,24 @@ const sections = computed(() => {
|
||||||
plat.push({ label: T('gospelInternet.drawer.messaging', 'Messaging apps (iOS downloads)'), text: T('gospelInternet.charts.notMeasured', 'Not measured'), note: T('gospelInternet.drawer.noFeed', 'This country is not in Apple\'s feed: its messaging apps are unknown here, not absent.') })
|
plat.push({ label: T('gospelInternet.drawer.messaging', 'Messaging apps (iOS downloads)'), text: T('gospelInternet.charts.notMeasured', 'Not measured'), note: T('gospelInternet.drawer.noFeed', 'This country is not in Apple\'s feed: its messaging apps are unknown here, not absent.') })
|
||||||
}
|
}
|
||||||
if (pc && pc.social.length) plat.push({ label: T('gospelInternet.drawer.social', 'Social platforms (web referrals)'), text: pc.social.map((x) => `${x.platform} ${n(x.pct)}%`).join(' · '), note: T('gospelInternet.drawer.platformNote', 'Share of web referrals among tracked social platforms in the country (StatCounter). Messaging apps such as WhatsApp are not measured.') })
|
if (pc && pc.social.length) plat.push({ label: T('gospelInternet.drawer.social', 'Social platforms (web referrals)'), text: pc.social.map((x) => `${x.platform} ${n(x.pct)}%`).join(' · '), note: T('gospelInternet.drawer.platformNote', 'Share of web referrals among tracked social platforms in the country (StatCounter). Messaging apps such as WhatsApp are not measured.') })
|
||||||
|
// Open data to start a translation from: five named, cited signals (no score). The last line is the
|
||||||
|
// honesty the data needs: strong open data and no New Testament FOUND often means one exists that the
|
||||||
|
// sources checked missed.
|
||||||
|
const rd = board.readiness.value.byIso.get(g.iso639_3)
|
||||||
|
const openLines = []
|
||||||
|
const openLinks = []
|
||||||
|
if (rd) {
|
||||||
|
openLines.push({ label: T('gospelInternet.drawer.openCount', 'Open data'), text: T('gospelInternet.drawer.openOf', '{n} of 5 signals', { n: n(rd.signals) }) })
|
||||||
|
openLines.push({ label: T('gospelInternet.col.openGrammar', 'Grammar (Glottolog)'), text: rd.grammar === null ? T('gospelInternet.drawer.notInSource', 'not in this source') : (rd.grammar || '—') })
|
||||||
|
openLines.push({ label: T('gospelInternet.col.openBooks', 'Scripture books (eBible)'), text: n(rd.scripture_books) || '0' })
|
||||||
|
openLines.push({ label: T('gospelInternet.col.openSpeech', 'Speech hours (Common Voice)'), text: rd.speech_hours ? n(rd.speech_hours) : '0' })
|
||||||
|
openLines.push({ label: T('gospelInternet.col.openBench', 'MT benchmark (FLORES+)'), text: rd.benchmark || '—' })
|
||||||
|
if (rd.wikipedia) openLinks.push({ label: T('gospelInternet.col.openWiki', 'Wikipedia') + ' (' + rd.wikipedia + ')', href: safeHref(`https://${rd.wikipedia}.wikipedia.org/`) })
|
||||||
|
if (rd.grammar !== null && g.iso639_3) openLinks.push({ label: 'Glottolog', href: safeHref(`https://glottolog.org/glottolog?iso=${g.iso639_3}`) })
|
||||||
|
}
|
||||||
|
const openNote = rd && !rd.nt && rd.signals >= 3
|
||||||
|
? T('gospelInternet.drawer.openCheck', 'Strong open data but no New Testament found: check first, one may exist that the sources checked missed.')
|
||||||
|
: T('gospelInternet.drawer.openNote', 'Sources: Glottolog (CC BY 4.0), eBible, Wikipedia (CC BY-SA 4.0), Common Voice (CC0), FLORES+ (CC BY-SA 4.0). A count of named facts, not a score.')
|
||||||
return [
|
return [
|
||||||
{ id: 'own', title: T('gospelInternet.drawer.own', 'In their own language'),
|
{ id: 'own', title: T('gospelInternet.drawer.own', 'In their own language'),
|
||||||
lead: { dot: g.access_detail, text: label(T, 'detail', g.access_detail) },
|
lead: { dot: g.access_detail, text: label(T, 'detail', g.access_detail) },
|
||||||
|
|
@ -79,6 +97,7 @@ const sections = computed(() => {
|
||||||
note: wayLines.length ? T('gospelInternet.drawer.wayNote', 'A neighbouring language, not a recommendation: whether a group speaks it is a question for someone on the ground.') : '' },
|
note: wayLines.length ? T('gospelInternet.drawer.wayNote', 'A neighbouring language, not a recommendation: whether a group speaks it is a question for someone on the ground.') : '' },
|
||||||
{ id: 'conn', title: T('gospelInternet.drawer.conn', 'Connectivity'), lines: conn, links: [] },
|
{ id: 'conn', title: T('gospelInternet.drawer.conn', 'Connectivity'), lines: conn, links: [] },
|
||||||
{ id: 'platforms', title: T('gospelInternet.drawer.platforms', 'Platforms in the country'), lines: plat, links: [] },
|
{ id: 'platforms', title: T('gospelInternet.drawer.platforms', 'Platforms in the country'), lines: plat, links: [] },
|
||||||
|
{ id: 'open', title: T('gospelInternet.drawer.openTitle', 'Open data to start a translation from'), lines: openLines, links: openLinks.filter((l) => l.href), note: rd ? openNote : '' },
|
||||||
].filter((s) => s.lines.length || s.links.length || s.lead)
|
].filter((s) => s.lines.length || s.links.length || s.lead)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ useShadowStyles(
|
||||||
<span>{{ T('gospelInternet.tree.languagesHere', 'languages here') }}</span>
|
<span>{{ T('gospelInternet.tree.languagesHere', 'languages here') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="card.n.st" class="gtr-c"><span class="gtr-dot" :style="{ background: TREE_COLOR[card.n.st] }"></span>{{ T('gospelInternet.tree.st.' + card.n.st, ST_EN[card.n.st]) }}</div>
|
<div v-else-if="card.n.st" class="gtr-c"><span class="gtr-dot" :style="{ background: TREE_COLOR[card.n.st] }"></span>{{ T('gospelInternet.tree.st.' + card.n.st, ST_EN[card.n.st]) }}</div>
|
||||||
|
<div v-if="card.n.iso && board.readiness.value.byIso.get(card.n.iso)" class="gtr-via" data-tree-open>{{ T('gospelInternet.drawer.openCount', 'Open data') }}: {{ T('gospelInternet.drawer.openOf', '{n} of 5 signals', { n: fmt(board.readiness.value.byIso.get(card.n.iso).signals) }) }}</div>
|
||||||
<div v-if="card.n.inh" class="gtr-via">{{ T('gospelInternet.tree.inherited', 'Colour of its language: no source catalogues resources by dialect.') }}</div>
|
<div v-if="card.n.inh" class="gtr-via">{{ T('gospelInternet.tree.inherited', 'Colour of its language: no source catalogues resources by dialect.') }}</div>
|
||||||
<div v-if="card.n.via" class="gtr-via">{{ T('gospelInternet.tree.via', 'Also on this path:') }} {{ card.n.via.join(' › ') }}</div>
|
<div v-if="card.n.via" class="gtr-via">{{ T('gospelInternet.tree.via', 'Also on this path:') }} {{ card.n.via.join(' › ') }}</div>
|
||||||
<button v-if="card.selected" type="button" @click="board.setTreeNode('')">{{ T('controls.clear', 'Clear') }}</button>
|
<button v-if="card.selected" type="button" @click="board.setTreeNode('')">{{ T('controls.clear', 'Clear') }}</button>
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ export function accessByBand(rows, measure = 'groups') {
|
||||||
export function sortRows(rows, { key, dir = 1 } = {}) {
|
export function sortRows(rows, { key, dir = 1 } = {}) {
|
||||||
if (!key) return rows
|
if (!key) return rows
|
||||||
const num = (v) => (v === null || v === '' || v === undefined ? null : Number(v))
|
const num = (v) => (v === null || v === '' || v === undefined ? null : Number(v))
|
||||||
const isNum = ['population', 'internet_pct', 'mobile_per_100', 'people_praying', 'state_internet_women', 'state_internet_men'].includes(key)
|
const isNum = ['population', 'internet_pct', 'mobile_per_100', 'people_praying', 'state_internet_women', 'state_internet_men', 'open_data'].includes(key)
|
||||||
return [...rows].sort((a, b) => {
|
return [...rows].sort((a, b) => {
|
||||||
const x = a[key], y = b[key]
|
const x = a[key], y = b[key]
|
||||||
if (isNum) {
|
if (isNum) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export function useBoard() {
|
||||||
const bySlug = shallowRef(new Map())
|
const bySlug = shallowRef(new Map())
|
||||||
const meta = shallowRef({})
|
const meta = shallowRef({})
|
||||||
const countries = shallowRef({}) // iso3 -> { messaging, top_messaging, in_app_feed, social, social_month }
|
const countries = shallowRef({}) // iso3 -> { messaging, top_messaging, in_app_feed, social, social_month }
|
||||||
|
const readiness = shallowRef({ meta: {}, byIso: new Map() }) // translation readiness, per language
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
const listId = computed(() => resolvePeopleGroupList(profileConfig.value))
|
const listId = computed(() => resolvePeopleGroupList(profileConfig.value))
|
||||||
|
|
@ -56,13 +57,27 @@ export function useBoard() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = ''
|
error.value = ''
|
||||||
try {
|
try {
|
||||||
const url = `${resolveAssetsBase(cfg())}/tables/gospel-internet.json`
|
const base = resolveAssetsBase(cfg())
|
||||||
const res = await fetch(url)
|
const [res, rres] = await Promise.all([fetch(`${base}/tables/gospel-internet.json`), fetch(`${base}/tables/gospel-internet-readiness.json`).catch(() => null)])
|
||||||
if (!res.ok) throw new Error(`gospel-internet.json HTTP ${res.status}`)
|
if (!res.ok) throw new Error(`gospel-internet.json HTTP ${res.status}`)
|
||||||
const doc = await res.json()
|
const doc = await res.json()
|
||||||
|
// translation readiness is an ADDITION: if it fails to load, the board still works (no column values)
|
||||||
|
if (rres && rres.ok) {
|
||||||
|
const rd = await rres.json()
|
||||||
|
readiness.value = markRaw({ meta: rd.meta || {}, byIso: new Map((rd.rows || []).map((r) => [r.iso, r])) })
|
||||||
|
}
|
||||||
// The universal `list` prop: the rows of the page's people-group list, and none if it cannot be
|
// The universal `list` prop: the rows of the page's people-group list, and none if it cannot be
|
||||||
// loaded (applyPeopleGroupList fails CLOSED — never DOXA's whole list under another list's name).
|
// loaded (applyPeopleGroupList fails CLOSED — never DOXA's whole list under another list's name).
|
||||||
const rows = await applyPeopleGroupList(M.normalizeRows(doc), profileConfig.value)
|
const rows = await applyPeopleGroupList(M.normalizeRows(doc), profileConfig.value)
|
||||||
|
for (const r of rows) {
|
||||||
|
const x = readiness.value.byIso.get(r.iso639_3)
|
||||||
|
r.open_data = x ? x.signals : null
|
||||||
|
r.open_grammar = x && x.grammar ? x.grammar : ''
|
||||||
|
r.open_scripture_books = x ? x.scripture_books : null
|
||||||
|
r.open_wikipedia = x ? x.wikipedia : ''
|
||||||
|
r.open_speech_hours = x ? x.speech_hours : null
|
||||||
|
r.open_benchmark = x ? x.benchmark : ''
|
||||||
|
}
|
||||||
meta.value = markRaw(doc.meta || {})
|
meta.value = markRaw(doc.meta || {})
|
||||||
countries.value = markRaw(doc.countries || {})
|
countries.value = markRaw(doc.countries || {})
|
||||||
all.value = markRaw(rows)
|
all.value = markRaw(rows)
|
||||||
|
|
@ -188,7 +203,7 @@ export function useBoard() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const board = {
|
const board = {
|
||||||
bus, all, bySlug, filtered, sorted, meta, countries, loading, error, listId, listIsDefault,
|
bus, all, bySlug, filtered, sorted, meta, countries, readiness, loading, error, listId, listIsDefault,
|
||||||
view, sort, openSlug, openRow, profileConfig,
|
view, sort, openSlug, openRow, profileConfig,
|
||||||
centre, tree, resources, treeNode, setCentre, setTreeNode, loadTree,
|
centre, tree, resources, treeNode, setCentre, setTreeNode, loadTree,
|
||||||
load, setView, openGroup, closeGroup, readUrl, groupLink,
|
load, setView, openGroup, closeGroup, readUrl, groupLink,
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -604,7 +604,7 @@
|
||||||
"bundle": "gospel-internet",
|
"bundle": "gospel-internet",
|
||||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||||
"integrity": "sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK",
|
"integrity": "sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV",
|
||||||
"elements": [
|
"elements": [
|
||||||
"gospel-internet-board"
|
"gospel-internet-board"
|
||||||
],
|
],
|
||||||
|
|
@ -623,7 +623,7 @@
|
||||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||||
<script src="../../gospel-internet.js" integrity="sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK" crossorigin="anonymous"></script>
|
<script src="../../gospel-internet.js" integrity="sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -604,7 +604,7 @@
|
||||||
"bundle": "gospel-internet",
|
"bundle": "gospel-internet",
|
||||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||||
"integrity": "sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK",
|
"integrity": "sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV",
|
||||||
"elements": [
|
"elements": [
|
||||||
"gospel-internet-board"
|
"gospel-internet-board"
|
||||||
],
|
],
|
||||||
|
|
@ -623,7 +623,7 @@
|
||||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-/5R1QCmIz5vgIpbnYsItuTQE5KCYezYAEesD36ijiZaqKmM7AAAR7G5DN7P8k2IK\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-qAcTOFyxfCu60sdF8d6Rbxlnn2RfoKmPiKl0WrqZRJjs+sW7iQXxgtXghS6uDhhV\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue