Merge the pilot (development 9222c7f36, the pinned-file cache fix) into the packet pace branch
This commit is contained in:
commit
36eb0cc66a
63 changed files with 1435 additions and 458 deletions
74
README.md
74
README.md
|
|
@ -173,6 +173,30 @@ the Research Gallery, which DX Life publishes as **Deep Research**. An eighth pr
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
### Print your first poster
|
||||
|
||||
1. **Open a poster wall:** *UPG-100 List*, *Country Posters*, or *Regions* (its **View country posters**
|
||||
button). Every card on the wall has a **Print Options** strip. India's whole-country poster isn't
|
||||
available yet; its state posters are.
|
||||
2. **Pick what to print:** **Poster Map** (the poster), **Prayer List** (choose **Full detail** or
|
||||
**Lightweight**) or **Card Deck** (choose a card size). On *UPG-100 List*, clicking the poster
|
||||
picture prints it too.
|
||||
3. **Your browser's print window opens, and it is the preview.** Choose the printer and print. Nothing
|
||||
is downloaded; to keep a file, choose **Save as PDF** instead of a printer.
|
||||
|
||||
Posters, lists and packets print on Letter-size pages (8.5 × 11 in). Cards print at their own size:
|
||||
2.5 × 3.5 in, 4 × 6 in or A6.
|
||||
|
||||
**Bigger posters.** *Bible Posters* and the *Wall of People Groups* also offer bigger sizes, up to 5 × 8
|
||||
ft, for a print shop: in the print window choose **Save as PDF** and send the file. The Wall's 5 × 8 ft
|
||||
poster prints as 3 sheets, one per page, stacked so that each overlaps the next by 6 in; every sheet is
|
||||
numbered (1 / 3, 2 / 3 …) and marked **glue here** where the next one goes.
|
||||
|
||||
**On a phone.** The same print window rises over the page; choose **Save as PDF** to keep the file or
|
||||
send it on. A phone prints page sizes only (Letter or A4 paper), and the largest poster sizes are
|
||||
switched off there. A few prints say they need a computer: *Bless India Posters*, the *Wall of People
|
||||
Groups* and a UPG-100 selection of more than 1,000 groups.
|
||||
|
||||
### Every capability ships every way
|
||||
|
||||
| Capability | Example | iframe | Mobile app | JavaScript embed | WordPress / Disciple Tools | Desktop |
|
||||
|
|
@ -697,25 +721,29 @@ your own page, set `"locale"` in its `profile-config`. Arabic reads right to lef
|
|||
**Many AI agents can build many plugins at once without breaking each other's work.** Every plugin
|
||||
has one agent that owns it, and the work moves through three kinds of branch:
|
||||
|
||||
- **The pilot branch (`development`)** is the shared working version. A development server with hot
|
||||
reload follows it, so each change that lands can be seen there within about 15 seconds.
|
||||
- **The landing branch (`main`)** is production. It moves only when you publish, and the production
|
||||
server rebuilds from it.
|
||||
- **PR branches** hold one feature each. They start from the landing branch and land on the pilot
|
||||
branch, one at a time, after the checks pass.
|
||||
- **The pilot branch (`development`)** is where reviewed PR branches come together. A pilot server
|
||||
with hot reload follows it, so each change that joins can be seen there within about 15 seconds.
|
||||
- **The landing branch (`main`)** is what ships. It moves only when a person approves a publish, and
|
||||
the landing server rebuilds from it.
|
||||
- **PR branches** hold one plugin or feature each. They start from the landing branch and join the
|
||||
pilot branch, one at a time, after the checks pass and a second reader has read the change.
|
||||
|
||||
**It scales by adding PR branches, not by sharing one.** Many people, each with several agents, can
|
||||
work on many plugins at the same time: every plugin or feature gets its own PR branch, and each one
|
||||
can be seen on the pilot server as soon as it joins the pilot.
|
||||
|
||||
**Bring your own harness.** dx-maps works with whatever AI coding agent or agent harness you already
|
||||
use. The repo gives you the branch strategy below, the checks (`bun run gates:pre`) and the Plugin
|
||||
Studio; it does not ship a harness. Roles such as a coordinator that puts the merges onto the pilot in order, or a
|
||||
gate-keeper that reads each change before it lands, are jobs your harness gives to its agents.
|
||||
gate-keeper that reads each change before it joins the pilot, are jobs your harness gives to its agents.
|
||||
|
||||

|
||||

|
||||
|
||||
<sub>[Open the diagram full size](documentation/readme-images/delegation-model.png): on a phone its small text needs it.</sub>
|
||||
|
||||
### Set up the branch strategy
|
||||
|
||||
1. **The landing branch (`main`) is production.** It moves only when you publish (step 7).
|
||||
1. **The landing branch (`main`) is what ships.** It moves only when a person approves a publish (step 7).
|
||||
2. **The pilot branch (`development`) is the shared working branch.** Create it once, from `main`:
|
||||
```bash
|
||||
git fetch origin && git switch -c development origin/main && git push -u origin development
|
||||
|
|
@ -732,7 +760,7 @@ gate-keeper that reads each change before it lands, are jobs your harness gives
|
|||
```bash
|
||||
bun x vite --port 5301 --strictPort # the next agent uses 5302, and so on
|
||||
```
|
||||
5. **Land on the pilot one at a time, through a lock.** Inside the lock, merge your PR branch into a
|
||||
5. **Join the pilot one at a time, through a lock that works like a merge queue.** Inside the lock, merge your PR branch into a
|
||||
throwaway copy of the pilot branch, run the checks, and push that merge only if nothing fails
|
||||
(`gates:pre` exits non-zero when a check fails, so the push never runs then). Your PR branch itself
|
||||
stays one feature on the landing branch; only the pilot gets the merge:
|
||||
|
|
@ -743,7 +771,7 @@ gate-keeper that reads each change before it lands, are jobs your harness gives
|
|||
bun run gates:pre && git push origin HEAD:development
|
||||
git switch regions/work'
|
||||
```
|
||||
If the merge stops on a conflict, run `git merge --abort`, fix the clash on your PR branch and land
|
||||
If the merge stops on a conflict, run `git merge --abort`, fix the clash on your PR branch and join
|
||||
again. `flock` guards one machine. Agents on several machines need a shared lock, such as one your
|
||||
harness provides.
|
||||
6. **One agent owns the full build**; the others build only their own plugin:
|
||||
|
|
@ -751,8 +779,8 @@ gate-keeper that reads each change before it lands, are jobs your harness gives
|
|||
BUILD_ALLOW=1 bun run build # the build owner: every plugin
|
||||
BUNDLE=<name> bun x vite build && bun run tree && bun run fix:sri # everyone else: one plugin
|
||||
```
|
||||
7. **Publish:** fast-forward the landing branch to a pilot commit that passed the checks, tag it, and
|
||||
deploy from the tag:
|
||||
7. **Publish, when a person approves it:** fast-forward the landing branch to a pilot commit that
|
||||
passed the checks, tag it, and deploy from the tag:
|
||||
```bash
|
||||
git fetch origin && git switch main && git merge --ff-only origin/main
|
||||
git merge --ff-only <development-commit> # a commit that passed the checks
|
||||
|
|
@ -760,12 +788,14 @@ gate-keeper that reads each change before it lands, are jobs your harness gives
|
|||
git tag -a v1.0.0 -m "Release v1.0.0" && git push origin main v1.0.0
|
||||
```
|
||||
The tag's `public/dx-maps/` folder is the built site: deploy that
|
||||
([how to deploy](./documentation/DEPLOY.md)).
|
||||
([how to deploy](./documentation/DEPLOY.md)). Publish to a public host, such as GitHub, only from
|
||||
the landing branch and only when it is ready.
|
||||
|
||||
### Developing in the cloud with a swarm
|
||||
|
||||
Keep the repository on a forge you host yourself: a swarm pushes often, and on a public host one wrong
|
||||
push publishes work you did not mean to share. Give each app two servers: a **pilot server** that
|
||||
Keep the repository on a git service you host yourself: a swarm pushes often, and an agent can
|
||||
publish by accident. On a public host, one wrong push publishes work you did not mean to share, so
|
||||
publish there only from the landing branch, when it is ready. Give each app two servers: a **pilot server** that
|
||||
follows the pilot branch with hot reload, and a **landing server** that rebuilds from the landing
|
||||
branch. The cloud container in `deployment/cloud/` runs both today (`BRANCH=development` for the pilot server,
|
||||
`PRODUCTION_BRANCH=main` for the landing server; `BRANCH` defaults to `main`). One pilot server per app, rather
|
||||
|
|
@ -787,19 +817,19 @@ All the maps here share **one project, one library and one build step**. That's
|
|||
work together, and it's also the danger: if one agent's change breaks the shared library, **every
|
||||
map breaks at once**. And when several agents work in the same project at the same time, they step on
|
||||
each other — two agents edit the same file, one change quietly erases another, or half-finished work
|
||||
lands in the version everyone else is using.
|
||||
ends up in the version everyone else is using.
|
||||
|
||||
So the project works like a busy kitchen:
|
||||
|
||||
1. **Each agent works in its own branch and copy of the project** — its own counter, so nobody bumps
|
||||
anybody. One owner per plugin, and one per shared file.
|
||||
2. **Only one change lands at a time.** Whoever holds the *pilot lock* first catches up with
|
||||
2. **Only one change joins the pilot at a time.** Whoever holds the *pilot lock* first catches up with
|
||||
everyone else's latest work, fixes any clash itself and runs every check; the change goes into the
|
||||
pilot branch only if nothing fails. The pilot branch always works.
|
||||
3. **Someone keeps order.** A coordinator can put the merges onto the pilot in order, and a gate-keeper can read
|
||||
each change by its content before it lands. Your harness gives these jobs to its agents.
|
||||
4. **The landing branch moves only when you publish**, after the checks pass on that exact version.
|
||||
The pilot server follows the pilot branch; the production server rebuilds from the landing branch.
|
||||
each change by its content before it joins the pilot. Your harness gives these jobs to its agents.
|
||||
4. **The landing branch moves only when a person approves a publish**, after the checks pass on that exact version.
|
||||
The pilot server follows the pilot branch; the landing server rebuilds from the landing branch.
|
||||
|
||||
That's how many plugins get built at the same time, in one project, without the maps breaking.
|
||||
|
||||
|
|
@ -812,7 +842,7 @@ That's how many plugins get built at the same time, in one project, without the
|
|||
|---|---|
|
||||
| **repo** | the project folder, with its full history |
|
||||
| **development** (the pilot) | the shared working version: every agent's change is added here, one at a time |
|
||||
| **main** (the landing) | the production version: it moves only when `development` is published |
|
||||
| **main** (the landing) | the version that ships: it moves only when a person approves publishing `development` |
|
||||
| **worktree** | a private copy of the project for one agent to work in |
|
||||
| **merge conflict** | two changes touched the same lines; someone has to decide how to combine them |
|
||||
| **merge** | combining your branch with everyone else's latest work; here it happens inside the pilot lock, in a throwaway copy of the pilot |
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 767 KiB After Width: | Height: | Size: 926 KiB |
|
|
@ -1,4 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="2086" viewBox="0 0 1500 2086" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="2256" viewBox="0 0 1500 2256" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
|
||||
<defs>
|
||||
<marker id="aA" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#2563eb"/></marker>
|
||||
<marker id="aS" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#7c3aed"/></marker>
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
<path id="agL" d="M 194,850 A 556,556 0 0 1 1306,850"/>
|
||||
<path id="mqL" d="M 679,884 A 71,71 0 0 0 821,884"/>
|
||||
</defs>
|
||||
<rect width="1500" height="2086" fill="#ffffff"/>
|
||||
<rect width="1500" height="2256" fill="#ffffff"/>
|
||||
<text x="750" y="54" text-anchor="middle" font-size="34" font-weight="800" fill="#0f172a">How dx-maps is built: one owner per plugin, one merge at a time</text>
|
||||
<circle cx="750" cy="850" r="540" fill="none" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="3 7" opacity=".75"/>
|
||||
<circle cx="750" cy="850" r="355" fill="none" stroke="#15803d" stroke-width="2.2" opacity=".85"/>
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
<text x="750" y="842" text-anchor="middle" font-size="24" font-weight="800" fill="#fff">pilot</text>
|
||||
<text x="750" y="862" text-anchor="middle" font-size="13" font-weight="700" fill="#dcfce7">development</text>
|
||||
<text x="750" y="882" text-anchor="middle" font-size="12.5" fill="#dcfce7">every change</text>
|
||||
<text x="750" y="897" text-anchor="middle" font-size="12.5" fill="#dcfce7">lands here</text>
|
||||
<text x="750" y="897" text-anchor="middle" font-size="12.5" fill="#dcfce7">joins here</text>
|
||||
<text font-size="16" font-weight="800" fill="#15803d" letter-spacing="3"><textPath href="#plL" startOffset="50%" text-anchor="middle">PLUGINS</textPath></text>
|
||||
<text font-size="16" font-weight="800" fill="#2563eb" letter-spacing="3"><textPath href="#agL" startOffset="18%" text-anchor="middle">AGENTS</textPath></text>
|
||||
<line x1="862.1" y1="579.3" x2="822.7" y2="674.5" stroke="#15803d" stroke-width="1.4" opacity=".45"/>
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
<circle cx="64" cy="366" r="11" fill="#f1f5f9" stroke="#334155" stroke-width="2.5"/>
|
||||
<text x="88" y="371" font-size="15" fill="#334155">gate-keeper — checks each merge</text>
|
||||
<rect x="60" y="1536" width="1380" height="232" rx="20" fill="#fef2f2" stroke="#fca5a5" stroke-width="2"/>
|
||||
<text x="750" y="1578" text-anchor="middle" font-size="22" font-weight="800" fill="#7f1d1d">How a change lands — one at a time, so many plugins can be built at once</text>
|
||||
<text x="750" y="1578" text-anchor="middle" font-size="22" font-weight="800" fill="#7f1d1d">How a change joins the pilot — one at a time, so many plugins can be built at once</text>
|
||||
<rect x="80.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
|
||||
<circle cx="114.0" cy="1634" r="18" fill="#dc2626"/>
|
||||
<text x="114.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">1</text>
|
||||
|
|
@ -158,7 +158,7 @@
|
|||
<text x="487.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">Second reader</text>
|
||||
<text x="445.0" y="1680" font-size="15" fill="#475569">another agent reads every</text>
|
||||
<text x="445.0" y="1702" font-size="15" fill="#475569">change by its content</text>
|
||||
<text x="445.0" y="1724" font-size="15" fill="#475569">before it may land</text>
|
||||
<text x="445.0" y="1724" font-size="15" fill="#475569">before it may join</text>
|
||||
<text x="750.0" y="1682" text-anchor="middle" font-size="26" font-weight="800" fill="#dc2626">→</text>
|
||||
<rect x="770.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
|
||||
<circle cx="804.0" cy="1634" r="18" fill="#dc2626"/>
|
||||
|
|
@ -173,12 +173,12 @@
|
|||
<text x="1149.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">4</text>
|
||||
<text x="1177.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">Publish to landing</text>
|
||||
<text x="1135.0" y="1680" font-size="15" fill="#475569">landing (main), production:</text>
|
||||
<text x="1135.0" y="1702" font-size="15" fill="#475569">moves only when the owner approves,</text>
|
||||
<text x="1135.0" y="1702" font-size="15" fill="#475569">moves only when a person approves,</text>
|
||||
<text x="1135.0" y="1724" font-size="15" fill="#475569">after full checks on that version</text>
|
||||
<line x1="750" y1="956" x2="750" y2="1786" stroke="#334155" stroke-width="2.5" stroke-dasharray="2 5" opacity=".0"/>
|
||||
<rect x="60" y="1812" width="1380" height="254" rx="20" fill="#f8fafc" stroke="#cbd5e1" stroke-width="2"/>
|
||||
<text x="750" y="1856" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">landing (main) → ONE build → one web folder → three outputs</text>
|
||||
<text x="750" y="1882" text-anchor="middle" font-size="16" fill="#475569">the pilot server follows development · the production server rebuilds from main</text>
|
||||
<text x="750" y="1882" text-anchor="middle" font-size="16" fill="#475569">the pilot server follows development · the landing server rebuilds from main</text>
|
||||
<rect x="80.0" y="1908" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
|
||||
<text x="290.0" y="1930" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 1</text>
|
||||
<text x="290.0" y="1962" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">The web folder</text>
|
||||
|
|
@ -197,4 +197,9 @@
|
|||
<text x="1210.0" y="1988" text-anchor="middle" font-size="15" fill="#475569">the same folder, wrapped by Tauri</text>
|
||||
<rect x="1110.0" y="2002" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
|
||||
<text x="1210.0" y="2020" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">WORKING</text>
|
||||
</svg>
|
||||
<rect x="60" y="2090" width="1380" height="146" rx="20" fill="#eff6ff" stroke="#93c5fd" stroke-width="2"/>
|
||||
<text x="750" y="2132" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">At scale: many people × many agents × many plugins</text>
|
||||
<text x="750" y="2164" text-anchor="middle" font-size="16" fill="#475569">one PR branch per plugin or feature → joins the pilot through the lock → previewed on the pilot server</text>
|
||||
<text x="750" y="2192" text-anchor="middle" font-size="16" fill="#475569">in the cloud: a self-hosted git service, because an agent can publish by accident</text>
|
||||
<text x="750" y="2218" text-anchor="middle" font-size="16" fill="#475569">publish to a public host only from landing (main), when it is ready</text>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
163
internal/check-pinned-fetch-fresh.mjs
Normal file
163
internal/check-pinned-fetch-fresh.mjs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env bun
|
||||
/**
|
||||
* check-pinned-fetch-fresh.mjs — a STALE cached copy of a pinned file never decides a print.
|
||||
*
|
||||
* THE DEFECT (2026-10-02, on a phone). The print-time files are pinned (poster-render.js, its classic copy,
|
||||
* packet-strings.json, ne-places.json, india-states.json) and fetched with cache: 'force-cache', which returns ANY
|
||||
* cached copy, however old. After a re-pin, a reader who had printed before kept the previous copy: it failed its pin
|
||||
* on every print and the print fell back without a word. Page 1 became the stored poster (the phone's packet), a
|
||||
* non-English packet would print in English, and India's state cards would be lost. library/packet/sha384.js
|
||||
* fetchPinned fetches force-cache first and, on a copy that is not served or does not match, ONCE more with cache:
|
||||
* 'reload'; every pinned loader calls it.
|
||||
*
|
||||
* A browser's HTTP cache is modelled: force-cache answers from it when it holds the URL, reload always asks the
|
||||
* server and refreshes it. The SERVER holds the current files (public/dx-maps/assets); the CACHE holds a stale copy.
|
||||
* A. fetchPinned: a stale cached copy → the current text, after exactly one fresh refetch;
|
||||
* B. a cached copy that matches is used as is: ONE request, force-cache (the fast, offline-friendly path stays);
|
||||
* C. a server that also serves the wrong bytes → rejected, err.integrity, after one fresh refetch;
|
||||
* D. a file that is not served → rejected (not an integrity failure);
|
||||
* E. loadPacketStrings with a stale cached table → the full table in every language (not the English fallback);
|
||||
* F. loadIndiaStates with a stale cached table → India's 36 states (not a rejection);
|
||||
* G. generateSheet with a stale cached generator → a drawn sheet (not an integrity refusal);
|
||||
* H. wiring: every pinned loader fetches through fetchPinned with its own pin, and none fetches its pinned file
|
||||
* directly; the classic-script path refreshes the HTTP cache and retries a refused tag once.
|
||||
* `--self-test`: fetchPinned without its fresh refetch, one that never uses the cache, one that accepts a
|
||||
* mismatch, and a loader that fetches its pinned file directly must each FAIL.
|
||||
* Two-sided by hand at the change: the previous loaders (the pilot before this) fail E, F and G.
|
||||
*/
|
||||
import { readFileSync, existsSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
|
||||
const REPO = new URL('..', import.meta.url).pathname
|
||||
const ASSETS = join(REPO, 'public/dx-maps/assets')
|
||||
const SHA_SRC = join(REPO, 'library/packet/sha384.js')
|
||||
const LOADERS = {
|
||||
'library/packet/posterSheets.js': ['POSTER_RENDER_SHA384', 'NE_PLACES_SHA384'],
|
||||
'library/packet/packetStrings.js': ['PACKET_STRINGS_SHA384'],
|
||||
'library/data/indiaStates.js': ['INDIA_STATES_SHA384'],
|
||||
}
|
||||
const PINNED_FILES = ['lib/poster-render.js', 'lib/packet-strings.json', 'boundaries/ne-places.json', 'people-groups/india-states.json']
|
||||
const served = (p) => { const f = join(ASSETS, p); return existsSync(f) ? readFileSync(f, 'utf8') : null }
|
||||
const asModule = (src) => import('data:text/javascript;base64,' + Buffer.from(src).toString('base64'))
|
||||
const realFetch = globalThis.fetch
|
||||
|
||||
// The browser, modelled: { cached: path -> stale text } in the HTTP cache, { wrong: path -> text } served instead of
|
||||
// the real file, { missing: [path] } not served at all.
|
||||
function world(host, { cached = {}, wrong = {}, missing = [] } = {}) {
|
||||
const http = new Map(Object.entries(cached).map(([p, t]) => [`${host}/${p}`, t]))
|
||||
const requests = []
|
||||
globalThis.fetch = async (input, init = {}) => {
|
||||
const url = String(input)
|
||||
if (!url.startsWith(host + '/')) return realFetch(input, init)
|
||||
const path = url.slice(host.length + 1).split('?')[0]
|
||||
const mode = init.cache || 'default'
|
||||
requests.push({ path, mode })
|
||||
let text = null
|
||||
if (mode !== 'reload' && mode !== 'no-store' && http.has(url)) text = http.get(url)
|
||||
else {
|
||||
text = missing.includes(path) ? null : (path in wrong ? wrong[path] : served(path))
|
||||
if (text !== null) http.set(url, text)
|
||||
}
|
||||
return text === null ? new Response('not found', { status: 404 }) : new Response(text, { status: 200 })
|
||||
}
|
||||
return { requests }
|
||||
}
|
||||
const stale = (p) => `/* an older build */\n${served(p)}`
|
||||
|
||||
async function auditFetchPinned(shaSrc) {
|
||||
const fails = []
|
||||
const { fetchPinned, sha384 } = await asModule(shaSrc)
|
||||
if (typeof fetchPinned !== 'function') return ['A: library/packet/sha384.js exports no fetchPinned']
|
||||
const P = 'lib/packet-strings.json', current = served(P), pin = await sha384(current)
|
||||
// A
|
||||
{ const w = world('https://a.test', { cached: { [P]: stale(P) } }); let got = null, err = null
|
||||
try { got = await fetchPinned(`https://a.test/${P}`, pin) } catch (e) { err = e }
|
||||
if (got !== current) fails.push(`A: a stale cached copy did not give the current file (${err ? `rejected: ${err.message}` : 'returned other bytes'})`)
|
||||
else if (w.requests.length !== 2 || w.requests[0].mode !== 'force-cache' || w.requests[1].mode !== 'reload') fails.push(`A: expected force-cache then ONE reload, got ${JSON.stringify(w.requests)}`) }
|
||||
// B
|
||||
{ const w = world('https://b.test', { cached: { [P]: current } }); let got = null
|
||||
try { got = await fetchPinned(`https://b.test/${P}`, pin) } catch { /* reported below */ }
|
||||
if (got !== current || w.requests.length !== 1 || w.requests[0].mode !== 'force-cache') fails.push(`B: a matching cached copy should be used with ONE force-cache request, got ${JSON.stringify(w.requests)}`) }
|
||||
// C
|
||||
{ const bad = current.replace('"en"', '"en" ') + ' '
|
||||
const w = world('https://c.test', { cached: { [P]: stale(P) }, wrong: { [P]: bad } }); let got = null, err = null
|
||||
try { got = await fetchPinned(`https://c.test/${P}`, pin) } catch (e) { err = e }
|
||||
if (got !== null || !err || err.integrity !== true) fails.push(`C: wrong bytes on the server were not refused as an integrity failure (${got !== null ? 'ACCEPTED' : err?.message})`)
|
||||
else if (w.requests.length !== 2) fails.push(`C: expected exactly one fresh refetch before refusing, got ${w.requests.length} request(s)`) }
|
||||
// D
|
||||
{ world('https://d.test', { missing: [P] }); let err = null
|
||||
try { await fetchPinned(`https://d.test/${P}`, pin) } catch (e) { err = e }
|
||||
if (!err || err.integrity) fails.push(`D: an unserved file should reject as not served (${err ? err.message : 'it resolved'})`) }
|
||||
globalThis.fetch = realFetch
|
||||
return fails
|
||||
}
|
||||
|
||||
async function auditLoaders() {
|
||||
const fails = []
|
||||
// E: the packet text
|
||||
{ world('https://e.test', { cached: { 'lib/packet-strings.json': stale('lib/packet-strings.json') } })
|
||||
const { loadPacketStrings } = await import(join(REPO, 'library/packet/packetStrings.js'))
|
||||
const warn = console.warn; console.warn = () => {}
|
||||
const t = await loadPacketStrings('https://e.test').finally(() => { console.warn = warn })
|
||||
const src = JSON.parse(served('lib/packet-strings.json'))
|
||||
if (Object.keys(t).join() === 'en' || t.zh?.zone_affinity_A017 !== src.zh?.zone_affinity_A017) fails.push(`E: a stale cached packet-strings.json made the packet English (got languages: ${Object.keys(t).join(',')})`) }
|
||||
// F: India's states
|
||||
{ world('https://f.test', { cached: { 'people-groups/india-states.json': stale('people-groups/india-states.json') } })
|
||||
const { loadIndiaStates } = await import(join(REPO, 'library/data/indiaStates.js'))
|
||||
let n = -1, err = null
|
||||
try { n = (await loadIndiaStates('https://f.test')).states.length } catch (e) { err = e }
|
||||
const want = JSON.parse(served('people-groups/india-states.json')).states.length
|
||||
if (n !== want) fails.push(`F: a stale cached india-states.json lost India's states (${err ? `rejected: ${err.message}` : `${n} of ${want}`})`) }
|
||||
// G: page 1's generator
|
||||
{ world('https://g.test', { cached: { 'lib/poster-render.js': stale('lib/poster-render.js'), 'boundaries/ne-places.json': stale('boundaries/ne-places.json') } })
|
||||
const { generateSheet, countryZone } = await import(join(REPO, 'library/packet/posterSheets.js'))
|
||||
const zone = countryZone({ id: 'country-tcd', iso3: 'TCD', label: 'Chad', count: 1, region: 'Africa' })
|
||||
const pins = [[12.1, 15.0], [13.8, 20.8], [9.1, 18.4]].map(([lat, lng], i) => ({ name: `Probe ${i + 1}`, lat, lng, slug: `probe-${i}`, country_code: 'TCD', population: 1000 }))
|
||||
const adm0 = JSON.parse(served('boundaries/world-adm0.geojson'))
|
||||
let html = '', err = null
|
||||
const warn = console.warn; console.warn = () => {}
|
||||
try { html = await generateSheet({ zone, pins, format: '3x3', seriesId: 'country', adm0, assetsBase: 'https://g.test', date: '2026-09-29' }) } catch (e) { err = e }
|
||||
console.warn = warn
|
||||
if (!(typeof html === 'string' && /<svg\b/.test(html))) fails.push(`G: a stale cached generator stopped the sheet from drawing (${err ? err.message.slice(0, 110) : 'no sheet'})`) }
|
||||
globalThis.fetch = realFetch
|
||||
return fails
|
||||
}
|
||||
|
||||
function auditWiring(srcOf) {
|
||||
const fails = []
|
||||
for (const [file, pins] of Object.entries(LOADERS)) {
|
||||
const s = srcOf(file)
|
||||
if (!/import \{[^}]*\bfetchPinned\b[^}]*\} from '[^']*sha384\.js'/.test(s)) fails.push(`H: ${file} does not import fetchPinned`)
|
||||
for (const pin of pins) if (!new RegExp(`fetchPinned\\([^)]*,\\s*${pin}\\)`).test(s)) fails.push(`H: ${file} does not fetch its ${pin} file through fetchPinned`)
|
||||
if (/fetch\(url,\s*\{\s*cache:\s*'force-cache'\s*\}\)/.test(s)) fails.push(`H: ${file} still fetches a pinned file directly with force-cache`)
|
||||
}
|
||||
const ps = srcOf('library/packet/posterSheets.js')
|
||||
const classic = (ps.match(/function loadClassic\(url\) \{[\s\S]*?\n\}/) || [''])[0]
|
||||
if (!/fetch\(url, \{ cache: 'reload' \}\)/.test(classic) || !/return tag\(\)\s*\n?\s*\}\)/.test(classic)) fails.push('H: the classic-script path does not refresh the HTTP cache and retry a refused tag once')
|
||||
for (const p of PINNED_FILES) if (served(p) === null) fails.push(`H: ${p} is not in the served tree (the gate would measure nothing)`)
|
||||
return fails
|
||||
}
|
||||
|
||||
const shaSrc = readFileSync(SHA_SRC, 'utf8')
|
||||
const read = (f) => readFileSync(join(REPO, f), 'utf8')
|
||||
if (process.argv.includes('--self-test')) {
|
||||
const FOR = "for (const cache of ['force-cache', 'reload']) {"
|
||||
const poisons = [
|
||||
['fetchPinned without its fresh refetch', () => auditFetchPinned(shaSrc.replace(FOR, "for (const cache of ['force-cache']) {")), /^A: /],
|
||||
['fetchPinned that never uses the cache', () => auditFetchPinned(shaSrc.replace(FOR, "for (const cache of ['reload', 'reload']) {")), /^B: /],
|
||||
['fetchPinned that accepts a mismatch', () => auditFetchPinned(shaSrc.replace(' if (got === pin) return text\n', ' return text\n')), /^C: /],
|
||||
['a loader that fetches its pinned file directly', () => auditWiring((f) => (f === 'library/packet/packetStrings.js'
|
||||
? read(f).replace('fetchPinned(url, PACKET_STRINGS_SHA384)', "(await fetch(url, { cache: 'force-cache' })).text()") : read(f))), /^H: library\/packet\/packetStrings\.js/],
|
||||
]
|
||||
let missed = 0
|
||||
for (const [name, run, rx] of poisons) {
|
||||
const f = await run(); const hit = f.find((x) => rx.test(x))
|
||||
console.log(hit ? `✓ caught: ${name} -> ${hit}` : `✗ MISSED: ${name}${f.length ? ` (failed instead: ${f[0]})` : ''}`)
|
||||
if (!hit) missed++
|
||||
}
|
||||
if (missed) process.exitCode = 1
|
||||
} else {
|
||||
const f = [...await auditFetchPinned(shaSrc), ...await auditLoaders(), ...auditWiring(read)]
|
||||
if (f.length) { for (const x of f) console.log('✗ ' + x); console.log(`FAIL check:pinned-fetch-fresh (${f.length})`); process.exitCode = 1 }
|
||||
else console.log('PASS check:pinned-fetch-fresh — a stale cached copy of a pinned file is refetched once, fresh: page 1 still draws, the packet keeps its language, India keeps its states; a matching cached copy is used as is; wrong bytes are refused; every pinned loader goes through fetchPinned')
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
// t.byShapeName → Map(shapeName → entry) (the map's ADM1 features carry shapeName)
|
||||
// t.byIso → Map(iso → entry)
|
||||
import { INDIA_STATES_SHA384 } from './indiaStates.integrity.js'
|
||||
import { sha384 } from '../packet/sha384.js'
|
||||
import { fetchPinned } from '../packet/sha384.js'
|
||||
|
||||
const PAGE_BASE = globalThis.document?.baseURI || undefined
|
||||
const cache = new Map()
|
||||
|
|
@ -30,10 +30,11 @@ export function loadIndiaStates(assetsBase) {
|
|||
try { url = indiaStatesUrl(assetsBase) } catch (e) { return Promise.reject(e) }
|
||||
if (!cache.has(url)) {
|
||||
const p = (async () => {
|
||||
const res = await fetch(url, { cache: 'force-cache' })
|
||||
if (!res.ok) throw new Error(`india-states.json not served (${res.status})`)
|
||||
const text = await res.text()
|
||||
if ((await sha384(text)) !== INDIA_STATES_SHA384) throw new Error('india-states.json failed its integrity check')
|
||||
// force-cache, and once more fresh on a mismatch: a stale cached copy after a re-pin must not cost a returning
|
||||
// reader India's state cards (../packet/sha384.js fetchPinned says why).
|
||||
let text
|
||||
try { text = await fetchPinned(url, INDIA_STATES_SHA384) }
|
||||
catch (e) { throw new Error(`india-states.json ${e?.message || e}`) }
|
||||
const data = JSON.parse(text)
|
||||
const states = Array.isArray(data.states) ? data.states : []
|
||||
return {
|
||||
|
|
|
|||
487
library/packet/circularLayout.js
Normal file
487
library/packet/circularLayout.js
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
/**
|
||||
* circularLayout.js — the poster "circular logic" (ring order + leader routing +
|
||||
* numbered four-sides + paired-row forks) as ONE pure, Worker-safe module.
|
||||
*
|
||||
* Numbers in, geometry out. The module returns POSITIONS, POLYLINES and STATS —
|
||||
* never SVG/HTML strings (those stay in poster-render.js). It is pure: no DOM, no
|
||||
* Vue, no fetch, no canvas, no module-level mutable format state, no Math.random,
|
||||
* and no reliance on Set/Map iteration order (every tie is broken by id). The same
|
||||
* input yields byte-identical output, which the byte-proof in step 3 depends on.
|
||||
*
|
||||
* It is a PORT of the proven geometry in library/packet/poster-render.js and of
|
||||
* the classic4 four-sides reference — the same math, lifted so a cheap phone (or a
|
||||
* Worker with no canvas) can lay a big poster out. The text measurer is PASSED IN
|
||||
* (`opts.measure`) because a Worker has no canvas; the default is the renderer's
|
||||
* own CHADV × WFUDGE advance table, lifted verbatim, so the numbers match.
|
||||
*
|
||||
* layoutCircular({ pins, states, box, mode, opts }) -> { numbers, pins, rows, leaders, badges, stats }
|
||||
*
|
||||
* MODES
|
||||
* 'sideLanes' — today's large-sheet L/R layout: octilinear leaders in margin
|
||||
* lanes, photo slots. Pins are NOT moved (byte identity in step 1).
|
||||
* 'fourSides' — design (1): NUMBERED, NO leaders. Numbers in the pin and before
|
||||
* the name; names on all four sides; 0 crossings by construction.
|
||||
* Pins de-overlapped in-state via placePinsInState.
|
||||
* 'pairedRows' — design (2): two groups per row, TWO leaders per row (octilinear
|
||||
* forks), in ring order, 0 crossings; pins spread in-state.
|
||||
*
|
||||
* `box` carries the per-poster geometry the renderer already computes (all px):
|
||||
* { PW, PH, MAP_X, MAP_W, MAP_Y, MAP_H, HEADER, FOOTER, SHEET_EDGE, GUTTER,
|
||||
* C4_BAND, PXI, FRAME_X, FRAME_Y, FRAME_W, FRAME_H, LABEL_TOP, LABEL_BOT,
|
||||
* proj(lng,lat)->[x,y] }
|
||||
* `opts`:
|
||||
* { measure(str,pt)->px, slotOf(pin,pt)->px, photoOf(pin)->url|null,
|
||||
* fmt:{ nameMaxPt, photos, rangeBadge, classic4, fork, sideLanes, pageWidthIn,
|
||||
* w, h }, seamYs:[y...], placePinsInState, forkRoute, feats:[...] }
|
||||
*
|
||||
* placePinsInState and forkRoute come from their sibling library modules (static
|
||||
* imports below); a caller may still override either via opts for a Worker that
|
||||
* injects its own. Both are pure ESM, so the static import stays Worker-portable.
|
||||
*/
|
||||
import { placePinsInState as libPlacePinsInState } from './pins-in-state.js';
|
||||
import { forkRoute as libForkRoute } from './fork-leaders.js';
|
||||
|
||||
// ── text advance (lifted verbatim from poster-render.js: CHADV × WFUDGE) ───────
|
||||
// Worker-safe: a static char-advance table, no canvas. Callers may override via
|
||||
// opts.measure, but the default MUST equal the renderer's or the bytes move.
|
||||
const CHADV = (ch) => {
|
||||
if ('iIjl|.,:;\'! '.includes(ch)) return 0.28;
|
||||
if ('ftr()[]-'.includes(ch)) return 0.34;
|
||||
if ('mwMW'.includes(ch)) return 0.86;
|
||||
if ('ABCDEFGHKLNOPQRSTUVXYZ0123456789'.includes(ch)) return 0.63;
|
||||
return 0.53;
|
||||
};
|
||||
const WFUDGE = 1.11;
|
||||
export const textW = (str, fs) => [...String(str)].reduce((a, ch) => a + CHADV(ch), 0) * fs * WFUDGE;
|
||||
|
||||
// ── octilinear leader primitives (lifted verbatim from poster-render.js) ───────
|
||||
export function octiRoute(it, laneX, dirOut, dfrac) {
|
||||
const STUB = 7;
|
||||
const P = [it.px, it.py];
|
||||
const xStub = it.px + dirOut * STUB;
|
||||
const dy = it.labelY - it.py;
|
||||
const vdir = dy === 0 ? 0 : Math.sign(dy);
|
||||
const gap = Math.abs(xStub - laneX);
|
||||
const diag = Math.max(0, Math.min(dfrac * Math.abs(dy), gap));
|
||||
const feeler = gap - diag;
|
||||
const pts = [P, [xStub, it.py]];
|
||||
pts.push([xStub + dirOut * feeler, it.py]);
|
||||
pts.push([laneX, it.py + vdir * diag]);
|
||||
pts.push([laneX, it.labelY]);
|
||||
return pts;
|
||||
}
|
||||
export function isOctilinear(pts, eps = 0.6) {
|
||||
for (let i = 0; i < pts.length - 1; i++) {
|
||||
const dx = Math.abs(pts[i + 1][0] - pts[i][0]), dy = Math.abs(pts[i + 1][1] - pts[i][1]);
|
||||
if (dx < eps || dy < eps) continue;
|
||||
if (Math.abs(dx - dy) < eps) continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Deterministic id tie-break by CODE UNIT (locale-independent, unlike localeCompare),
|
||||
// so the layout is byte-identical on any runtime/locale (Node, a phone in ar or zh).
|
||||
function cmpId(a, b) { const x = String(a), y = String(b); return x < y ? -1 : x > y ? 1 : 0; }
|
||||
|
||||
function segCrossXY(p, q) {
|
||||
const o = (ax, ay, bx, by, cx, cy) => Math.sign((bx - ax) * (cy - ay) - (by - ay) * (cx - ax));
|
||||
const [a, b] = p, [c, d] = q;
|
||||
const same = (u, v) => Math.abs(u[0] - v[0]) < 0.5 && Math.abs(u[1] - v[1]) < 0.5;
|
||||
if (same(a, c) || same(a, d) || same(b, c) || same(b, d)) return false;
|
||||
const o1 = o(...a, ...b, ...c), o2 = o(...a, ...b, ...d), o3 = o(...c, ...d, ...a), o4 = o(...c, ...d, ...b);
|
||||
return o1 !== o2 && o3 !== o4 && o1 !== 0 && o2 !== 0 && o3 !== 0 && o4 !== 0;
|
||||
}
|
||||
// Count crossings between polylines, skipping same-polyline pairs (same li). A
|
||||
// FORK must be passed as ONE polyline id (its unique segs), never its two polys.
|
||||
export function countPolyCrossings(polys) {
|
||||
const segs = [];
|
||||
polys.forEach((pts, li) => { for (let i = 0; i < pts.length - 1; i++) segs.push({ s: [pts[i], pts[i + 1]], li }); });
|
||||
let n = 0;
|
||||
for (let i = 0; i < segs.length; i++) for (let j = i + 1; j < segs.length; j++) {
|
||||
if (segs[i].li === segs[j].li) continue;
|
||||
if (segCrossXY(segs[i].s, segs[j].s)) n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
// A leader that passes within r of ANOTHER group's dot ("touch"). segs: array of
|
||||
// { li, pts }, dots: [{ id, x, y }]. Skips the leader's own endpoint dot by id.
|
||||
function countTouches(leaderPolys, dots, r) {
|
||||
let touches = 0;
|
||||
for (const lp of leaderPolys) {
|
||||
for (const dot of dots) {
|
||||
if (dot.id === lp.id) continue;
|
||||
if (polyNearPoint(lp.pts, dot.x, dot.y, r)) touches++;
|
||||
}
|
||||
}
|
||||
return touches;
|
||||
}
|
||||
function polyNearPoint(pts, px, py, r) {
|
||||
for (let i = 0; i < pts.length - 1; i++) {
|
||||
if (distPointToSeg(px, py, pts[i][0], pts[i][1], pts[i + 1][0], pts[i + 1][1]) <= r) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function distPointToSeg(px, py, ax, ay, bx, by) {
|
||||
const abx = bx - ax, aby = by - ay;
|
||||
const len2 = abx * abx + aby * aby;
|
||||
let t = len2 ? ((px - ax) * abx + (py - ay) * aby) / len2 : 0;
|
||||
t = t < 0 ? 0 : t > 1 ? 1 : t;
|
||||
const x = ax + t * abx, y = ay + t * aby;
|
||||
return Math.hypot(px - x, py - y);
|
||||
}
|
||||
|
||||
// ── point-in-ring / state polygon helpers (for in-state de-overlap inputs) ─────
|
||||
function inRing(lng, lat, r) {
|
||||
let o = false;
|
||||
for (let i = 0, j = r.length - 1; i < r.length; j = i++) {
|
||||
const xi = r[i][0], yi = r[i][1], xj = r[j][0], yj = r[j][1];
|
||||
if (((yi > lat) !== (yj > lat)) && (lng < (xj - xi) * (lat - yi) / (yj - yi) + xi)) o = !o;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function inPoly(lng, lat, p) {
|
||||
if (!inRing(lng, lat, p[0])) return false;
|
||||
for (let k = 1; k < p.length; k++) if (inRing(lng, lat, p[k])) return false;
|
||||
return true;
|
||||
}
|
||||
function inFeat(lng, lat, g) {
|
||||
return g.type === 'Polygon' ? inPoly(lng, lat, g.coordinates)
|
||||
: g.type === 'MultiPolygon' ? g.coordinates.some((p) => inPoly(lng, lat, p)) : false;
|
||||
}
|
||||
// Nearest ADM1 shapeName for an off-polygon point (island fallback), lifted from
|
||||
// classic4Layout.nearest. Deterministic: first feature wins a tie by scan order.
|
||||
function nearestState(lng, lat, feats) {
|
||||
let best = null, bd = Infinity;
|
||||
const cl = Math.cos(lat * Math.PI / 180);
|
||||
for (const f of feats) {
|
||||
const ps = f.geometry.type === 'Polygon' ? [f.geometry.coordinates] : f.geometry.coordinates;
|
||||
for (const po of ps) for (const r of po) for (let i = 0, j = r.length - 1; i < r.length; j = i++) {
|
||||
const ax = r[j][0], ay = r[j][1], bx = r[i][0], by = r[i][1];
|
||||
const dx = (bx - ax) * cl, dy = by - ay, pax = (lng - ax) * cl, pay = lat - ay, l2 = dx * dx + dy * dy;
|
||||
let t = l2 ? (pax * dx + pay * dy) / l2 : 0; t = Math.max(0, Math.min(1, t));
|
||||
const qx = pax - t * dx, qy = pay - t * dy, d = qx * qx + qy * qy;
|
||||
if (d < bd) { bd = d; best = f.properties.shapeName; }
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
// Build { shapeName: polygonsPx } for placePinsInState, projecting every ring.
|
||||
function statesToPx(feats, proj) {
|
||||
const statesPx = {};
|
||||
for (const f of feats) {
|
||||
const sn = f.properties.shapeName;
|
||||
const ps = f.geometry.type === 'Polygon' ? [f.geometry.coordinates] : f.geometry.coordinates;
|
||||
const parts = ps.map((poly) => poly.map((ring) => ring.map(([lng, lat]) => proj(lng, lat))));
|
||||
(statesPx[sn] = statesPx[sn] || []).push(...parts);
|
||||
}
|
||||
return statesPx;
|
||||
}
|
||||
|
||||
// ── dependency resolution (injected; lazy Node fallback) ───────────────────────
|
||||
function resolveDeps(opts) {
|
||||
// The library implementations by default; a Worker may inject its own via opts.
|
||||
return {
|
||||
placePinsInState: (opts && opts.placePinsInState) || libPlacePinsInState,
|
||||
forkRoute: (opts && opts.forkRoute) || libForkRoute,
|
||||
};
|
||||
}
|
||||
|
||||
// ── clustering (id-stable; CL_R on the given coordinate pair) ──────────────────
|
||||
// Scans pins in input order; nearest existing cluster within CL_R wins, ties by
|
||||
// cluster creation order (first found). Deterministic — no Map/Set ordering.
|
||||
function clusterBy(pins, CL_R, getX, getY) {
|
||||
const clusters = [];
|
||||
for (const p of pins) {
|
||||
let best = null, bd = CL_R;
|
||||
for (const c of clusters) {
|
||||
const d = Math.hypot(getX(c) - getX(p), getY(c) - getY(p));
|
||||
if (d <= bd) { bd = d; best = c; }
|
||||
}
|
||||
if (best) {
|
||||
best.items.push(p);
|
||||
best._sx += (getX(p) - best._sx) / best.items.length;
|
||||
best._sy += (getY(p) - best._sy) / best.items.length;
|
||||
} else {
|
||||
clusters.push({ items: [p], _sx: getX(p), _sy: getY(p) });
|
||||
}
|
||||
}
|
||||
return clusters;
|
||||
}
|
||||
|
||||
// ───────────────────────────────── MAIN ───────────────────────────────────────
|
||||
export async function layoutCircular({ pins, states, box, mode, opts = {} }) {
|
||||
if (!Array.isArray(pins)) throw new TypeError('pins must be an array');
|
||||
if (!box || typeof box !== 'object') throw new TypeError('box (geometry) is required');
|
||||
if (!['sideLanes', 'fourSides', 'pairedRows'].includes(mode)) throw new TypeError(`unknown mode: ${mode}`);
|
||||
const measure = opts.measure || textW;
|
||||
const fmt = opts.fmt || {};
|
||||
const { placePinsInState, forkRoute } = resolveDeps(opts);
|
||||
if (mode === 'fourSides') return fourSides({ pins, box, opts, fmt, measure, placePinsInState });
|
||||
if (mode === 'pairedRows') return pairedRows({ pins, box, opts, fmt, measure, placePinsInState, forkRoute });
|
||||
return sideLanes({ pins, box, opts, fmt, measure });
|
||||
}
|
||||
|
||||
// ── FOUR-SIDES (design 1): numbered, no leaders. Ported from classic4Layout. ───
|
||||
function fourSides({ pins0 = null, pins, box, opts, fmt, measure, placePinsInState }) {
|
||||
const { PW, PH, MAP_X, MAP_W, MAP_Y, MAP_H, HEADER, FOOTER, SHEET_EDGE, C4_BAND, PXI, FRAME_X, FRAME_Y, FRAME_W, FRAME_H, proj } = box;
|
||||
const feats = opts.feats || [];
|
||||
const RANGE = !!fmt.rangeBadge;
|
||||
// project pins; px/py are the engine-settled coords passed in on each pin as _px/_py.
|
||||
const P = pins.map((p) => {
|
||||
const [rx, ry] = proj ? proj(+p.lng, +p.lat) : [p._px, p._py];
|
||||
return { ...p, px: p._px, py: p._py, rx, ry };
|
||||
});
|
||||
// state assignment + island fallback (deterministic scan order)
|
||||
let islandFallback = 0;
|
||||
for (const p of P) {
|
||||
let st = null;
|
||||
for (const f of feats) if (inFeat(+p.lng, +p.lat, f.geometry)) { st = f.properties.shapeName; break; }
|
||||
if (!st) { st = nearestState(+p.lng, +p.lat, feats); if (st) islandFallback++; }
|
||||
p._state = st;
|
||||
}
|
||||
// cluster co-located pins on RAW projected coords (CL_R=12), consecutive numbers
|
||||
const CL_R = 12;
|
||||
const clusters = [];
|
||||
for (const p of P) {
|
||||
let c = null, bd = CL_R;
|
||||
for (const q of clusters) { const d = Math.hypot(q.rx - p.rx, q.ry - p.ry); if (d <= bd) { bd = d; c = q; } }
|
||||
if (c) {
|
||||
c.items.push(p);
|
||||
c.rx += (p.rx - c.rx) / c.items.length; c.ry += (p.ry - c.ry) / c.items.length;
|
||||
c.cx += (p.px - c.cx) / c.items.length; c.cy += (p.py - c.cy) / c.items.length;
|
||||
} else clusters.push({ items: [p], rx: p.rx, ry: p.ry, cx: p.px, cy: p.py, state: p._state });
|
||||
}
|
||||
// geometry: L/R columns at the sheet edges; T/B rows on the reserved bands
|
||||
const colTop = HEADER, colBot = PH - FOOTER, colH = colBot - colTop;
|
||||
const lcolX = SHEET_EDGE + 6, rcolX = PW - SHEET_EDGE - 6;
|
||||
const rowY_T = HEADER + C4_BAND - 8, rowX0 = MAP_X + 8, rowX1 = MAP_X + MAP_W - 8, rowW = rowX1 - rowX0;
|
||||
const pitchCol = (f) => f * 1.14, pitchRow = (f) => f * 1.5;
|
||||
const capCol = (f) => Math.floor(colH / pitchCol(f)), capRow = (f) => Math.floor(rowW / pitchRow(f));
|
||||
const fCap = (fmt.nameMaxPt || 11) / 72 * PXI;
|
||||
let font = 5;
|
||||
for (let f = fCap; f >= 5; f -= 0.1) { if (2 * capRow(f) + 2 * capCol(f) >= P.length) { font = f; break; } }
|
||||
// assign whole clusters to sides (balanced by member count)
|
||||
const fRow = Math.min(capRow(font), Math.max(1, Math.floor(P.length * 0.22)));
|
||||
const byCy = [...clusters].sort((a, b) => a.cy - b.cy || a.cx - b.cx);
|
||||
const used = new Set();
|
||||
const T = [], B = []; let cT = 0, cB = 0;
|
||||
for (const c of byCy) { if (cT + c.items.length <= fRow) { T.push(c); cT += c.items.length; used.add(c); } else break; }
|
||||
for (let i = byCy.length - 1; i >= 0; i--) { const c = byCy[i]; if (used.has(c)) break; if (cB + c.items.length <= fRow) { B.push(c); cB += c.items.length; used.add(c); } else break; }
|
||||
const midc = clusters.filter((c) => !used.has(c)).sort((a, b) => a.cx - b.cx || a.cy - b.cy);
|
||||
const halfN = Math.ceil(midc.reduce((a, c) => a + c.items.length, 0) / 2);
|
||||
const L = [], R = []; let cL = 0;
|
||||
for (const c of midc) { if (cL < halfN) { L.push(c); cL += c.items.length; } else R.push(c); }
|
||||
L.sort((a, b) => b.cy - a.cy || a.cx - b.cx); R.sort((a, b) => a.cy - b.cy || a.cx - b.cx);
|
||||
T.sort((a, b) => a.cx - b.cx || a.cy - b.cy); B.sort((a, b) => b.cx - a.cx || a.cy - b.cy);
|
||||
// number 1..N in ring order [L, T, R, B]
|
||||
const ringC = [...L, ...T, ...R, ...B]; let num = 0;
|
||||
const sideOf = new Map(); L.forEach((c) => sideOf.set(c, 'L')); T.forEach((c) => sideOf.set(c, 'T')); R.forEach((c) => sideOf.set(c, 'R')); B.forEach((c) => sideOf.set(c, 'B'));
|
||||
for (const c of ringC) { c.first = num + 1; const sd = sideOf.get(c); for (const p of c.items) { p.num = ++num; p.side = sd; } c.last = num; }
|
||||
const Lp = L.flatMap((c) => c.items), Rp = R.flatMap((c) => c.items), Tp = T.flatMap((c) => c.items), Bp = B.flatMap((c) => c.items);
|
||||
// bottom row hug: slant -45, anchor one longest-name diagonal below the map
|
||||
const nmLen = (p) => `${p.num}. ${String(p.name)}`.length;
|
||||
const maxBExt = Bp.length ? Math.max(...Bp.map((p) => nmLen(p) * font * 0.55 * Math.SQRT1_2)) : 0;
|
||||
const rowY_B = Math.min(PH - FOOTER - 8, MAP_Y + MAP_H + maxBExt + 10);
|
||||
// in-state de-overlap (clusters in range mode, else individual pins)
|
||||
const rBadge = Math.max(5, font * 0.62);
|
||||
const statesPx = statesToPx(feats, proj);
|
||||
let dres;
|
||||
if (RANGE) {
|
||||
dres = placePinsInState({ pins: clusters.map((c, i) => ({ id: i, x: c.cx, y: c.cy, stateId: c.state })), states: statesPx, r: rBadge, gap: 1, iters: 400, maxDrift: 80 });
|
||||
const byId = new Map(dres.pins.map((q) => [q.id, q]));
|
||||
clusters.forEach((c, i) => { const q = byId.get(i); c.bx = q ? q.x : c.cx; c.by = q ? q.y : c.cy; });
|
||||
} else {
|
||||
dres = placePinsInState({ pins: P.map((p, i) => ({ id: i, x: p.px, y: p.py, stateId: p._state })), states: statesPx, r: rBadge, gap: 1, iters: 400, maxDrift: 80 });
|
||||
const byId = new Map(dres.pins.map((q) => [q.id, q]));
|
||||
P.forEach((p, i) => { const q = byId.get(i); if (q) { p.px = q.x; p.py = q.y; } });
|
||||
}
|
||||
// emit geometry (NOT svg): label positions + badge/dot positions
|
||||
const labels = [];
|
||||
const placeCol = (arr, x, anchor, side) => { const n = arr.length || 1, pitch = colH / n; arr.forEach((p, i) => labels.push({ x, y: colTop + pitch * (i + 0.5), pt: font, anchor, rotate: 0, num: p.num, name: String(p.name), side })); };
|
||||
const placeRow = (arr, y, side) => { const n = arr.length || 1, pitch = rowW / n; arr.forEach((p, i) => { const x = rowX0 + pitch * (i + 0.5); labels.push({ x, y, pt: font, anchor: 'start', rotate: -45, num: p.num, name: String(p.name), side }); }); };
|
||||
placeCol(Lp, lcolX, 'start', 'L'); placeCol(Rp, rcolX, 'end', 'R'); placeRow(Tp, rowY_T, 'T'); placeRow(Bp, rowY_B, 'B');
|
||||
const badges = [];
|
||||
if (RANGE) for (const c of clusters) badges.push({ x: c.bx, y: c.by, first: c.first, last: c.last, k: c.items.length, pt: font });
|
||||
const dots = RANGE ? clusters.map((c) => ({ x: c.bx, y: c.by })) : P.map((p) => ({ x: p.px, y: p.py, num: p.num }));
|
||||
// stats
|
||||
const marks = RANGE ? clusters.map((c) => ({ px: c.bx, py: c.by })) : P;
|
||||
const offFrame = marks.filter((q) => q.px < FRAME_X || q.px > FRAME_X + FRAME_W || q.py < FRAME_Y || q.py > FRAME_Y + FRAME_H).length;
|
||||
const allNums = P.map((p) => p.num).sort((a, b) => a - b);
|
||||
const numberDupes = allNums.filter((n, i) => i && n === allNums[i - 1]).length;
|
||||
const numbersRingOrdered = allNums.every((n, i) => n === i + 1);
|
||||
const stats = {
|
||||
placed: P.length, total: pins.length, namePt: +(font / PXI * 72).toFixed(1),
|
||||
crossings: 0, touches: 0, overflow: offFrame,
|
||||
numberDupes, numbersRingOrdered,
|
||||
pinsOutsideState: dres.outsideState, pinOverlaps: dres.overlapsRemaining,
|
||||
pinsMoved: dres.moved, maxDisp: +dres.maxDisp.toFixed(1), islandFallback, infeasible: dres.infeasible.length,
|
||||
sides: { L: Lp.length, R: Rp.length, T: Tp.length, B: Bp.length },
|
||||
rangeBadges: RANGE ? clusters.filter((c) => c.items.length > 1).length : 0,
|
||||
};
|
||||
return { numbers: P.map((p) => ({ id: p.id, num: p.num })), pins: P.map((p) => ({ id: p.id, x: p.px, y: p.py, num: p.num, side: p.side, state: p._state })), rows: { L: Lp.length, R: Rp.length, T: Tp.length, B: Bp.length }, leaders: [], badges, labels, dots, stats };
|
||||
}
|
||||
|
||||
// ── PAIRED-ROWS (design 2): two groups per row, two octilinear leaders. ────────
|
||||
function pairedRows({ pins, box, opts, fmt, measure, placePinsInState, forkRoute }) {
|
||||
const { MAP_X, MAP_W, MAP_Y, MAP_H, PXI, FRAME_X, FRAME_Y, FRAME_W, FRAME_H, proj } = box;
|
||||
const feats = opts.feats || [];
|
||||
const P = pins.map((p) => ({ ...p, px: p._px, py: p._py }));
|
||||
// state assignment for spreading
|
||||
for (const p of P) {
|
||||
let st = null;
|
||||
for (const f of feats) if (inFeat(+p.lng, +p.lat, f.geometry)) { st = f.properties.shapeName; break; }
|
||||
if (!st) st = nearestState(+p.lng, +p.lat, feats);
|
||||
p._state = st;
|
||||
}
|
||||
// spread pins in-state (design 2 moves pins)
|
||||
const font = Math.max(5, (fmt.nameMaxPt || 11) / 72 * PXI);
|
||||
const rPin = Math.max(5, font * 0.62);
|
||||
const statesPx = statesToPx(feats, proj);
|
||||
if (feats.length) {
|
||||
const dres = placePinsInState({ pins: P.map((p, i) => ({ id: i, x: p.px, y: p.py, stateId: p._state })), states: statesPx, r: rPin, gap: 1, iters: 400, maxDrift: 80 });
|
||||
const byId = new Map(dres.pins.map((q) => [q.id, q]));
|
||||
P.forEach((p, i) => { const q = byId.get(i); if (q) { p.px = q.x; p.py = q.y; } });
|
||||
var spread = { outsideState: dres.outsideState, overlaps: dres.overlapsRemaining, moved: dres.moved, maxDisp: dres.maxDisp, infeasible: dres.infeasible.length };
|
||||
} else {
|
||||
var spread = { outsideState: 0, overlaps: 0, moved: 0, maxDisp: 0, infeasible: 0 };
|
||||
}
|
||||
// ring order: median x-split into L/R, then y within a side (monotone, non-crossing)
|
||||
const byX = [...P].sort((a, b) => a.px - b.px || cmpId(a.id, b.id));
|
||||
const half = Math.ceil(byX.length / 2);
|
||||
byX.forEach((p, i) => { p.side = i < half ? 'L' : 'R'; });
|
||||
const rowsOut = []; const leaderPolys = []; const allDots = P.map((p) => ({ id: p.id, x: p.px, y: p.py }));
|
||||
const bandTop = box.LABEL_TOP ?? MAP_Y, bandBot = box.LABEL_BOT ?? (MAP_Y + MAP_H);
|
||||
for (const side of ['L', 'R']) {
|
||||
const dirOut = side === 'L' ? -1 : 1;
|
||||
const laneX = side === 'L' ? MAP_X - 6 : MAP_X + MAP_W + 6;
|
||||
const col = P.filter((p) => p.side === side).sort((a, b) => a.py - b.py || cmpId(a.id, b.id));
|
||||
// two groups per row, in ring (y) order. A row's PORT sits at the mean y of its
|
||||
// own two pins (not an evenly-pitched slot): because the pairs are consecutive
|
||||
// in y, these port ys are themselves monotone, so each fork stays local to its
|
||||
// pins and neighbouring forks cannot sweep across one another. (An evenly-pitched
|
||||
// port put a row's port far from its pins and produced same-side crossings.)
|
||||
for (let i = 0; i < col.length; i += 2) {
|
||||
const a = col[i], b = col[i + 1] || col[i];
|
||||
const rowY = (a.py + (b.py)) / 2;
|
||||
const fork = forkRoute({
|
||||
lane: { x: laneX, y: rowY },
|
||||
a: { id: a.id, x: a.px, y: a.py }, b: { id: b.id, x: b.px, y: b.py },
|
||||
dirOut, mode: 'row',
|
||||
obstacles: allDots.filter((d) => d.id !== a.id && d.id !== b.id), r: rPin,
|
||||
});
|
||||
rowsOut.push({ side, rowY, aId: a.id, bId: b.id, octilinear: fork.octilinear, throughPins: fork.throughPins });
|
||||
leaderPolys.push({ id: `${side}${i}`, polys: fork.polys, segs: fork.segs });
|
||||
}
|
||||
}
|
||||
// crossings: one polyline id per fork (its deduped segs), skip same-id
|
||||
// build as [ [segpts...] per fork ] so countPolyCrossings skips intra-fork
|
||||
const perFork = leaderPolys.map((lp) => lp.segs.map((s) => [s[0], s[1]]));
|
||||
let crossings = 0;
|
||||
{
|
||||
const segs = [];
|
||||
perFork.forEach((forkSegs, li) => { for (const s of forkSegs) segs.push({ s, li }); });
|
||||
for (let i = 0; i < segs.length; i++) for (let j = i + 1; j < segs.length; j++) {
|
||||
if (segs[i].li === segs[j].li) continue;
|
||||
if (segCrossXY(segs[i].s, segs[j].s)) crossings++;
|
||||
}
|
||||
}
|
||||
const touches = rowsOut.reduce((a, r) => a + (r.throughPins ? r.throughPins.length : 0), 0);
|
||||
const octilinear = rowsOut.every((r) => r.octilinear);
|
||||
const offFrame = P.filter((q) => q.px < FRAME_X || q.px > FRAME_X + FRAME_W || q.py < FRAME_Y || q.py > FRAME_Y + FRAME_H).length;
|
||||
const stats = {
|
||||
placed: P.length, total: pins.length, rows: rowsOut.length, namePt: +(font / PXI * 72).toFixed(1),
|
||||
crossings, touches, overflow: offFrame, octilinear,
|
||||
pinsOutsideState: spread.outsideState, pinOverlaps: spread.overlaps,
|
||||
pinsMoved: spread.moved, maxDisp: +(+spread.maxDisp).toFixed(1), infeasible: spread.infeasible,
|
||||
};
|
||||
return { numbers: P.map((p, i) => ({ id: p.id, num: i + 1 })), pins: P.map((p) => ({ id: p.id, x: p.px, y: p.py, state: p._state })), rows: rowsOut, leaders: leaderPolys.map((lp) => ({ id: lp.id, polys: lp.polys || null, segs: lp.segs })), badges: [], labels: [], dots: allDots, stats };
|
||||
}
|
||||
|
||||
// ── SIDE-LANES (today's L/R large sheet). Ported from layoutLabels + lanes. ─────
|
||||
// Pins are NOT moved. Returns leader polylines (octilinear) + label ports + stats.
|
||||
function sideLanes({ pins, box, opts, fmt, measure }) {
|
||||
const { MAP_X, MAP_W, MAP_Y, MAP_H, SHEET_EDGE, GUTTER, PXI, FRAME_X, FRAME_Y, FRAME_W, FRAME_H, proj } = box;
|
||||
const photoOf = opts.photoOf || (() => null);
|
||||
// project + clamp into the map rect (uses engine-settled _px/_py when present)
|
||||
const items = pins.map((p) => {
|
||||
const [lx, ly] = (p._fixed || p._px != null) ? [p._px, p._py] : proj(+p.lng, +p.lat);
|
||||
const x = Math.max(MAP_X + 2, Math.min(MAP_X + MAP_W - 2, lx));
|
||||
const y = Math.max(MAP_Y + 2, Math.min(MAP_Y + MAP_H - 2, ly));
|
||||
return { ...p, px: x, py: y };
|
||||
});
|
||||
// median x-split → L/R (disjoint bands, non-crossing by construction)
|
||||
const byX = [...items].sort((a, b) => a.px - b.px || cmpId(a.id, b.id));
|
||||
const halfB = Math.ceil(byX.length / 2);
|
||||
byX.forEach((it, i) => { it.side = i < halfB ? 'L' : 'R'; });
|
||||
const LABEL_TOP = box.LABEL_TOP ?? MAP_Y, LABEL_BOT = box.LABEL_BOT ?? (MAP_Y + MAP_H);
|
||||
const segCross = (a, b) => {
|
||||
const d = (p1, p2, p3) => (p3.y - p1.y) * (p2.x - p1.x) - (p2.y - p1.y) * (p3.x - p1.x);
|
||||
const A1 = { x: a.sx, y: a.sy }, A2 = { x: a.px, y: a.py };
|
||||
const B1 = { x: b.sx, y: b.sy }, B2 = { x: b.px, y: b.py };
|
||||
return (d(A1, A2, B1) > 0) !== (d(A1, A2, B2) > 0) && (d(B1, B2, A1) > 0) !== (d(B1, B2, A2) > 0);
|
||||
};
|
||||
// intra-column ring order by greedy crossing repair (bubble on adjacent pairs)
|
||||
for (const sd of ['L', 'R']) {
|
||||
const col = items.filter((i) => i.side === sd).sort((a, b) => a.py - b.py || cmpId(a.id, b.id));
|
||||
const n2 = col.length || 1;
|
||||
const rowH0 = (LABEL_BOT - LABEL_TOP) / n2;
|
||||
const sxCol = sd === 'L' ? MAP_X - 6 : MAP_X + MAP_W + 6;
|
||||
col.forEach((it, i) => { it.sx = sxCol; it.sy = LABEL_TOP + rowH0 * (i + 0.5); });
|
||||
for (let pass = 0; pass < 60; pass++) {
|
||||
let improved = false;
|
||||
for (let i = 0; i < col.length - 1; i++) {
|
||||
const a = col[i], b = col[i + 1];
|
||||
const before = segCross(a, b) ? 1 : 0;
|
||||
const ay = a.sy, by = b.sy; a.sy = by; b.sy = ay;
|
||||
const after = segCross(a, b) ? 1 : 0;
|
||||
if (after < before) { col[i] = b; col[i + 1] = a; improved = true; } else { a.sy = ay; b.sy = by; }
|
||||
}
|
||||
if (!improved) break;
|
||||
}
|
||||
col.forEach((it, i) => { it.ringIdx = i; });
|
||||
}
|
||||
// place rows in ring order, evenly pitched over the band; assign lanes
|
||||
const SHEET_MARGIN = SHEET_EDGE + 8;
|
||||
const LANE_EDGE_GAP = 6, LABEL_GAP = 6, LANE_PITCH_MAX = 3;
|
||||
const LABEL_RES = GUTTER - SHEET_MARGIN - LANE_EDGE_GAP - 24;
|
||||
const laid = [];
|
||||
for (const side of ['L', 'R']) {
|
||||
const col = items.filter((i) => i.side === side).sort((a, b) => a.ringIdx - b.ringIdx);
|
||||
const n = col.length || 1;
|
||||
const bandH = LABEL_BOT - LABEL_TOP, rowH = bandH / n;
|
||||
const dirOut = side === 'L' ? -1 : 1;
|
||||
const edge = side === 'L' ? MAP_X : MAP_X + MAP_W;
|
||||
const band = MAP_X - LABEL_RES - LANE_EDGE_GAP - LABEL_GAP;
|
||||
const pitch = Math.min(LANE_PITCH_MAX, band / Math.max(1, n - 1));
|
||||
col.forEach((it, k) => {
|
||||
it.labelY = LABEL_TOP + rowH * (k + 0.5);
|
||||
it.laneX = edge + dirOut * (LANE_EDGE_GAP + k * pitch);
|
||||
it.dirOut = dirOut;
|
||||
it.tanchor = side === 'L' ? 'end' : 'start';
|
||||
laid.push(it);
|
||||
});
|
||||
}
|
||||
// route leaders at dfrac 0 (current dev sweep is [0]); octilinear by construction
|
||||
const routesFor = (d) => laid.map((it) => octiRoute(it, it.laneX, it.dirOut, d));
|
||||
let bestD = 0, bestX = Infinity;
|
||||
for (const d of [0]) { const x = countPolyCrossings(routesFor(d)); if (x < bestX) { bestX = x; bestD = d; } }
|
||||
const routes = routesFor(bestD);
|
||||
const octiOK = routes.every((r) => isOctilinear(r));
|
||||
const dots = laid.map((it) => ({ id: it.id, x: it.px, y: it.py }));
|
||||
const touches = countTouches(routes.map((pts, i) => ({ id: laid[i].id, pts })), dots, 2);
|
||||
const stats = {
|
||||
placed: laid.length, total: pins.length, crossings: bestX, touches, overflow: 0,
|
||||
octilinear: octiOK, dfrac: bestD, pinsOutsideState: 0,
|
||||
photos: laid.filter((it) => photoOf(it)).length,
|
||||
sides: { L: items.filter((i) => i.side === 'L').length, R: items.filter((i) => i.side === 'R').length },
|
||||
};
|
||||
return {
|
||||
numbers: [], pins: laid.map((it) => ({ id: it.id, x: it.px, y: it.py })),
|
||||
rows: [], badges: [],
|
||||
labels: laid.map((it) => ({ x: it.laneX, y: it.labelY, anchor: it.tanchor, name: String(it.name) })),
|
||||
leaders: routes.map((pts, i) => ({ id: laid[i].id, pts })),
|
||||
dots, stats,
|
||||
};
|
||||
}
|
||||
|
||||
export default layoutCircular;
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import { en as EN } from '../scripts/posters/packet-strings.json'
|
||||
import { PACKET_STRINGS_SHA384 } from './poster-render.integrity.js'
|
||||
import { sha384 } from './sha384.js'
|
||||
import { fetchPinned } from './sha384.js'
|
||||
|
||||
// Captured when the module evaluates, as in posterSheets.js: a relative asset base resolves against the page
|
||||
// that loaded the map, even if a single-page host changes its URL before the click.
|
||||
|
|
@ -33,11 +33,9 @@ export function loadPacketStrings(assetsBase) {
|
|||
try { url = new URL(`${assetsBase}/lib/packet-strings.json`, PAGE_BASE).href } catch { return Promise.resolve(ENGLISH_ONLY) }
|
||||
if (!cache.has(url)) {
|
||||
const p = (async () => {
|
||||
const res = await fetch(url, { cache: 'force-cache' })
|
||||
if (!res.ok) throw new Error(`not served (${res.status})`)
|
||||
const text = await res.text()
|
||||
if ((await sha384(text)) !== PACKET_STRINGS_SHA384) throw new Error('failed its integrity check')
|
||||
return JSON.parse(text)
|
||||
// force-cache, and once more fresh on a mismatch: a stale cached copy after a re-pin must not turn a
|
||||
// returning reader's packet English (sha384.js fetchPinned says why).
|
||||
return JSON.parse(await fetchPinned(url, PACKET_STRINGS_SHA384))
|
||||
})().catch((e) => {
|
||||
console.warn(`[packetStrings] ${url}: ${e?.message || e} — printing in English`)
|
||||
cache.delete(url) // a later print tries again rather than inheriting one failure
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* ISO3_NAME, series: { totalGroups, totalLists, index } })
|
||||
*/
|
||||
import { POSTER_RENDER_SHA384, NE_PLACES_SHA384, POSTER_RENDER_GLOBAL_SHA384 } from './poster-render.integrity.js'
|
||||
import { sha384 } from './sha384.js'
|
||||
import { fetchPinned } from './sha384.js'
|
||||
|
||||
// ★ THE GENERATOR IS SERVED, NOT BUNDLED, AND IT IS INTEGRITY-PINNED. poster-render.js is served verbatim
|
||||
// at <assets>/lib/poster-render.js (generate-tree) and loaded at the FIRST print: a single-file build
|
||||
|
|
@ -33,9 +33,11 @@ const PAGE_BASE = globalThis.document?.baseURI || undefined
|
|||
const abs = (u) => new URL(u, PAGE_BASE).href
|
||||
// The classic-script path: the browser checks POSTER_RENDER_GLOBAL_SHA384 itself and refuses to run a
|
||||
// file that does not match (onerror), so nothing unverified executes here either.
|
||||
// A refused tag is tried ONCE more after a fetch with cache: 'reload' has refreshed the HTTP cache: a stale cached
|
||||
// copy after a re-pin fails the browser's own check, exactly as it fails fetchPinned's (sha384.js says why).
|
||||
function loadClassic(url) {
|
||||
if (globalThis.DoxaPosterRender?.createPosterGenerator) return Promise.resolve(globalThis.DoxaPosterRender.createPosterGenerator)
|
||||
return new Promise((resolve, reject) => {
|
||||
const tag = () => new Promise((resolve, reject) => {
|
||||
const el = document.createElement('script')
|
||||
el.src = url
|
||||
el.integrity = POSTER_RENDER_GLOBAL_SHA384
|
||||
|
|
@ -44,9 +46,13 @@ function loadClassic(url) {
|
|||
el.onload = () => (globalThis.DoxaPosterRender?.createPosterGenerator
|
||||
? resolve(globalThis.DoxaPosterRender.createPosterGenerator)
|
||||
: reject(new Error(`the sheet generator at ${url} loaded but did not define DoxaPosterRender`)))
|
||||
el.onerror = () => reject(new Error(`the sheet generator at ${url} was refused (integrity or network) — not running it`))
|
||||
el.onerror = () => { el.remove(); reject(new Error(`the sheet generator at ${url} was refused (integrity or network) — not running it`)) }
|
||||
document.head.appendChild(el)
|
||||
})
|
||||
return tag().catch(async (first) => {
|
||||
try { await fetch(url, { cache: 'reload' }) } catch { throw first }
|
||||
return tag()
|
||||
})
|
||||
}
|
||||
const generatorCache = new Map()
|
||||
function loadGenerator(assetsBase) {
|
||||
|
|
@ -54,13 +60,10 @@ function loadGenerator(assetsBase) {
|
|||
const url = abs(`${assetsBase}/lib/poster-render.js`)
|
||||
if (!generatorCache.has(url)) {
|
||||
const p = (async () => {
|
||||
const res = await fetch(url, { cache: 'force-cache' })
|
||||
if (!res.ok) throw new Error(`the sheet generator is not served (${res.status}) at ${url}`)
|
||||
const text = await res.text()
|
||||
const got = await sha384(text)
|
||||
if (got !== POSTER_RENDER_SHA384) {
|
||||
throw new Error(`the sheet generator at ${url} failed its integrity check (expected ${POSTER_RENDER_SHA384}, got ${got}) — refusing to run it`)
|
||||
}
|
||||
// force-cache, and once more fresh on a mismatch (sha384.js fetchPinned says why); only a match runs.
|
||||
let text
|
||||
try { text = await fetchPinned(url, POSTER_RENDER_SHA384) }
|
||||
catch (e) { throw new Error(`the sheet generator at ${url} ${e?.message || e} — refusing to run it`) }
|
||||
const blobUrl = URL.createObjectURL(new Blob([text], { type: 'text/javascript' }))
|
||||
try { return (await import(/* @vite-ignore */ blobUrl)).createPosterGenerator }
|
||||
catch (e) {
|
||||
|
|
@ -96,16 +99,17 @@ function loadPlaces(assetsBase) {
|
|||
const url = abs(`${assetsBase}/boundaries/ne-places.json`)
|
||||
if (!placesCache.has(url)) {
|
||||
const p = (async () => {
|
||||
const res = await fetch(url, { cache: 'force-cache' })
|
||||
if (!res.ok) return []
|
||||
const text = await res.text()
|
||||
if ((await sha384(text)) !== NE_PLACES_SHA384) {
|
||||
console.warn(`[posterSheets] ${url} failed its integrity check — drawing no city dots`)
|
||||
let text
|
||||
try { text = await fetchPinned(url, NE_PLACES_SHA384) }
|
||||
catch (e) {
|
||||
if (!e?.integrity) throw e // not served, or offline: a later print tries again (below)
|
||||
console.warn(`[posterSheets] ${url} failed its integrity check, also when fetched fresh — drawing no city dots`)
|
||||
return []
|
||||
}
|
||||
return JSON.parse(text).places || []
|
||||
})().catch(() => [])
|
||||
placesCache.set(url, p)
|
||||
})()
|
||||
// Wrong bytes stay refused for the session; a transient failure is forgotten, as in the other loaders.
|
||||
placesCache.set(url, p.catch(() => { placesCache.delete(url); return [] }))
|
||||
}
|
||||
return placesCache.get(url)
|
||||
}
|
||||
|
|
|
|||
238
library/packet/scripts/check-circular-layout.mjs
Normal file
238
library/packet/scripts/check-circular-layout.mjs
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-circular-layout.mjs — gate for library/packet/circularLayout.js.
|
||||
*
|
||||
* Builds a FROZEN synthetic 855-pin India-scale fixture (sheet 2500x4000, the
|
||||
* classic4 60x96 constants) with a grid of fake ADM1 "states", then asserts:
|
||||
*
|
||||
* fourSides — numbersRingOrdered true, numberDupes 0, pinsOutsideState 0,
|
||||
* >= 800 pins placed (no vacuous pass).
|
||||
* pairedRows — 0 crossings on the clean set, pinsOutsideState 0, octilinear true.
|
||||
* sideLanes — runs, returns stats with a pin-count floor and octilinear leaders.
|
||||
* determinism — two fourSides runs byte-identical.
|
||||
* poison — a state far too small for its pins is NAMED in infeasible
|
||||
* (never silently stacked), surfaced via stats.infeasible > 0.
|
||||
* budget — fourSides on 855 pins runs under BUDGET_MS (1.5x a measured
|
||||
* baseline) and under a heap ceiling. Median of 3, so it is not flaky.
|
||||
*
|
||||
* Node only, headless, deterministic. Exit 0 PASS / 1 FAIL / 75 import failure.
|
||||
*/
|
||||
let layoutCircular;
|
||||
try { ({ layoutCircular } = await import('../circularLayout.js')); }
|
||||
catch (e) { console.error(`NOT MEASURED: cannot import circularLayout.js — ${e.message}`); process.exit(75); }
|
||||
|
||||
const fails = [], note = [];
|
||||
|
||||
// Independent recounts — defined HERE, not imported from the module, so a broken
|
||||
// counter in circularLayout.js cannot make its own stats agree with itself.
|
||||
function gateInRing(px, py, ring) {
|
||||
let hit = false;
|
||||
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
||||
const [xi, yi] = ring[i], [xj, yj] = ring[j];
|
||||
if ((yi > py) !== (yj > py) && px < ((xj - xi) * (py - yi)) / ((yj - yi) || 1e-12) + xi) hit = !hit;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
function gateInState(px, py, parts) {
|
||||
for (const part of parts) {
|
||||
const [outer, ...holes] = part;
|
||||
if (!outer || outer.length < 3 || !gateInRing(px, py, outer)) continue;
|
||||
if (!holes.some((h) => h && h.length >= 3 && gateInRing(px, py, h))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Recount, from the OUTPUT pins, how many sit outside their own state. Projects the
|
||||
// fixture feats to px the same way the module does (box.proj), keyed by shapeName.
|
||||
function recountOutside(outPins, feats) {
|
||||
const statesPx = {};
|
||||
for (const f of feats) {
|
||||
const sn = f.properties.shapeName;
|
||||
const ps = f.geometry.type === 'Polygon' ? [f.geometry.coordinates] : f.geometry.coordinates;
|
||||
const parts = ps.map((poly) => poly.map((ring) => ring.map(([lng, lat]) => box.proj(lng, lat))));
|
||||
(statesPx[sn] = statesPx[sn] || []).push(...parts);
|
||||
}
|
||||
let out = 0;
|
||||
for (const p of outPins) {
|
||||
const parts = statesPx[p.state];
|
||||
if (parts && !gateInState(p.x, p.y, parts)) out++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function segCrossGate(p, q) {
|
||||
const o = (ax, ay, bx, by, cx, cy) => Math.sign((bx - ax) * (cy - ay) - (by - ay) * (cx - ax));
|
||||
const [a, b] = p, [c, d] = q;
|
||||
return o(a[0], a[1], b[0], b[1], c[0], c[1]) !== o(a[0], a[1], b[0], b[1], d[0], d[1]) &&
|
||||
o(c[0], c[1], d[0], d[1], a[0], a[1]) !== o(c[0], c[1], d[0], d[1], b[0], b[1]);
|
||||
}
|
||||
|
||||
// ── 60x96 classic4 geometry (the 60x96c4b FORMATS entry: w2500 h4000 gutter165) ──
|
||||
const PW = 2500, PH = 4000, PXI = PW / 60; // pageWidthIn 60
|
||||
const SHEET_EDGE = 26, GUTTER = 165;
|
||||
const HEADER = 355, FOOTER = 316;
|
||||
const C4_BAND = Math.round(PH * 0.096);
|
||||
const MAP_X = GUTTER, MAP_W = PW - 2 * GUTTER;
|
||||
const MAP_Y = HEADER + C4_BAND, MAP_H = PH - HEADER - FOOTER - 2 * C4_BAND;
|
||||
const FRAME_X = MAP_X, FRAME_Y = MAP_Y, FRAME_W = MAP_W, FRAME_H = MAP_H;
|
||||
|
||||
// A linear "projection" over an India-ish bbox (68..98 lng, 6..37 lat) into the map rect.
|
||||
const LNG0 = 68, LNG1 = 98, LAT0 = 6, LAT1 = 37;
|
||||
const proj = (lng, lat) => [
|
||||
MAP_X + ((lng - LNG0) / (LNG1 - LNG0)) * MAP_W,
|
||||
MAP_Y + ((LAT1 - lat) / (LAT1 - LAT0)) * MAP_H,
|
||||
];
|
||||
const box = { PW, PH, MAP_X, MAP_W, MAP_Y, MAP_H, HEADER, FOOTER, SHEET_EDGE, GUTTER, C4_BAND, PXI, FRAME_X, FRAME_Y, FRAME_W, FRAME_H, proj };
|
||||
|
||||
// ── fixture: 855 pins across a 6x5 grid of rectangular "states" (lng/lat space) ─
|
||||
// Deterministic PRNG (mulberry32) so pins are varied but fixed run-to-run.
|
||||
function rng(seed) { return () => { seed |= 0; seed = (seed + 0x6D2B79F5) | 0; let t = Math.imul(seed ^ (seed >>> 15), 1 | seed); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
|
||||
function makeFixture(N) {
|
||||
const cols = 6, rows = 5, feats = [];
|
||||
const dLng = (LNG1 - LNG0) / cols, dLat = (LAT1 - LAT0) / rows;
|
||||
for (let c = 0; c < cols; c++) for (let r = 0; r < rows; r++) {
|
||||
const x0 = LNG0 + c * dLng, x1 = x0 + dLng, y0 = LAT0 + r * dLat, y1 = y0 + dLat;
|
||||
feats.push({ properties: { shapeName: `S${c}_${r}` }, geometry: { type: 'Polygon', coordinates: [[[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]]] } });
|
||||
}
|
||||
const rand = rng(12345);
|
||||
const pins = [];
|
||||
for (let i = 0; i < N; i++) {
|
||||
// keep a margin inside a state so the point-in-poly is unambiguous
|
||||
const lng = LNG0 + 0.5 + rand() * (LNG1 - LNG0 - 1);
|
||||
const lat = LAT0 + 0.5 + rand() * (LAT1 - LAT0 - 1);
|
||||
const [px, py] = proj(lng, lat);
|
||||
pins.push({ id: `p${i}`, name: `Group ${i} ${'abcdefgh'[i % 8]}`, lng, lat, _px: px, _py: py, image_url: null });
|
||||
}
|
||||
return { pins, feats };
|
||||
}
|
||||
|
||||
const { pins, feats } = makeFixture(855);
|
||||
const fmt4 = { nameMaxPt: 11, classic4: true, rangeBadge: true, photos: false, pageWidthIn: 60, w: PW, h: PH };
|
||||
const optsBase = { fmt: fmt4, feats };
|
||||
|
||||
// ── 1. fourSides ──────────────────────────────────────────────────────────────
|
||||
const four = await layoutCircular({ pins, states: null, box, mode: 'fourSides', opts: optsBase });
|
||||
note.push(`fourSides: placed ${four.stats.placed}, ringOrdered ${four.stats.numbersRingOrdered}, dupes ${four.stats.numberDupes}, outsideState ${four.stats.pinsOutsideState}, islandFallback ${four.stats.islandFallback}, namePt ${four.stats.namePt}, sides ${JSON.stringify(four.stats.sides)}`);
|
||||
if (!four.stats.numbersRingOrdered) fails.push('fourSides: numbers not ring-ordered 1..N');
|
||||
if (four.stats.numberDupes !== 0) fails.push(`fourSides: ${four.stats.numberDupes} duplicate numbers`);
|
||||
if (four.stats.pinsOutsideState !== 0) fails.push(`fourSides: ${four.stats.pinsOutsideState} pins outside their state`);
|
||||
if (four.stats.placed < 800) fails.push(`fourSides: only ${four.stats.placed} pins placed (floor 800) — vacuous`);
|
||||
// (3) SIDE SEQUENCE: numbering must run L < T < R < B, and be monotone within each
|
||||
// side — numbersRingOrdered alone (1..N, no gap) passes a scrambled side order too.
|
||||
{
|
||||
const SEQ = ['L', 'T', 'R', 'B'];
|
||||
const bySide = { L: [], T: [], R: [], B: [] };
|
||||
for (const p of four.pins) (bySide[p.side] || (bySide[p.side] = [])).push(p.num);
|
||||
// side ranges from the pins (for the L<T<R<B sequence)
|
||||
let lo = 0, seqOk = true;
|
||||
for (const sd of SEQ) {
|
||||
const nums = bySide[sd] || [];
|
||||
for (const n of nums) if (n <= lo) seqOk = false;
|
||||
if (nums.length) lo = Math.max(lo, ...nums);
|
||||
}
|
||||
// monotone WITHIN a side = tested against GEOMETRY, not the emission arrays (which
|
||||
// numbering walks, so an emission-order check cannot fail — studio P2). Per classic4:
|
||||
// L cy DESC (num↑ ⇒ screen y DOWN), R cy ASC (y UP), T cx ASC (x UP), B cx DESC (x DOWN).
|
||||
// Pins are post-spread, so allow a drift tolerance = 60% of the side's mean step; a
|
||||
// reversed sort (studio's poison) still fails, normal de-overlap drift does not.
|
||||
const AXIS = { L: ['y', -1], R: ['y', +1], T: ['x', +1], B: ['x', -1] };
|
||||
let monoOk = true, monoWhy = '';
|
||||
for (const sd of SEQ) {
|
||||
const ps = four.pins.filter((p) => p.side === sd).sort((a, b) => a.num - b.num);
|
||||
if (ps.length < 3) continue;
|
||||
const [axis, dir] = AXIS[sd];
|
||||
const coords = ps.map((p) => p[axis] * dir); // expected non-decreasing
|
||||
const span = coords[coords.length - 1] - coords[0];
|
||||
const tol = 0.6 * Math.abs(span) / (coords.length - 1); // 60% of mean step
|
||||
let inversions = 0;
|
||||
for (let i = 1; i < coords.length; i++) if (coords[i] < coords[i - 1] - tol) inversions++;
|
||||
// a correct side has only small local drift inversions; a reversed sort inverts ~everything
|
||||
if (inversions > coords.length * 0.2) { monoOk = false; monoWhy = `${sd}:${inversions}/${coords.length}`; }
|
||||
}
|
||||
if (!seqOk) fails.push('fourSides: numbers not in side sequence L<T<R<B');
|
||||
if (!monoOk) fails.push(`fourSides: numbering not geometrically monotone within a side (${monoWhy})`);
|
||||
// (4) RECOUNT outside-state from the OUTPUT (pins vs state rings), not from stats.
|
||||
const outFx = recountOutside(four.pins, feats);
|
||||
if (outFx !== 0) fails.push(`fourSides: recount found ${outFx} pins outside their state (stats said ${four.stats.pinsOutsideState})`);
|
||||
note.push(`fourSides check: sideSeq ${seqOk}, monotone ${monoOk}, outside(recount) ${outFx}`);
|
||||
}
|
||||
|
||||
// ── 2. pairedRows ─────────────────────────────────────────────────────────────
|
||||
const paired = await layoutCircular({ pins, states: null, box, mode: 'pairedRows', opts: optsBase });
|
||||
note.push(`pairedRows: rows ${paired.stats.rows}, crossings ${paired.stats.crossings}, touches ${paired.stats.touches}, outsideState ${paired.stats.pinsOutsideState}, octilinear ${paired.stats.octilinear}`);
|
||||
if (paired.stats.crossings !== 0) fails.push(`pairedRows: ${paired.stats.crossings} leader crossings (expected 0)`);
|
||||
if (paired.stats.pinsOutsideState !== 0) fails.push(`pairedRows: ${paired.stats.pinsOutsideState} pins outside their state`);
|
||||
if (!paired.stats.octilinear) fails.push('pairedRows: a leader is not octilinear');
|
||||
if (paired.stats.placed < 800) fails.push(`pairedRows: only ${paired.stats.placed} pins placed (floor 800)`);
|
||||
// (4) RECOUNT pairedRows crossings from the OUTPUT leaders[].segs (one id per fork,
|
||||
// skip same-id), and outside-state from the output pins — not from stats.
|
||||
{
|
||||
const segs = [];
|
||||
paired.leaders.forEach((lf, li) => { for (const s of (lf.segs || [])) segs.push({ s, li }); });
|
||||
let xr = 0;
|
||||
for (let i = 0; i < segs.length; i++) for (let j = i + 1; j < segs.length; j++) {
|
||||
if (segs[i].li === segs[j].li) continue;
|
||||
if (segCrossGate(segs[i].s, segs[j].s)) xr++;
|
||||
}
|
||||
if (xr !== 0) fails.push(`pairedRows: recount found ${xr} crossings (stats said ${paired.stats.crossings})`);
|
||||
const outPr = recountOutside(paired.pins, feats);
|
||||
if (outPr !== 0) fails.push(`pairedRows: recount found ${outPr} pins outside their state`);
|
||||
// (P3) every leader must actually carry its two polylines — a dropped polys passed before.
|
||||
const badPolys = paired.leaders.filter((l) => !Array.isArray(l.polys) || l.polys.length !== 2).length;
|
||||
if (badPolys !== 0) fails.push(`pairedRows: ${badPolys} leaders missing polys.length===2`);
|
||||
note.push(`pairedRows check: crossings(recount) ${xr}, outside(recount) ${outPr}, leaders-with-2-polys ${paired.leaders.length - badPolys}/${paired.leaders.length}`);
|
||||
}
|
||||
|
||||
// ── 3. sideLanes ──────────────────────────────────────────────────────────────
|
||||
const sideFmt = { nameMaxPt: 14, sideLanes: true, photos: false, pageWidthIn: 60, w: PW, h: PH };
|
||||
const side = await layoutCircular({ pins, states: null, box: { ...box, LABEL_TOP: HEADER - 40, LABEL_BOT: PH - FOOTER + 40 }, mode: 'sideLanes', opts: { fmt: sideFmt, feats } });
|
||||
note.push(`sideLanes: placed ${side.stats.placed}, crossings ${side.stats.crossings}, touches ${side.stats.touches}, octilinear ${side.stats.octilinear}, sides ${JSON.stringify(side.stats.sides)}`);
|
||||
if (side.stats.placed < 800) fails.push(`sideLanes: only ${side.stats.placed} placed (floor 800)`);
|
||||
if (!side.stats.octilinear) fails.push('sideLanes: leaders not all octilinear');
|
||||
|
||||
// ── 4. determinism ────────────────────────────────────────────────────────────
|
||||
const four2 = await layoutCircular({ pins, states: null, box, mode: 'fourSides', opts: optsBase });
|
||||
if (JSON.stringify(four.labels) !== JSON.stringify(four2.labels) || JSON.stringify(four.dots) !== JSON.stringify(four2.dots)) fails.push('NON-DETERMINISTIC: two fourSides runs differ');
|
||||
|
||||
// ── 5. poison — a tiny state cannot hold its pins → infeasible NAMED ───────────
|
||||
{
|
||||
// one tiny state in lng/lat; pack many pins into it
|
||||
const tinyFeats = [{ properties: { shapeName: 'TINY' }, geometry: { type: 'Polygon', coordinates: [[[80, 20], [80.02, 20], [80.02, 20.02], [80, 20.02], [80, 20]]] } }];
|
||||
const tinyPins = [];
|
||||
for (let i = 0; i < 40; i++) { const [px, py] = proj(80.01, 20.01); tinyPins.push({ id: `t${i}`, name: `T${i}`, lng: 80.01, lat: 20.01, _px: px, _py: py }); }
|
||||
const pf = { nameMaxPt: 11, classic4: true, rangeBadge: false, photos: false, pageWidthIn: 60, w: PW, h: PH };
|
||||
const pres = await layoutCircular({ pins: tinyPins, states: null, box, mode: 'fourSides', opts: { fmt: pf, feats: tinyFeats } });
|
||||
note.push(`poison: infeasible ${pres.stats.infeasible}, outsideState ${pres.stats.pinsOutsideState}`);
|
||||
if (pres.stats.infeasible < 1) fails.push('POISON: a too-small state was NOT named in infeasible');
|
||||
if (pres.stats.pinsOutsideState !== 0) fails.push(`POISON: ${pres.stats.pinsOutsideState} pins escaped the tiny state`);
|
||||
}
|
||||
|
||||
// ── 6. budget (step 2 node half): median of 3, heap delta ───────────────────────
|
||||
// BASELINE: measured on this box at ~1.0-1.4s for 855 pins (fourSides, placePinsInState
|
||||
// 400 iters). Budget fails at 1.5x of 3500ms = 5250ms to leave headroom on a slow CI
|
||||
// box; the browser half (390px, 6x CPU throttle) is measured separately on the shared browser.
|
||||
const BUDGET_MS = 5250;
|
||||
const HEAP_CEIL_MB = 300;
|
||||
const times = [];
|
||||
let heapDelta = 0;
|
||||
for (let k = 0; k < 3; k++) {
|
||||
if (globalThis.gc) globalThis.gc();
|
||||
const h0 = process.memoryUsage().heapUsed;
|
||||
const t0 = process.hrtime.bigint();
|
||||
await layoutCircular({ pins, states: null, box, mode: 'fourSides', opts: optsBase });
|
||||
const t1 = process.hrtime.bigint();
|
||||
times.push(Number(t1 - t0) / 1e6);
|
||||
heapDelta = Math.max(heapDelta, (process.memoryUsage().heapUsed - h0) / 1048576);
|
||||
}
|
||||
times.sort((a, b) => a - b);
|
||||
const medMs = times[1];
|
||||
note.push(`budget: fourSides median ${medMs.toFixed(0)}ms (runs ${times.map((t) => t.toFixed(0)).join('/')}), heapΔ ~${heapDelta.toFixed(0)}MB; budget ${BUDGET_MS}ms / ${HEAP_CEIL_MB}MB`);
|
||||
if (medMs > BUDGET_MS) fails.push(`budget: ${medMs.toFixed(0)}ms over ${BUDGET_MS}ms`);
|
||||
if (heapDelta > HEAP_CEIL_MB) fails.push(`budget: heapΔ ${heapDelta.toFixed(0)}MB over ${HEAP_CEIL_MB}MB`);
|
||||
|
||||
for (const n of note) console.log(` · ${n}`);
|
||||
if (fails.length) {
|
||||
console.error('FAIL check:circular-layout');
|
||||
for (const f of fails) console.error(` ✗ ${f}`);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log(`PASS check:circular-layout — fourSides ring-ordered 0-dupes 0-outside, pairedRows 0-crossings, sideLanes octilinear, deterministic, poison named, ${medMs.toFixed(0)}ms < ${BUDGET_MS}ms budget`);
|
||||
}
|
||||
|
|
@ -7,3 +7,25 @@ export async function sha384(text) {
|
|||
for (const b of d) bin += String.fromCharCode(b)
|
||||
return `sha384-${btoa(bin)}`
|
||||
}
|
||||
|
||||
// ★ A PINNED FILE THAT FAILS ITS PIN IS FETCHED ONCE MORE, FRESH. The loaders fetch with cache: 'force-cache' (fast,
|
||||
// and it works offline once cached), which returns ANY cached copy, however old. After a re-pin, a reader who had
|
||||
// printed before kept the previous file: it failed its pin on every print, and the print fell back without a word
|
||||
// (the stored poster for page 1, English for the packet text) until the browser evicted it. So a copy that is not
|
||||
// served or does not match is fetched ONCE more with cache: 'reload', which skips the HTTP cache and refreshes it,
|
||||
// and only that answer decides. Resolves with the verified text; rejects with the last reason (err.integrity is
|
||||
// true when the bytes were wrong rather than missing).
|
||||
export async function fetchPinned(url, pin) {
|
||||
let last = null
|
||||
for (const cache of ['force-cache', 'reload']) {
|
||||
try {
|
||||
const res = await fetch(url, { cache })
|
||||
if (!res.ok) { last = new Error(`not served (${res.status})`); continue }
|
||||
const text = await res.text()
|
||||
const got = await sha384(text)
|
||||
if (got === pin) return text
|
||||
last = Object.assign(new Error(`failed its integrity check (expected ${pin}, got ${got})`), { integrity: true })
|
||||
} catch (e) { last = e }
|
||||
}
|
||||
throw last
|
||||
}
|
||||
|
|
|
|||
11
package.json
11
package.json
|
|
@ -225,6 +225,7 @@
|
|||
"check:selector-fields:self-test": "node internal/check-selector-fields.mjs --self-test",
|
||||
"check:packet-strings-parity": "node internal/check-packet-strings-parity.mjs",
|
||||
"check:packet-variants": "node internal/check-packet-variants.mjs",
|
||||
"check:circular-layout": "node library/packet/scripts/check-circular-layout.mjs",
|
||||
"check:fork-leaders": "node library/packet/scripts/check-fork-leaders.mjs",
|
||||
"check:pins-in-state": "node library/packet/scripts/check-pins-in-state.mjs",
|
||||
"check:label-key-coverage": "node internal/check-label-key-coverage.mjs",
|
||||
|
|
@ -355,8 +356,8 @@
|
|||
"dev": "bun x vite",
|
||||
"fix:sri": "node internal/fix-sri.mjs",
|
||||
"gallery": "node internal/generate-gallery.mjs",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh",
|
||||
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
||||
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
||||
"library-index": "node internal/generate-library-index.mjs",
|
||||
|
|
@ -435,9 +436,12 @@
|
|||
"check:host-floor": "node internal/check-host-floor.mjs",
|
||||
"check:host-floor:self-test": "node internal/check-host-floor.mjs --self-test",
|
||||
"check:phone-print-keep": "node internal/check-phone-print-keep.mjs",
|
||||
"check:phone-print-keep:self-test": "node internal/check-phone-print-keep.mjs --self-test"
|
||||
"check:phone-print-keep:self-test": "node internal/check-phone-print-keep.mjs --self-test",
|
||||
"check:pinned-fetch-fresh": "bun internal/check-pinned-fetch-fresh.mjs",
|
||||
"check:pinned-fetch-fresh:self-test": "bun internal/check-pinned-fetch-fresh.mjs --self-test"
|
||||
},
|
||||
"//scripts": {
|
||||
"check:pinned-fetch-fresh": "a STALE cached copy of a pinned print-time file never decides a print: library/packet/sha384.js fetchPinned fetches force-cache, and on a copy that is not served or fails its pin, ONCE more with cache:'reload'; every pinned loader (posterSheets poster-render.js + ne-places.json, packetStrings, indiaStates) calls it, and the classic-script path refreshes the cache and retries a refused tag once. With a modelled HTTP cache holding stale copies: the current file after one fresh refetch; a matching cached copy used with one force-cache request; wrong bytes refused; page 1 still draws (generateSheet), the packet keeps every language, India keeps its 36 states. Self-test poisons: no fresh refetch, never the cache, a mismatch accepted, a loader fetching its pinned file directly.",
|
||||
"check:phone-print-keep": "on a PHONE the in-page print document (#dxm-print-root and its print style, library/composables/printInPlace.js) and printImageBlob's object URL outlive afterprint, because Android Chrome fires afterprint once the PREVIEW is built and renders a saved PDF later, from the page as it is then (a phone's saved packet was the bare host page). A timeline on fake timers and a stub DOM with an Android user agent: still mounted 30 s after afterprint; released once the reader is back (shown again after hidden, focused again after blur, or touched after print() but not in its first TOUCH_SETTLE_MS) plus BACK_GRACE_MS (60 s), or at the ceiling; going away again during the grace cancels the pending drop; the Print tap of a late print does not count; a new print replaces it; desktop is the frame path, verbatim. --impl=<path> runs it against another copy (the pre-fix file fails). Self-test poisons: the old drop at afterprint, no release when back, listeners armed at mount, no grace, printImageBlob revoking at afterprint, no ceiling, no cancel when away again, no touch settle window.",
|
||||
"_": "What each script does. These notes used to sit inside the command strings as trailing \"# …\" comments, which made the shell discard any arguments passed after \"--\" (so a gate given --url silently measured its hardcoded default port — possibly another agent's server). Keep notes here, never in a command.",
|
||||
"browser-gates": "lists every package.json script that launches a browser (the same detection run-parallel uses to route them through internal/browser-slot.sh). Run each as internal/browser-slot.sh bun run <name>.",
|
||||
|
|
@ -589,6 +593,7 @@
|
|||
"check:packet-variants": "the poster wall's Prayer List prints the PACKET (not the columnar list), and every variant it offers exists in packet-render's VARIANTS. A variant may drop fixed pages but never people: lightweight keeps every group. By the UPG-100 owner; mutation-tested. Headless; in gates:pre.",
|
||||
"check:pins-in-state": "library/packet/pins-in-state.js places whole-India poster pins so no two overlap AND every pin stays inside its own ADM1 state polygon, at the 60x96in sheet scale (2500x4000px, PIN_R 8). A deterministic repulsion relaxation (imitating poster-render.js, read not called) with the map-rect clamp replaced by a per-state multipolygon clamp: a pin pushed off its land is pulled to the nearest point just inside, holes and multi-part states (islands/coasts) honoured. Runs on the real India 855-pin data when present, else a synthetic 60x96 fixture (floor 200 pins, no vacuous pass); asserts 0 pins outside their state and 0 overlaps that are not NAMED in `infeasible` (a too-small state is reported, never silently stacked), plus a hole/island arm and a poison arm. Node only, headless, deterministic.",
|
||||
"check:fork-leaders": "library/packet/fork-leaders.js routes ONE paired-row leader as an octilinear fork: a stem forks at a 45° chamfer into two short H/V legs, one per pin. Modes row and trunk. Returns polylines + a deduped segs list (one polyline id per fork for crossings). Reports octilinear + throughPins. Pure, px-only, deterministic. The gate asserts both modes octilinear, legs land on pins, 0 crossings on a 220-row set (floor 200), through-pin hit+miss, determinism, and a poison. Node only, headless.",
|
||||
"check:circular-layout": "library/packet/circularLayout.js is the poster circular-logic (ring order + leader routing + numbered four-sides + paired-row forks) as one pure Worker-safe module: numbers in, geometry out, no SVG. Modes sideLanes, fourSides (numbered, no leaders), pairedRows (two leaders/row). forkRoute + placePinsInState are static imports (opts may override). Gate asserts on a frozen 855-pin 60x96 fixture: fourSides ring-ordered + 0 dupes + 0 pins-outside-state + side sequence L<T<R<B + geometric monotonicity, pairedRows 0 crossings + octilinear + every leader polys.length===2, determinism, a poison, output recounts, and a node budget. Deterministic; ties by code unit. Node only, headless.",
|
||||
"check:label-key-coverage": "node internal/check-label-key-coverage.mjs",
|
||||
"check:host-locale-fetch": "node internal/check-host-locale-fetch.mjs",
|
||||
"check:packet-a1-structure": "the prayer packet is built to its specified structure, read page by page from each sheet's CONTENT: full detail = map, triangle, life calendar, % evangelical, profiles, bounded set, centered set, wheel, points; lightweight = map, triangle, profiles, wheel, points. Page 1 places a map-only vertical sheet on the packet's own margin and says it is one of the UPG 100 prayer lists only when a count is supplied; page 2 is one inverted triangle whose packets tier and \"- N\" steps appear only where true; the wheel carries the Metacamp Module 1 PDF's colours and opens at nine o'clock; all 28 legend zones resolve, Deaf included.",
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Toggle list", openViews: "Open the list of views", expandList: "Expand list", collapseList: "Collapse list", collapse: "Collapse", home: "Back to homepage",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Prayer Walk Planner", 'tab.upg-neighbor': "UPG Neighbor", 'tab.key-cities': "Key Cities", 'tab.all-people-groups': "All People Groups", 'tab.pplr-data-maps': "PPLR Data Maps", 'tab.wall-of-people-groups': "Wall of People Groups", 'tab.bless-india-posters': "Bless India Posters", 'tab.country-posters': "Country Posters", 'sub.country-posters': "a poster for every country", 'tab.poster-design': "Poster Design", 'sub.poster-design': "every poster style and size", 'tab.doxa-vision-card': "Doxa Vision Card",
|
||||
'tab.prayer-walk-planner': "Prayer Walk Planner", 'tab.upg-neighbor': "UPG Neighbor", 'tab.key-cities': "Key Cities", 'tab.all-people-groups': "All People Groups", 'tab.pplr-data-maps': "PPLR Data Maps", 'tab.wall-of-people-groups': "Wall of People Groups", 'tab.bless-india-posters': "Bless India Posters", 'tab.gospel-internet': "Gospel × Internet", 'tab.country-posters': "Country Posters", 'sub.country-posters': "a poster for every country", 'tab.poster-design': "Poster Design", 'sub.poster-design': "every poster style and size", 'tab.doxa-vision-card': "Doxa Vision Card",
|
||||
},
|
||||
es: {
|
||||
backToTop: 'Volver arriba',
|
||||
|
|
@ -55,7 +55,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Mostrar u ocultar la lista", openViews: "Abrir la lista de vistas", expandList: "Expandir la lista", collapseList: "Contraer la lista", collapse: "Contraer", home: "Volver a la página de inicio",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Caminatas de oración", 'tab.upg-neighbor': "Vecino UPG", 'tab.key-cities': "Ciudades clave", 'tab.all-people-groups': "Todos los pueblos", 'tab.pplr-data-maps': "Mapas de datos PPLR", 'tab.wall-of-people-groups': "Muro de los pueblos", 'tab.bless-india-posters': "Pósteres «Bendice a la India»", 'tab.country-posters': "Carteles por país", 'sub.country-posters': "un cartel para cada país", 'tab.poster-design': "Diseño de carteles", 'sub.poster-design': "todos los estilos y tamaños de cartel", 'tab.doxa-vision-card': "Tarjeta de visión Doxa",
|
||||
'tab.prayer-walk-planner': "Caminatas de oración", 'tab.upg-neighbor': "Vecino UPG", 'tab.key-cities': "Ciudades clave", 'tab.all-people-groups': "Todos los pueblos", 'tab.pplr-data-maps': "Mapas de datos PPLR", 'tab.wall-of-people-groups': "Muro de los pueblos", 'tab.bless-india-posters': "Pósteres «Bendice a la India»", 'tab.gospel-internet': "Evangelio × Internet", 'tab.country-posters': "Carteles por país", 'sub.country-posters': "un cartel para cada país", 'tab.poster-design': "Diseño de carteles", 'sub.poster-design': "todos los estilos y tamaños de cartel", 'tab.doxa-vision-card': "Tarjeta de visión Doxa",
|
||||
},
|
||||
fr: {
|
||||
backToTop: 'Retour en haut',
|
||||
|
|
@ -76,7 +76,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Afficher ou masquer la liste", openViews: "Ouvrir la liste des vues", expandList: "Déplier la liste", collapseList: "Replier la liste", collapse: "Replier", home: "Retour à l’accueil",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Marches de prière", 'tab.upg-neighbor': "Voisin UPG", 'tab.key-cities': "Villes clés", 'tab.all-people-groups': "Tous les peuples", 'tab.pplr-data-maps': "Cartes de données PPLR", 'tab.wall-of-people-groups': "Mur des peuples", 'tab.bless-india-posters': "Affiches « Bénis l’Inde »", 'tab.country-posters': "Affiches par pays", 'sub.country-posters': "une affiche pour chaque pays", 'tab.poster-design': "Conception d’affiches", 'sub.poster-design': "tous les styles et formats d’affiche", 'tab.doxa-vision-card': "Carte de vision Doxa",
|
||||
'tab.prayer-walk-planner': "Marches de prière", 'tab.upg-neighbor': "Voisin UPG", 'tab.key-cities': "Villes clés", 'tab.all-people-groups': "Tous les peuples", 'tab.pplr-data-maps': "Cartes de données PPLR", 'tab.wall-of-people-groups': "Mur des peuples", 'tab.bless-india-posters': "Affiches « Bénis l’Inde »", 'tab.gospel-internet': "Évangile × Internet", 'tab.country-posters': "Affiches par pays", 'sub.country-posters': "une affiche pour chaque pays", 'tab.poster-design': "Conception d’affiches", 'sub.poster-design': "tous les styles et formats d’affiche", 'tab.doxa-vision-card': "Carte de vision Doxa",
|
||||
},
|
||||
de: {
|
||||
backToTop: 'Nach oben',
|
||||
|
|
@ -97,7 +97,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Liste ein-/ausblenden", openViews: "Ansichtsliste öffnen", expandList: "Liste ausklappen", collapseList: "Liste einklappen", collapse: "Einklappen", home: "Zurück zur Startseite",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Gebetsspaziergänge", 'tab.upg-neighbor': "UPG-Nachbar", 'tab.key-cities': "Schlüsselstädte", 'tab.all-people-groups': "Alle Volksgruppen", 'tab.pplr-data-maps': "PPLR-Datenkarten", 'tab.wall-of-people-groups': "Wand der Volksgruppen", 'tab.bless-india-posters': "„Segne Indien“-Poster", 'tab.country-posters': "Länderposter", 'sub.country-posters': "ein Poster für jedes Land", 'tab.poster-design': "Postergestaltung", 'sub.poster-design': "alle Posterstile und -größen", 'tab.doxa-vision-card': "Doxa-Visionskarte",
|
||||
'tab.prayer-walk-planner': "Gebetsspaziergänge", 'tab.upg-neighbor': "UPG-Nachbar", 'tab.key-cities': "Schlüsselstädte", 'tab.all-people-groups': "Alle Volksgruppen", 'tab.pplr-data-maps': "PPLR-Datenkarten", 'tab.wall-of-people-groups': "Wand der Volksgruppen", 'tab.bless-india-posters': "„Segne Indien“-Poster", 'tab.gospel-internet': "Evangelium × Internet", 'tab.country-posters': "Länderposter", 'sub.country-posters': "ein Poster für jedes Land", 'tab.poster-design': "Postergestaltung", 'sub.poster-design': "alle Posterstile und -größen", 'tab.doxa-vision-card': "Doxa-Visionskarte",
|
||||
},
|
||||
pt: {
|
||||
backToTop: 'Voltar ao topo',
|
||||
|
|
@ -118,7 +118,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Mostrar ou ocultar a lista", openViews: "Abrir a lista de visualizações", expandList: "Expandir a lista", collapseList: "Recolher a lista", collapse: "Recolher", home: "Voltar à página inicial",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Caminhadas de oração", 'tab.upg-neighbor': "Vizinho UPG", 'tab.key-cities': "Cidades-chave", 'tab.all-people-groups': "Todos os povos", 'tab.pplr-data-maps': "Mapas de dados PPLR", 'tab.wall-of-people-groups': "Mural dos povos", 'tab.bless-india-posters': "Pôsteres «Abençoe a Índia»", 'tab.country-posters': "Cartazes por país", 'sub.country-posters': "um cartaz para cada país", 'tab.poster-design': "Design de cartazes", 'sub.poster-design': "todos os estilos e tamanhos de cartaz", 'tab.doxa-vision-card': "Cartão de visão Doxa",
|
||||
'tab.prayer-walk-planner': "Caminhadas de oração", 'tab.upg-neighbor': "Vizinho UPG", 'tab.key-cities': "Cidades-chave", 'tab.all-people-groups': "Todos os povos", 'tab.pplr-data-maps': "Mapas de dados PPLR", 'tab.wall-of-people-groups': "Mural dos povos", 'tab.bless-india-posters': "Pôsteres «Abençoe a Índia»", 'tab.gospel-internet': "Evangelho × Internet", 'tab.country-posters': "Cartazes por país", 'sub.country-posters': "um cartaz para cada país", 'tab.poster-design': "Design de cartazes", 'sub.poster-design': "todos os estilos e tamanhos de cartaz", 'tab.doxa-vision-card': "Cartão de visão Doxa",
|
||||
},
|
||||
it: {
|
||||
backToTop: 'Torna su',
|
||||
|
|
@ -141,7 +141,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Mostra o nascondi l’elenco", openViews: "Apri l’elenco delle viste", expandList: "Espandi l’elenco", collapseList: "Comprimi l’elenco", collapse: "Comprimi", home: "Torna alla home page",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Passeggiate di preghiera", 'tab.upg-neighbor': "Vicino UPG", 'tab.key-cities': "Città chiave", 'tab.all-people-groups': "Tutti i popoli", 'tab.pplr-data-maps': "Mappe dati PPLR", 'tab.wall-of-people-groups': "Muro dei popoli", 'tab.bless-india-posters': "Poster «Benedici l’India»", 'tab.country-posters': "Poster per paese", 'sub.country-posters': "un poster per ogni paese", 'tab.poster-design': "Design dei poster", 'sub.poster-design': "tutti gli stili e i formati dei poster", 'tab.doxa-vision-card': "Scheda visione Doxa",
|
||||
'tab.prayer-walk-planner': "Passeggiate di preghiera", 'tab.upg-neighbor': "Vicino UPG", 'tab.key-cities': "Città chiave", 'tab.all-people-groups': "Tutti i popoli", 'tab.pplr-data-maps': "Mappe dati PPLR", 'tab.wall-of-people-groups': "Muro dei popoli", 'tab.bless-india-posters': "Poster «Benedici l’India»", 'tab.gospel-internet': "Vangelo × Internet", 'tab.country-posters': "Poster per paese", 'sub.country-posters': "un poster per ogni paese", 'tab.poster-design': "Design dei poster", 'sub.poster-design': "tutti gli stili e i formati dei poster", 'tab.doxa-vision-card': "Scheda visione Doxa",
|
||||
},
|
||||
ro: {
|
||||
backToTop: 'Sus',
|
||||
|
|
@ -162,7 +162,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Afișează sau ascunde lista", openViews: "Deschide lista de vizualizări", expandList: "Extinde lista", collapseList: "Restrânge lista", collapse: "Restrânge", home: "Înapoi la pagina principală",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Plimbări de rugăciune", 'tab.upg-neighbor': "Vecin UPG", 'tab.key-cities': "Orașe-cheie", 'tab.all-people-groups': "Toate popoarele", 'tab.pplr-data-maps': "Hărți de date PPLR", 'tab.wall-of-people-groups': "Zidul popoarelor", 'tab.bless-india-posters': "Postere „Binecuvântează India”", 'tab.country-posters': "Afișe pe țări", 'sub.country-posters': "un afiș pentru fiecare țară", 'tab.poster-design': "Design de afișe", 'sub.poster-design': "toate stilurile și dimensiunile de afiș", 'tab.doxa-vision-card': "Card de viziune Doxa",
|
||||
'tab.prayer-walk-planner': "Plimbări de rugăciune", 'tab.upg-neighbor': "Vecin UPG", 'tab.key-cities': "Orașe-cheie", 'tab.all-people-groups': "Toate popoarele", 'tab.pplr-data-maps': "Hărți de date PPLR", 'tab.wall-of-people-groups': "Zidul popoarelor", 'tab.bless-india-posters': "Postere „Binecuvântează India”", 'tab.gospel-internet': "Evanghelie × internet", 'tab.country-posters': "Afișe pe țări", 'sub.country-posters': "un afiș pentru fiecare țară", 'tab.poster-design': "Design de afișe", 'sub.poster-design': "toate stilurile și dimensiunile de afiș", 'tab.doxa-vision-card': "Card de viziune Doxa",
|
||||
},
|
||||
ru: {
|
||||
backToTop: 'Наверх',
|
||||
|
|
@ -183,7 +183,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "Показать или скрыть список", openViews: "Открыть список представлений", expandList: "Развернуть список", collapseList: "Свернуть список", collapse: "Свернуть", home: "На главную страницу",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "Молитвенные прогулки", 'tab.upg-neighbor': "Сосед UPG", 'tab.key-cities': "Ключевые города", 'tab.all-people-groups': "Все народы", 'tab.pplr-data-maps': "Карты данных PPLR", 'tab.wall-of-people-groups': "Стена народов", 'tab.bless-india-posters': "Плакаты «Благослови Индию»", 'tab.country-posters': "Плакаты по странам", 'sub.country-posters': "плакат для каждой страны", 'tab.poster-design': "Дизайн плакатов", 'sub.poster-design': "все стили и размеры плакатов", 'tab.doxa-vision-card': "Карточка видения Doxa",
|
||||
'tab.prayer-walk-planner': "Молитвенные прогулки", 'tab.upg-neighbor': "Сосед UPG", 'tab.key-cities': "Ключевые города", 'tab.all-people-groups': "Все народы", 'tab.pplr-data-maps': "Карты данных PPLR", 'tab.wall-of-people-groups': "Стена народов", 'tab.bless-india-posters': "Плакаты «Благослови Индию»", 'tab.gospel-internet': "Евангелие × интернет", 'tab.country-posters': "Плакаты по странам", 'sub.country-posters': "плакат для каждой страны", 'tab.poster-design': "Дизайн плакатов", 'sub.poster-design': "все стили и размеры плакатов", 'tab.doxa-vision-card': "Карточка видения Doxa",
|
||||
},
|
||||
ar: {
|
||||
backToTop: 'إلى الأعلى',
|
||||
|
|
@ -204,7 +204,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "إظهار القائمة أو إخفاؤها", openViews: "فتح قائمة العروض", expandList: "توسيع القائمة", collapseList: "طي القائمة", collapse: "طي", home: "العودة إلى الصفحة الرئيسية",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "جولات الصلاة", 'tab.upg-neighbor': "جار UPG", 'tab.key-cities': "المدن الرئيسية", 'tab.all-people-groups': "جميع الشعوب", 'tab.pplr-data-maps': "خرائط بيانات PPLR", 'tab.wall-of-people-groups': "جدار الشعوب", 'tab.bless-india-posters': "ملصقات باركوا الهند", 'tab.country-posters': "ملصقات الدول", 'sub.country-posters': "ملصق لكل دولة", 'tab.poster-design': "تصميم الملصقات", 'sub.poster-design': "كل أنماط الملصقات وأحجامها", 'tab.doxa-vision-card': "بطاقة رؤية Doxa",
|
||||
'tab.prayer-walk-planner': "جولات الصلاة", 'tab.upg-neighbor': "جار UPG", 'tab.key-cities': "المدن الرئيسية", 'tab.all-people-groups': "جميع الشعوب", 'tab.pplr-data-maps': "خرائط بيانات PPLR", 'tab.wall-of-people-groups': "جدار الشعوب", 'tab.bless-india-posters': "ملصقات باركوا الهند", 'tab.gospel-internet': "الإنجيل × الإنترنت", 'tab.country-posters': "ملصقات الدول", 'sub.country-posters': "ملصق لكل دولة", 'tab.poster-design': "تصميم الملصقات", 'sub.poster-design': "كل أنماط الملصقات وأحجامها", 'tab.doxa-vision-card': "بطاقة رؤية Doxa",
|
||||
},
|
||||
hi: {
|
||||
backToTop: 'ऊपर जाएँ',
|
||||
|
|
@ -225,7 +225,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "सूची दिखाएँ या छिपाएँ", openViews: "दृश्यों की सूची खोलें", expandList: "सूची फैलाएँ", collapseList: "सूची संक्षिप्त करें", collapse: "संक्षिप्त करें", home: "होमपेज पर वापस जाएँ",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "प्रार्थना पदयात्रा", 'tab.upg-neighbor': "UPG पड़ोसी", 'tab.key-cities': "प्रमुख शहर", 'tab.all-people-groups': "सभी जनसमूह", 'tab.pplr-data-maps': "PPLR डेटा मानचित्र", 'tab.wall-of-people-groups': "जनसमूहों की दीवार", 'tab.bless-india-posters': "भारत को आशीष दें — पोस्टर", 'tab.country-posters': "देश पोस्टर", 'sub.country-posters': "हर देश के लिए एक पोस्टर", 'tab.poster-design': "पोस्टर डिज़ाइन", 'sub.poster-design': "हर पोस्टर शैली और आकार", 'tab.doxa-vision-card': "Doxa दर्शन कार्ड",
|
||||
'tab.prayer-walk-planner': "प्रार्थना पदयात्रा", 'tab.upg-neighbor': "UPG पड़ोसी", 'tab.key-cities': "प्रमुख शहर", 'tab.all-people-groups': "सभी जनसमूह", 'tab.pplr-data-maps': "PPLR डेटा मानचित्र", 'tab.wall-of-people-groups': "जनसमूहों की दीवार", 'tab.bless-india-posters': "भारत को आशीष दें — पोस्टर", 'tab.gospel-internet': "सुसमाचार × इंटरनेट", 'tab.country-posters': "देश पोस्टर", 'sub.country-posters': "हर देश के लिए एक पोस्टर", 'tab.poster-design': "पोस्टर डिज़ाइन", 'sub.poster-design': "हर पोस्टर शैली और आकार", 'tab.doxa-vision-card': "Doxa दर्शन कार्ड",
|
||||
},
|
||||
zh: {
|
||||
backToTop: '回到顶部',
|
||||
|
|
@ -246,7 +246,7 @@ export const STRINGS = {
|
|||
// (plugin studio's catalog) so both shells name the same buttons the same way.
|
||||
toggleList: "显示或隐藏列表", openViews: "打开视图列表", expandList: "展开列表", collapseList: "折叠列表", collapse: "折叠", home: "返回首页",
|
||||
// Experimental bundles known today (rail-length names; a bundle not listed keeps its manifest title).
|
||||
'tab.prayer-walk-planner': "祷告行走", 'tab.upg-neighbor': "UPG 邻居", 'tab.key-cities': "重点城市", 'tab.all-people-groups': "所有民族", 'tab.pplr-data-maps': "PPLR 数据地图", 'tab.wall-of-people-groups': "民族之墙", 'tab.bless-india-posters': "祝福印度海报", 'tab.country-posters': "国家海报", 'sub.country-posters': "每个国家一张海报", 'tab.poster-design': "海报设计", 'sub.poster-design': "所有海报样式与尺寸", 'tab.doxa-vision-card': "Doxa 异象卡",
|
||||
'tab.prayer-walk-planner': "祷告行走", 'tab.upg-neighbor': "UPG 邻居", 'tab.key-cities': "重点城市", 'tab.all-people-groups': "所有民族", 'tab.pplr-data-maps': "PPLR 数据地图", 'tab.wall-of-people-groups': "民族之墙", 'tab.bless-india-posters': "祝福印度海报", 'tab.gospel-internet': "福音 × 互联网", 'tab.country-posters': "国家海报", 'sub.country-posters': "每个国家一张海报", 'tab.poster-design': "海报设计", 'sub.poster-design': "所有海报样式与尺寸", 'tab.doxa-vision-card': "Doxa 异象卡",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
* D. posterverse.meta.json `composes` == the bundle/profile of every row whose bundle exists in
|
||||
* plugin-designs/ (two-sided: nothing declared that the rail cannot show, nothing shown undeclared).
|
||||
* E. strings: every locale carries every English key, and every key the shell reads exists in English.
|
||||
* F. a rail label named in LABEL_FOLLOWS equals that plugin's own catalogue title, in every locale.
|
||||
*
|
||||
* Headless, no browser. Exit 0 pass · 1 fail · 75 not measured (no built manifest).
|
||||
*/
|
||||
|
|
@ -40,10 +41,14 @@ const GATED = 'key-cities'
|
|||
// Rows whose plugin is a natural-height page: mounted unpinned so the pane scrolls them. Named, because a
|
||||
// pinned scroll page traps its own content and nothing else would notice.
|
||||
const EXPECT_SCROLL = ['bless-india-posters']
|
||||
// Rail labels that must EQUAL the plugin's own title (vocabulary follows the plugin), per locale:
|
||||
// row id -> [catalogue area file under library/i18n/locales/<locale>/, key inside it]. Copied, not read at
|
||||
// runtime: naming the area from the shell would ship the plugin's whole catalogue inside posterverse.js.
|
||||
const LABEL_FOLLOWS = { 'bless-india-posters': ['blessIndiaPosters.json', 'title'] }
|
||||
|
||||
const sameList = (a, b) => a.length === b.length && a.every((x, i) => x === b[i])
|
||||
|
||||
export function checkShelf({ SECTIONS, TABS, NEVER, resolveTabs, manifest, meta, bundleExists, STRINGS }) {
|
||||
export function checkShelf({ SECTIONS, TABS, NEVER, resolveTabs, manifest, meta, bundleExists, STRINGS, pluginTitles = {} }) {
|
||||
const errs = []
|
||||
const notes = []
|
||||
// A. exact membership, per section, in order
|
||||
|
|
@ -104,6 +109,14 @@ export function checkShelf({ SECTIONS, TABS, NEVER, resolveTabs, manifest, meta,
|
|||
const v = STRINGS[l][k]
|
||||
if (typeof v !== 'string' || !v.trim()) errs.push(`E: ${l} is missing "${k}"`)
|
||||
}
|
||||
// F. labels that follow a plugin's own title, per locale
|
||||
for (const [id, byLocale] of Object.entries(pluginTitles)) {
|
||||
for (const [l, want] of Object.entries(byLocale)) {
|
||||
const got = (STRINGS[l] || {})['tab.' + id]
|
||||
if (want === undefined) errs.push(`F: ${l}: the plugin's own title for ${id} is missing from its catalogue`)
|
||||
else if (got !== want) errs.push(`F: ${l}: tab.${id} is ${JSON.stringify(got)}, the plugin's own title is ${JSON.stringify(want)}`)
|
||||
}
|
||||
}
|
||||
return { errs, notes, counts: { rows: TABS.length, resolved: resolved.length, composes: composes.length, locales: locales.length, keys: Object.keys(en).length } }
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +128,17 @@ async function load() {
|
|||
const mf = join(ROOT, 'public', TREE_NAME, 'manifest.json')
|
||||
const manifest = existsSync(mf) ? JSON.parse(readFileSync(mf, 'utf8')) : null
|
||||
const bundleExists = (b, p) => existsSync(join(ROOT, 'plugin-designs', b, `${p}.vue`))
|
||||
return { ...tabs, STRINGS, meta, manifest, bundleExists }
|
||||
const pluginTitles = {}
|
||||
for (const [id, [file, key]] of Object.entries(LABEL_FOLLOWS)) {
|
||||
pluginTitles[id] = {}
|
||||
for (const l of Object.keys(STRINGS)) {
|
||||
const f = join(ROOT, 'library/i18n/locales', l, file)
|
||||
let v
|
||||
try { const j = JSON.parse(readFileSync(f, 'utf8')); v = key.split('.').reduce((o, k) => (o == null ? o : o[k]), j) } catch { v = undefined }
|
||||
pluginTitles[id][l] = v
|
||||
}
|
||||
}
|
||||
return { ...tabs, STRINGS, meta, manifest, bundleExists, pluginTitles }
|
||||
}
|
||||
|
||||
function selfTest(base) {
|
||||
|
|
@ -130,6 +153,7 @@ function selfTest(base) {
|
|||
['C: a composite row falls back to a leaf', (c) => { c.manifest = clone(c.manifest); const b = c.manifest.bundles.find((x) => x.bundle === 'my-upg-100-list'); b.profiles = b.profiles.filter((p) => p.profile !== 'upg-100-mfe') }, /^C: row upg-100 opens/],
|
||||
['D: composes drift', (c) => { c.meta = { ...c.meta, composes: c.meta.composes.slice(1) } }, /^D: the rail shows/],
|
||||
['D: composes a ref the rail cannot show', (c) => { c.meta = { ...c.meta, composes: [...c.meta.composes, 'key-cities/key-cities'] } }, /^D: meta composes/],
|
||||
['F: a rail label drifts from the plugin title', (c) => { c.STRINGS = clone(c.STRINGS); c.STRINGS.ar['tab.bless-india-posters'] = 'باركوا الهند: ملصقات' }, /^F: ar: tab\.bless-india-posters is/],
|
||||
['E: a locale loses a key', (c) => { c.STRINGS = clone(c.STRINGS); delete c.STRINGS.ar['tab.upg-100'] }, /^E: ar is missing "tab.upg-100"/],
|
||||
['E: a row without an English label', (c) => { c.STRINGS = clone(c.STRINGS); delete c.STRINGS.en['tab.bible-posters'] }, /^E: the shell reads "tab.bible-posters"/],
|
||||
]
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Diseño de carteles', 'sub.poster-design': 'todos los estilos y tamaños de cartel',
|
||||
'tab.wall-of-people-groups': 'Muro de los pueblos',
|
||||
'tab.bible-posters': 'Carteles bíblicos',
|
||||
'tab.bless-india-posters': 'Bendigan a la India: carteles',
|
||||
'tab.bless-india-posters': 'Pósteres «Bendice a la India»',
|
||||
experimentalSub: 'mapa experimental', lab: 'beta',
|
||||
loading: 'Cargando {label}…', loadFailed: 'No se pudo cargar {label}.',
|
||||
manifestHint: 'Esta pestaña se compone a partir de manifest.json: compila el árbol o sirve el árbol compilado para cargarla.',
|
||||
|
|
@ -50,7 +50,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Conception d’affiches', 'sub.poster-design': 'tous les styles et formats d’affiche',
|
||||
'tab.wall-of-people-groups': 'Mur des peuples',
|
||||
'tab.bible-posters': 'Affiches bibliques',
|
||||
'tab.bless-india-posters': 'Bénissez l’Inde : affiches',
|
||||
'tab.bless-india-posters': 'Affiches « Bénis l’Inde »',
|
||||
experimentalSub: 'carte expérimentale', lab: 'bêta',
|
||||
loading: 'Chargement de {label}…', loadFailed: 'Impossible de charger {label}.',
|
||||
manifestHint: "Cet onglet est composé à partir de manifest.json : construisez l'arborescence ou servez l'arborescence construite pour le charger.",
|
||||
|
|
@ -65,7 +65,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Postergestaltung', 'sub.poster-design': 'alle Posterstile und -größen',
|
||||
'tab.wall-of-people-groups': 'Wand der Volksgruppen',
|
||||
'tab.bible-posters': 'Bibelposter',
|
||||
'tab.bless-india-posters': 'Segnet Indien: Poster',
|
||||
'tab.bless-india-posters': '„Segne Indien“-Poster',
|
||||
experimentalSub: 'experimentelle Karte', lab: 'Beta',
|
||||
loading: '{label} wird geladen…', loadFailed: '{label} konnte nicht geladen werden.',
|
||||
manifestHint: 'Dieser Tab wird aus manifest.json zusammengesetzt – bauen Sie den Baum oder stellen Sie den gebauten Baum bereit, um ihn zu laden.',
|
||||
|
|
@ -80,7 +80,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Design de cartazes', 'sub.poster-design': 'todos os estilos e tamanhos de cartaz',
|
||||
'tab.wall-of-people-groups': 'Mural dos povos',
|
||||
'tab.bible-posters': 'Cartazes bíblicos',
|
||||
'tab.bless-india-posters': 'Abençoem a Índia: cartazes',
|
||||
'tab.bless-india-posters': 'Pôsteres «Abençoe a Índia»',
|
||||
experimentalSub: 'mapa experimental', lab: 'beta',
|
||||
loading: 'Carregando {label}…', loadFailed: 'Não foi possível carregar {label}.',
|
||||
manifestHint: 'Esta aba é composta a partir do manifest.json — compile a árvore ou sirva a árvore compilada para carregá-la.',
|
||||
|
|
@ -95,7 +95,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Design dei poster', 'sub.poster-design': 'tutti gli stili e i formati dei poster',
|
||||
'tab.wall-of-people-groups': 'Muro dei popoli',
|
||||
'tab.bible-posters': 'Poster biblici',
|
||||
'tab.bless-india-posters': 'Benedite l’India: poster',
|
||||
'tab.bless-india-posters': 'Poster «Benedici l’India»',
|
||||
experimentalSub: 'mappa sperimentale', lab: 'beta',
|
||||
loading: 'Caricamento di {label}…', loadFailed: 'Impossibile caricare {label}.',
|
||||
manifestHint: "Questa scheda è composta da manifest.json: compila l'albero o pubblica l'albero compilato per caricarla.",
|
||||
|
|
@ -110,7 +110,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Design de afișe', 'sub.poster-design': 'toate stilurile și dimensiunile de afiș',
|
||||
'tab.wall-of-people-groups': 'Zidul popoarelor',
|
||||
'tab.bible-posters': 'Afișe biblice',
|
||||
'tab.bless-india-posters': 'Binecuvântați India: afișe',
|
||||
'tab.bless-india-posters': 'Postere „Binecuvântează India”',
|
||||
experimentalSub: 'hartă experimentală', lab: 'beta',
|
||||
loading: 'Se încarcă {label}…', loadFailed: '{label} nu a putut fi încărcat.',
|
||||
manifestHint: 'Această filă este compusă din manifest.json — construiți arborele sau serviți arborele construit pentru a o încărca.',
|
||||
|
|
@ -125,7 +125,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'Дизайн плакатов', 'sub.poster-design': 'все стили и размеры плакатов',
|
||||
'tab.wall-of-people-groups': 'Стена народов',
|
||||
'tab.bible-posters': 'Библейские плакаты',
|
||||
'tab.bless-india-posters': 'Благословляйте Индию: плакаты',
|
||||
'tab.bless-india-posters': 'Плакаты «Благослови Индию»',
|
||||
experimentalSub: 'экспериментальная карта', lab: 'бета',
|
||||
loading: 'Загрузка: {label}…', loadFailed: 'Не удалось загрузить: {label}.',
|
||||
manifestHint: 'Эта вкладка собирается из manifest.json — соберите дерево или разместите собранное дерево, чтобы загрузить её.',
|
||||
|
|
@ -140,7 +140,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'تصميم الملصقات', 'sub.poster-design': 'كل أنماط الملصقات وأحجامها',
|
||||
'tab.wall-of-people-groups': 'جدار الشعوب',
|
||||
'tab.bible-posters': 'ملصقات الكتاب المقدس',
|
||||
'tab.bless-india-posters': 'باركوا الهند: ملصقات',
|
||||
'tab.bless-india-posters': 'ملصقات باركوا الهند',
|
||||
experimentalSub: 'خريطة تجريبية', lab: 'تجريبي',
|
||||
loading: 'جارٍ تحميل {label}…', loadFailed: 'تعذّر تحميل {label}.',
|
||||
manifestHint: 'تُبنى علامة التبويب هذه من manifest.json — ابنِ الشجرة أو قدّم الشجرة المبنية لتحميلها.',
|
||||
|
|
@ -155,7 +155,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': 'पोस्टर डिज़ाइन', 'sub.poster-design': 'हर पोस्टर शैली और आकार',
|
||||
'tab.wall-of-people-groups': 'जनसमूहों की दीवार',
|
||||
'tab.bible-posters': 'बाइबल पोस्टर',
|
||||
'tab.bless-india-posters': 'भारत को आशीष दो: पोस्टर',
|
||||
'tab.bless-india-posters': 'भारत को आशीष दें — पोस्टर',
|
||||
experimentalSub: 'प्रायोगिक मानचित्र', lab: 'बीटा',
|
||||
loading: '{label} लोड हो रहा है…', loadFailed: '{label} लोड नहीं हो सका।',
|
||||
manifestHint: 'यह टैब manifest.json से बनता है — इसे लोड करने के लिए ट्री बनाएँ या बना हुआ ट्री सर्व करें।',
|
||||
|
|
@ -170,7 +170,7 @@ export const STRINGS = {
|
|||
'tab.poster-design': '海报设计', 'sub.poster-design': '所有海报样式与尺寸',
|
||||
'tab.wall-of-people-groups': '民族之墙',
|
||||
'tab.bible-posters': '圣经海报',
|
||||
'tab.bless-india-posters': '祝福印度:海报',
|
||||
'tab.bless-india-posters': '祝福印度海报',
|
||||
experimentalSub: '实验性地图', lab: '测试版',
|
||||
loading: '正在加载{label}…', loadFailed: '无法加载{label}。',
|
||||
manifestHint: '此标签页由 manifest.json 组成——请构建目录树或提供已构建的目录树以加载它。',
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <bless-india-posters> custom element. -->
|
||||
<script src="../bless-india-posters.js" integrity="sha384-N4Is1VLeBix374JisKagCQ7GdOv5sQ3ZC3U06EJWCntIK5uZxp3KRWAAlqzDZ4hE" crossorigin="anonymous"></script>
|
||||
<script src="../bless-india-posters.js" integrity="sha384-F/xHry5clzqFNR6xCRL+2XDeV3MTD5Ulz5EH8wKdRwwQfMfrb6kBlYel/k6YBAhW" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
|
||||
<script src="../country-posters.js" integrity="sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t" crossorigin="anonymous"></script>
|
||||
<script src="../country-posters.js" integrity="sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||
<script src="../../doxa-maps-spa.js" integrity="sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj" crossorigin="anonymous"></script>
|
||||
<script src="../../doxa-maps-spa.js" integrity="sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
|
||||
<script src="../doxa-maps-spa.js" integrity="sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj" crossorigin="anonymous"></script>
|
||||
<script src="../doxa-maps-spa.js" integrity="sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@
|
|||
"bundle": "bless-india-posters",
|
||||
"scriptUrl": "./bless-india-posters/bless-india-posters.js",
|
||||
"output": "dx-maps/bless-india-posters/bless-india-posters.js",
|
||||
"integrity": "sha384-N4Is1VLeBix374JisKagCQ7GdOv5sQ3ZC3U06EJWCntIK5uZxp3KRWAAlqzDZ4hE",
|
||||
"integrity": "sha384-F/xHry5clzqFNR6xCRL+2XDeV3MTD5Ulz5EH8wKdRwwQfMfrb6kBlYel/k6YBAhW",
|
||||
"elements": [
|
||||
"bless-india-posters"
|
||||
],
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
"scriptUrl": "./bless-india-posters/bless-india-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./bless-india-posters/bless-india-posters/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=\"./bless-india-posters/bless-india-posters.js\" integrity=\"sha384-N4Is1VLeBix374JisKagCQ7GdOv5sQ3ZC3U06EJWCntIK5uZxp3KRWAAlqzDZ4hE\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<bless-india-posters profile-config='{\"profile\":\"bless-india-posters\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bless-india-posters>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./bless-india-posters/bless-india-posters.js\" integrity=\"sha384-F/xHry5clzqFNR6xCRL+2XDeV3MTD5Ulz5EH8wKdRwwQfMfrb6kBlYel/k6YBAhW\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<bless-india-posters profile-config='{\"profile\":\"bless-india-posters\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bless-india-posters>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -269,7 +269,7 @@
|
|||
"bundle": "country-posters",
|
||||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"output": "dx-maps/country-posters/country-posters.js",
|
||||
"integrity": "sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t",
|
||||
"integrity": "sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS",
|
||||
"elements": [
|
||||
"country-posters-map"
|
||||
],
|
||||
|
|
@ -292,8 +292,8 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -309,7 +309,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"provider\":\"maplibre\",\"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-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -325,8 +325,8 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"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>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -342,7 +342,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/poster-section/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-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"poster-section\",\"provider\":\"maplibre\",\"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-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"poster-section\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -446,7 +446,7 @@
|
|||
"bundle": "doxa-maps-spa",
|
||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||
"integrity": "sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj",
|
||||
"integrity": "sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ",
|
||||
"elements": [
|
||||
"doxa-maps-spa"
|
||||
],
|
||||
|
|
@ -476,7 +476,7 @@
|
|||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -503,7 +503,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz",
|
||||
"integrity": "sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -522,8 +522,8 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -966,7 +966,7 @@
|
|||
"bundle": "my-upg-100-list",
|
||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||
"integrity": "sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD",
|
||||
"integrity": "sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -989,7 +989,7 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1005,8 +1005,8 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1022,8 +1022,8 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1154,7 +1154,7 @@
|
|||
"bundle": "poster-design",
|
||||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"output": "dx-maps/poster-design/poster-design.js",
|
||||
"integrity": "sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR",
|
||||
"integrity": "sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0",
|
||||
"elements": [
|
||||
"poster-design"
|
||||
],
|
||||
|
|
@ -1177,7 +1177,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-design-mfe/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-design-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-design-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1193,7 +1193,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-sizes/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-sizes\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-sizes\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1209,7 +1209,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-styles/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-styles\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-styles\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1218,7 +1218,7 @@
|
|||
"bundle": "poster-sections",
|
||||
"scriptUrl": "./poster-sections/poster-sections.js",
|
||||
"output": "dx-maps/poster-sections/poster-sections.js",
|
||||
"integrity": "sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ",
|
||||
"integrity": "sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv",
|
||||
"elements": [
|
||||
"poster-sections"
|
||||
],
|
||||
|
|
@ -1237,7 +1237,7 @@
|
|||
"scriptUrl": "./poster-sections/poster-sections.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-sections/poster-sections/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=\"./poster-sections/poster-sections.js\" integrity=\"sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-sections profile-config='{\"profile\":\"poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-sections>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-sections/poster-sections.js\" integrity=\"sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-sections profile-config='{\"profile\":\"poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-sections>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1382,7 +1382,7 @@
|
|||
"bundle": "posterverse",
|
||||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"output": "dx-maps/posterverse/posterverse.js",
|
||||
"integrity": "sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9",
|
||||
"integrity": "sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq",
|
||||
"elements": [
|
||||
"posterverse-app"
|
||||
],
|
||||
|
|
@ -1409,7 +1409,7 @@
|
|||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./posterverse/posterverse/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=\"./posterverse/posterverse.js\" integrity=\"sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1494,7 +1494,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD",
|
||||
"integrity": "sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1517,7 +1517,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/country-poster-sections/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-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"country-poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"country-poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1533,8 +1533,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1550,7 +1550,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1566,8 +1566,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1701,7 +1701,7 @@
|
|||
"bundle": "upg-neighbor",
|
||||
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
|
||||
"output": "dx-maps/upg-neighbor/upg-neighbor.js",
|
||||
"integrity": "sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za",
|
||||
"integrity": "sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp",
|
||||
"elements": [
|
||||
"upg-neighbor"
|
||||
],
|
||||
|
|
@ -1720,8 +1720,8 @@
|
|||
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./upg-neighbor/upg-neighbor/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../doxa-research-map.js" integrity="sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz" crossorigin="anonymous"></script>
|
||||
<script src="../doxa-research-map.js" integrity="sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz" crossorigin="anonymous"></script>
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@
|
|||
"bundle": "bless-india-posters",
|
||||
"scriptUrl": "./bless-india-posters/bless-india-posters.js",
|
||||
"output": "dx-maps/bless-india-posters/bless-india-posters.js",
|
||||
"integrity": "sha384-N4Is1VLeBix374JisKagCQ7GdOv5sQ3ZC3U06EJWCntIK5uZxp3KRWAAlqzDZ4hE",
|
||||
"integrity": "sha384-F/xHry5clzqFNR6xCRL+2XDeV3MTD5Ulz5EH8wKdRwwQfMfrb6kBlYel/k6YBAhW",
|
||||
"elements": [
|
||||
"bless-india-posters"
|
||||
],
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
"scriptUrl": "./bless-india-posters/bless-india-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./bless-india-posters/bless-india-posters/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=\"./bless-india-posters/bless-india-posters.js\" integrity=\"sha384-N4Is1VLeBix374JisKagCQ7GdOv5sQ3ZC3U06EJWCntIK5uZxp3KRWAAlqzDZ4hE\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<bless-india-posters profile-config='{\"profile\":\"bless-india-posters\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bless-india-posters>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./bless-india-posters/bless-india-posters.js\" integrity=\"sha384-F/xHry5clzqFNR6xCRL+2XDeV3MTD5Ulz5EH8wKdRwwQfMfrb6kBlYel/k6YBAhW\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<bless-india-posters profile-config='{\"profile\":\"bless-india-posters\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></bless-india-posters>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -269,7 +269,7 @@
|
|||
"bundle": "country-posters",
|
||||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"output": "dx-maps/country-posters/country-posters.js",
|
||||
"integrity": "sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t",
|
||||
"integrity": "sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS",
|
||||
"elements": [
|
||||
"country-posters-map"
|
||||
],
|
||||
|
|
@ -292,8 +292,8 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -309,7 +309,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"provider\":\"maplibre\",\"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-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -325,8 +325,8 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"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>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -342,7 +342,7 @@
|
|||
"scriptUrl": "./country-posters/country-posters.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./country-posters/poster-section/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-tMDfL2HxmYk5+2J1goxHB2aKjzb35maIBZemUmtfST+ZwVTtQHskUGJa+r9cG/2t\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"poster-section\",\"provider\":\"maplibre\",\"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-hItzhbxfYgIKRBgCHxTq9ZUSLrktOTGfqwtiXa0jxhAb2fglUyXYSYHxVrNU/fPS\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<country-posters-map profile-config='{\"profile\":\"poster-section\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -446,7 +446,7 @@
|
|||
"bundle": "doxa-maps-spa",
|
||||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
|
||||
"integrity": "sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj",
|
||||
"integrity": "sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ",
|
||||
"elements": [
|
||||
"doxa-maps-spa"
|
||||
],
|
||||
|
|
@ -476,7 +476,7 @@
|
|||
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-npxyK5BtVl4vjxoMg11/0pGcwx2AOeSs26c7nf5GuwCU9tSjEB0WX3vwWT0ieiZj\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-Iupu7V/Y1jCpZPFNt6vYRrUFBmdTydxMoFxaQ0M/w1XHT2DhonFofebe1p/SuYoJ\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -503,7 +503,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz",
|
||||
"integrity": "sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -522,8 +522,8 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-n6VRb6mvV8rKH+CraDsi5t7eMPWxrH6TVOv9R9M9Rd+dBlKdYRNymJB2AyAg6nvz\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-znuGNmdgiF7KNRlLjsitmtEBs+v5g02PXUdVMqhGJxFz7psYOvcJEwL1yHKNZ8KV\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -966,7 +966,7 @@
|
|||
"bundle": "my-upg-100-list",
|
||||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
|
||||
"integrity": "sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD",
|
||||
"integrity": "sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU",
|
||||
"elements": [
|
||||
"my-upg-100-list-map"
|
||||
],
|
||||
|
|
@ -989,7 +989,7 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1005,8 +1005,8 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1022,8 +1022,8 @@
|
|||
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1154,7 +1154,7 @@
|
|||
"bundle": "poster-design",
|
||||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"output": "dx-maps/poster-design/poster-design.js",
|
||||
"integrity": "sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR",
|
||||
"integrity": "sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0",
|
||||
"elements": [
|
||||
"poster-design"
|
||||
],
|
||||
|
|
@ -1177,7 +1177,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-design-mfe/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-design-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-design-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1193,7 +1193,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-sizes/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-sizes\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-sizes\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1209,7 +1209,7 @@
|
|||
"scriptUrl": "./poster-design/poster-design.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-design/poster-styles/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=\"./poster-design/poster-design.js\" integrity=\"sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-styles\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-design/poster-design.js\" integrity=\"sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-design profile-config='{\"profile\":\"poster-styles\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-design>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1218,7 +1218,7 @@
|
|||
"bundle": "poster-sections",
|
||||
"scriptUrl": "./poster-sections/poster-sections.js",
|
||||
"output": "dx-maps/poster-sections/poster-sections.js",
|
||||
"integrity": "sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ",
|
||||
"integrity": "sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv",
|
||||
"elements": [
|
||||
"poster-sections"
|
||||
],
|
||||
|
|
@ -1237,7 +1237,7 @@
|
|||
"scriptUrl": "./poster-sections/poster-sections.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./poster-sections/poster-sections/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=\"./poster-sections/poster-sections.js\" integrity=\"sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-sections profile-config='{\"profile\":\"poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-sections>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./poster-sections/poster-sections.js\" integrity=\"sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<poster-sections profile-config='{\"profile\":\"poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></poster-sections>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1382,7 +1382,7 @@
|
|||
"bundle": "posterverse",
|
||||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"output": "dx-maps/posterverse/posterverse.js",
|
||||
"integrity": "sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9",
|
||||
"integrity": "sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq",
|
||||
"elements": [
|
||||
"posterverse-app"
|
||||
],
|
||||
|
|
@ -1409,7 +1409,7 @@
|
|||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./posterverse/posterverse/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=\"./posterverse/posterverse.js\" integrity=\"sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1494,7 +1494,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD",
|
||||
"integrity": "sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -1517,7 +1517,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/country-poster-sections/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-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"country-poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"country-poster-sections\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1533,8 +1533,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1550,7 +1550,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -1566,8 +1566,8 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1701,7 +1701,7 @@
|
|||
"bundle": "upg-neighbor",
|
||||
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
|
||||
"output": "dx-maps/upg-neighbor/upg-neighbor.js",
|
||||
"integrity": "sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za",
|
||||
"integrity": "sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp",
|
||||
"elements": [
|
||||
"upg-neighbor"
|
||||
],
|
||||
|
|
@ -1720,8 +1720,8 @@
|
|||
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./upg-neighbor/upg-neighbor/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-HqSdKHcaaQaYtvYxPlILUMKV4V7+gxamlp3ZmLs907KcIWUXGpCzNu/+LiJPXmiD" crossorigin="anonymous"></script>
|
||||
<script src="../my-upg-100-list.js" integrity="sha384-GB1+VanfIYtIBPTw7N3LNrkYywZKEwxc6Nyu1BJ30y/SdsLesRrFhfq69zAixHRU" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-design> custom element. -->
|
||||
<script src="../poster-design.js" integrity="sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR" crossorigin="anonymous"></script>
|
||||
<script src="../poster-design.js" integrity="sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-design> custom element. -->
|
||||
<script src="../poster-design.js" integrity="sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR" crossorigin="anonymous"></script>
|
||||
<script src="../poster-design.js" integrity="sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-design> custom element. -->
|
||||
<script src="../poster-design.js" integrity="sha384-TcATAe79bd0FU1IBDHv7oGT6r6rq51Ebh2kPFz/6IktKUO/jj2SIFfo3Q3SPIKpR" crossorigin="anonymous"></script>
|
||||
<script src="../poster-design.js" integrity="sha384-QdRaV8A13ObkrWdo6zRj3KO9k7EubF3zw8EtDrOhwhs5c2/shlMUUBds/FreVAG0" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <poster-sections> custom element. -->
|
||||
<script src="../poster-sections.js" integrity="sha384-tclMXCMWIj0yJIQiNm53iKOVQ1rTr9SfvrzwLX6UHvXIzflongV3exo+I5+jHDBJ" crossorigin="anonymous"></script>
|
||||
<script src="../poster-sections.js" integrity="sha384-DVk9jhTsT7XrNPJZ5lKquqNeM33fOjRJNUkduckdlXyiQklDj0cA2hnko4lkj7kv" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <posterverse-app> custom element. -->
|
||||
<script src="../../posterverse.js" integrity="sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9" crossorigin="anonymous"></script>
|
||||
<script src="../../posterverse.js" integrity="sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <posterverse-app> custom element. -->
|
||||
<script src="../posterverse.js" integrity="sha384-HTRxdoXjuz/Pt8Z0ReAFj1n2FoKHopWMbxkQ0Ph3lmaonh3ux0r5Gd4z7F8MoIj9" crossorigin="anonymous"></script>
|
||||
<script src="../posterverse.js" integrity="sha384-fhGrEVacRshXwvvIkRf5ki1FVUD3KZ+f5BoNMKO/n7AnkUnjRzhQsZb5/N9zO7Lq" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-fc/Y67GjGyNZDDUpjNtDoVWThuDk2qUEQ3XIoxrvXeloheSv/XcylccJf+XijeWD" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-TTP6I2SoYK+KRiC71PzX/BCxTOf0IgmhiUBEwSvPUl5EPH7BOJjPr+gv/5vG0P4h" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-S+QWlHax5SLCSpfyP/dNBuDfVrLhptZOM8fTqOBpjHPljZw4FmqMDkLB5raOp9za" crossorigin="anonymous"></script>
|
||||
<script src="../../upg-neighbor.js" integrity="sha384-h4ndNKMjWZNCdCZlbonIpEFy0urEGgBUgg8scBYZb9ma3qeQhRh4+KqooS8QT/Jp" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue