Update from source 46b1e857b
This commit is contained in:
parent
079266367c
commit
d9548e5959
37 changed files with 326 additions and 181 deletions
|
|
@ -705,6 +705,8 @@ The studio is a plugin like any other: `plugin-designs/plugin-studio/plugin-stud
|
||||||
their browser within seconds, with no rebuild. Add OIDC settings and it puts a "Sign in with *your
|
their browser within seconds, with no rebuild. Add OIDC settings and it puts a "Sign in with *your
|
||||||
provider*" page in front of everything, open only to the groups you allow. Recipe and settings:
|
provider*" page in front of everything, open only to the groups you allow. Recipe and settings:
|
||||||
[deployment/cloud/](./deployment/cloud/README.md).
|
[deployment/cloud/](./deployment/cloud/README.md).
|
||||||
|
Working from your own laptop alongside the team (following the shared branch, the team's PocketBase):
|
||||||
|
[documentation/HOWTO-join-the-table.md](./documentation/HOWTO-join-the-table.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ async function proxy(req, url, prefix, port) {
|
||||||
Bun.serve({
|
Bun.serve({
|
||||||
hostname: '127.0.0.1',
|
hostname: '127.0.0.1',
|
||||||
port: 5175,
|
port: 5175,
|
||||||
|
// No idle cut-off: PocketBase's realtime stream (/pb/api/realtime) sits quiet while someone signs in in the
|
||||||
|
// popup, and Bun's default (10 s) closed it before the sign-in result could arrive.
|
||||||
|
idleTimeout: 0,
|
||||||
async fetch(req) {
|
async fetch(req) {
|
||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const p = url.pathname
|
const p = url.pathname
|
||||||
|
|
|
||||||
|
|
@ -113,12 +113,12 @@ So it cannot surprise you mid-thought. You can also check that any time at `/api
|
||||||
|
|
||||||
## The database, and the one thing that surprises people
|
## The database, and the one thing that surprises people
|
||||||
|
|
||||||
There are three databases and you only ever touch one.
|
There are three databases. You work against one of the first two — never the third.
|
||||||
|
|
||||||
| Where | What is in it | Who touches it |
|
| Where | What is in it | Who touches it |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Your laptop | your own sandbox data | you, freely |
|
| Your laptop | your own sandbox data | you, freely |
|
||||||
| The shared dev server | the team's shared test data | the team |
|
| The team's shared one | the team's shared test data | the team — this is usually the default |
|
||||||
| Production | what the public sees | nobody directly |
|
| Production | what the public sees | nobody directly |
|
||||||
|
|
||||||
**You never publish a database.** Not yours, not anyone's. What travels is the *shape* — the tables and
|
**You never publish a database.** Not yours, not anyone's. What travels is the *shape* — the tables and
|
||||||
|
|
@ -132,12 +132,26 @@ This is deliberate. A database rule that opens something to the public arrives a
|
||||||
read** rather than as a setting somebody clicked at midnight. If you have ever inherited a system where the
|
read** rather than as a setting somebody clicked at midnight. If you have ever inherited a system where the
|
||||||
live config did not match the repo, you already know why.
|
live config did not match the repo, you already know why.
|
||||||
|
|
||||||
**You do not have to set up the database at all.** The first time you run `bun run dev` it downloads and
|
### Which one your laptop talks to
|
||||||
starts one for you, on your laptop, with its data in `.pb/`. You can open its admin screen from the dev
|
|
||||||
server at `/api/pb/_/`.
|
|
||||||
|
|
||||||
The only time you touch this is if the log says port 8090 is already in use — then set `DX_PB_PORT` to
|
Most teams point every laptop at the **shared** one, so you are all working against the same test data.
|
||||||
something else in `.env.local`.
|
Put this in `.env.local`:
|
||||||
|
|
||||||
|
```
|
||||||
|
DX_PB_URL=https://<your team's dev server>/pb
|
||||||
|
```
|
||||||
|
|
||||||
|
You sign in with the same team account you use for everything else — there is no separate password. Ask
|
||||||
|
whoever set up your team for the address if you do not have it.
|
||||||
|
|
||||||
|
**Leave it unset and you get a private one instead.** The first time you run `bun run dev` it downloads and
|
||||||
|
starts a database on your laptop, with its data in `.pb/`, and you can open its admin screen at
|
||||||
|
`/api/pb/_/`. That is the fallback, and it is a fine way to work while you are finding your feet.
|
||||||
|
|
||||||
|
The only other thing here is `DX_PB_PORT`, which you set only if the log says port 8090 is already in use.
|
||||||
|
|
||||||
|
> **New collections start locked.** Your plugin's data is not readable until a migration opens it —
|
||||||
|
> deliberately, so nothing is public by accident. That migration is a commit like any other.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
98
internal/_composed-tiers.mjs
Normal file
98
internal/_composed-tiers.mjs
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* _composed-tiers.mjs — the ONE place the composition tier is derived from `composes` edges.
|
||||||
|
*
|
||||||
|
* Shared on purpose. The generator WRITES this tier into the manifest and check-capability-derived
|
||||||
|
* CHECKS it, and for a while each held its own copy of the rule. A rule with three ref vocabularies
|
||||||
|
* and a self-exclusion will not stay identical in two files, and the drift has a specific shape: a
|
||||||
|
* gate that passes a manifest the generator would refuse to write. One implementation, two callers.
|
||||||
|
*
|
||||||
|
* What stays independent is the DATA, which is the half worth duplicating: the generator derives from
|
||||||
|
* the profiles it is about to emit, the gate rebuilds the same edges from the <profile>.meta.json files
|
||||||
|
* on disk and feeds them to this function against the PUBLISHED manifest. So a manifest that no longer
|
||||||
|
* matches its own sources still fails, while the rule itself cannot fork.
|
||||||
|
*
|
||||||
|
* Imports nothing — pure over the bundle rows, which is what makes it testable from either side.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive the composition tier from the `composes` edges, and refuse to disagree with an author.
|
||||||
|
*
|
||||||
|
* ★ WHY DERIVE AT ALL (the agent, 2026-09-27). Tiers 3-5 were AUTHORED ONLY — discover.mjs infers just
|
||||||
|
* `single` and `parameterized`, so a composite with no meta.json shipped as capability 1. That is not
|
||||||
|
* hypothetical: research-dashboard did exactly that while nesting ten views, and the warning in
|
||||||
|
* detectProfileType exists because of it. A missing file is indistinguishable from a deliberate choice.
|
||||||
|
*
|
||||||
|
* THE RULE, measured against all 25 bundles before it was written: a profile that composes anything is
|
||||||
|
* cap-4 (nested-elements-mfe); if any of the things it composes is itself cap-4, it is cap-5
|
||||||
|
* (nested-mfe-spa). Keyed per PROFILE, and refs are accepted in BOTH published forms — 'bundle/profile'
|
||||||
|
* (doxa-maps-spa) and a bare 'bundle' (plugin-studio). Getting either of those wrong is not academic:
|
||||||
|
* keying on the bundle derived 11 false tiers, and resolving only the slashed form demoted plugin-studio
|
||||||
|
* from 5 to 4. With both handled: 10 composing profiles, 10 agree, 0 disagree.
|
||||||
|
*
|
||||||
|
* AN EXPLICIT type STAYS AUTHORITATIVE AND MUST AGREE. It is not overridden — it is CHECKED. A
|
||||||
|
* declaration that contradicts the structure is the interesting case: either the meta is stale or the
|
||||||
|
* composes list is, and both are worth a loud build failure rather than a silent pick between them.
|
||||||
|
*
|
||||||
|
* An UNRESOLVED ref is reported separately and never silently treated as "not cap-4", because a typo in
|
||||||
|
* composes and a genuinely non-composite child look identical from here.
|
||||||
|
*/
|
||||||
|
export function deriveComposedTiers(bundles) {
|
||||||
|
const TIER = { 'nested-mfe-spa': 5, 'nested-elements-mfe': 4, monolithic: 3, parameterized: 2, single: 1 }
|
||||||
|
const byKey = new Map(), byName = new Map(), byElement = new Map()
|
||||||
|
const reg = (m, k, bundle, type) => { if (!m.has(k)) m.set(k, []); m.get(k).push([bundle, type || null]) }
|
||||||
|
for (const b of bundles) {
|
||||||
|
for (const p of b.profiles || []) {
|
||||||
|
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
|
||||||
|
reg(byName, b.bundle, b.bundle, p.type)
|
||||||
|
reg(byName, p.profile, b.bundle, p.type)
|
||||||
|
if (p.element) reg(byElement, p.element, b.bundle, p.type)
|
||||||
|
}
|
||||||
|
for (const e of b.elements || []) reg(byElement, e, b.bundle, null)
|
||||||
|
}
|
||||||
|
// A name that covers SEVERAL profiles resolves to the HIGHEST tier among them, and both non-slashed
|
||||||
|
// vocabularies resolve the same way. They have to: a bare bundle name and that bundle's element tag
|
||||||
|
// both mean "this bundle", so taking the first profile for one and the highest for the other made
|
||||||
|
// the answer depend on discovery order. gospel-resources is the case that shows it — four `single`
|
||||||
|
// leaves and one cap-4 composite in one bundle, so "first" is a coin flip between 1 and 4, and
|
||||||
|
// losing the 4 silently demotes whoever composes it. Highest is also the truthful reading of a
|
||||||
|
// whole-bundle ref: nesting a bundle nests the most composed thing in it.
|
||||||
|
const best = (rows, selfBundle) => {
|
||||||
|
const others = rows.filter(([b, t]) => b !== selfBundle && t)
|
||||||
|
if (!others.length) return null
|
||||||
|
return others.sort((a, z) => (TIER[z[1]] || 0) - (TIER[a[1]] || 0))[0][1]
|
||||||
|
}
|
||||||
|
// ★ `composes` SPEAKS THREE VOCABULARIES, and only knowing two of them invents defects.
|
||||||
|
// Measured on the tree: 'bundle/profile' (doxa-maps-spa), a bare 'bundle' (plugin-studio's first four
|
||||||
|
// entries) and an ELEMENT TAG (its last three, plus big-picture and stack-demo). Resolving only the
|
||||||
|
// first two left FIVE refs "unresolved" and reported as possible typos — they were all element tags,
|
||||||
|
// written correctly by their authors. The data was right and the resolver was short.
|
||||||
|
//
|
||||||
|
// ★ AND A SELF-REFERENCE IS AN INTERNAL CHILD, NOT A NESTED PLUGIN. big-picture composes
|
||||||
|
// 'bp-research-header', which is its OWN element (src/components/BpResearchHeader.vue). Resolving that
|
||||||
|
// to the bundle registering it — itself, cap-4 — made big-picture look like it composes a cap-4 and
|
||||||
|
// promoted it to cap-5. Excluding self is what keeps "nests other plugins" from meaning "has parts".
|
||||||
|
const UNRESOLVED = Symbol('unresolved')
|
||||||
|
const resolve = (ref, selfBundle) => {
|
||||||
|
if (ref.includes('/')) {
|
||||||
|
if (!byKey.has(ref)) return UNRESOLVED
|
||||||
|
return ref.split('/')[0] === selfBundle ? null : byKey.get(ref)
|
||||||
|
}
|
||||||
|
if (byName.has(ref)) return best(byName.get(ref), selfBundle)
|
||||||
|
if (byElement.has(ref)) return best(byElement.get(ref), selfBundle)
|
||||||
|
return UNRESOLVED
|
||||||
|
}
|
||||||
|
const conflicts = [], unresolved = []
|
||||||
|
for (const b of bundles) for (const p of b.profiles || []) {
|
||||||
|
const own = p.composesOwn
|
||||||
|
if (!own || !own.length) continue
|
||||||
|
const kinds = own.map((ref) => {
|
||||||
|
const k = resolve(ref, b.bundle)
|
||||||
|
if (k === UNRESOLVED) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`)
|
||||||
|
return k
|
||||||
|
})
|
||||||
|
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
|
||||||
|
if (!p.type) { p.type = derived; continue }
|
||||||
|
if (p.type !== derived) conflicts.push(`${b.bundle}/${p.profile}: declared tier "${p.type}" disagrees with the "${derived}" its composes edges derive`)
|
||||||
|
}
|
||||||
|
return { conflicts, unresolved }
|
||||||
|
}
|
||||||
|
|
@ -21,12 +21,15 @@
|
||||||
* - `composes` is PER-PROFILE at source and HOISTED TO THE BUNDLE in the manifest. Deriving from
|
* - `composes` is PER-PROFILE at source and HOISTED TO THE BUNDLE in the manifest. Deriving from
|
||||||
* the bundle row applies a composite's edges to its plain sibling leaves: gospel-resources has one
|
* the bundle row applies a composite's edges to its plain sibling leaves: gospel-resources has one
|
||||||
* composite and four single leaves, and all four derived as cap-4. 11 false failures.
|
* composite and four single leaves, and all four derived as cap-4. 11 false failures.
|
||||||
* - refs appear in TWO FORMS in the same field: 'bundle/profile' and a bare 'bundle'. Resolving
|
* - refs appear in THREE FORMS in the same field: 'bundle/profile', a bare 'bundle', and an ELEMENT
|
||||||
* only the first demoted plugin-studio from 5 to 4.
|
* TAG. Resolving only the first demoted plugin-studio from 5 to 4; not knowing the third left five
|
||||||
|
* refs "unresolved" and reported as possible typos when all five were correct.
|
||||||
* With both handled: 10 composing profiles, 10 agree, 0 disagree, on the tree as it stands.
|
* With both handled: 10 composing profiles, 10 agree, 0 disagree, on the tree as it stands.
|
||||||
*
|
*
|
||||||
* An UNRESOLVED ref is REPORTED, never counted as "not cap-4": a typo and a genuine non-composite
|
* An UNRESOLVED ref now FAILS. It was only ever REPORTED because five were outstanding and they turned
|
||||||
* child look identical from here, and quietly treating one as the other is how a tier silently drops.
|
* out to be correct data this gate could not read — failing then would have blamed five authors for a
|
||||||
|
* gap here. At zero, the reasoning inverts: a typo and a genuine non-composite child still look
|
||||||
|
* identical from here, so the one thing that must not happen is quietly reading one as the other.
|
||||||
*
|
*
|
||||||
* Headless, no browser. Exit 0 pass · 1 fail.
|
* Headless, no browser. Exit 0 pass · 1 fail.
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,6 +37,7 @@ import { readFileSync, existsSync } from 'node:fs'
|
||||||
import { resolve, dirname, join } from 'node:path'
|
import { resolve, dirname, join } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import { TREE_NAME } from './_tree-name.mjs'
|
import { TREE_NAME } from './_tree-name.mjs'
|
||||||
|
import { deriveComposedTiers } from './_composed-tiers.mjs'
|
||||||
|
|
||||||
const TAG = 'CAPABILITY-DERIVED'
|
const TAG = 'CAPABILITY-DERIVED'
|
||||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
@ -54,36 +58,31 @@ for (const b of bundles) for (const p of b.profiles || []) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 2. a declared tier must agree with the edges it declares ────────────────────────────────────
|
// ── 2. a declared tier must agree with the edges it declares ────────────────────────────────────
|
||||||
|
// Uses the SHARED resolver (internal/_composed-tiers.mjs) rather than a second copy. Two implementations of a rule this
|
||||||
|
// fiddly — three ref vocabularies and a self-exclusion — would drift, and the drift would show up as a
|
||||||
|
// gate that passes a manifest the generator would refuse to write. What stays independent is the DATA:
|
||||||
|
// the gate rebuilds composesOwn from the <profile>.meta.json files on disk and checks the PUBLISHED
|
||||||
|
// manifest against them, so a manifest that no longer matches its own sources still fails.
|
||||||
const readMeta = (bundle, profile) => {
|
const readMeta = (bundle, profile) => {
|
||||||
const f = join(ROOT, 'plugin-designs', bundle, `${profile}.meta.json`)
|
const f = join(ROOT, 'plugin-designs', bundle, `${profile}.meta.json`)
|
||||||
try { return existsSync(f) ? JSON.parse(readFileSync(f, 'utf8')) : null } catch { return null }
|
try { return existsSync(f) ? JSON.parse(readFileSync(f, 'utf8')) : null } catch { return null }
|
||||||
}
|
}
|
||||||
const byKey = new Map(), byName = new Map()
|
|
||||||
for (const b of bundles) for (const p of b.profiles || []) {
|
|
||||||
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
|
|
||||||
if (!byName.has(b.bundle)) byName.set(b.bundle, p.type || null)
|
|
||||||
if (!byName.has(p.profile)) byName.set(p.profile, p.type || null)
|
|
||||||
}
|
|
||||||
const resolveRef = (ref) => (ref.includes('/') ? byKey.get(ref) : byName.get(ref))
|
|
||||||
const unresolved = []
|
|
||||||
let composing = 0
|
let composing = 0
|
||||||
for (const b of bundles) for (const p of b.profiles || []) {
|
const probe = bundles.map((b) => ({
|
||||||
const meta = readMeta(b.bundle, p.profile)
|
...b,
|
||||||
const own = Array.isArray(meta?.composes) ? meta.composes.map(String).filter(Boolean) : []
|
profiles: (b.profiles || []).map((p) => {
|
||||||
if (!own.length) continue
|
const meta = readMeta(b.bundle, p.profile)
|
||||||
composing++
|
const own = Array.isArray(meta?.composes) ? meta.composes.map(String).filter(Boolean) : []
|
||||||
const kinds = own.map((ref) => { const k = resolveRef(ref); if (k === undefined) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`); return k })
|
if (own.length) composing++
|
||||||
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
|
return { ...p, composesOwn: own.length ? own : null }
|
||||||
if (p.type !== derived) {
|
}),
|
||||||
fails.push(`${b.bundle}/${p.profile}: declares "${p.type}" but its own composes edges derive "${derived}" — one of the two is stale.`)
|
}))
|
||||||
}
|
const { conflicts, unresolved } = deriveComposedTiers(probe)
|
||||||
}
|
for (const c of conflicts) fails.push(`${c} — the meta.json or the composes list is stale.`)
|
||||||
|
for (const u of unresolved) fails.push(`${u}: composes ref resolves to nothing. A ref may be "<bundle>/<profile>", a bare "<bundle>", or a registered element tag.`)
|
||||||
|
|
||||||
console.log(` · ${checked} profile(s) across ${bundles.length} bundle(s); ${composing} declare composes edges`)
|
console.log(` · ${checked} profile(s) across ${bundles.length} bundle(s); ${composing} declare composes edges`)
|
||||||
if (unresolved.length) {
|
|
||||||
console.log(` · ${unresolved.length} composes ref(s) resolve to no known bundle/profile. Reported, NOT treated as "not a composite" — a typo and a plain child look the same from here:`)
|
|
||||||
for (const u of unresolved) console.log(` ${u}`)
|
|
||||||
}
|
|
||||||
if (fails.length) {
|
if (fails.length) {
|
||||||
console.error(`\n${TAG}: FAIL`)
|
console.error(`\n${TAG}: FAIL`)
|
||||||
for (const f of fails) console.error(` ✗ ${f}`)
|
for (const f of fails) console.error(` ✗ ${f}`)
|
||||||
|
|
|
||||||
32
internal/check-no-repo-pb-hooks.mjs
Normal file
32
internal/check-no-repo-pb-hooks.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* check-no-repo-pb-hooks.mjs — no PocketBase hooks (pb_hooks, *.pb.js) may live in the repo.
|
||||||
|
*
|
||||||
|
* WHY: the cloud container pulls this repo every few seconds. A PocketBase hook is server-side JS; one pushed
|
||||||
|
* by any plugin writer would run on the team backend within seconds, which is the rogue-writer hole the
|
||||||
|
* roundtable test closed. The container never points PocketBase at the repo (--hooksDir is outside the
|
||||||
|
* pulled tree; the one team sign-in hook is baked into the image and pinned, deployment/cloud/Dockerfile).
|
||||||
|
* This gate keeps anyone from adding a hooks folder that LOOKS like it would run, or that a later recipe
|
||||||
|
* change could start running.
|
||||||
|
*
|
||||||
|
* HOW: every tracked path; a self-test on every run (a poisoned list must fail), so the gate cannot go blind.
|
||||||
|
*/
|
||||||
|
import { execFileSync } from 'node:child_process'
|
||||||
|
import { join, dirname } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const ROOT = process.env.DOXA_REPO || join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
|
|
||||||
|
export const offending = (paths) => paths.filter((p) => /(^|\/)pb_hooks(\/|$)/.test(p) || /\.pb\.(js|ts)$/.test(p))
|
||||||
|
|
||||||
|
if (offending(['README.md', 'backend/pocketbase/pb_hooks/x.pb.js', 'a/b.pb.ts']).length !== 2) {
|
||||||
|
console.error('✗ check:no-repo-pb-hooks self-test failed: the matcher went blind'); process.exit(1)
|
||||||
|
}
|
||||||
|
const tracked = execFileSync('git', ['ls-files', '-z'], { cwd: ROOT }).toString().split('\0').filter(Boolean)
|
||||||
|
const bad = offending(tracked)
|
||||||
|
if (bad.length) {
|
||||||
|
console.error(`✗ PocketBase hooks in the repo (server-side JS must never ride the live pull):\n${bad.map((p) => ' ' + p).join('\n')}`)
|
||||||
|
console.error(' The team sign-in hook is baked into the image (deployment/cloud/Dockerfile); anything else needs a design review.')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
console.log(`✓ no PocketBase hooks among ${tracked.length} tracked files`)
|
||||||
|
|
@ -57,6 +57,16 @@ const BUNDLES = [
|
||||||
'upg-neighbor', 'wall-of-people-groups', 'key-cities', 'gospel-internet',
|
'upg-neighbor', 'wall-of-people-groups', 'key-cities', 'gospel-internet',
|
||||||
]
|
]
|
||||||
const ALLOW = {
|
const ALLOW = {
|
||||||
|
'*:LOC-ENUS:library/utils/formatCount.js':
|
||||||
|
'HELD DECISION, and this file IS the decision: formatCount() is the one place the count locale is '
|
||||||
|
+ 'chosen, so COUNT_LOCALE = \'en-US\' is the policy written down rather than a bundle ignoring the '
|
||||||
|
+ 'reader. NUMERALS ARE HELD -- counts do not follow the locale -- and folding every dashboard onto '
|
||||||
|
+ 'this constant is what makes that auditable in one line instead of scattered across eight call '
|
||||||
|
+ 'sites. Bundle-wildcarded ON PURPOSE: the alternative is one entry per importer, so the LOCALE '
|
||||||
|
+ 'column warns every time a bundle adopts the shared helper -- punishing the fix and teaching '
|
||||||
|
+ 'people to stop reading the column. Restricted to library/ (see the lookup): no per-bundle source '
|
||||||
|
+ 'can be wildcarded, and a new toLocaleString(\'en-US\') inside research-dashboard or '
|
||||||
|
+ 'people-groups-grid still warns. Revisit only if the agent unholds numerals.',
|
||||||
'prayer-walk-planner:ENG-PIN': 'keyless by design: always MapLibre, needs no token (index.js header)',
|
'prayer-walk-planner:ENG-PIN': 'keyless by design: always MapLibre, needs no token (index.js header)',
|
||||||
'regions-dashboard:LOC-ENUS:plugin-designs/regions-dashboard/src/RegionCountryMap.vue':
|
'regions-dashboard:LOC-ENUS:plugin-designs/regions-dashboard/src/RegionCountryMap.vue':
|
||||||
'HELD DECISION, not an oversight: the map popup formats population as fixed en-US on purpose. '
|
'HELD DECISION, not an oversight: the map popup formats population as fixed en-US on purpose. '
|
||||||
|
|
@ -175,6 +185,15 @@ if (locWrong.length) {
|
||||||
+ locWrong.map(([f, l]) => `${f ? 'missed' : 'false-flagged'}: ${l.slice(0, 56)}`).join(' | '))
|
+ locWrong.map(([f, l]) => `${f ? 'missed' : 'false-flagged'}: ${l.slice(0, 56)}`).join(' | '))
|
||||||
process.exit(3)
|
process.exit(3)
|
||||||
}
|
}
|
||||||
|
// The bundle-wildcard is honoured ONLY under library/. Pinned because the failure is silent: widen it
|
||||||
|
// to any path and one entry could clear the column for a bundle's own source.
|
||||||
|
const wildcardKeys = Object.keys(ALLOW).filter((k) => k.startsWith('*:'))
|
||||||
|
const badWildcard = wildcardKeys.filter((k) => !k.split(':').slice(2).join(':').startsWith('library/'))
|
||||||
|
if (badWildcard.length) {
|
||||||
|
console.error('UNIVERSAL-PROPS: SELF-TEST FAILED — a `*:RULE:file` ALLOW entry outside library/ would '
|
||||||
|
+ 'never be honoured by the lookup, so it silently exempts nothing: ' + badWildcard.join(', '))
|
||||||
|
process.exit(3)
|
||||||
|
}
|
||||||
if (missed.length || falsePos.length) {
|
if (missed.length || falsePos.length) {
|
||||||
console.error(`UNIVERSAL-PROPS: SELF-TEST FAILED — ${missed.length ? 'rules blind to a planted bypass: ' + missed.join(', ') : ''}${falsePos.length ? ' false positives on clean code: ' + falsePos.join(', ') : ''}`)
|
console.error(`UNIVERSAL-PROPS: SELF-TEST FAILED — ${missed.length ? 'rules blind to a planted bypass: ' + missed.join(', ') : ''}${falsePos.length ? ' false positives on clean code: ' + falsePos.join(', ') : ''}`)
|
||||||
process.exit(3)
|
process.exit(3)
|
||||||
|
|
@ -251,7 +270,16 @@ for (const b of BUNDLES.filter((x) => !ONLY || ONLY.includes(x))) {
|
||||||
// silenced any FUTURE operative en-US anywhere in that bundle -- clearing a column by going
|
// silenced any FUTURE operative en-US anywhere in that bundle -- clearing a column by going
|
||||||
// blind. A `bundle:RULE:file` key exempts the one file that earned it and leaves the rest of the
|
// blind. A `bundle:RULE:file` key exempts the one file that earned it and leaves the rest of the
|
||||||
// bundle answerable.
|
// bundle answerable.
|
||||||
const allowed = ALLOW[`${b}:${r.id}:${relative(ROOT, f)}`] || ALLOW[`${b}:${r.id}`]
|
// ★ AND A SHARED LIBRARY FILE CAN BE ALLOWED FOR EVERY BUNDLE THAT IMPORTS IT. A `*:RULE:file`
|
||||||
|
// key is honoured only for a path under library/, because that is the one case where the site is
|
||||||
|
// not the bundle's: library/utils/formatCount.js holds the HELD numerals decision for eight call
|
||||||
|
// sites, and it is attributed to every bundle that compiles it. Per-importer entries would mean
|
||||||
|
// the LOCALE column warns each time a bundle adopts the shared helper -- the column punishing the
|
||||||
|
// fold that made the policy auditable. The library/ restriction is the whole guard: a bundle's own
|
||||||
|
// source can never be wildcarded, so this cannot be used to clear a column broadly.
|
||||||
|
const rel = relative(ROOT, f).replace(/\\/g, '/')
|
||||||
|
const allowed = ALLOW[`${b}:${r.id}:${rel}`] || ALLOW[`${b}:${r.id}`]
|
||||||
|
|| (rel.startsWith('library/') ? ALLOW[`*:${r.id}:${rel}`] : undefined)
|
||||||
if (allowed) { if (matrix[b][r.prop] === 'ok') matrix[b][r.prop] = 'allowed'; continue }
|
if (allowed) { if (matrix[b][r.prop] === 'ok') matrix[b][r.prop] = 'allowed'; continue }
|
||||||
findings.push({ b, rule: r.id, prop: r.prop, warn: !!r.warn, where: `${relative(ROOT, f)}:${lineOf(src, idx)}`, text: src.slice(idx, idx + 70).replace(/\s+/g, ' ').trim() })
|
findings.push({ b, rule: r.id, prop: r.prop, warn: !!r.warn, where: `${relative(ROOT, f)}:${lineOf(src, idx)}`, text: src.slice(idx, idx + 70).replace(/\s+/g, ' ').trim() })
|
||||||
matrix[b][r.prop] = r.warn ? (matrix[b][r.prop] === 'BYPASS' ? 'BYPASS' : 'warn') : 'BYPASS'
|
matrix[b][r.prop] = r.warn ? (matrix[b][r.prop] === 'BYPASS' ? 'BYPASS' : 'warn') : 'BYPASS'
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ import { createHash } from 'node:crypto'
|
||||||
import { detectProfileType } from './plugin-gallery/discover.mjs'
|
import { detectProfileType } from './plugin-gallery/discover.mjs'
|
||||||
import { profileMetaFields, bundleStage } from './profile-meta.mjs'
|
import { profileMetaFields, bundleStage } from './profile-meta.mjs'
|
||||||
import { TREE_NAME as CONFIGURED_TREE_NAME } from './_tree-name.mjs'
|
import { TREE_NAME as CONFIGURED_TREE_NAME } from './_tree-name.mjs'
|
||||||
|
import { deriveComposedTiers } from './_composed-tiers.mjs'
|
||||||
import { syncAppShells } from './sync-app-shells.mjs'
|
import { syncAppShells } from './sync-app-shells.mjs'
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
@ -396,48 +397,6 @@ function composesAMapLeaf(dir, profileName, file) {
|
||||||
* composesAMapLeaf reads (see its point 1) but returns the author's data itself rather than
|
* composesAMapLeaf reads (see its point 1) but returns the author's data itself rather than
|
||||||
* a map-ness boolean derived from it — the manifest needs the edges, not just the verdict.
|
* a map-ness boolean derived from it — the manifest needs the edges, not just the verdict.
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* Derive the composition tier from the `composes` edges, and refuse to disagree with an author.
|
|
||||||
*
|
|
||||||
* ★ WHY DERIVE AT ALL (the agent, 2026-09-27). Tiers 3-5 were AUTHORED ONLY — discover.mjs infers just
|
|
||||||
* `single` and `parameterized`, so a composite with no meta.json shipped as capability 1. That is not
|
|
||||||
* hypothetical: research-dashboard did exactly that while nesting ten views, and the warning in
|
|
||||||
* detectProfileType exists because of it. A missing file is indistinguishable from a deliberate choice.
|
|
||||||
*
|
|
||||||
* THE RULE, measured against all 25 bundles before it was written: a profile that composes anything is
|
|
||||||
* cap-4 (nested-elements-mfe); if any of the things it composes is itself cap-4, it is cap-5
|
|
||||||
* (nested-mfe-spa). Keyed per PROFILE, and refs are accepted in BOTH published forms — 'bundle/profile'
|
|
||||||
* (doxa-maps-spa) and a bare 'bundle' (plugin-studio). Getting either of those wrong is not academic:
|
|
||||||
* keying on the bundle derived 11 false tiers, and resolving only the slashed form demoted plugin-studio
|
|
||||||
* from 5 to 4. With both handled: 10 composing profiles, 10 agree, 0 disagree.
|
|
||||||
*
|
|
||||||
* AN EXPLICIT type STAYS AUTHORITATIVE AND MUST AGREE. It is not overridden — it is CHECKED. A
|
|
||||||
* declaration that contradicts the structure is the interesting case: either the meta is stale or the
|
|
||||||
* composes list is, and both are worth a loud build failure rather than a silent pick between them.
|
|
||||||
*
|
|
||||||
* An UNRESOLVED ref is reported separately and never silently treated as "not cap-4", because a typo in
|
|
||||||
* composes and a genuinely non-composite child look identical from here.
|
|
||||||
*/
|
|
||||||
export function deriveComposedTiers(bundles) {
|
|
||||||
const byKey = new Map(), byBundle = new Map()
|
|
||||||
for (const b of bundles) for (const p of b.profiles || []) {
|
|
||||||
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
|
|
||||||
if (!byBundle.has(b.bundle)) byBundle.set(b.bundle, p.type || null)
|
|
||||||
if (!byBundle.has(p.profile)) byBundle.set(p.profile, p.type || null)
|
|
||||||
}
|
|
||||||
const resolve = (ref) => (ref.includes('/') ? byKey.get(ref) : byBundle.get(ref))
|
|
||||||
const conflicts = [], unresolved = []
|
|
||||||
for (const b of bundles) for (const p of b.profiles || []) {
|
|
||||||
const own = p.composesOwn
|
|
||||||
if (!own || !own.length) continue
|
|
||||||
const kinds = own.map((ref) => { const k = resolve(ref); if (k === undefined) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`); return k })
|
|
||||||
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
|
|
||||||
if (!p.type) { p.type = derived; continue }
|
|
||||||
if (p.type !== derived) conflicts.push(`${b.bundle}/${p.profile}: meta.json declares "${p.type}" but its composes edges derive "${derived}"`)
|
|
||||||
}
|
|
||||||
return { conflicts, unresolved }
|
|
||||||
}
|
|
||||||
|
|
||||||
function readComposes(dir, profileName) {
|
function readComposes(dir, profileName) {
|
||||||
try {
|
try {
|
||||||
const metaPath = join(dir, `${profileName}.meta.json`)
|
const metaPath = join(dir, `${profileName}.meta.json`)
|
||||||
|
|
@ -1415,9 +1374,15 @@ function writeManifestAndHtml(root, bundles, tokenUrlExpr, bakedToken) {
|
||||||
// author forgot a meta.json, and a stale meta can no longer disagree with the structure in silence.
|
// author forgot a meta.json, and a stale meta can no longer disagree with the structure in silence.
|
||||||
{
|
{
|
||||||
const { conflicts, unresolved } = deriveComposedTiers(bundles)
|
const { conflicts, unresolved } = deriveComposedTiers(bundles)
|
||||||
|
// FAILS rather than warns, now that the resolver understands all three vocabularies and the tree has
|
||||||
|
// ZERO unresolved refs. While five were outstanding a warning was right — they turned out to be
|
||||||
|
// correct data my resolver could not read, and failing would have blamed five authors for my gap.
|
||||||
|
// With the count at 0, a new unresolved ref is a genuinely broken edge and silently weakens a tier.
|
||||||
if (unresolved.length) {
|
if (unresolved.length) {
|
||||||
console.warn(`[tree] ${unresolved.length} composes ref(s) resolve to no known bundle/profile — a typo here silently weakens a tier:`)
|
console.error(`[tree] ${unresolved.length} composes ref(s) resolve to nothing — a broken edge silently weakens a tier:`)
|
||||||
for (const u of unresolved) console.warn(` ${u}`)
|
for (const u of unresolved) console.error(` ${u}`)
|
||||||
|
console.error(' A ref may be "<bundle>/<profile>", a bare "<bundle>", or a registered element tag.')
|
||||||
|
process.exit(1)
|
||||||
}
|
}
|
||||||
if (conflicts.length) {
|
if (conflicts.length) {
|
||||||
console.error('[tree] composition tier CONFLICT — a profile\'s meta.json disagrees with its own composes edges:')
|
console.error('[tree] composition tier CONFLICT — a profile\'s meta.json disagrees with its own composes edges:')
|
||||||
|
|
|
||||||
|
|
@ -352,14 +352,14 @@ const VTL_SHADOW_CSS = `
|
||||||
.vtl-chev svg { width:15px; height:15px; }
|
.vtl-chev svg { width:15px; height:15px; }
|
||||||
.vtl-chev.open { transform:rotate(90deg); }
|
.vtl-chev.open { transform:rotate(90deg); }
|
||||||
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
||||||
/* MATERIAL NAV-ROW METRICS (2026-09-21). the agent: "people are used to the YouTube layout, Google
|
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
|
||||||
layout is just way better. We do not need to create custom styles people are not used to."
|
Material/YouTube list layout rather than custom styling readers are not used to.
|
||||||
Measured before this change: 44px rows with an 8px radius.
|
Measured before this change: 44px rows with an 8px radius.
|
||||||
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
||||||
label still grows instead of clipping.
|
label still grows instead of clipping.
|
||||||
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
||||||
The 999px stadium above was a real instruction ("imitate the YouTube
|
The 999px stadium above was a real instruction ("imitate the YouTube
|
||||||
active row") and it shipped. The agent then measured it against the
|
active row") and it shipped. It was then measured against the
|
||||||
rest of the product and reversed it: "the roundedness of the tabs is a
|
rest of the product and reversed it: "the roundedness of the tabs is a
|
||||||
little bit too round because there is nowhere else in the app that has
|
little bit too round because there is nowhere else in the app that has
|
||||||
that same roundedness. Even the collapse button is not that round...
|
that same roundedness. Even the collapse button is not that round...
|
||||||
|
|
@ -841,14 +841,14 @@ export default defineComponent({
|
||||||
.vtl-chev svg { width:15px; height:15px; }
|
.vtl-chev svg { width:15px; height:15px; }
|
||||||
.vtl-chev.open { transform:rotate(90deg); }
|
.vtl-chev.open { transform:rotate(90deg); }
|
||||||
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
||||||
/* MATERIAL NAV-ROW METRICS (2026-09-21). the agent: "people are used to the YouTube layout, Google
|
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
|
||||||
layout is just way better. We do not need to create custom styles people are not used to."
|
Material/YouTube list layout rather than custom styling readers are not used to.
|
||||||
Measured before this change: 44px rows with an 8px radius.
|
Measured before this change: 44px rows with an 8px radius.
|
||||||
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
||||||
label still grows instead of clipping.
|
label still grows instead of clipping.
|
||||||
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
||||||
The 999px stadium above was a real instruction ("imitate the YouTube
|
The 999px stadium above was a real instruction ("imitate the YouTube
|
||||||
active row") and it shipped. The agent then measured it against the
|
active row") and it shipped. It was then measured against the
|
||||||
rest of the product and reversed it: "the roundedness of the tabs is a
|
rest of the product and reversed it: "the roundedness of the tabs is a
|
||||||
little bit too round because there is nowhere else in the app that has
|
little bit too round because there is nowhere else in the app that has
|
||||||
that same roundedness. Even the collapse button is not that round...
|
that same roundedness. Even the collapse button is not that round...
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null })
|
||||||
.pg-h1{margin:2px 0 0;font:700 40px Georgia,serif;color:#1b1a17}
|
.pg-h1{margin:2px 0 0;font:700 40px Georgia,serif;color:#1b1a17}
|
||||||
.pg-lede{margin:0 0 22px;max-width:1180px;font:400 19px/1.5 Georgia,serif;color:#413d35}
|
.pg-lede{margin:0 0 22px;max-width:1180px;font:400 19px/1.5 Georgia,serif;color:#413d35}
|
||||||
/* ⚠ THE CELLS ARE RECTANGLES, NOT SQUARES, and that is forced by the sheet rather than chosen.
|
/* ⚠ THE CELLS ARE RECTANGLES, NOT SQUARES, and that is forced by the sheet rather than chosen.
|
||||||
52 columns is fixed by the data (weeks in a year) and 100 rows by the agent's "100 year life",
|
52 columns is fixed by the data (weeks in a year) and 100 rows by the product's "100 year life" framing,
|
||||||
so both dimensions are given and only the SHAPE is free. Squares would need
|
so both dimensions are given and only the SHAPE is free. Squares would need
|
||||||
(1380/52)=26.5px per side x 100 rows = 2,654px of grid in 1,521px of printable height — it
|
(1380/52)=26.5px per side x 100 rows = 2,654px of grid in 1,521px of printable height — it
|
||||||
overflows the page by 1.7x. Caught by computing the height before rendering rather than by
|
overflows the page by 1.7x. Caught by computing the height before rendering rather than by
|
||||||
|
|
@ -169,7 +169,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null })
|
||||||
justify-content:center;font:italic 13px Georgia,serif;color:#a89f8c;text-align:center;padding:6px}
|
justify-content:center;font:italic 13px Georgia,serif;color:#a89f8c;text-align:center;padding:6px}
|
||||||
.nm{font:700 25px Georgia,serif;color:#1b1a17;line-height:1.1}
|
.nm{font:700 25px Georgia,serif;color:#1b1a17;line-height:1.1}
|
||||||
.mt{font:400 17px Georgia,serif;color:#6d766e}
|
.mt{font:400 17px Georgia,serif;color:#6d766e}
|
||||||
/* FINE PRINT — the agent: "attribution minimal, fine print small". */
|
/* FINE PRINT — product decision: attribution minimal, fine print small. */
|
||||||
.fine{position:absolute;left:0;right:0;bottom:22px;text-align:center;
|
.fine{position:absolute;left:0;right:0;bottom:22px;text-align:center;
|
||||||
font:400 13px Georgia,serif;color:#a89f8c}
|
font:400 13px Georgia,serif;color:#a89f8c}
|
||||||
/* PRINT. The sheet is authored at ${W}px wide while @page is physical, so without
|
/* PRINT. The sheet is authored at ${W}px wide while @page is physical, so without
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"purpose": "EVERY human-readable string in the UPG-100 prayer packet, in one file, so a new language is a new block here and NOT a code change. packet.mjs reads LANG (default 'en') and falls back to 'en' key-by-key, so a partial translation renders the translated keys and leaves the rest in English rather than blanking.",
|
"purpose": "EVERY human-readable string in the UPG-100 prayer packet, in one file, so a new language is a new block here and NOT a code change. packet.mjs reads LANG (default 'en') and falls back to 'en' key-by-key, so a partial translation renders the translated keys and leaves the rest in English rather than blanking.",
|
||||||
"how_to_translate": "Copy the \"en\" block, change the key to the ISO code, translate the values. Keep {placeholders} exactly as they are — they are substituted at render time. Do not translate scripture REFERENCES (book names are resolved by the reader's own Bible); DO translate the prayer text.",
|
"how_to_translate": "Copy the \"en\" block, change the key to the ISO code, translate the values. Keep {placeholders} exactly as they are — they are substituted at render time. Do not translate scripture REFERENCES (book names are resolved by the reader's own Bible); DO translate the prayer text.",
|
||||||
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:1-20, printed in full at the agent's instruction). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
|
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:1-20, printed in full by product decision). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
|
||||||
"note_on_references": "Scripture REFERENCES (Matthew 27:27, Mark 5:1-20) are deliberately left in English in every language block, so a reader can look them up in their own Bible regardless of the packet's language. ⚠ MEASURED TRADEOFF, not an oversight: on a rendered French page the English book names are visibly foreign next to fully-translated prayer text. If a language wants localised book names, add a `books` map to that block and teach the renderer to use it — do NOT translate the refs inline, because the same strings identify the passage for any future lookup.",
|
"note_on_references": "Scripture REFERENCES (Matthew 27:27, Mark 5:1-20) are deliberately left in English in every language block, so a reader can look them up in their own Bible regardless of the packet's language. ⚠ MEASURED TRADEOFF, not an oversight: on a rendered French page the English book names are visibly foreign next to fully-translated prayer text. If a language wants localised book names, add a `books` map to that block and teach the renderer to use it — do NOT translate the refs inline, because the same strings identify the passage for any future lookup.",
|
||||||
"note_on_scripts": "ALL 11 app locales now ship. Script coverage MEASURED by rendering at 48px and READING THE PIXELS: Latin, Cyrillic (ru), Arabic (ar) and CJK (zh) shape correctly with the system Georgia/Palatino/serif stack. DEVANAGARI (hi) does NOT — it renders as tofu boxes — so Noto Serif Devanagari is vendored (OFL) and base64-INLINED into hi packets by the renderer's SCRIPT_FONT map. Inlined, not linked, because a packet is a standalone file that must print offline; ~165KB on a 3.5MB packet, and only for that language. mr and ne map to the same face.\n⚠ TWO MEASUREMENTS LIED ABOUT THIS, so do not automate it cheaply: (1) comparing shaped width against a missing font reported ar and zh BROKEN and hi FINE — exactly backwards, because Devanagari tofu boxes match real glyph advance; (2) an ink-column-profile heuristic scored CORRECTLY-RENDERED Devanagari the same as tofu (3 vs 2 distinct heights), because its baseline bar gives a uniform profile. check:packet-render therefore asserts only that a DECLARED @font-face LOADED — the mechanical half — and leaves glyph correctness to a human reading a screenshot. A detector that blocks working packets is worse than none.",
|
"note_on_scripts": "ALL 11 app locales now ship. Script coverage MEASURED by rendering at 48px and READING THE PIXELS: Latin, Cyrillic (ru), Arabic (ar) and CJK (zh) shape correctly with the system Georgia/Palatino/serif stack. DEVANAGARI (hi) does NOT — it renders as tofu boxes — so Noto Serif Devanagari is vendored (OFL) and base64-INLINED into hi packets by the renderer's SCRIPT_FONT map. Inlined, not linked, because a packet is a standalone file that must print offline; ~165KB on a 3.5MB packet, and only for that language. mr and ne map to the same face.\n⚠ TWO MEASUREMENTS LIED ABOUT THIS, so do not automate it cheaply: (1) comparing shaped width against a missing font reported ar and zh BROKEN and hi FINE — exactly backwards, because Devanagari tofu boxes match real glyph advance; (2) an ink-column-profile heuristic scored CORRECTLY-RENDERED Devanagari the same as tofu (3 vs 2 distinct heights), because its baseline bar gives a uniform profile. check:packet-render therefore asserts only that a DECLARED @font-face LOADED — the mechanical half — and leaves glyph correctness to a human reading a screenshot. A detector that blocks working packets is worse than none.",
|
||||||
"note_on_rtl": "ar is right-to-left. The renderer emits dir on <html> from an RTL set (packet-render.js), and scripture REFERENCES are wrapped in dir=ltr + unicode-bidi:isolate. Without that isolation the bidi algorithm reorders a reference that STARTS WITH A DIGIT: '1 Peter 5:6-11' rendered as 'Peter 5:6-11 1'. Note the reference LIST then reads right-to-left on an RTL page (first item rightmost) — that is correct for an RTL reader, not a defect."
|
"note_on_rtl": "ar is right-to-left. The renderer emits dir on <html> from an RTL set (packet-render.js), and scripture REFERENCES are wrapped in dir=ltr + unicode-bidi:isolate. Without that isolation the bidi algorithm reorders a reference that STARTS WITH A DIGIT: '1 Peter 5:6-11' rendered as 'Peter 5:6-11 1'. Note the reference LIST then reads right-to-left on an RTL page (first item rightmost) — that is correct for an RTL reader, not a defect."
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@
|
||||||
"check:one-palette:self-test": "node internal/check-one-palette.mjs --self-test",
|
"check:one-palette:self-test": "node internal/check-one-palette.mjs --self-test",
|
||||||
"check:optional-t-equivalence": "node internal/check-optional-t-equivalence.mjs",
|
"check:optional-t-equivalence": "node internal/check-optional-t-equivalence.mjs",
|
||||||
"check:package-json-unique-keys": "node internal/check-package-json-unique-keys.mjs",
|
"check:package-json-unique-keys": "node internal/check-package-json-unique-keys.mjs",
|
||||||
|
"check:no-repo-pb-hooks": "node internal/check-no-repo-pb-hooks.mjs",
|
||||||
"check:packet-browser": "node internal/check-packet-browser.mjs",
|
"check:packet-browser": "node internal/check-packet-browser.mjs",
|
||||||
"check:packet-fixture": "node internal/generate-packet-fixture.mjs --check",
|
"check:packet-fixture": "node internal/generate-packet-fixture.mjs --check",
|
||||||
"check:packet-render": "node internal/check-packet-render.mjs",
|
"check:packet-render": "node internal/check-packet-render.mjs",
|
||||||
|
|
@ -247,7 +248,7 @@
|
||||||
"fix:sri": "node internal/fix-sri.mjs",
|
"fix:sri": "node internal/fix-sri.mjs",
|
||||||
"gallery": "node internal/generate-gallery.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: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:regions-uses-library check:shadow-css-parses check:square-map-controls",
|
"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: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:regions-uses-library check:shadow-css-parses check:square-map-controls",
|
||||||
"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-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion",
|
"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",
|
||||||
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
||||||
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
||||||
"library-index": "node internal/generate-library-index.mjs",
|
"library-index": "node internal/generate-library-index.mjs",
|
||||||
|
|
@ -395,6 +396,7 @@
|
||||||
"check:no-silent-engine": "A profile must NEVER fall back to a different map engine than its provider asked for. `engineGlobal(provider) || window.mapboxgl` looks defensive and is not: engineGlobal already returns the right global for the requested provider (useMapInstance.js:115 falls back to mapbox's NAME only for an UNKNOWN provider, never a missing engine), so the || fires in exactly one case — the page asked for maplibre and maplibre failed to load — and hands back the TOKEN-GATED engine to a page that asked for the KEYLESS one. Worse, accessToken is gated on !isMaplibre, so the substitute arrives WITHOUT a token: 401s on every tile instead of a legible failure. Found by regions' C3 read 2026-09-26; 2 offenders remained (cities-internet, gospel-resources) after my-upg-100-list was fixed. NOT a duplicate of check:leaf-engine-per-provider / check:provider-switch / check:auto-engine — all three assert the HAPPY path (what loads) and this bug only appears when something does NOT load, so all three were green while it existed. A SOURCE check on purpose: reproducing it live means serving a leaf with MapLibre deliberately blocked, spending a browser slot on what a grep decides. Exits 75 when no file calls engineGlobal — 'found nothing' is not 'found nothing wrong'. Run :self-test to prove the pattern still matches.",
|
"check:no-silent-engine": "A profile must NEVER fall back to a different map engine than its provider asked for. `engineGlobal(provider) || window.mapboxgl` looks defensive and is not: engineGlobal already returns the right global for the requested provider (useMapInstance.js:115 falls back to mapbox's NAME only for an UNKNOWN provider, never a missing engine), so the || fires in exactly one case — the page asked for maplibre and maplibre failed to load — and hands back the TOKEN-GATED engine to a page that asked for the KEYLESS one. Worse, accessToken is gated on !isMaplibre, so the substitute arrives WITHOUT a token: 401s on every tile instead of a legible failure. Found by regions' C3 read 2026-09-26; 2 offenders remained (cities-internet, gospel-resources) after my-upg-100-list was fixed. NOT a duplicate of check:leaf-engine-per-provider / check:provider-switch / check:auto-engine — all three assert the HAPPY path (what loads) and this bug only appears when something does NOT load, so all three were green while it existed. A SOURCE check on purpose: reproducing it live means serving a leaf with MapLibre deliberately blocked, spending a browser slot on what a grep decides. Exits 75 when no file calls engineGlobal — 'found nothing' is not 'found nothing wrong'. Run :self-test to prove the pattern still matches.",
|
||||||
"check:optional-t-equivalence": "C4's shared guarded translator (library/composables/useOptionalT.js) must behave like the twenty hand-written try{useI18n()}catch blocks it replaces: all three host states, and the per-site register asserts each migrated file still passes ITS OWN fallback rather than inheriting the catalogue, because routing them through tStatic would change what seven bare-host bundles render. EVERY LATER C4 WAVE APPENDS A ROW. Extract-and-executes the module source, since useOptionalT imports vue-i18n and an i18n index that calls import.meta.glob.",
|
"check:optional-t-equivalence": "C4's shared guarded translator (library/composables/useOptionalT.js) must behave like the twenty hand-written try{useI18n()}catch blocks it replaces: all three host states, and the per-site register asserts each migrated file still passes ITS OWN fallback rather than inheriting the catalogue, because routing them through tStatic would change what seven bare-host bundles render. EVERY LATER C4 WAVE APPENDS A ROW. Extract-and-executes the module source, since useOptionalT imports vue-i18n and an i18n index that calls import.meta.glob.",
|
||||||
"check:package-json-unique-keys": "no object in package.json may carry the same key twice: JSON.parse keeps the last silently, so a duplicate kills the first entry while every gate that reads the PARSED object passes (a //scripts note sat twice after a merge). A small scanner tracks keys per object; its self-test runs every time.",
|
"check:package-json-unique-keys": "no object in package.json may carry the same key twice: JSON.parse keeps the last silently, so a duplicate kills the first entry while every gate that reads the PARSED object passes (a //scripts note sat twice after a merge). A small scanner tracks keys per object; its self-test runs every time.",
|
||||||
|
"check:no-repo-pb-hooks": "no PocketBase hooks (pb_hooks/, *.pb.js) in the repo: the cloud container pulls it live, so a pushed hook would be server-side JS from any writer; the one team sign-in hook is baked into the image",
|
||||||
"check:packet-browser": "the packet the READER gets — the legend's Export > Prayer packet path, proving the shared renderer runs in a BROWSER. Asserts the same 12 points / 12 wheel labels / page-1 geography / print layer as check:packet-render, which it did not until 2026-09-24. CONDITIONAL: SKIPs without a server over the repo root (python3 -m http.server 4898) and a reachable records API.",
|
"check:packet-browser": "the packet the READER gets — the legend's Export > Prayer packet path, proving the shared renderer runs in a BROWSER. Asserts the same 12 points / 12 wheel labels / page-1 geography / print layer as check:packet-render, which it did not until 2026-09-24. CONDITIONAL: SKIPs without a server over the repo root (python3 -m http.server 4898) and a reachable records API.",
|
||||||
"check:packet-fixture": "the committed fixture must still match clusters.json and must never carry image_url (CI would fetch 43 photos from someone else's CDN).",
|
"check:packet-fixture": "the committed fixture must still match clusters.json and must never carry image_url (CI would fetch 43 photos from someone else's CDN).",
|
||||||
"check:packet-render:expect-funnel": "check:packet-render with the page-2 FUNNEL declared REQUIRED. Exists because of a real near-miss: a merge resolved with `git checkout --ours` deleted the printPacket call site that supplies the funnel data (60 lines) and EVERY GATE STAYED GREEN — it had to, because the funnel page is OPTIONAL by design (buildPacket omits it when the arg is null), so a packet without page 2 is not malformed, just smaller. Always requiring it would be the wrong fix: the 11 pre-funnel laos packets and any host with no funnel data would go red, and a false red costs as much as a false green. So the CALLER, which knows whether this packet was built with funnel data, declares it — an absence is then either declared (no flag) or a failure (flag passed, page missing), never a silent nothing. Pass it for any packet from a profile that wires packetFunnel(). Browser gate.",
|
"check:packet-render:expect-funnel": "check:packet-render with the page-2 FUNNEL declared REQUIRED. Exists because of a real near-miss: a merge resolved with `git checkout --ours` deleted the printPacket call site that supplies the funnel data (60 lines) and EVERY GATE STAYED GREEN — it had to, because the funnel page is OPTIONAL by design (buildPacket omits it when the arg is null), so a packet without page 2 is not malformed, just smaller. Always requiring it would be the wrong fix: the 11 pre-funnel laos packets and any host with no funnel data would go red, and a false red costs as much as a false green. So the CALLER, which knows whether this packet was built with funnel data, declares it — an absence is then either declared (no flag) or a failure (flag passed, page missing), never a silent nothing. Pass it for any packet from a profile that wires packetFunnel(). Browser gate.",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||||
import { usePplrT } from '../composables/usePplrT.js'
|
import { usePplrT } from '../composables/usePplrT.js'
|
||||||
|
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the agent
|
||||||
import { tStatic } from '@map/i18n/index.js'
|
import { tStatic } from '@map/i18n/index.js'
|
||||||
/**
|
/**
|
||||||
* pplr-coverage.vue — Country choropleth: avg # of locales filled per PG in that country.
|
* pplr-coverage.vue — Country choropleth: avg # of locales filled per PG in that country.
|
||||||
|
|
@ -126,7 +127,7 @@ onMounted(async () => {
|
||||||
new (glFor(map.value)).Popup({ maxWidth: '320px' })
|
new (glFor(map.value)).Popup({ maxWidth: '320px' })
|
||||||
.setLngLat(f.geometry.coordinates).setHTML(popupForPG(f.properties)).addTo(map.value)
|
.setLngLat(f.geometry.coordinates).setHTML(popupForPG(f.properties)).addTo(map.value)
|
||||||
})
|
})
|
||||||
status.value = t('pplr.status.readyCoverage', { countries: countryStats.size, rows: [...countryStats.values()].reduce((n, c) => n + c.pgCount, 0).toLocaleString('en-US') })
|
status.value = t('pplr.status.readyCoverage', { countries: countryStats.size, rows: formatCount([...countryStats.values()].reduce((n, c) => n + c.pgCount, 0)) })
|
||||||
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
|
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
|
||||||
await whenGeojsonDrawn(map.value)
|
await whenGeojsonDrawn(map.value)
|
||||||
dataReady.value = true
|
dataReady.value = true
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
|
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
|
||||||
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||||
import { usePplrT } from '../composables/usePplrT.js'
|
import { usePplrT } from '../composables/usePplrT.js'
|
||||||
|
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the agent
|
||||||
import { tStatic } from '@map/i18n/index.js'
|
import { tStatic } from '@map/i18n/index.js'
|
||||||
import { useMapInstance } from '@map/composables/useMapInstance.js'
|
import { useMapInstance } from '@map/composables/useMapInstance.js'
|
||||||
import { addCountryPolygons, addPGPoints, popupForPG, POPUP_CSS } from '../utils/pplrMap.js'
|
import { addCountryPolygons, addPGPoints, popupForPG, POPUP_CSS } from '../utils/pplrMap.js'
|
||||||
|
|
@ -58,7 +59,7 @@ onMounted(async () => {
|
||||||
.setHTML(popupForPG(f.properties))
|
.setHTML(popupForPG(f.properties))
|
||||||
.addTo(map.value)
|
.addTo(map.value)
|
||||||
})
|
})
|
||||||
status.value = t('pplr.status.readyPins', { pins: fc.features.length.toLocaleString('en-US') })
|
status.value = t('pplr.status.readyPins', { pins: formatCount(fc.features.length) })
|
||||||
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
|
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
|
||||||
await whenGeojsonDrawn(map.value)
|
await whenGeojsonDrawn(map.value)
|
||||||
dataReady.value = true
|
dataReady.value = true
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||||
<script src="../country-posters.js" integrity="sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML" crossorigin="anonymous"></script>
|
<script src="../country-posters.js" integrity="sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||||
<script src="../country-posters.js" integrity="sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML" crossorigin="anonymous"></script>
|
<script src="../country-posters.js" integrity="sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||||
<script src="../country-posters.js" integrity="sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML" crossorigin="anonymous"></script>
|
<script src="../country-posters.js" integrity="sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -98,14 +98,14 @@
|
||||||
.vtl-chev svg { width:15px; height:15px; }
|
.vtl-chev svg { width:15px; height:15px; }
|
||||||
.vtl-chev.open { transform:rotate(90deg); }
|
.vtl-chev.open { transform:rotate(90deg); }
|
||||||
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
||||||
/* MATERIAL NAV-ROW METRICS (2026-09-21). the agent: "people are used to the YouTube layout, Google
|
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
|
||||||
layout is just way better. We do not need to create custom styles people are not used to."
|
Material/YouTube list layout rather than custom styling readers are not used to.
|
||||||
Measured before this change: 44px rows with an 8px radius.
|
Measured before this change: 44px rows with an 8px radius.
|
||||||
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
||||||
label still grows instead of clipping.
|
label still grows instead of clipping.
|
||||||
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
||||||
The 999px stadium above was a real instruction ("imitate the YouTube
|
The 999px stadium above was a real instruction ("imitate the YouTube
|
||||||
active row") and it shipped. The agent then measured it against the
|
active row") and it shipped. It was then measured against the
|
||||||
rest of the product and reversed it: "the roundedness of the tabs is a
|
rest of the product and reversed it: "the roundedness of the tabs is a
|
||||||
little bit too round because there is nowhere else in the app that has
|
little bit too round because there is nowhere else in the app that has
|
||||||
that same roundedness. Even the collapse button is not that round...
|
that same roundedness. Even the collapse button is not that round...
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||||
<script src="../../doxa-maps-spa.js" integrity="sha384-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ" crossorigin="anonymous"></script>
|
<script src="../../doxa-maps-spa.js" integrity="sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||||
<script src="../doxa-maps-spa.js" integrity="sha384-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ" crossorigin="anonymous"></script>
|
<script src="../doxa-maps-spa.js" integrity="sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
"bundle": "country-posters",
|
"bundle": "country-posters",
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"output": "dx-maps/country-posters/country-posters.js",
|
"output": "dx-maps/country-posters/country-posters.js",
|
||||||
"integrity": "sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML",
|
"integrity": "sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ",
|
||||||
"elements": [
|
"elements": [
|
||||||
"country-posters-map"
|
"country-posters-map"
|
||||||
],
|
],
|
||||||
|
|
@ -187,7 +187,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -202,7 +202,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -217,7 +217,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -317,7 +317,7 @@
|
||||||
"bundle": "doxa-maps-spa",
|
"bundle": "doxa-maps-spa",
|
||||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"integrity": "sha384-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ",
|
"integrity": "sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw",
|
||||||
"elements": [
|
"elements": [
|
||||||
"doxa-maps-spa"
|
"doxa-maps-spa"
|
||||||
],
|
],
|
||||||
|
|
@ -344,7 +344,7 @@
|
||||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"embed": {
|
"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>",
|
"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-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"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-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
@ -814,7 +814,7 @@
|
||||||
"bundle": "my-upg-100-list",
|
"bundle": "my-upg-100-list",
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||||
"integrity": "sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i",
|
"integrity": "sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l",
|
||||||
"elements": [
|
"elements": [
|
||||||
"my-upg-100-list-map"
|
"my-upg-100-list-map"
|
||||||
],
|
],
|
||||||
|
|
@ -836,7 +836,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"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-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -851,7 +851,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -866,7 +866,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -938,7 +938,7 @@
|
||||||
"bundle": "plugin-studio",
|
"bundle": "plugin-studio",
|
||||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||||
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
||||||
"integrity": "sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e",
|
"integrity": "sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD",
|
||||||
"elements": [
|
"elements": [
|
||||||
"plugin-studio"
|
"plugin-studio"
|
||||||
],
|
],
|
||||||
|
|
@ -968,7 +968,7 @@
|
||||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/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=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
@ -995,7 +995,7 @@
|
||||||
"bundle": "pplr-data-maps",
|
"bundle": "pplr-data-maps",
|
||||||
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
||||||
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
|
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
|
||||||
"integrity": "sha384-HyV8R97czSk4eeg7lOFsB9NePlf3dJ7N0q6wlX0fKY1Zf0ner2lZ+QRwsHjRELVv",
|
"integrity": "sha384-01tSl+RnPCA0oGugtwlOJb+TBg01zGbmgF/Dpf5qHu/Ok/eFNzFG027mEM4crbT7",
|
||||||
"elements": [
|
"elements": [
|
||||||
"pplr-data-maps"
|
"pplr-data-maps"
|
||||||
],
|
],
|
||||||
|
|
@ -1013,7 +1013,7 @@
|
||||||
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-HyV8R97czSk4eeg7lOFsB9NePlf3dJ7N0q6wlX0fKY1Zf0ner2lZ+QRwsHjRELVv\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-01tSl+RnPCA0oGugtwlOJb+TBg01zGbmgF/Dpf5qHu/Ok/eFNzFG027mEM4crbT7\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
|
||||||
},
|
},
|
||||||
"bundle": "pplr-data-maps"
|
"bundle": "pplr-data-maps"
|
||||||
}
|
}
|
||||||
|
|
@ -1050,7 +1050,7 @@
|
||||||
"bundle": "regions-dashboard",
|
"bundle": "regions-dashboard",
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||||
"integrity": "sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z",
|
"integrity": "sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X",
|
||||||
"elements": [
|
"elements": [
|
||||||
"regions-dashboard"
|
"regions-dashboard"
|
||||||
],
|
],
|
||||||
|
|
@ -1072,7 +1072,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1087,7 +1087,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"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-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1102,7 +1102,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<plugin-studio tree-base="."></plugin-studio>
|
<plugin-studio tree-base="."></plugin-studio>
|
||||||
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e" crossorigin="anonymous"></script>
|
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD" crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
"bundle": "country-posters",
|
"bundle": "country-posters",
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"output": "dx-maps/country-posters/country-posters.js",
|
"output": "dx-maps/country-posters/country-posters.js",
|
||||||
"integrity": "sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML",
|
"integrity": "sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ",
|
||||||
"elements": [
|
"elements": [
|
||||||
"country-posters-map"
|
"country-posters-map"
|
||||||
],
|
],
|
||||||
|
|
@ -187,7 +187,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -202,7 +202,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -217,7 +217,7 @@
|
||||||
"scriptUrl": "./country-posters/country-posters.js",
|
"scriptUrl": "./country-posters/country-posters.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-qvahseKUBbt8fF4+sve6YfLB3ylz2zosiN772O5HbXVxvaDvM6K/SwWnMNKJ9lML\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-LIBXLNfvnjdauLi7aG74iDswH2Tzd29d/hp342/mDbmQYFz89Sw3RvjkkTCoW+CQ\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -317,7 +317,7 @@
|
||||||
"bundle": "doxa-maps-spa",
|
"bundle": "doxa-maps-spa",
|
||||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"integrity": "sha384-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ",
|
"integrity": "sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw",
|
||||||
"elements": [
|
"elements": [
|
||||||
"doxa-maps-spa"
|
"doxa-maps-spa"
|
||||||
],
|
],
|
||||||
|
|
@ -344,7 +344,7 @@
|
||||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||||
"embed": {
|
"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>",
|
"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-PNd2QYytXnHHGBEvXVjgoA93Owlm7Nnji5tJeBP81rq2merTNg2pSfFwt19x1AMJ\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"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-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
@ -814,7 +814,7 @@
|
||||||
"bundle": "my-upg-100-list",
|
"bundle": "my-upg-100-list",
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||||
"integrity": "sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i",
|
"integrity": "sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l",
|
||||||
"elements": [
|
"elements": [
|
||||||
"my-upg-100-list-map"
|
"my-upg-100-list-map"
|
||||||
],
|
],
|
||||||
|
|
@ -836,7 +836,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"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-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -851,7 +851,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -866,7 +866,7 @@
|
||||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -938,7 +938,7 @@
|
||||||
"bundle": "plugin-studio",
|
"bundle": "plugin-studio",
|
||||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||||
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
||||||
"integrity": "sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e",
|
"integrity": "sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD",
|
||||||
"elements": [
|
"elements": [
|
||||||
"plugin-studio"
|
"plugin-studio"
|
||||||
],
|
],
|
||||||
|
|
@ -968,7 +968,7 @@
|
||||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/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=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
{
|
{
|
||||||
|
|
@ -995,7 +995,7 @@
|
||||||
"bundle": "pplr-data-maps",
|
"bundle": "pplr-data-maps",
|
||||||
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
||||||
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
|
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
|
||||||
"integrity": "sha384-HyV8R97czSk4eeg7lOFsB9NePlf3dJ7N0q6wlX0fKY1Zf0ner2lZ+QRwsHjRELVv",
|
"integrity": "sha384-01tSl+RnPCA0oGugtwlOJb+TBg01zGbmgF/Dpf5qHu/Ok/eFNzFG027mEM4crbT7",
|
||||||
"elements": [
|
"elements": [
|
||||||
"pplr-data-maps"
|
"pplr-data-maps"
|
||||||
],
|
],
|
||||||
|
|
@ -1013,7 +1013,7 @@
|
||||||
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
|
||||||
"embed": {
|
"embed": {
|
||||||
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-HyV8R97czSk4eeg7lOFsB9NePlf3dJ7N0q6wlX0fKY1Zf0ner2lZ+QRwsHjRELVv\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-01tSl+RnPCA0oGugtwlOJb+TBg01zGbmgF/Dpf5qHu/Ok/eFNzFG027mEM4crbT7\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
|
||||||
},
|
},
|
||||||
"bundle": "pplr-data-maps"
|
"bundle": "pplr-data-maps"
|
||||||
}
|
}
|
||||||
|
|
@ -1050,7 +1050,7 @@
|
||||||
"bundle": "regions-dashboard",
|
"bundle": "regions-dashboard",
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||||
"integrity": "sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z",
|
"integrity": "sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X",
|
||||||
"elements": [
|
"elements": [
|
||||||
"regions-dashboard"
|
"regions-dashboard"
|
||||||
],
|
],
|
||||||
|
|
@ -1072,7 +1072,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1087,7 +1087,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"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-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1102,7 +1102,7 @@
|
||||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||||
"embed": {
|
"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>",
|
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"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
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||||
<script src="../my-upg-100-list.js" integrity="sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i" crossorigin="anonymous"></script>
|
<script src="../my-upg-100-list.js" integrity="sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||||
<script src="../my-upg-100-list.js" integrity="sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i" crossorigin="anonymous"></script>
|
<script src="../my-upg-100-list.js" integrity="sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||||
<script src="../my-upg-100-list.js" integrity="sha384-hAswKX2m8kfhk4SAPBie72rFlYYtXYgLXr6HLz6cMU8MD5V8T4cMcgfSwsK4vI5i" crossorigin="anonymous"></script>
|
<script src="../my-upg-100-list.js" integrity="sha384-W485SqOh5YedO5tXj85tPYyRqjSeQlBnxahf5YgX7q9118qZk3uDCpfqJUSCRD4l" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,14 @@
|
||||||
.vtl-chev svg { width:15px; height:15px; }
|
.vtl-chev svg { width:15px; height:15px; }
|
||||||
.vtl-chev.open { transform:rotate(90deg); }
|
.vtl-chev.open { transform:rotate(90deg); }
|
||||||
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
|
||||||
/* MATERIAL NAV-ROW METRICS (2026-09-21). the agent: "people are used to the YouTube layout, Google
|
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
|
||||||
layout is just way better. We do not need to create custom styles people are not used to."
|
Material/YouTube list layout rather than custom styling readers are not used to.
|
||||||
Measured before this change: 44px rows with an 8px radius.
|
Measured before this change: 44px rows with an 8px radius.
|
||||||
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
min-height:48px the Material list-item height. min-height, not height, so a wrapping
|
||||||
label still grows instead of clipping.
|
label still grows instead of clipping.
|
||||||
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
|
||||||
The 999px stadium above was a real instruction ("imitate the YouTube
|
The 999px stadium above was a real instruction ("imitate the YouTube
|
||||||
active row") and it shipped. The agent then measured it against the
|
active row") and it shipped. It was then measured against the
|
||||||
rest of the product and reversed it: "the roundedness of the tabs is a
|
rest of the product and reversed it: "the roundedness of the tabs is a
|
||||||
little bit too round because there is nowhere else in the app that has
|
little bit too round because there is nowhere else in the app that has
|
||||||
that same roundedness. Even the collapse button is not that round...
|
that same roundedness. Even the collapse button is not that round...
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||||
<script src="../plugin-studio.js" integrity="sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e" crossorigin="anonymous"></script>
|
<script src="../plugin-studio.js" integrity="sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||||
<script src="../../plugin-studio.js" integrity="sha384-8qq9TrPab9dfj4aHBbSMKj2dwCzyuH2gA2xGq4YhK4GNEy38/uVVmeEhJIXiEr1e" crossorigin="anonymous"></script>
|
<script src="../../plugin-studio.js" integrity="sha384-TIIWS9puN8S1tAFHIeIOLIWlWADIW9lxmKLv2M+BKWGp7yjd/dVcpjU41RfH77WD" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <pplr-data-maps> custom element. -->
|
<!-- Bundle IIFE — registers the <pplr-data-maps> custom element. -->
|
||||||
<script src="../pplr-data-maps.js" integrity="sha384-HyV8R97czSk4eeg7lOFsB9NePlf3dJ7N0q6wlX0fKY1Zf0ner2lZ+QRwsHjRELVv" crossorigin="anonymous"></script>
|
<script src="../pplr-data-maps.js" integrity="sha384-01tSl+RnPCA0oGugtwlOJb+TBg01zGbmgF/Dpf5qHu/Ok/eFNzFG027mEM4crbT7" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||||
<script src="../regions-dashboard.js" integrity="sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z" crossorigin="anonymous"></script>
|
<script src="../regions-dashboard.js" integrity="sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||||
<script src="../regions-dashboard.js" integrity="sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z" crossorigin="anonymous"></script>
|
<script src="../regions-dashboard.js" integrity="sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||||
<script src="../regions-dashboard.js" integrity="sha384-cIs9LG3sHsQf+LV4UsaqNOYrDMoMfhku9CDHAd1V+BSmE2R9Xvjrz/vYadIINH9Z" crossorigin="anonymous"></script>
|
<script src="../regions-dashboard.js" integrity="sha384-3aB5szRuMvvvZRSWB9CcCWnJW8d/fVTHZClloQyv1pjS4E+30OV2rzK6sRXPyX+X" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue