Merge remote-tracking branch 'origin/development' into bundler-2/panelang
This commit is contained in:
commit
b3e67c7f2b
33 changed files with 879 additions and 190 deletions
280
internal/check-pane-config-reforward.mjs
Normal file
280
internal/check-pane-config-reforward.mjs
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-pane-config-reforward — a composite's panes keep following the outer config for the whole
|
||||
* session, and a locale change never rewrites a filter into a display name.
|
||||
*
|
||||
* ★ THE BUG THIS GUARDS, measured by rega on development 92ca8b6e6 across FOUR composites
|
||||
* (regions-mfe, upg-100-mfe, country-posters-mfe, research-map-plus-grid). The outer element's
|
||||
* profile-config reached locale 'ar' by +1.5 s — attribute AND property, same node — while every
|
||||
* NESTED host carried NO locale key at boot and still none at +15 s. Text per composite at +15 s:
|
||||
* the chrome switched (3 Arabic / 0 Latin) and the panes did not (0/205, 0/190, 0/618, 0/43).
|
||||
* The cause is one line per composite: the pane's profile-config is written ONCE, in onMounted, so
|
||||
* the pane holds a JSON STRING and every later change stops at the composite. The leaf's own chain
|
||||
* is fully reactive and was never at fault.
|
||||
*
|
||||
* ★ IT RUNS THE SHIPPED HELPER WITH REAL VUE. usePaneConfig is imported, not re-typed, and driven
|
||||
* by real refs through a real watchEffect — the dependency-tracking hole this gate's case 3 covers
|
||||
* (a plain array leaves a LATER entry's getter untracked) is invisible to any test that fakes
|
||||
* reactivity, and it was found by studio only because their test used real Vue.
|
||||
*
|
||||
* ★ AND IT ASSERTS THE DOM, NOT THE RETURN VALUE. Every case reads the attribute back off the
|
||||
* element, because "the helper decided to write" and "the pane was told" are different claims and
|
||||
* only the second one is the fix.
|
||||
*
|
||||
* Exit 0 pass · 1 fail.
|
||||
*/
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { usePaneConfig } from '../library/composables/usePaneConfig.js'
|
||||
|
||||
let bad = 0
|
||||
const ok = (cond, what) => { if (!cond) bad++; console.log(` ${cond ? 'ok ' : 'FAIL'} ${what}`) }
|
||||
|
||||
/**
|
||||
* The smallest element that can hold attributes and answer contains(). Not a DOM shim in general —
|
||||
* only the surface the helper actually touches, so a change in what it touches breaks loudly here
|
||||
* rather than passing against a stub that pretends to be a browser.
|
||||
*/
|
||||
function makeEl(name = 'pane') {
|
||||
const attrs = new Map()
|
||||
return {
|
||||
name,
|
||||
isConnected: true,
|
||||
writes: 0,
|
||||
getAttribute: (k) => (attrs.has(k) ? attrs.get(k) : null),
|
||||
setAttribute(k, v) { attrs.set(k, String(v)); this.writes++ },
|
||||
}
|
||||
}
|
||||
const makeHost = (children) => ({ contains: (el) => children.includes(el) })
|
||||
|
||||
// ★ NULL-SAFE DELIBERATELY. When the re-forward is broken the attribute is absent, and a gate that
|
||||
// CRASHES on that reports "something went wrong somewhere" instead of naming the pane that stopped
|
||||
// following. Verified against the plain-array mutation: it turns a TypeError into a named FAIL.
|
||||
const cfgOf = (el) => {
|
||||
const raw = el.getAttribute('profile-config')
|
||||
if (!raw) return {}
|
||||
try { return JSON.parse(raw) } catch { return {} }
|
||||
}
|
||||
|
||||
// ── 1. THE MEASURED DEFECT. A locale change after mount must reach the pane.
|
||||
{
|
||||
const outer = ref({ locale: 'en', apiBaseUrl: '/api' })
|
||||
const el = makeEl()
|
||||
const host = makeHost([el])
|
||||
const paneConfig = usePaneConfig(() => host)
|
||||
// Mount-time write, exactly as the composite does it before registering.
|
||||
el.setAttribute('profile-config', JSON.stringify({ ...outer.value, profile: 'regions-list' }))
|
||||
paneConfig.register(el, () => ({ ...outer.value, profile: 'regions-list' }))
|
||||
await nextTick()
|
||||
const atMount = el.writes
|
||||
ok(cfgOf(el).locale === 'en', 'at mount the pane has the outer locale')
|
||||
|
||||
outer.value = { locale: 'ar', apiBaseUrl: '/api' }
|
||||
await nextTick()
|
||||
ok(cfgOf(el).locale === 'ar', 'after a live locale switch the pane has been told (this is the bug: it used to stay en)')
|
||||
ok(el.writes === atMount + 1, `exactly one re-write, not a loop (${el.writes - atMount})`)
|
||||
ok(cfgOf(el).profile === 'regions-list', "the pane's own keys survive the re-forward")
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 1b. NO LOCALE KEY AT BOOT IS THE REAL BEFORE-STATE, not a stale one. rega measured the nested
|
||||
// hosts carrying no locale key at all, so the first re-forward is absent -> 'ar'.
|
||||
{
|
||||
const outer = ref({ apiBaseUrl: '/api' })
|
||||
const el = makeEl()
|
||||
const paneConfig = usePaneConfig(() => makeHost([el]))
|
||||
el.setAttribute('profile-config', JSON.stringify({ ...outer.value }))
|
||||
paneConfig.register(el, () => ({ ...outer.value }))
|
||||
await nextTick()
|
||||
ok(cfgOf(el).locale === undefined, 'the measured boot state: no locale key on the nested host')
|
||||
outer.value = { apiBaseUrl: '/api', locale: 'ar' }
|
||||
await nextTick()
|
||||
ok(cfgOf(el).locale === 'ar', 'an ABSENT locale key is still a change, so the write fires')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 2. NO WRITE WHEN NOTHING CHANGED. Setting profile-config re-parses it in the child and can
|
||||
// remount what it drives, so an unconditional write on every reactive tick is a rerender loop.
|
||||
{
|
||||
const outer = ref({ locale: 'en' })
|
||||
const unrelated = ref(0)
|
||||
const el = makeEl()
|
||||
const paneConfig = usePaneConfig(() => makeHost([el]))
|
||||
el.setAttribute('profile-config', JSON.stringify(outer.value))
|
||||
paneConfig.register(el, () => ({ ...outer.value, tick: unrelated.value && 0 }))
|
||||
await nextTick()
|
||||
const before = el.writes
|
||||
unrelated.value = 7 // reactive churn that does not change the config
|
||||
await nextTick()
|
||||
ok(el.writes === before, `an unchanged config writes nothing (${el.writes - before} writes)`)
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 3. EVERY PANE FOLLOWS, NOT ONLY THE FIRST. ★ THE REGRESSION STUDIO FOUND. With a plain array
|
||||
// the watchEffect tracks only the getters reachable on its FIRST run, so pane 2's source is never a
|
||||
// dependency: changing it produced ZERO writes. That is this very bug, reappearing inside its own
|
||||
// fix, for any adopter whose panes read different sources.
|
||||
// It is also plugin-studio's load-bearing property, recorded at plugin-studio.vue:897: "EVERY
|
||||
// mounted pane, not only the one on screen: a kept-alive pane showed the old language when the
|
||||
// reader came back to it."
|
||||
{
|
||||
const a = ref('en')
|
||||
const b = ref('en')
|
||||
const elA = makeEl('a')
|
||||
const elB = makeEl('b')
|
||||
const paneConfig = usePaneConfig(() => makeHost([elA, elB]))
|
||||
paneConfig.register(elA, () => ({ locale: a.value }))
|
||||
paneConfig.register(elB, () => ({ locale: b.value }))
|
||||
await nextTick()
|
||||
b.value = 'ar' // ONLY the second pane's source
|
||||
await nextTick()
|
||||
ok(cfgOf(elB).locale === 'ar', 'the SECOND registered pane follows its own source (a plain array left this untracked)')
|
||||
ok(cfgOf(elA).locale === 'en', 'and the first pane is not disturbed by it')
|
||||
a.value = 'ro'
|
||||
await nextTick()
|
||||
ok(cfgOf(elA).locale === 'ro', 'the first pane still follows after the second has fired')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 4. A DETACHED PANE IS DROPPED, not written to. A pane column rebuild replaces the elements.
|
||||
{
|
||||
const outer = ref({ locale: 'en' })
|
||||
const kept = makeEl('kept')
|
||||
const gone = makeEl('gone')
|
||||
let children = [kept, gone]
|
||||
const paneConfig = usePaneConfig(() => makeHost(children))
|
||||
paneConfig.register(kept, () => ({ ...outer.value }))
|
||||
paneConfig.register(gone, () => ({ ...outer.value }))
|
||||
await nextTick()
|
||||
ok(paneConfig.count() === 2, 'both panes registered')
|
||||
children = [kept] // the column was rebuilt; `gone` is no longer under it
|
||||
gone.isConnected = false
|
||||
const goneWrites = gone.writes
|
||||
outer.value = { locale: 'ar' }
|
||||
await nextTick()
|
||||
ok(gone.writes === goneWrites, 'a detached pane is not written to')
|
||||
ok(paneConfig.count() === 1, `and it is PRUNED rather than re-tested forever (count ${paneConfig.count()})`)
|
||||
ok(cfgOf(kept).locale === 'ar', 'the surviving pane still follows')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 5. ONE PANE'S THROWING GETTER DOES NOT TAKE THE OTHERS DOWN. Inside a watchEffect an exception
|
||||
// stops every LATER entry in the same pass — which would silently freeze panes that are fine.
|
||||
{
|
||||
const outer = ref({ locale: 'en' })
|
||||
const boom = makeEl('boom')
|
||||
const fine = makeEl('fine')
|
||||
const paneConfig = usePaneConfig(() => makeHost([boom, fine]))
|
||||
const realError = console.error
|
||||
let errors = 0
|
||||
console.error = () => { errors++ }
|
||||
paneConfig.register(boom, () => { throw new Error('pane getter exploded') })
|
||||
paneConfig.register(fine, () => ({ ...outer.value }))
|
||||
await nextTick()
|
||||
outer.value = { locale: 'ar' }
|
||||
await nextTick()
|
||||
console.error = realError
|
||||
ok(cfgOf(fine).locale === 'ar', 'a pane registered AFTER a throwing one still follows the outer config')
|
||||
ok(errors >= 1, `and the throw is reported rather than swallowed (${errors})`)
|
||||
ok(errors <= 2, `but not once per reactive tick forever (${errors})`)
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 6. registerAttrs: THE SECOND PANE SHAPE. people-groups-grid takes three separate attributes
|
||||
// rather than one JSON blob (research-map-plus-grid.vue:430-435). Same list, same effect, same
|
||||
// write-on-change — the point of generalising rather than letting the second adopter fork.
|
||||
{
|
||||
const linked = reactive({ region: '', religion: '', language: 'arb' })
|
||||
const grid = makeEl('grid')
|
||||
const paneConfig = usePaneConfig(() => makeHost([grid]))
|
||||
paneConfig.registerAttrs(grid, () => ({
|
||||
'wagf-region': linked.region,
|
||||
'religion-family': linked.religion,
|
||||
'primary-language': linked.language,
|
||||
}))
|
||||
await nextTick()
|
||||
ok(grid.getAttribute('primary-language') === 'arb', 'an attribute-configured pane is written at registration')
|
||||
const before = grid.writes
|
||||
linked.region = 'africa'
|
||||
await nextTick()
|
||||
ok(grid.getAttribute('wagf-region') === 'africa', 'a changed attribute is written')
|
||||
ok(grid.writes === before + 1, `ONLY the changed attribute is written, not all three (${grid.writes - before})`)
|
||||
ok(grid.getAttribute('religion-family') === '', 'an empty value is written as empty, never the string "undefined"')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 6b. A KEY THE GETTER LATER OMITS IS CLEARED, not left applied. A stale filter silently
|
||||
// narrowing the grid is the same class of lie as the frozen config this helper exists to fix.
|
||||
{
|
||||
const linked = reactive({ region: 'africa', present: true })
|
||||
const grid = makeEl('grid')
|
||||
const paneConfig = usePaneConfig(() => makeHost([grid]))
|
||||
paneConfig.registerAttrs(grid, () => (linked.present
|
||||
? { 'wagf-region': linked.region, 'religion-family': 'islam' }
|
||||
: { 'religion-family': 'islam' }))
|
||||
await nextTick()
|
||||
ok(grid.getAttribute('wagf-region') === 'africa', 'the filter is applied')
|
||||
linked.present = false
|
||||
await nextTick()
|
||||
ok(grid.getAttribute('wagf-region') === '', 'an omitted key CLEARS its attribute rather than leaving a stale filter')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 7. ★ LOCALE-INVARIANCE OF A FILTER VALUE (sr's property, SR-ADOPT-ANSWERS). A re-forward
|
||||
// triggered by a LOCALE change must produce the SAME primary-language string it produced before.
|
||||
// The hazard is real and general even though it does not bite today: research-map-plus-grid's
|
||||
// gridLanguage() falls back to `linked.language.value || linked.language.label`, and `label` is a
|
||||
// DISPLAY NAME. The grid's valueMatches() compares whole normalised values, so a name fetched in
|
||||
// one language matches no row in another — the failure that took the grid 2,107 -> 0 and read as
|
||||
// "no results" (rega, 2026-09-26). This asserts the CLASS, not today's instance.
|
||||
{
|
||||
const locale = ref('en')
|
||||
// A language whose display label follows the locale, as the API returns it, but whose code does not.
|
||||
const NAMES = { en: 'Arabic, Sudanese', ar: 'العربية السودانية' }
|
||||
const linkedLanguage = () => ({ codes: ['apd'], value: 'apd', label: NAMES[locale.value] })
|
||||
const gridLanguage = () => {
|
||||
const l = linkedLanguage()
|
||||
const codes = Array.isArray(l.codes) ? l.codes : []
|
||||
if (codes.length > 1) return codes.join('|')
|
||||
return l.value || l.label
|
||||
}
|
||||
const grid = makeEl('grid')
|
||||
const paneConfig = usePaneConfig(() => makeHost([grid]))
|
||||
paneConfig.registerAttrs(grid, () => ({ 'primary-language': gridLanguage(), 'wagf-region': `r-${locale.value === 'x' ? 1 : 0}` }))
|
||||
await nextTick()
|
||||
const beforeSwitch = grid.getAttribute('primary-language')
|
||||
locale.value = 'ar'
|
||||
await nextTick()
|
||||
ok(grid.getAttribute('primary-language') === beforeSwitch,
|
||||
`a locale change leaves primary-language unchanged ('${beforeSwitch}' -> '${grid.getAttribute('primary-language')}')`)
|
||||
ok(!/[-ۿ]/.test(grid.getAttribute('primary-language')),
|
||||
'the filter is a CODE, never a localised display name')
|
||||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 8. DISPOSE STOPS THE EFFECT. A composite unmounted and left watching is a leak that keeps
|
||||
// writing to detached elements.
|
||||
{
|
||||
const outer = ref({ locale: 'en' })
|
||||
const el = makeEl()
|
||||
const paneConfig = usePaneConfig(() => makeHost([el]))
|
||||
paneConfig.register(el, () => ({ ...outer.value }))
|
||||
await nextTick()
|
||||
paneConfig.dispose()
|
||||
const after = el.writes
|
||||
outer.value = { locale: 'ar' }
|
||||
await nextTick()
|
||||
ok(el.writes === after, 'after dispose() the outer config is no longer followed')
|
||||
ok(paneConfig.count() === 0, 'and the entry list is emptied')
|
||||
}
|
||||
|
||||
// ── 9. IT DOES NOT THROW OUTSIDE setup(). Every case above runs outside a component instance, which
|
||||
// is the un-guarded onBeforeUnmount hazard studio raised — if that guard regressed, this file would
|
||||
// have failed at the first register() rather than here. Stated so the reason is on the record.
|
||||
ok(true, 'the whole file ran outside setup(): the getCurrentInstance() guard holds')
|
||||
|
||||
if (bad) {
|
||||
console.error(`\nPANE-CONFIG-REFORWARD: FAIL — ${bad} case(s). A composite's panes no longer follow the`)
|
||||
console.error('outer profile-config, so a live locale switch leaves every nested pane in the old language.')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('\nPANE-CONFIG-REFORWARD: PASS — panes follow the outer config for the session, and a locale change never rewrites a filter value.')
|
||||
169
library/composables/usePaneConfig.js
Normal file
169
library/composables/usePaneConfig.js
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/**
|
||||
* usePaneConfig — keep a composite's panes' profile-config in step with the outer element's.
|
||||
*
|
||||
* ★ THE BUG THIS EXISTS FOR. A composite builds each pane by creating the child custom element and
|
||||
* writing its profile-config ONCE, inside onMounted:
|
||||
*
|
||||
* el.setAttribute('profile-config', JSON.stringify(pcfg)) // and never again
|
||||
*
|
||||
* That is correct at mount and wrong for the rest of the session. The pane is handed a JSON STRING,
|
||||
* not a reactive object, so a later change to the OUTER element's profile-config updates the
|
||||
* composite's own `cfg` and reaches nothing below it. MEASURED on Regions: a live locale switch
|
||||
* en -> ar left the panes in English for the whole session, because regions-dashboard is kept alive
|
||||
* by v-show rather than remounted — the one code path that would have rewritten the attribute never
|
||||
* runs again. The leaf's own chain is fully reactive and was never at fault: it is reactive to its
|
||||
* own prop, and its prop is frozen.
|
||||
*
|
||||
* ★ WHY A HELPER RATHER THAN THREE FIXES. regions-mfe, upg-100-mfe and country-posters-mfe all build
|
||||
* their panes the same way — assemble a config object, stringify it, set the attribute once. They
|
||||
* differ only in WHICH keys they inherit. So the composite keeps its own INHERITED_PAGE_KEYS and its
|
||||
* own assembly, and hands the result here; this owns the part that was missing everywhere.
|
||||
*
|
||||
* ★ IT WRITES ONLY WHEN THE STRING CHANGES. Setting profile-config re-parses it in the child and can
|
||||
* remount what it drives, so an unconditional write on every reactive tick would be a rerender loop.
|
||||
* The previous value is remembered per element and compared before touching the DOM.
|
||||
*
|
||||
* const panes = usePaneConfig(() => stage.value, TAG)
|
||||
* panes.register(el, () => paneConfigFor(pane)) // at mount, after appendChild
|
||||
*
|
||||
* Re-forwarding happens inside a watchEffect, so any reactive source the getter reads — the outer
|
||||
* config, a computed spec, the pane's own config — triggers it.
|
||||
*
|
||||
* ★ NOT EVERY PANE IS CONFIGURED BY profile-config. people-groups-grid takes its filters as THREE
|
||||
* separate attributes (wagf-region, religion-family, primary-language) rather than one JSON blob, so
|
||||
* research-map-plus-grid has one pane of each kind. registerAttrs covers that second shape:
|
||||
*
|
||||
* panes.registerAttrs(grid, () => ({ 'wagf-region': region.value, 'religion-family': fam.value }))
|
||||
*
|
||||
* It shares this list, this watchEffect, this prune and this write-only-on-change — deliberately, so
|
||||
* the second adopter rides ONE mechanism instead of forking a second. A helper with a single caller
|
||||
* has not been shown to generalise at all; this is the shape that showed it.
|
||||
*/
|
||||
import { watchEffect, onBeforeUnmount, shallowReactive, getCurrentInstance } from 'vue'
|
||||
|
||||
/**
|
||||
* @param {() => (Element|null|undefined)} hostGetter the element the panes were appended under; used
|
||||
* only to drop registrations whose element has left the DOM (a pane column can be rebuilt).
|
||||
* ★ IT MUST BE IN THE SAME TREE AS THE PANES. Element.contains() does NOT cross a shadow
|
||||
* boundary, so passing the custom element while its panes live in its shadow root would make
|
||||
* every pane look detached and skip every write, silently.
|
||||
* @returns {{ register: (el: Element, configGetter: () => object) => void,
|
||||
* registerAttrs: (el: Element, attrsGetter: () => Record<string,unknown>) => void,
|
||||
* dispose: () => void, count: () => number }}
|
||||
*/
|
||||
export function usePaneConfig(hostGetter) {
|
||||
// ★ shallowReactive, NOT a plain array. The watchEffect below runs once, at the FIRST register();
|
||||
// with a plain array a LATER entry's getter is never tracked, so its pane stays frozen until
|
||||
// something the first entry reads happens to change. MEASURED with real Vue by studio: two panes
|
||||
// reading different refs, changing only pane 2's source produced ZERO writes. That is the very bug
|
||||
// this helper exists to fix, reappearing for any adopter whose panes read different sources.
|
||||
// Making the list reactive re-runs the effect on register() and re-tracks every getter.
|
||||
/**
|
||||
* One entry per registered pane. `attrs` is the ATTRIBUTE NAMES this entry owns: the single-key
|
||||
* ['profile-config'] for a JSON-configured pane, or the caller's list for an attribute-configured
|
||||
* one. `last` holds the previously written value PER ATTRIBUTE, so a getter that changes one of
|
||||
* three attributes writes one of three.
|
||||
* @type {Array<{el: Element, get: () => object, attrs: string[]|null, last: Record<string,string|null>, warned: boolean}>}
|
||||
*/
|
||||
const entries = shallowReactive([])
|
||||
let stop = null
|
||||
|
||||
const alive = (el) => {
|
||||
if (!el || !el.isConnected) return false
|
||||
const host = typeof hostGetter === 'function' ? hostGetter() : hostGetter
|
||||
// A pane column rebuild replaces the elements; an entry whose element is no longer under the
|
||||
// current host is stale and must not be written to.
|
||||
return !host || host.contains(el)
|
||||
}
|
||||
|
||||
/** Add an entry and make sure the one shared effect is running. */
|
||||
function add(entry) {
|
||||
entries.push(entry)
|
||||
if (stop) return
|
||||
stop = watchEffect(() => {
|
||||
// PRUNE rather than skip: an adopter that rebuilds its pane column would otherwise keep
|
||||
// detached elements in the list and re-run their getters on every pass, forever.
|
||||
for (let i = entries.length - 1; i >= 0; i--) if (!alive(entries[i].el)) entries.splice(i, 1)
|
||||
for (const e of entries) forward(e)
|
||||
})
|
||||
}
|
||||
|
||||
/** Re-evaluate one entry's getter and write only what changed. */
|
||||
function forward(entry) {
|
||||
let value
|
||||
// A getter that throws must not take the other panes down with it: this runs inside a
|
||||
// watchEffect, where an exception would stop every later entry in the same pass. It is
|
||||
// reported ONCE per entry -- silence here would recreate the symptom this helper fixes.
|
||||
try { value = entry.get() } catch (e) {
|
||||
if (!entry.warned) { entry.warned = true; console.error('[usePaneConfig] pane config getter threw; this pane will not follow the outer config:', e) }
|
||||
return
|
||||
}
|
||||
if (!entry.attrs) {
|
||||
// JSON pane: the whole config is one attribute.
|
||||
let next
|
||||
try { next = JSON.stringify(value) } catch (e) {
|
||||
if (!entry.warned) { entry.warned = true; console.error('[usePaneConfig] pane config did not stringify; this pane will not follow the outer config:', e) }
|
||||
return
|
||||
}
|
||||
if (next === entry.last['profile-config']) return
|
||||
entry.last['profile-config'] = next
|
||||
entry.el.setAttribute('profile-config', next)
|
||||
return
|
||||
}
|
||||
// Attribute pane: each named attribute is compared and written independently, so a getter whose
|
||||
// region changed does not rewrite (and so re-trigger) the two that did not.
|
||||
const bag = value && typeof value === 'object' ? value : {}
|
||||
for (const name of entry.attrs) {
|
||||
// An absent/null/undefined value is written as '' rather than the string "undefined" -- the
|
||||
// grid reads these as plain filter strings and "undefined" would be a filter that matches
|
||||
// nothing, which is the empty-grid failure this repo has already paid for once.
|
||||
const raw = bag[name]
|
||||
const next = raw === undefined || raw === null ? '' : String(raw)
|
||||
if (next === entry.last[name]) continue
|
||||
entry.last[name] = next
|
||||
entry.el.setAttribute(name, next)
|
||||
}
|
||||
}
|
||||
|
||||
function register(el, configGetter) {
|
||||
if (!el || typeof configGetter !== 'function') return
|
||||
// The attribute the caller already set at mount is the baseline: recording it here means the
|
||||
// first watchEffect pass does not rewrite an identical value.
|
||||
add({ el, get: configGetter, attrs: null, last: { 'profile-config': el.getAttribute('profile-config') }, warned: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribute-configured sibling. `attrsGetter` returns an object keyed by ATTRIBUTE NAME
|
||||
* (kebab-case, as written in the DOM), e.g. { 'wagf-region': 'africa' }.
|
||||
* ★ THE NAME LIST IS FIXED AT REGISTRATION, from the getter's first result. A pane's attribute
|
||||
* surface is static -- it is the element's contract -- and pinning it means a later getter that
|
||||
* omits a key CLEARS that attribute rather than silently leaving a stale filter applied, which is
|
||||
* the same class of lie as the frozen config this helper exists to fix.
|
||||
*/
|
||||
function registerAttrs(el, attrsGetter) {
|
||||
if (!el || typeof attrsGetter !== 'function') return
|
||||
let first
|
||||
try { first = attrsGetter() } catch (e) {
|
||||
console.error('[usePaneConfig] attrs getter threw at registration; this pane is not registered:', e)
|
||||
return
|
||||
}
|
||||
const attrs = Object.keys(first && typeof first === 'object' ? first : {})
|
||||
if (!attrs.length) {
|
||||
console.error('[usePaneConfig] attrs getter returned no attribute names; this pane is not registered.')
|
||||
return
|
||||
}
|
||||
const last = {}
|
||||
for (const name of attrs) last[name] = el.getAttribute(name)
|
||||
add({ el, get: attrsGetter, attrs, last, warned: false })
|
||||
}
|
||||
|
||||
// ★ GUARDED, the house pattern (useMapData.js:144). onBeforeUnmount only binds inside setup(); a
|
||||
// caller outside one gets a Vue warning and no auto-cleanup. `dispose` is returned so such a
|
||||
// caller has something to call -- silently leaking a watchEffect would be the worse half.
|
||||
const dispose = () => { if (stop) { stop(); stop = null } entries.length = 0 }
|
||||
if (getCurrentInstance()) onBeforeUnmount(dispose)
|
||||
|
||||
return { register, registerAttrs, dispose, count: () => entries.length }
|
||||
}
|
||||
|
||||
export default usePaneConfig
|
||||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "لم يُحدَّد شيء",
|
||||
"selectionCardsFailed": "فشل إنشاء بطاقات التحديد: {reason}",
|
||||
"selectionPosterNeedsZone": "الملصقات متاحة لكل منطقة في مفتاح الخريطة — استخدم «قائمة الصلاة» لتحديد على الخريطة",
|
||||
"mapDataFailed": "تعذّر تحميل بيانات الخريطة"
|
||||
"mapDataFailed": "تعذّر تحميل بيانات الخريطة",
|
||||
"infoLead": "قائمة UPG-100 على خريطة واحدة: الشعوب غير المُبشَّرة، مجمّعة في مناطق يمكنك أن تتبنّاها بالصلاة.",
|
||||
"infoTakeaway": "لكل منطقة: ملصق للحائط، وحزمة صلاة للتوزيع، ومجموعة من بطاقات الصلاة. المثال أدناه هو المنطقة التي تضم أكبر عدد من الناس في شعوب لا يعمل أحد بعد على غرس كنائس بينها."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Nichts ausgewählt",
|
||||
"selectionCardsFailed": "Karten der Auswahl fehlgeschlagen: {reason}",
|
||||
"selectionPosterNeedsZone": "Plakate gibt es pro Gebiet in der Legende – nutzen Sie Gebetsliste für eine Auswahl auf der Karte",
|
||||
"mapDataFailed": "Die Kartendaten konnten nicht geladen werden"
|
||||
"mapDataFailed": "Die Kartendaten konnten nicht geladen werden",
|
||||
"infoLead": "Die UPG-100-Liste auf einer Karte: unerreichte Volksgruppen, zusammengefasst in Zonen, die Sie im Gebet übernehmen können.",
|
||||
"infoTakeaway": "für jede Zone ein Wandposter, ein Gebetsheft zum Weitergeben und ein Satz Gebetskarten. Das Beispiel unten ist die Zone mit den meisten Menschen in Volksgruppen, unter denen noch niemand Gemeinden gründet."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Nothing is selected",
|
||||
"selectionCardsFailed": "Selection card deck failed: {reason}",
|
||||
"selectionPosterNeedsZone": "Posters exist per territory on the legend — use Prayer List for a map selection",
|
||||
"mapDataFailed": "The map data could not be loaded"
|
||||
"mapDataFailed": "The map data could not be loaded",
|
||||
"infoLead": "The UPG-100 list on one map: unreached people groups, gathered into zones you can adopt in prayer.",
|
||||
"infoTakeaway": "for any zone, a wall poster, a prayer packet to hand out and a deck of prayer cards. The example below is the zone with the most people in groups where no one is planting churches yet."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "No hay nada seleccionado",
|
||||
"selectionCardsFailed": "Error al generar las tarjetas de la selección: {reason}",
|
||||
"selectionPosterNeedsZone": "Hay carteles por territorio en la leyenda; usa Lista de oración para una selección en el mapa",
|
||||
"mapDataFailed": "No se pudieron cargar los datos del mapa"
|
||||
"mapDataFailed": "No se pudieron cargar los datos del mapa",
|
||||
"infoLead": "La lista UPG-100 en un solo mapa: pueblos no alcanzados, agrupados en zonas que usted puede adoptar en oración.",
|
||||
"infoTakeaway": "para cada zona, un póster para la pared, un paquete de oración para repartir y un mazo de tarjetas de oración. El ejemplo de abajo es la zona con más personas en pueblos donde todavía nadie está plantando iglesias."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Rien n’est sélectionné",
|
||||
"selectionCardsFailed": "Échec des cartes de la sélection : {reason}",
|
||||
"selectionPosterNeedsZone": "Les affiches existent par territoire dans la légende — utilisez Liste de prière pour une sélection sur la carte",
|
||||
"mapDataFailed": "Les données de la carte n’ont pas pu être chargées"
|
||||
"mapDataFailed": "Les données de la carte n’ont pas pu être chargées",
|
||||
"infoLead": "La liste UPG-100 sur une seule carte : les peuples non atteints, regroupés en zones que vous pouvez adopter dans la prière.",
|
||||
"infoTakeaway": "pour chaque zone, une affiche murale, un livret de prière à distribuer et un jeu de cartes de prière. L'exemple ci-dessous est la zone qui compte le plus de personnes dans des peuples où personne n'implante encore d'Églises."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "कुछ भी चुना नहीं गया है",
|
||||
"selectionCardsFailed": "चयन के कार्ड विफल: {reason}",
|
||||
"selectionPosterNeedsZone": "पोस्टर लेजेंड में हर क्षेत्र के लिए हैं — मानचित्र पर चयन के लिए प्रार्थना सूची का उपयोग करें",
|
||||
"mapDataFailed": "मानचित्र का डेटा लोड नहीं हो सका"
|
||||
"mapDataFailed": "मानचित्र का डेटा लोड नहीं हो सका",
|
||||
"infoLead": "UPG-100 सूची एक ही नक्शे पर: अपहुँचे जन-समूह, क्षेत्रों में बाँटे गए, जिन्हें आप प्रार्थना में अपना सकते हैं।",
|
||||
"infoTakeaway": "हर क्षेत्र के लिए दीवार का एक पोस्टर, बाँटने के लिए एक प्रार्थना पुस्तिका और प्रार्थना कार्डों का एक सेट। नीचे का उदाहरण वह क्षेत्र है जहाँ ऐसे जन-समूहों में सबसे अधिक लोग हैं जिनके बीच अभी कोई कलीसिया स्थापित नहीं कर रहा है।"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Nessuna selezione",
|
||||
"selectionCardsFailed": "Carte della selezione non riuscite: {reason}",
|
||||
"selectionPosterNeedsZone": "I manifesti esistono per territorio nella legenda: usa Lista di preghiera per una selezione sulla mappa",
|
||||
"mapDataFailed": "Impossibile caricare i dati della mappa"
|
||||
"mapDataFailed": "Impossibile caricare i dati della mappa",
|
||||
"infoLead": "La lista UPG-100 su un'unica mappa: popoli non raggiunti, raggruppati in zone che puoi adottare nella preghiera.",
|
||||
"infoTakeaway": "per ogni zona, un poster da parete, un libretto di preghiera da distribuire e un mazzo di carte di preghiera. L'esempio qui sotto è la zona con più persone in popoli dove nessuno sta ancora fondando chiese."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Nada está selecionado",
|
||||
"selectionCardsFailed": "Falha ao gerar os cartões da seleção: {reason}",
|
||||
"selectionPosterNeedsZone": "Há cartazes por território na legenda — use Lista de oração para uma seleção no mapa",
|
||||
"mapDataFailed": "Não foi possível carregar os dados do mapa"
|
||||
"mapDataFailed": "Não foi possível carregar os dados do mapa",
|
||||
"infoLead": "A lista UPG-100 em um só mapa: povos não alcançados, agrupados em zonas que você pode adotar em oração.",
|
||||
"infoTakeaway": "para cada zona, um pôster de parede, um pacote de oração para distribuir e um baralho de cartões de oração. O exemplo abaixo é a zona com mais pessoas em povos onde ninguém ainda está plantando igrejas."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Nimic nu este selectat",
|
||||
"selectionCardsFailed": "Cărțile selecției au eșuat: {reason}",
|
||||
"selectionPosterNeedsZone": "Afișele există pe teritoriu în legendă — folosiți Listă de rugăciune pentru o selecție pe hartă",
|
||||
"mapDataFailed": "Datele hărții nu au putut fi încărcate"
|
||||
"mapDataFailed": "Datele hărții nu au putut fi încărcate",
|
||||
"infoLead": "Lista UPG-100 pe o singură hartă: popoare neatinse, grupate în zone pe care le poți adopta în rugăciune.",
|
||||
"infoTakeaway": "pentru fiecare zonă, un poster de perete, un pachet de rugăciune de împărțit și un set de cartonașe de rugăciune. Exemplul de mai jos este zona cu cei mai mulți oameni din popoare în care nimeni nu plantează încă biserici."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "Ничего не выбрано",
|
||||
"selectionCardsFailed": "Не удалось создать карточки выбора: {reason}",
|
||||
"selectionPosterNeedsZone": "Плакаты есть для каждой территории в легенде — для выбора на карте используйте «Молитвенный список»",
|
||||
"mapDataFailed": "Не удалось загрузить данные карты"
|
||||
"mapDataFailed": "Не удалось загрузить данные карты",
|
||||
"infoLead": "Список UPG-100 на одной карте: недостигнутые народы, объединённые в зоны, которые вы можете взять на молитвенное попечение.",
|
||||
"infoTakeaway": "для каждой зоны — настенный плакат, молитвенный буклет для раздачи и набор молитвенных карточек. Ниже показана зона, где больше всего людей в народах, среди которых пока никто не основывает церкви."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
"nothingSelected": "未选择任何内容",
|
||||
"selectionCardsFailed": "所选内容的卡片生成失败:{reason}",
|
||||
"selectionPosterNeedsZone": "海报按图例中的区域提供——地图上的选择请使用“祷告名单”",
|
||||
"mapDataFailed": "无法加载地图数据"
|
||||
"mapDataFailed": "无法加载地图数据",
|
||||
"infoLead": "UPG-100 名单尽在一张地图上:未得之民按区域分组,你可以在祷告中认领一个区域。",
|
||||
"infoTakeaway": "每个区域都有一张墙面海报、一本可分发的祷告手册和一套祷告卡。下面的示例是这样一个区域:在尚无人植堂的族群中,这里的人数最多。"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@
|
|||
"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",
|
||||
"check:pane-config-reforward": "node internal/check-pane-config-reforward.mjs",
|
||||
"check:control-inset": "node internal/check-control-inset-measured.mjs",
|
||||
"check:viewport-meta": "node internal/check-viewport-meta.mjs",
|
||||
"check:viewport-meta:self-test": "VIEWPORT_META_SELFTEST=1 node internal/check-viewport-meta.mjs",
|
||||
|
|
@ -340,7 +341,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:done-evidence check:script-flags check:backlog-status 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:backlog-refs 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",
|
||||
"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: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-new-driver-references check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned 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:dxlife check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch",
|
||||
"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: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-new-driver-references check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls 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: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:dxlife check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
"instances": [
|
||||
{
|
||||
"id": "app",
|
||||
"title": "Research Gallery — Big Picture + every research map (app-shell)",
|
||||
"title": "Deep Research — Big Picture + every research map (app-shell)",
|
||||
"props": {
|
||||
"profile": "doxa-maps-spa",
|
||||
"provider": "maplibre",
|
||||
"instanceId": "doxa-maps-spa-app",
|
||||
"title": "Research Gallery"
|
||||
"title": "Deep Research"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
"cities-internet/connectivity-map",
|
||||
"gospel-resources/resources-map"
|
||||
],
|
||||
"label": "Research Gallery (vertical-tab app shell: the seven production maps)"
|
||||
"label": "Deep Research (vertical-tab app shell: the seven production maps)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
:dir="uiDir"
|
||||
:lang="uiLocale"
|
||||
:labels="layoutLabels"
|
||||
:title="heading"
|
||||
:title="headingText"
|
||||
:nav-label="t('navLabel')"
|
||||
:header="showHeader"
|
||||
:groups="navGroups"
|
||||
|
|
@ -136,6 +136,10 @@
|
|||
<button type="button" class="dms-mobile-notice-x" :aria-label="tr('dismiss')" @click="dismissMobileNotice(t.id)">×</button>
|
||||
</div>
|
||||
<div class="dms-slot" :ref="el => setSlot(i, el)"></div>
|
||||
<!-- The tab's "what can this do for you?" button (library MapInfo), from src/tabInfo.js. It sits
|
||||
over the pane, top-right; profile-config info:false removes it. -->
|
||||
<MapInfo v-if="infoFor(t)" :key="'info-' + t.id" v-bind="infoFor(t)"
|
||||
:assets-base="assetsBase" :locale="effectiveLocale" />
|
||||
<div v-if="t.state === 'loading'" class="dms-hint">{{ tr('loading', { label: tabLabel(t) }) }}</div>
|
||||
<div v-else-if="t.state === 'error'" class="dms-hint err">
|
||||
{{ tr('loadFailed', { label: tabLabel(t) }) }}<br><small>{{ t.error }}</small>
|
||||
|
|
@ -198,6 +202,8 @@ import { SWITCHER_LANGUAGES, loadLocale, saveLocale, getLanguage } from '@map/la
|
|||
import { translate, LOCALES, hasKey } from './src/strings.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
import { helpFor } from './src/experimentalHelp.js'
|
||||
import { TAB_INFO } from './src/tabInfo.js'
|
||||
import MapInfo from '@map/components/info/MapInfo.vue'
|
||||
import { loadScriptOnce, whenTagDefined } from '@map/utils/embedScript.js'
|
||||
|
||||
// THE HOST PAGE'S LANGUAGE, by the same ladder every nested map already uses (library/i18n
|
||||
|
|
@ -746,7 +752,7 @@ export default defineComponent({
|
|||
// (measured 2026-09-25). .vtl survives today only because it declares display:grid !important.
|
||||
// Everything the layout needs (dir, lang, labels, …) is passed explicitly below.
|
||||
inheritAttrs: false,
|
||||
components: { VerticalTabsLayout, BackToTopButton },
|
||||
components: { VerticalTabsLayout, BackToTopButton, MapInfo },
|
||||
// profile-config props the standalone leaf page + gallery hand every element. treeBase lets a
|
||||
// host pin the tree root explicitly; the rest are accepted so the element is a well-behaved
|
||||
// member of the bundler (profile/instanceId/assetsBase/tk/shareUrl/qa are ignored here — the
|
||||
|
|
@ -759,7 +765,9 @@ export default defineComponent({
|
|||
// mount that it will overwrite the native one. Both capability-5 shells had the same
|
||||
// declaration, which is the same duplicate-implementation pattern that turned one resolver
|
||||
// assumption into two separate outages — when one shell is fixed, grep for its twin.
|
||||
heading: { type: String, default: 'DX-Maps' },
|
||||
// DX Life publishes this gallery as "Deep Research" (a hidden page on its site), so that is the
|
||||
// default name. A host may still pass its own, as this prop or as profile-config.heading.
|
||||
heading: { type: String, default: 'Deep Research' },
|
||||
// Optional: pin the Mapbox token / token URL forwarded to each tab's element via profile-config.
|
||||
tokenUrl: { type: String, default: '' },
|
||||
tk: { type: String, default: '' },
|
||||
|
|
@ -924,6 +932,15 @@ export default defineComponent({
|
|||
// gone — every row is in the rail on every width, same order, always). The ONLY width-driven
|
||||
// thing left is which row is DISABLED (Big Picture, on mobile — see isDesktopOnly) and
|
||||
// which row auto-opens (see firstVisibleIndex) — both presentation, neither touches NAV_MODEL.
|
||||
showInfo() { const v = this.cfg.info; return !(v === false || v === 'false' || v === 'off') },
|
||||
headingText() { return String(this.cfg.heading || this.heading || '').trim() || 'Deep Research' },
|
||||
// profile-config `experimental: false` (or "hidden") hides the Experimental folder: no discovery, no
|
||||
// rows, and a tab= request for an experimental map falls back to the first visible tab. OFF only on
|
||||
// request, so every other host keeps the folder exactly as before.
|
||||
showExperimental() {
|
||||
const v = this.cfg.experimental
|
||||
return !(v === false || v === 'false' || v === 'hidden' || v === 'off')
|
||||
},
|
||||
navGroups() {
|
||||
const byId = Object.fromEntries(this.tabs.map(t => [t.id, t]))
|
||||
// ONE `seen` set threaded across ALL groups (not per-group): the rail must hold one node per tab
|
||||
|
|
@ -954,6 +971,7 @@ export default defineComponent({
|
|||
// The Experimental folder is not authored — it is FILLED with every discovered tab (any
|
||||
// built bundle no curated section placed). This is the one group whose rows come from the
|
||||
// manifest rather than NAV_MODEL, which is what makes a new plugin appear by itself.
|
||||
if (g.key === 'experimental' && !this.showExperimental) return { key: g.key, rows: [] }
|
||||
if (g.key === 'experimental') {
|
||||
// Discovered rows go through the SAME de-dup gate as curated ones. Belt-and-braces: a
|
||||
// discovered bundle should already be excluded by curatedBundles()/NOT_EXPERIMENTAL, but
|
||||
|
|
@ -1044,21 +1062,29 @@ export default defineComponent({
|
|||
},
|
||||
watch: {
|
||||
activeIndex() { this.helpOpen = false },
|
||||
// When the parent page changes the inherited `language` prop at runtime, re-drive the CURRENTLY
|
||||
// visible tab into the new language by re-setting its element's profile-config.locale (which is
|
||||
// languages.js's contract). Other tabs pick it up lazily on their next open, since mountElement
|
||||
// reads effectiveLocale fresh. ONE path now — every tab is a real element, so the old
|
||||
// iframe-src-repoint branch is gone along with the iframes.
|
||||
effectiveLocale(loc) {
|
||||
const t = this.tabs[this.activeIndex]
|
||||
// ★ A LANGUAGE SWITCH REMOUNTS, IT DOES NOT RE-SET THE ATTRIBUTE. Re-setting the visible tab's
|
||||
// profile-config was the old path, and it relied on every nested map re-reading its whole config
|
||||
// live. Two production maps do not: Big Picture's tStatic strings are resolved once (2/352 changed,
|
||||
// measured), and Simple Research's composite copies its config into its panes once (0/43, 0/105).
|
||||
// A fresh element reads effectiveLocale at mount, so the visible tab is rebuilt in the new language
|
||||
// whatever each map does internally, the same way a provider change rebuilds. View state (filters,
|
||||
// zoom) is lost on a language switch, which is acceptable.
|
||||
// Hidden tabs that are still MOUNTED (a non-heavy tab stays mounted when hidden, and select() does
|
||||
// not remount a mounted tab) are released, so their next open mounts fresh in the new language.
|
||||
effectiveLocale() {
|
||||
// Reset IN PLACE, not with releaseTab: releaseTab deletes the slot ref, and a light (v-show) pane
|
||||
// is rendered once, so its slot ref would never be set again and the next mount would find none.
|
||||
// Emptying the slot runs the old element's disconnected lifecycle, which frees its map.
|
||||
const reset = (i, t) => {
|
||||
try { const slot = this._slots && this._slots[i]; if (slot) slot.innerHTML = '' } catch { /* reset anyway */ }
|
||||
t.mounted = false; t.state = 'idle'; t.error = ''
|
||||
}
|
||||
this.tabs.forEach((t, i) => { if (t.mounted && i !== this.activeIndex) reset(i, t) })
|
||||
const i = this.activeIndex
|
||||
const t = this.tabs[i]
|
||||
if (!t || !t.mounted) return
|
||||
try {
|
||||
const slot = this._slots && this._slots[this.activeIndex]
|
||||
const el = slot && slot.firstElementChild
|
||||
// Rebuild the SAME config the mount used (childConfig), so a language switch cannot silently
|
||||
// drop the profile/instance/token and re-render a different view in the new language.
|
||||
if (el && el.setAttribute) el.setAttribute('profile-config', JSON.stringify(this.childConfig(t)))
|
||||
} catch { /* non-fatal: the tab keeps its previous language */ }
|
||||
reset(i, t)
|
||||
this.mountElement(i)
|
||||
},
|
||||
// A host re-pointing the `tab` attribute after mount (e.g. from its own nav) switches the gallery.
|
||||
tab(id) { if (id) this.onSelect(id) }
|
||||
|
|
@ -1071,6 +1097,13 @@ export default defineComponent({
|
|||
this.$nextTick(() => back && back.focus && back.focus())
|
||||
},
|
||||
// Does this tab have what/how text? Marks its pane, so a map's hosted "?" knows to show.
|
||||
// A tab's button shows only when its lead text is in the bundled catalogue: a key that has not
|
||||
// landed would otherwise open a popup of raw key names. English is the check because every
|
||||
// locale falls back to it.
|
||||
infoFor(t) {
|
||||
const e = this.showInfo && t && TAB_INFO[t.id]
|
||||
return e && (!e.leadKey || tStatic(e.leadKey, 'en')) ? e : null
|
||||
},
|
||||
tabHasHelp(t) { return !!(t && t.discovered && helpFor(t.id, this.uiLocale)) },
|
||||
// A map's "?" (library HelpButton) asked for help. Answer only for the active tab, and only when
|
||||
// it has text; remember the exact button (composedPath reaches into the map's shadow root) so
|
||||
|
|
@ -1262,7 +1295,7 @@ export default defineComponent({
|
|||
kept.push(t)
|
||||
}
|
||||
const have = new Set(kept.map(t => t.id))
|
||||
for (const d of experimentalTabsFromManifest(m)) {
|
||||
if (this.showExperimental) for (const d of experimentalTabsFromManifest(m)) {
|
||||
if (have.has(d.id)) continue
|
||||
kept.push({ ...d, resolved: true, mounted: false, state: 'idle', error: '' })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
with no page reload; each map tab loads lazily on first open.</p>
|
||||
</div>
|
||||
<div class="frame">
|
||||
<doxa-maps-spa id="dms" title="DX-Maps"></doxa-maps-spa>
|
||||
<doxa-maps-spa id="dms" heading="Deep Research"></doxa-maps-spa>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
74
plugin-designs/doxa-maps-spa/src/tabInfo.js
Normal file
74
plugin-designs/doxa-maps-spa/src/tabInfo.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* tabInfo.js — what each gallery tab's info button (library MapInfo) says and shows.
|
||||
*
|
||||
* Keyed by the gallery's TAB id. A tab with no entry gets no button. Each OWNER supplies its words and
|
||||
* example files; the example files are real, pre-generated output under the tree's assets folder, so the
|
||||
* popup opens instantly.
|
||||
*
|
||||
* ★ EVERY KEY IS IN THE 'mapInfo' AREA, as mapInfo.tab.<tabId>.<field>, and never in the map's own area.
|
||||
* The build gives each bundle only the catalogue areas its source names (internal/i18n-areas.mjs): a key
|
||||
* in 'regions' or 'upgMap' would either render blank here or, named literally in this file, pull that
|
||||
* map's WHOLE catalogue, in eleven locales, into the gallery bundle. upg100 owns 'mapInfo' and merges
|
||||
* every tab's translated strings into it. Name keys LITERALLY here: that is what the area scan reads.
|
||||
*
|
||||
* ★ ADD AN EXAMPLE ONLY WHEN ITS FILE IS IN THE TREE. A missing file renders the popup's "not
|
||||
* available" box in front of the audience; an example that is not there yet is simply left out.
|
||||
* ★ KEYS MUST NOT CONTAIN A DOT beyond the area separator: the gallery has no vue-i18n, so MapInfo
|
||||
* resolves through tStatic, which splits the path on "." and would never find a sentence-shaped key.
|
||||
*/
|
||||
export const TAB_INFO = {
|
||||
'upg-100': {
|
||||
storageKey: 'upg-100',
|
||||
leadKey: 'mapInfo.tab.upg-100.lead',
|
||||
takeawayKey: 'mapInfo.tab.upg-100.takeaway',
|
||||
// The packet pages (12) and the card deck (70) join this list when their pre-generated shots land
|
||||
// in assets/previews/examples/middle-east-core/.
|
||||
examples: [
|
||||
{ kind: 'image', src: 'previews/middle-east-core.webp', full: 'posters/middle-east-core.html' },
|
||||
],
|
||||
},
|
||||
'regions-dashboard': {
|
||||
storageKey: 'regions-dashboard',
|
||||
leadKey: 'mapInfo.tab.regions-dashboard.lead',
|
||||
takeawayKey: 'mapInfo.tab.regions-dashboard.takeaway',
|
||||
// "except India and China": India is genuinely unsupported -- no sheet, no geometry, and 855
|
||||
// people groups, too many to fit one poster legibly (library/data/country-posters.json carries
|
||||
// that reason itself). CHINA IS DIFFERENT: it is technically supported TODAY (sheet 3x4,
|
||||
// geometry present, 154 groups -- the 3x4 tier exists precisely so it renders) and is withheld
|
||||
// deliberately, not because the pipeline cannot do it. Do not "fix" this by enabling China;
|
||||
// that is a decision above this file.
|
||||
noteKey: 'mapInfo.tab.regions-dashboard.note',
|
||||
// The Sudan poster, packet pages and card deck join when rega's shots are in the tree.
|
||||
examples: [],
|
||||
},
|
||||
'dashboard-plus-grid': {
|
||||
storageKey: 'dashboard-plus-grid',
|
||||
leadKey: 'mapInfo.tab.dashboard-plus-grid.lead',
|
||||
takeawayKey: 'mapInfo.tab.dashboard-plus-grid.takeaway',
|
||||
examples: [],
|
||||
},
|
||||
'research-map-plus-grid': {
|
||||
storageKey: 'research-map-plus-grid',
|
||||
leadKey: 'mapInfo.tab.research-map-plus-grid.lead',
|
||||
takeawayKey: 'mapInfo.tab.research-map-plus-grid.takeaway',
|
||||
examples: [],
|
||||
},
|
||||
'prayer-map': {
|
||||
storageKey: 'prayer-map',
|
||||
leadKey: 'mapInfo.tab.prayer-map.lead',
|
||||
takeawayKey: 'mapInfo.tab.prayer-map.takeaway',
|
||||
examples: [],
|
||||
},
|
||||
'cities-internet': {
|
||||
storageKey: 'cities-internet',
|
||||
leadKey: 'mapInfo.tab.cities-internet.lead',
|
||||
takeawayKey: 'mapInfo.tab.cities-internet.takeaway',
|
||||
examples: [],
|
||||
},
|
||||
'gospel-resources': {
|
||||
storageKey: 'gospel-resources',
|
||||
leadKey: 'mapInfo.tab.gospel-resources.lead',
|
||||
takeawayKey: 'mapInfo.tab.gospel-resources.takeaway',
|
||||
examples: [],
|
||||
},
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
* wall's 'show-on-map', and it keeps each pane under its own ProfileLoader/Pinia.
|
||||
*/
|
||||
import { ref, computed, inject, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { usePaneConfig } from '@map/composables/usePaneConfig.js'
|
||||
import { buildPaneColumn, PANE_GRID_STYLES } from '@map/layouts/pane-wrapper/pane-wrapper.js'
|
||||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
import { SHADOW_BOX_SIZING_RESET } from './src/shadowReset.js'
|
||||
|
|
@ -113,16 +114,27 @@ let offScroll = null
|
|||
// below), and this was the one genuinely missing.
|
||||
const INHERITED_PAGE_KEYS = ['assetsBase', 'apiBaseUrl', 'prayBaseUrl', 'tokenUrl', 'dataSource', 'locale', 'lang', 'languageCode', 'isDark', 'qa', 'pinHint', 'urlSync', 'provider', 'list']
|
||||
|
||||
function paneElement(pane) {
|
||||
const el = document.createElement(TAG)
|
||||
// ★ SPLIT OUT SO IT CAN BE RE-EVALUATED. This reads cfg.value and spec.value, so calling it again
|
||||
// after the outer profile-config changes yields the NEW pane config. It used to be inline in
|
||||
// paneElement, which ran once per pane in onMounted and never again -- that is the whole defect:
|
||||
// the pane is handed a JSON STRING, so a later locale change reached this element and stopped.
|
||||
// stage is the element the panes are appended UNDER, in the same tree as them -- contains() does
|
||||
// not cross a shadow boundary, so the host must not be the custom element itself.
|
||||
const paneConfig = usePaneConfig(() => stage.value)
|
||||
|
||||
function paneConfigFor(pane) {
|
||||
const host = cfg.value || {}
|
||||
const inherited = {}
|
||||
for (const k of INHERITED_PAGE_KEYS) {
|
||||
if (host[k] !== undefined && host[k] !== null && host[k] !== '') inherited[k] = host[k]
|
||||
}
|
||||
if (inherited.locale === undefined && inherited.lang !== undefined) inherited.locale = inherited.lang
|
||||
const pcfg = { ...inherited, ...spec.value.config, ...pane.config }
|
||||
el.setAttribute('profile-config', JSON.stringify(pcfg))
|
||||
return { ...inherited, ...spec.value.config, ...pane.config }
|
||||
}
|
||||
|
||||
function paneElement(pane) {
|
||||
const el = document.createElement(TAG)
|
||||
el.setAttribute('profile-config', JSON.stringify(paneConfigFor(pane)))
|
||||
return el
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +172,10 @@ onMounted(() => {
|
|||
if (!column) return
|
||||
for (const pane of column.panes) {
|
||||
if (!pane.config) continue
|
||||
column.mountEl(pane.id)?.appendChild(paneElement(pane))
|
||||
const el = paneElement(pane)
|
||||
column.mountEl(pane.id)?.appendChild(el)
|
||||
// Keep this pane's profile-config in step with the outer element's for the rest of the session.
|
||||
paneConfig.register(el, () => paneConfigFor(pane))
|
||||
}
|
||||
// Tabs are a readout as well as a control — follow the user's scroll.
|
||||
offScroll = column.onScroll(() => {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -9,7 +9,7 @@
|
|||
is never touched. Absence must mean restraint — an embedded plugin flipping a partner's
|
||||
whole <html> because a reader followed a ?lang=ar link is the bug this prevents. -->
|
||||
<script>window.MAP_OWNS_PAGE = true;</script>
|
||||
<title>Research Gallery — Big Picture + every research map (app-shell) · doxa-maps-spa</title>
|
||||
<title>Deep Research — Big Picture + every research map (app-shell) · doxa-maps-spa</title>
|
||||
<link rel="icon" href="data:,">
|
||||
<!-- NON-MAP leaf (app-shell / composite / grid / card / chart-table): NO map peer.
|
||||
This element draws no map tiles, so it needs no Mapbox/MapLibre engine and MUST NOT
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||
<script src="../../doxa-maps-spa.js" integrity="sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR" crossorigin="anonymous"></script>
|
||||
<script src="../../doxa-maps-spa.js" integrity="sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"doxa-maps-spa","provider":"maplibre","instanceId":"doxa-maps-spa-app","title":"Research Gallery"};
|
||||
var BASE_CONFIG = {"assetsBase":"../../../assets","profile":"doxa-maps-spa","provider":"maplibre","instanceId":"doxa-maps-spa-app","title":"Deep Research"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||
<script src="../doxa-maps-spa.js" integrity="sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR" crossorigin="anonymous"></script>
|
||||
<script src="../doxa-maps-spa.js" integrity="sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@
|
|||
"bundle": "doxa-maps-spa",
|
||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||
"integrity": "sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR",
|
||||
"integrity": "sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF",
|
||||
"elements": [
|
||||
"doxa-maps-spa"
|
||||
],
|
||||
|
|
@ -379,7 +379,7 @@
|
|||
{
|
||||
"profile": "doxa-maps-spa",
|
||||
"stage": "experimental",
|
||||
"label": "Research Gallery (vertical-tab app shell: the seven production maps)",
|
||||
"label": "Deep Research (vertical-tab app shell: the seven production maps)",
|
||||
"file": "doxa-maps-spa.vue",
|
||||
"description": "The DX-maps app itself: one element whose vertical-tab rail nests every other",
|
||||
"element": "doxa-maps-spa",
|
||||
|
|
@ -389,18 +389,18 @@
|
|||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/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=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"id": "app",
|
||||
"title": "Research Gallery — Big Picture + every research map (app-shell)",
|
||||
"title": "Deep Research — Big Picture + every research map (app-shell)",
|
||||
"apiBaseUrl": "",
|
||||
"props": {
|
||||
"profile": "doxa-maps-spa",
|
||||
"provider": "maplibre",
|
||||
"instanceId": "doxa-maps-spa-app",
|
||||
"title": "Research Gallery"
|
||||
"title": "Deep Research"
|
||||
},
|
||||
"element": "doxa-maps-spa",
|
||||
"iframeUrl": "./doxa-maps-spa/doxa-maps-spa/app/index.html",
|
||||
|
|
@ -880,7 +880,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M",
|
||||
"integrity": "sha384-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -903,7 +903,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -919,8 +919,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -936,8 +936,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1126,7 +1126,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6",
|
||||
"integrity": "sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1149,8 +1149,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" 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<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" 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<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1166,7 +1166,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1182,8 +1182,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" 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<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" 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<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@
|
|||
"bundle": "doxa-maps-spa",
|
||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||
"integrity": "sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR",
|
||||
"integrity": "sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF",
|
||||
"elements": [
|
||||
"doxa-maps-spa"
|
||||
],
|
||||
|
|
@ -379,7 +379,7 @@
|
|||
{
|
||||
"profile": "doxa-maps-spa",
|
||||
"stage": "experimental",
|
||||
"label": "Research Gallery (vertical-tab app shell: the seven production maps)",
|
||||
"label": "Deep Research (vertical-tab app shell: the seven production maps)",
|
||||
"file": "doxa-maps-spa.vue",
|
||||
"description": "The DX-maps app itself: one element whose vertical-tab rail nests every other",
|
||||
"element": "doxa-maps-spa",
|
||||
|
|
@ -389,18 +389,18 @@
|
|||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/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=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-8eKM96DKrUU0Bc7c8olQXs8pbadgwJcVgb/NBw76Lm1BdnExXuBQWvDmP63ZOpKR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-yngki2IqP9U/C9ViLIWHmyI0AhpQhOraOeRs5msKfniBS4Vlv7zgsB065ovhwTfF\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"id": "app",
|
||||
"title": "Research Gallery — Big Picture + every research map (app-shell)",
|
||||
"title": "Deep Research — Big Picture + every research map (app-shell)",
|
||||
"apiBaseUrl": "",
|
||||
"props": {
|
||||
"profile": "doxa-maps-spa",
|
||||
"provider": "maplibre",
|
||||
"instanceId": "doxa-maps-spa-app",
|
||||
"title": "Research Gallery"
|
||||
"title": "Deep Research"
|
||||
},
|
||||
"element": "doxa-maps-spa",
|
||||
"iframeUrl": "./doxa-maps-spa/doxa-maps-spa/app/index.html",
|
||||
|
|
@ -880,7 +880,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M",
|
||||
"integrity": "sha384-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -903,7 +903,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -919,8 +919,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -936,8 +936,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg\" 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>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1126,7 +1126,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6",
|
||||
"integrity": "sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1149,8 +1149,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" 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<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" 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<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1166,7 +1166,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1182,8 +1182,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" 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<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" 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<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -61,7 +61,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -81,7 +81,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-ciOPngKJlqQPWUMvMl/ZH8vg0XJXKGnKsFRo4z6pzhSdFFCzkVqA1LgKYGuN/Y3M" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-tq7SWn561xOpMPNO5YJ0Rg7UY2rFAmgxAQydqd7PXipT5FXNBdHVLlaYOKAOeitg" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-+u2vDSnYni3VeNKSYdNWfw5bjKtriFjik/k10lugA0nw6Ozfi/vKUYp3a9sbMAp6" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-YNNxkm78b9Z8oKetaufWw+ajPKAEqk89gSrY5imw8fbVMMAyVvg6hU+9E+osig8s" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue