From d97cf9eab560264c69c03e3209134bc537a17719 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Wed, 23 Sep 2026 19:14:27 +0000 Subject: [PATCH] Say why a tab could not load instead of painting an empty grey pane The Simple Research tab rendered as a featureless grey rectangle with no message, no overlay and nothing in the console. It reads as a broken app, and it hid a plain missing-file condition through four separate reports. Two silent failure paths produced it, one layer apart: - doxa-maps-spa swallowed a failed manifest.json fetch. Every tab except Big Picture is composed from that manifest (Big Picture alone is baked), so losing it leaves each tab with no scriptUrl. mountTab then returns early and the pane stays in state 'idle' -- which renders neither the loading hint nor the error hint. The manifest fetch now tries the built tree location as a second candidate and, if every candidate fails, sets a message the pane displays. - StackLayout's per-section catch deliberately left a failed section's host empty so the rest of the stack still renders. Keeping the stack alive was right; leaving the band blank and silent was not. A failed section now shows which element failed and which URL it came from, and still does not abort its siblings. Tree-relative scriptUrls are also resolved against the manifest they came from rather than the current document. The two roots are identical in the built tree and differ elsewhere, which turned every composed tab's bundle into a 404 against a path that exists nowhere. Measured, built tree: research-map-plus-grid mounts both children, 4778px of content, live canvas, zero 4xx -- unchanged. dashboard-plus-grid, stack-demo and research-map-plus-grid all render with a painted canvas and no failure cards. Where the bundles genuinely cannot be reached, the pane now names the element and the URL instead of showing grey. --- library/layouts/StackLayout.vue | 35 +++++++- .../doxa-maps-spa/doxa-maps-spa.vue | 81 +++++++++++++++++-- .../dashboard-plus-grid.js | 2 +- .../dashboard-plus-grid/default/index.html | 2 +- .../dashboard-plus-grid/index.html | 2 +- .../doxa-maps-spa/app/index.html | 2 +- .../doxa-maps-spa/doxa-maps-spa/index.html | 2 +- public/doxa-maps/index.html | 2 +- public/doxa-maps/manifest.json | 20 ++--- .../research-dashboard/index.html | 2 +- .../research-map-plus-grid.js | 2 +- .../research-map-plus-grid/default/index.html | 2 +- .../research-map-plus-grid/index.html | 2 +- public/doxa-maps/stack-demo/stack-demo.js | 10 +-- .../stack-demo/stack-demo/index.html | 2 +- .../stack-demo/stack-demo/pair/index.html | 2 +- 16 files changed, 135 insertions(+), 35 deletions(-) diff --git a/library/layouts/StackLayout.vue b/library/layouts/StackLayout.vue index 8fdcac86a..a3c64fed2 100644 --- a/library/layouts/StackLayout.vue +++ b/library/layouts/StackLayout.vue @@ -224,7 +224,40 @@ export default defineComponent({ host.innerHTML = '' host.appendChild(el) }) - .catch(() => { /* a failed section leaves its host empty; the rest of the stack still renders */ }) + // ★ A FAILED SECTION MUST SAY SO (BUG-SIMPLE-RESEARCH-GREY-PANE, Driver reported 4x). + // The rest of the stack still renders — that part was always right, and is why this catch + // is per-section rather than around the whole loop. What was wrong is that it left the host + // EMPTY and silent, so a composite whose children all failed rendered as a blank rectangle + // with nothing in the console at this site. MEASURED under the dev server: mounted (count 1) with BOTH children 404 — 794px of pure grey and no message. + // An empty band inside a working page is indistinguishable from a broken app, and it hid + // this defect through four separate reports. + // + // The message is deliberately plain text in the host rather than a thrown error: throwing + // here would abort the other sections, which is the one behaviour this catch exists to + // prevent. Styling stays inline because the host is the consumer's node, not ours. + .catch((e) => { + const why = (e && e.message) || String(e) + console.error('[StackLayout] section "' + sec.key + '" failed to mount <' + + sec.element + '>' + (sec.src ? ' from ' + sec.src : '') + ': ' + why) + try { + host.innerHTML = '' + const d = document.createElement('div') + d.setAttribute('role', 'status') + // overflow-wrap + break-word, because the payload is a URL: a long unbroken path + // otherwise runs straight out of the card (measured — it overflowed the 1024px pane). + // box-sizing + max-width:100% keep the card inside the host: the host can be narrower + // than the message, and without these the margin is ADDED to a 100% width and the text + // runs off the pane (measured — the URL escaped the 1024px pane twice before this). + d.style.cssText = 'box-sizing:border-box;max-width:100%;' + + 'padding:16px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;' + + 'color:#6d766e;background:#fff;border:1px solid #d1d4cd;border-radius:8px;margin:12px 0;' + + 'overflow-wrap:anywhere;word-break:break-word' + d.textContent = 'Could not load <' + sec.element + '>' + + (sec.src ? ' from ' + sec.src : '') + ' — ' + why + host.appendChild(d) + } catch { /* host detached mid-flight: nothing to report into */ } + }) } } }) diff --git a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue index f567ef6b1..2b975fbc1 100644 --- a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue +++ b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue @@ -131,6 +131,15 @@
Could not load {{ t.label }}.
{{ t.error }}
+ +
+ Could not load {{ t.label }}.
+ {{ manifestError }}
+ This tab is composed from manifest.json — build the tree, or serve the built tree, to load it. +
@@ -706,6 +715,14 @@ export default defineComponent({ // onSelect's intercept). '' renders nothing; _noticeTimer clears any earlier message's timeout // so two quick clicks don't fight over when it disappears. disabledNotice: '', _noticeTimer: null, + // Set when EVERY manifest candidate failed. The manifest carries each tab's scriptUrl, so + // without it no src-composed tab can mount; this turns that into a visible pane message + // instead of an empty grey rectangle. See loadManifest(). + manifestError: '', + // The DIRECTORY of the manifest that actually answered, with a trailing slash. Tree-relative + // scriptUrls are resolved against THIS, not the document — see resolve(). Empty until a + // manifest lands, which is exactly when there are no scriptUrls to resolve anyway. + manifestBase: '', // i18n locale switcher (reuses app-wrapper-material/languages.js — persisted, offline, no dep). locale: loadLocale(), localeOpen: false, @@ -927,14 +944,55 @@ export default defineComponent({ // // Fail-soft by design: any error (no manifest shipped, a file:// drop where fetch is blocked, // malformed JSON) leaves the curated tabs unresolved and Experimental empty rather than throwing. + // + // ★ FAIL-SOFT IS NOT FAIL-SILENT (BUG-SIMPLE-RESEARCH-GREY-PANE, Driver reported 4x). + // Every `src`-composed tab — Simple Research, Regions, every map — gets its `scriptUrl` from + // this manifest and from nowhere else. Only tab 1 (Big Picture) is BAKED, so only tab 1 can + // paint without it. When this fetch 404'd the old code swallowed it, mountTab() hit + // `if (!t.scriptUrl) return`, and the pane stayed in state 'idle' — which renders NEITHER the + // loading hint NOR the error hint. The result was a perfectly empty grey pane with no console + // error, no overlay, and a correctly-highlighted rail row: it looks exactly like a mount + // failure and is actually a missing file. MEASURED under `bun run dev` at + // /plugin-designs/doxa-maps-spa/index.html: 404 /plugin-designs/manifest.json, deep element + // count 134, count 0. The SAME shell on the BUILT tree resolved the + // manifest and painted 4778px of content with a live canvas. + // + // TWO CANDIDATES, because the shell runs in two trees that put the manifest in different + // places. The built tree has it beside the bundle folders (resolve() → /manifest.json). + // The dev tree serves SOURCE from /plugin-designs/, where no manifest exists — it is a BUILD + // ARTIFACT and lives under /public/doxa-maps/. Trying the built-tree path second means a dev + // run finds the real manifest instead of going dark, and a production run is unchanged + // (candidate 1 answers, candidate 2 is never requested). loadManifest() { - const url = this.resolve('manifest.json') - try { - fetch(url, { credentials: 'omit' }) - .then(r => (r && r.ok) ? r.json() : null) - .then(m => { if (m) this.applyManifest(m) }) - .catch(() => { /* non-fatal: see pruning note in applyManifest */ }) - } catch { /* fetch unavailable (non-browser): same fail-soft path */ } + const candidates = [this.resolve('manifest.json')] + const devFallback = '/public/doxa-maps/manifest.json' + if (candidates.indexOf(devFallback) === -1) candidates.push(devFallback) + const tried = [] + const attempt = (i) => { + if (i >= candidates.length) { + // Every candidate failed. Record it on the tabs so the PANE says so — see mountTab(). + this.manifestError = 'manifest.json not found (tried ' + tried.join(', ') + ')' + console.error('[doxa-maps-spa] ' + this.manifestError + + ' — every tab except Big Picture is composed from it, so their panes cannot mount.') + return + } + const url = candidates[i] + tried.push(url) + return fetch(url, { credentials: 'omit' }) + .then(r => { if (!r || !r.ok) throw new Error(url + ' → HTTP ' + (r ? r.status : '?')); return r.json() }) + .then(m => { + if (!m) throw new Error(url + ' → empty') + this.manifestError = '' + // Anchor every tree-relative scriptUrl on the directory this manifest came from. + // new URL() against location resolves '../' and rooted forms alike, so a caller- + // supplied treeBase, a built-tree path and the dev fallback all normalise here. + try { this.manifestBase = new URL(url, location.href).href.replace(/[^/]*$/, '') } + catch { this.manifestBase = '' } + this.applyManifest(m) + }) + .catch(() => attempt(i + 1)) + } + try { attempt(0) } catch { /* fetch unavailable (non-browser): same fail-soft path */ } }, // Complete the curated tabs from the manifest, drop any whose bundle this tree does not ship, // then append the discovered Experimental tabs — and finally (re)drive the active tab's mount, @@ -1014,6 +1072,15 @@ export default defineComponent({ // trees rather than a dev-only special case. if (/^(https?:)?\/\//.test(raw) || raw.startsWith('/')) return raw const r = raw.replace(/^\.\//, '') + // ★ TREE-RELATIVE REFS FOLLOW THE MANIFEST THAT SUPPLIED THEM, not this document. + // Every scriptUrl comes out of manifest.json as a tree-relative path ("/.js"), + // so it is only meaningful against the root the MANIFEST was read from. Those two roots are + // the same in the built tree and DIFFERENT under the dev server, where the page is served + // from /plugin-designs/ while the manifest lives at /public/doxa-maps/. Resolving against the + // document there produced 404 /plugin-designs/research-map-plus-grid/research-map-plus-grid.js + // — a path that exists nowhere. Anchoring on the manifest's own directory makes one rule + // correct for both trees (in the built tree manifestBase === base, so nothing changes). + if (this.manifestBase) return this.manifestBase.replace(/\/+$/, '') + '/' + r // Join through exactly one slash: base() normalises to a trailing "/", but a caller-supplied // tree-base may not, and a double slash 404s just as surely as a wrong prefix. if (this.base) return this.base.replace(/\/+$/, '') + '/' + r diff --git a/public/doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js b/public/doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js index 6e9e9db53..51dafeb3e 100644 --- a/public/doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js +++ b/public/doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js @@ -67,7 +67,7 @@ .stl ::-webkit-scrollbar-thumb { background:#c4c8c0; border-radius:8px; } .stl ::-webkit-scrollbar-thumb:hover { background:#9aa197; } .stl ::-webkit-scrollbar-corner { background:transparent; } -`,Zb=An({name:"StackLayout",props:{sections:{type:Array,default:()=>[]},title:{type:String,default:""},maxSectionHeight:{type:String,default:""},minSectionHeight:{type:String,default:""}},setup(){At(Jb,"stack-layout")},data(){return{_hosts:{},_mounted:{}}},mounted(){for(const e of this.sections||[])e.element&&this.mountSection(e)},methods:{registerHost(e,t){t&&(this._hosts[e]=t)},sectionStyle(e){const t={},o=e.maxHeight||this.maxSectionHeight,n=e.minHeight||this.minSectionHeight,r=!!(o&&n&&o===n);return o&&(t.maxHeight=o,r||(t.overflow="auto")),n&&(t.minHeight=n),Object.keys(t).length?t:null},hasDefiniteHeight(e){const t=e.maxHeight||this.maxSectionHeight,o=e.minHeight||this.minSectionHeight;return!!(t&&o&&t===o)},mountSection(e){if(this._mounted[e.key])return;this._mounted[e.key]=!0;const t=this._hosts[e.key];t&&Yb(e.src).then(()=>Xb(e.element)).then(()=>{if(!customElements.get(e.element))return;const o=document.createElement(e.element),n=e.attrs||{};for(const r in n){const s=n[r];try{o[r]=s}catch{}try{o.setAttribute(r,s==null?"":String(s))}catch{}}t.innerHTML="",t.appendChild(o)}).catch(o=>{const n=o&&o.message||String(o);console.error('[StackLayout] section "'+e.key+'" failed to mount <'+e.element+">"+(e.src?" from "+e.src:"")+": "+n);try{t.innerHTML="";const r=document.createElement("div");r.setAttribute("role","status"),r.style.cssText="padding:16px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#6d766e;background:#fff;border:1px solid #d1d4cd;border-radius:8px;margin:12px",r.textContent="Could not load <"+e.element+">"+(e.src?" from "+e.src:"")+" — "+n,t.appendChild(r)}catch{}})}}}),Qb={class:"stl"},e_={key:0,class:"stl-top"},t_={class:"stl-brand"},o_={key:0,class:"stl-title"},n_={class:"stl-meta"},r_={class:"stl-stack"},s_={key:0,class:"stl-sec-head"},a_={class:"stl-sec-title"},l_={key:0,class:"stl-sec-sub"},i_={key:2,class:"stl-slot"},c_={class:"stl-tail"};function u_(e,t,o,n,r,s){return V(),J("div",Qb,[e.$slots.brand||e.$slots.meta||e.title?(V(),J("header",e_,[N("span",t_,[Oo(e.$slots,"brand")]),e.title?(V(),J("b",o_,de(e.title),1)):Ie("",!0),N("span",n_,[Oo(e.$slots,"meta")])])):Ie("",!0),N("div",r_,[(V(!0),J(Se,null,Ye(e.sections,a=>(V(),J("section",{key:a.key,class:je(["stl-sec",{"stl-sec-fill":e.hasDefiniteHeight(a)}]),style:it(e.sectionStyle(a))},[a.title?(V(),J("div",s_,[N("b",a_,de(a.title),1),a.sub?(V(),J("span",l_,de(a.sub),1)):Ie("",!0)])):Ie("",!0),a.element?(V(),J("div",{key:1,class:"stl-host",ref_for:!0,ref:l=>e.registerHost(a.key,l)},null,512)):(V(),J("div",i_,[Oo(e.$slots,"section-"+a.key)]))],6))),128)),N("div",c_,[Oo(e.$slots,"default")])])])}const d_=fn(Zb,[["render",u_],["styles",[Kb]]]);function f_(e){const t={};for(const o of(e==null?void 0:e.facetRail)||[]){const n=Array.isArray(o.drill)?o.drill.filter(Boolean):[];for(let r=0;r!t[n[r]].includes(a))):s}}return t}function p_(){const e=No({}),t=new Set,o=ue(0),n=ue(""),r=new Map;function s(y,p){return r.has(y)||r.set(y,new Set),r.get(y).add(p),()=>{var g;return(g=r.get(y))==null?void 0:g.delete(p)}}function a(y,p){var g;(g=r.get(y))==null||g.forEach(_=>{try{_(p)}catch{}})}let l={};function i(y){l=f_(y)}function c(y,p){if(p==null){delete e[y];for(const g of l[y]||[])delete e[g]}else e[y]=p;a("filter",e)}function u(){Object.keys(e).forEach(y=>delete e[y]),a("filter",e)}function f(y){n.value=y==null?"":String(y),a("search",n.value)}function m(){o.value++,a("select",t)}function v(y){t.has(y)?t.delete(y):t.add(y),m()}function A(){t.size&&(t.clear(),m())}function x(y,{additive:p=!0}={}){let g=!1;p||t.size&&(t.clear(),g=!0);for(const _ of y)t.has(_)||(t.add(_),g=!0);return g&&m(),g}function w(y){let p=!1;for(const g of y)t.delete(g)&&(p=!0);return p&&m(),p}function L(y){const p=y instanceof Set?y:new Set(y);if(p.size===t.size){let g=!0;for(const _ of p)if(!t.has(_)){g=!1;break}if(g)return!1}t.clear();for(const g of p)t.add(g);return m(),!0}return{filterSet:e,selectionSet:t,selectionVersion:o,searchTerm:n,on:s,emit:a,setFilter:c,clearFilters:u,setSearch:f,configureHierarchy:i,toggleSelect:v,clearSelection:A,selectMany:x,deselectMany:w,setSelection:L}}function wa(){return typeof window<"u"&&window.MAP_APP_API_URL||typeof{url:Go&&Go.tagName.toUpperCase()==="SCRIPT"&&Go.src||new URL("dashboard-plus-grid.js",document.baseURI).href}<"u"&&"https://pray.doxa.life"||""}const zt={_meta:{_comment:"Single source of truth for data-source connections across all doxa-maps bundles.",_comment_token:"Mapbox access token is fetched at runtime from window.MAP_TOKEN_URL (same modular pattern as window.MAP_APP_API_URL). Not hardcoded to any host — set mapboxTokenUrl below or override window.MAP_TOKEN_URL on the host page.",mapboxTokenUrl:"window.MAP_TOKEN_URL"},activeSource:"pray-tools",sources:{"pray-tools":{id:"pray-tools",name:"Prayer.Tools API",type:"rest-api",description:"pray.doxa.life live API — people-group prayer, engagement, and adoption data. Base URL read from window.MAP_APP_API_URL or VITE_API_BASE_URL at runtime.",endpoints:{bulk:"/api/people-groups/list",detail:"/api/people-groups/detail/{slug}",statistics:"/api/people-groups/statistics"},queryParams:{lang:"en"},defaultFields:["slug","name","latitude","longitude","wagf_region","wagf_block","wagf_member","rop1","imb_reg_of_people_2","imb_reg_of_people_25","imb_reg_of_people_3","country_code","religion","population","has_photo","image_url","people_praying","people_committed","adopted_by_churches","engagement_status","imb_gsec","primary_language","imb_language_family","imb_language_class","imb_language_speakers"],pollFields:["slug","people_praying"],pollInterval:3e5,fallbackSourceId:null,fieldMappings:{uniqueId:"slug",slug:"slug",name:"name",latitude:"latitude",longitude:"longitude",wagfRegion:"wagf_region",doxaRegion:"wagf_region",wagfBlock:"wagf_block",wagfMember:"wagf_member",affinityBlock:"rop1",countryIso:"country_code",religion:"religion",religionCode:"religion",population:"population",hasPhoto:"has_photo",imageUrl:"image_url",photoUrl:"image_url",peoplePraying:"people_praying",peopleCommitted:"people_committed",engagementStatus:"engagement_status",adoptionStatus:"adopted_by_churches",language:"primary_language",cluster:"imb_reg_of_people_2",peopleGroup:"imb_reg_of_people_25",peopleGroupCountry:"imb_reg_of_people_3",languageFamily:"imb_language_family",languageClass:"imb_language_class",languageSpeakers:"imb_language_speakers"},imageConfig:{useField:"imageUrl",fallbackField:null,fallbackUrlTemplate:null,placeholderUrl:"https://www.peoplegroups.org/images/pgphotosearch/NoImageAvailable_search.jpg",useSvgPlaceholder:!0}},"doxa-csv":{id:"doxa-csv",name:"DOXA People Groups CSV",type:"csv",path:"assets/data/Joshua-project-ids-Doxa-1439.csv",description:"People groups dataset from DOXA / Joshua Project",fieldMappings:{uniqueId:"ROP3",peopleGroupId:"ROP3",countryCode:"ROG",peopleId3:"PeopleID3",name:"Name",displayName:"NmDisp",alternateName:"NmAlt",description:"PeopleDesc",locationDescription:"LocationDe",country:"Ctry",countryIso:"ISOalpha3",region:"Regn",subRegion:"RegnSub",wagfRegion:"WAGF Region",doxaRegion:"WAGF Region",wagfBlock:"WAGF BLOCK",affinityBloc:"Affbloc",affinityBlock:"ROP1",affinityCode:"AffCd",affinityName:"Aff",peopleCluster:"PplClstr",ethneName:"Ethne",latitude:"Latitude",longitude:"Longitude",population:"Pop",populationClass:"PopCls",status:"Status",engagementStatus:"EngStat",evangelicalLevel:"EvngLvl",gsec:"GSEC",gsecBrief:"GSECbrf",gsecLong:"GSEClng",spiScore:"SPI",spiDescription:"SPIdesc",language:"Lang",languageCode:"ROL",languageFamily:"LangFamily",religion:"Rlgn",religionCode:"ROR",religionDescription:"RORdesc",religionBase:"RlgnBs",religionDiv:"RlgnDiv",bible:"Bible",jesusFilm:"Jesus",radio:"Radio",gospel:"Gospel",audio:"Audio",stories:"Stories",resourcesTotal:"ResTot",bibleLevel:"LvlBible",yearPublished:"YrPub",photoCredit:"PicCrdt",photoUrl:"PicURL",hasPhoto:"Photo",isIndigenous:"Indigenous"},imageConfig:{useField:"photoUrl",fallbackField:"peopleId3",fallbackUrlTemplate:"https://joshuaproject.net/assets/media/profiles/photos/p{peopleId3}.jpg",placeholderUrl:"https://www.peoplegroups.org/images/pgphotosearch/NoImageAvailable_search.jpg"}}},systemFields:{uniqueId:{description:"Unique identifier per row (slug for API, ROP3+ROG for CSV)",required:!0},peopleGroupId:{description:"People group ID — same group can appear in multiple countries",required:!0},name:{description:"People group display name",required:!0},latitude:{description:"Latitude coordinate for map pin",required:!0},longitude:{description:"Longitude coordinate for map pin",required:!0},engagementStatus:{description:"Boolean — true if engaged_status = 'engaged'",required:!1},adoptionStatus:{description:"Boolean — true if adopted_by_churches > 0",required:!1},peoplePraying:{description:"Number of people currently praying for this group — from pray-tools API",required:!1},peopleCommitted:{description:"Raw count of committed workers for this group — source of engagementStatus",required:!1},languageFamily:{description:"Language family name",required:!1},religion:{description:"Primary religion",required:!1},population:{description:"Population count",required:!1},doxaRegion:{description:"WAGF/DOXA region name",required:!1},photoUrl:{description:"URL to people group photo",required:!1},description:{description:"People group description text",required:!1}}};function g_(e={}){const t=ue(!1),o=ue(null),n=wn(new Map),r=wn([]),s=ue(null),a=ue(0),l=e.source||zt.activeSource;async function i(){var c,u,f,m;t.value=!0,o.value=null;try{const v=((c=zt==null?void 0:zt.sources)==null?void 0:c[l])||{},A=wa(),x=((u=v.endpoints)==null?void 0:u.bulk)||"/api/people-groups/list",w=(v.defaultFields||[]).join(","),L=((f=v.queryParams)==null?void 0:f.lang)||"en",y=`${A}${x}?${w?`fields=${w}&`:""}lang=${L}&_=${Date.now()}`,p=await fetch(y,{cache:"no-store"});if(!p.ok)throw new Error(`list HTTP ${p.status}`);const g=await p.json(),_=Array.isArray(g)?g:g.posts||g.data||g.results||[],S=new Map;for(const D of _){const I=D&&(D.slug||D.id);I&&S.set(I,D)}n.value=S,r.value=_,a.value=S.size;const $=((m=v.endpoints)==null?void 0:m.statistics)||"/api/people-groups/statistics";try{const D=await fetch(`${A}${$}?_=${Date.now()}`,{cache:"no-store"});D.ok&&(D.headers.get("content-type")||"").includes("json")&&(s.value=await D.json())}catch{}a.value===0&&(o.value="No records loaded from the live API.")}catch(v){o.value=v&&v.message?v.message:String(v)}finally{t.value=!1}}return{loading:t,error:o,rowStore:n,rows:r,stats:s,total:a,load:i,sourceId:l}}const Wr=["slug","name","imb_alternate_name","doxa_wagf_uid","imb_uid","imb_peid","imb_pgid","joshua_project_id","imb_affinity_code","latitude","longitude","country_code","region","wagf_region","wagf_block","wagf_member","imb_subregion","location_description","rop1","imb_reg_of_people_2","imb_reg_of_people_25","imb_reg_of_people_3","primary_language","imb_language_family","imb_language_class","imb_language_speakers","work_in_local_language","imb_is_indigenous","religion","imb_reg_of_religion_3","imb_reg_of_religion_4","population","imb_population_class","believers_count","evangelical_pct","imb_evangelical_level","imb_congregation_existing","people_praying","people_committed","committed_duration","adopted_by_churches","adopted_by_count","adopted_by_names","engagement_status","status","reason_engaged","reason_unlisted","global_start_date","workers_long_term","imb_church_planting","disciple_and_church_multiplication","imb_bible_available","imb_bible_translation_level","imb_bible_year_published","imb_bible_stories_available","imb_audio_scripture_available","imb_gospel_recordings_available","imb_jesus_film_available","imb_radio_broadcast_available","imb_total_resources_available","imb_gsec","imb_lostness_priority_index","imb_strategic_priority_index","has_photo","image_url","picture_credit","imb_people_description"];function ka({rowStore:e,rows:t,selectionSet:o,filterSet:n,FACET_ACC:r,dataOpts:s={},labelFor:a=null}){let l=null,i=null;function c(){return i||(i=(async()=>{var oe,K,W;const _=s.source||zt.activeSource,S=((oe=zt==null?void 0:zt.sources)==null?void 0:oe[_])||{},$=Array.isArray(S.exportFields)&&S.exportFields.length?S.exportFields:Wr,D=((K=S.endpoints)==null?void 0:K.bulk)||"/api/people-groups/list",I=((W=S.queryParams)==null?void 0:W.lang)||"en",H=`${wa()}${D}?fields=${$.join(",")}&lang=${I}`,Q=await fetch(H,{cache:"no-store"});if(!Q.ok)throw new Error(`export list HTTP ${Q.status}`);const se=await Q.json(),_e=Array.isArray(se)?se:se.posts||se.data||se.results||[],q=new Map;for(const T of _e){const B=T&&(T.slug||T.id);B&&q.set(B,T)}return l=q,q})().catch(_=>{throw i=null,_}),i)}function u(_){if(!l)return _;const S=l.get(_&&(_.slug||_.id));return S?{..._,...S}:_}function f(){if(o&&o.size)return[...o].map(S=>e.value.get(S)).filter(Boolean);const _=Object.keys(n);return _.length?(t.value||[]).filter(S=>_.every($=>{const D=r[$];return D?D(S)===n[$]:!0})):t.value||[]}function m(){return o&&o.size?`selection (${o.size})`:Object.keys(n).length?"filter result":"all"}function v(_){return _==null?_:Array.isArray(_)?_.map(S=>v(S)).filter(S=>S!==""&&S!==null&&S!==void 0).join(" | "):typeof _=="object"?_.label??_.value??_.text??_.name??_.link??JSON.stringify(_):_}function A(_){const S={};for(const $ of Object.keys(_))S[$]=v(_[$]);return S}function x(_){let S=_==null?"":String(_);return/^[=+\-@]/.test(S)&&(S="'"+S),/[",\n\r]/.test(S)&&(S='"'+S.replace(/"/g,'""')+'"'),S}function w(){const _=f().map(u).map(A),S=_.reduce((Q,se)=>(Object.keys(se).forEach(_e=>Q.add(_e)),Q),new Set),$=[...Wr.filter(Q=>S.has(Q)),...[...S].filter(Q=>!Wr.includes(Q))],D=Object.entries(n).map(([Q,se])=>`${Q}=${a?a(Q,se):se}`).join(" | ")||"none",I=`# Research Dashboard export — scope: ${m()}; filters: ${D}; rows: ${_.length}`;return[$.map(x).join(","),..._.map(Q=>$.map(se=>x(Q[se])).join(",")),I].join(`\r +`,Zb=An({name:"StackLayout",props:{sections:{type:Array,default:()=>[]},title:{type:String,default:""},maxSectionHeight:{type:String,default:""},minSectionHeight:{type:String,default:""}},setup(){At(Jb,"stack-layout")},data(){return{_hosts:{},_mounted:{}}},mounted(){for(const e of this.sections||[])e.element&&this.mountSection(e)},methods:{registerHost(e,t){t&&(this._hosts[e]=t)},sectionStyle(e){const t={},o=e.maxHeight||this.maxSectionHeight,n=e.minHeight||this.minSectionHeight,r=!!(o&&n&&o===n);return o&&(t.maxHeight=o,r||(t.overflow="auto")),n&&(t.minHeight=n),Object.keys(t).length?t:null},hasDefiniteHeight(e){const t=e.maxHeight||this.maxSectionHeight,o=e.minHeight||this.minSectionHeight;return!!(t&&o&&t===o)},mountSection(e){if(this._mounted[e.key])return;this._mounted[e.key]=!0;const t=this._hosts[e.key];t&&Yb(e.src).then(()=>Xb(e.element)).then(()=>{if(!customElements.get(e.element))return;const o=document.createElement(e.element),n=e.attrs||{};for(const r in n){const s=n[r];try{o[r]=s}catch{}try{o.setAttribute(r,s==null?"":String(s))}catch{}}t.innerHTML="",t.appendChild(o)}).catch(o=>{const n=o&&o.message||String(o);console.error('[StackLayout] section "'+e.key+'" failed to mount <'+e.element+">"+(e.src?" from "+e.src:"")+": "+n);try{t.innerHTML="";const r=document.createElement("div");r.setAttribute("role","status"),r.style.cssText="box-sizing:border-box;max-width:100%;padding:16px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#6d766e;background:#fff;border:1px solid #d1d4cd;border-radius:8px;margin:12px 0;overflow-wrap:anywhere;word-break:break-word",r.textContent="Could not load <"+e.element+">"+(e.src?" from "+e.src:"")+" — "+n,t.appendChild(r)}catch{}})}}}),Qb={class:"stl"},e_={key:0,class:"stl-top"},t_={class:"stl-brand"},o_={key:0,class:"stl-title"},n_={class:"stl-meta"},r_={class:"stl-stack"},s_={key:0,class:"stl-sec-head"},a_={class:"stl-sec-title"},l_={key:0,class:"stl-sec-sub"},i_={key:2,class:"stl-slot"},c_={class:"stl-tail"};function u_(e,t,o,n,r,s){return V(),J("div",Qb,[e.$slots.brand||e.$slots.meta||e.title?(V(),J("header",e_,[N("span",t_,[Oo(e.$slots,"brand")]),e.title?(V(),J("b",o_,de(e.title),1)):Ie("",!0),N("span",n_,[Oo(e.$slots,"meta")])])):Ie("",!0),N("div",r_,[(V(!0),J(Se,null,Ye(e.sections,a=>(V(),J("section",{key:a.key,class:je(["stl-sec",{"stl-sec-fill":e.hasDefiniteHeight(a)}]),style:it(e.sectionStyle(a))},[a.title?(V(),J("div",s_,[N("b",a_,de(a.title),1),a.sub?(V(),J("span",l_,de(a.sub),1)):Ie("",!0)])):Ie("",!0),a.element?(V(),J("div",{key:1,class:"stl-host",ref_for:!0,ref:l=>e.registerHost(a.key,l)},null,512)):(V(),J("div",i_,[Oo(e.$slots,"section-"+a.key)]))],6))),128)),N("div",c_,[Oo(e.$slots,"default")])])])}const d_=fn(Zb,[["render",u_],["styles",[Kb]]]);function f_(e){const t={};for(const o of(e==null?void 0:e.facetRail)||[]){const n=Array.isArray(o.drill)?o.drill.filter(Boolean):[];for(let r=0;r!t[n[r]].includes(a))):s}}return t}function p_(){const e=No({}),t=new Set,o=ue(0),n=ue(""),r=new Map;function s(y,p){return r.has(y)||r.set(y,new Set),r.get(y).add(p),()=>{var g;return(g=r.get(y))==null?void 0:g.delete(p)}}function a(y,p){var g;(g=r.get(y))==null||g.forEach(_=>{try{_(p)}catch{}})}let l={};function i(y){l=f_(y)}function c(y,p){if(p==null){delete e[y];for(const g of l[y]||[])delete e[g]}else e[y]=p;a("filter",e)}function u(){Object.keys(e).forEach(y=>delete e[y]),a("filter",e)}function f(y){n.value=y==null?"":String(y),a("search",n.value)}function m(){o.value++,a("select",t)}function v(y){t.has(y)?t.delete(y):t.add(y),m()}function A(){t.size&&(t.clear(),m())}function x(y,{additive:p=!0}={}){let g=!1;p||t.size&&(t.clear(),g=!0);for(const _ of y)t.has(_)||(t.add(_),g=!0);return g&&m(),g}function w(y){let p=!1;for(const g of y)t.delete(g)&&(p=!0);return p&&m(),p}function L(y){const p=y instanceof Set?y:new Set(y);if(p.size===t.size){let g=!0;for(const _ of p)if(!t.has(_)){g=!1;break}if(g)return!1}t.clear();for(const g of p)t.add(g);return m(),!0}return{filterSet:e,selectionSet:t,selectionVersion:o,searchTerm:n,on:s,emit:a,setFilter:c,clearFilters:u,setSearch:f,configureHierarchy:i,toggleSelect:v,clearSelection:A,selectMany:x,deselectMany:w,setSelection:L}}function wa(){return typeof window<"u"&&window.MAP_APP_API_URL||typeof{url:Go&&Go.tagName.toUpperCase()==="SCRIPT"&&Go.src||new URL("dashboard-plus-grid.js",document.baseURI).href}<"u"&&"https://pray.doxa.life"||""}const zt={_meta:{_comment:"Single source of truth for data-source connections across all doxa-maps bundles.",_comment_token:"Mapbox access token is fetched at runtime from window.MAP_TOKEN_URL (same modular pattern as window.MAP_APP_API_URL). Not hardcoded to any host — set mapboxTokenUrl below or override window.MAP_TOKEN_URL on the host page.",mapboxTokenUrl:"window.MAP_TOKEN_URL"},activeSource:"pray-tools",sources:{"pray-tools":{id:"pray-tools",name:"Prayer.Tools API",type:"rest-api",description:"pray.doxa.life live API — people-group prayer, engagement, and adoption data. Base URL read from window.MAP_APP_API_URL or VITE_API_BASE_URL at runtime.",endpoints:{bulk:"/api/people-groups/list",detail:"/api/people-groups/detail/{slug}",statistics:"/api/people-groups/statistics"},queryParams:{lang:"en"},defaultFields:["slug","name","latitude","longitude","wagf_region","wagf_block","wagf_member","rop1","imb_reg_of_people_2","imb_reg_of_people_25","imb_reg_of_people_3","country_code","religion","population","has_photo","image_url","people_praying","people_committed","adopted_by_churches","engagement_status","imb_gsec","primary_language","imb_language_family","imb_language_class","imb_language_speakers"],pollFields:["slug","people_praying"],pollInterval:3e5,fallbackSourceId:null,fieldMappings:{uniqueId:"slug",slug:"slug",name:"name",latitude:"latitude",longitude:"longitude",wagfRegion:"wagf_region",doxaRegion:"wagf_region",wagfBlock:"wagf_block",wagfMember:"wagf_member",affinityBlock:"rop1",countryIso:"country_code",religion:"religion",religionCode:"religion",population:"population",hasPhoto:"has_photo",imageUrl:"image_url",photoUrl:"image_url",peoplePraying:"people_praying",peopleCommitted:"people_committed",engagementStatus:"engagement_status",adoptionStatus:"adopted_by_churches",language:"primary_language",cluster:"imb_reg_of_people_2",peopleGroup:"imb_reg_of_people_25",peopleGroupCountry:"imb_reg_of_people_3",languageFamily:"imb_language_family",languageClass:"imb_language_class",languageSpeakers:"imb_language_speakers"},imageConfig:{useField:"imageUrl",fallbackField:null,fallbackUrlTemplate:null,placeholderUrl:"https://www.peoplegroups.org/images/pgphotosearch/NoImageAvailable_search.jpg",useSvgPlaceholder:!0}},"doxa-csv":{id:"doxa-csv",name:"DOXA People Groups CSV",type:"csv",path:"assets/data/Joshua-project-ids-Doxa-1439.csv",description:"People groups dataset from DOXA / Joshua Project",fieldMappings:{uniqueId:"ROP3",peopleGroupId:"ROP3",countryCode:"ROG",peopleId3:"PeopleID3",name:"Name",displayName:"NmDisp",alternateName:"NmAlt",description:"PeopleDesc",locationDescription:"LocationDe",country:"Ctry",countryIso:"ISOalpha3",region:"Regn",subRegion:"RegnSub",wagfRegion:"WAGF Region",doxaRegion:"WAGF Region",wagfBlock:"WAGF BLOCK",affinityBloc:"Affbloc",affinityBlock:"ROP1",affinityCode:"AffCd",affinityName:"Aff",peopleCluster:"PplClstr",ethneName:"Ethne",latitude:"Latitude",longitude:"Longitude",population:"Pop",populationClass:"PopCls",status:"Status",engagementStatus:"EngStat",evangelicalLevel:"EvngLvl",gsec:"GSEC",gsecBrief:"GSECbrf",gsecLong:"GSEClng",spiScore:"SPI",spiDescription:"SPIdesc",language:"Lang",languageCode:"ROL",languageFamily:"LangFamily",religion:"Rlgn",religionCode:"ROR",religionDescription:"RORdesc",religionBase:"RlgnBs",religionDiv:"RlgnDiv",bible:"Bible",jesusFilm:"Jesus",radio:"Radio",gospel:"Gospel",audio:"Audio",stories:"Stories",resourcesTotal:"ResTot",bibleLevel:"LvlBible",yearPublished:"YrPub",photoCredit:"PicCrdt",photoUrl:"PicURL",hasPhoto:"Photo",isIndigenous:"Indigenous"},imageConfig:{useField:"photoUrl",fallbackField:"peopleId3",fallbackUrlTemplate:"https://joshuaproject.net/assets/media/profiles/photos/p{peopleId3}.jpg",placeholderUrl:"https://www.peoplegroups.org/images/pgphotosearch/NoImageAvailable_search.jpg"}}},systemFields:{uniqueId:{description:"Unique identifier per row (slug for API, ROP3+ROG for CSV)",required:!0},peopleGroupId:{description:"People group ID — same group can appear in multiple countries",required:!0},name:{description:"People group display name",required:!0},latitude:{description:"Latitude coordinate for map pin",required:!0},longitude:{description:"Longitude coordinate for map pin",required:!0},engagementStatus:{description:"Boolean — true if engaged_status = 'engaged'",required:!1},adoptionStatus:{description:"Boolean — true if adopted_by_churches > 0",required:!1},peoplePraying:{description:"Number of people currently praying for this group — from pray-tools API",required:!1},peopleCommitted:{description:"Raw count of committed workers for this group — source of engagementStatus",required:!1},languageFamily:{description:"Language family name",required:!1},religion:{description:"Primary religion",required:!1},population:{description:"Population count",required:!1},doxaRegion:{description:"WAGF/DOXA region name",required:!1},photoUrl:{description:"URL to people group photo",required:!1},description:{description:"People group description text",required:!1}}};function g_(e={}){const t=ue(!1),o=ue(null),n=wn(new Map),r=wn([]),s=ue(null),a=ue(0),l=e.source||zt.activeSource;async function i(){var c,u,f,m;t.value=!0,o.value=null;try{const v=((c=zt==null?void 0:zt.sources)==null?void 0:c[l])||{},A=wa(),x=((u=v.endpoints)==null?void 0:u.bulk)||"/api/people-groups/list",w=(v.defaultFields||[]).join(","),L=((f=v.queryParams)==null?void 0:f.lang)||"en",y=`${A}${x}?${w?`fields=${w}&`:""}lang=${L}&_=${Date.now()}`,p=await fetch(y,{cache:"no-store"});if(!p.ok)throw new Error(`list HTTP ${p.status}`);const g=await p.json(),_=Array.isArray(g)?g:g.posts||g.data||g.results||[],S=new Map;for(const D of _){const I=D&&(D.slug||D.id);I&&S.set(I,D)}n.value=S,r.value=_,a.value=S.size;const $=((m=v.endpoints)==null?void 0:m.statistics)||"/api/people-groups/statistics";try{const D=await fetch(`${A}${$}?_=${Date.now()}`,{cache:"no-store"});D.ok&&(D.headers.get("content-type")||"").includes("json")&&(s.value=await D.json())}catch{}a.value===0&&(o.value="No records loaded from the live API.")}catch(v){o.value=v&&v.message?v.message:String(v)}finally{t.value=!1}}return{loading:t,error:o,rowStore:n,rows:r,stats:s,total:a,load:i,sourceId:l}}const Wr=["slug","name","imb_alternate_name","doxa_wagf_uid","imb_uid","imb_peid","imb_pgid","joshua_project_id","imb_affinity_code","latitude","longitude","country_code","region","wagf_region","wagf_block","wagf_member","imb_subregion","location_description","rop1","imb_reg_of_people_2","imb_reg_of_people_25","imb_reg_of_people_3","primary_language","imb_language_family","imb_language_class","imb_language_speakers","work_in_local_language","imb_is_indigenous","religion","imb_reg_of_religion_3","imb_reg_of_religion_4","population","imb_population_class","believers_count","evangelical_pct","imb_evangelical_level","imb_congregation_existing","people_praying","people_committed","committed_duration","adopted_by_churches","adopted_by_count","adopted_by_names","engagement_status","status","reason_engaged","reason_unlisted","global_start_date","workers_long_term","imb_church_planting","disciple_and_church_multiplication","imb_bible_available","imb_bible_translation_level","imb_bible_year_published","imb_bible_stories_available","imb_audio_scripture_available","imb_gospel_recordings_available","imb_jesus_film_available","imb_radio_broadcast_available","imb_total_resources_available","imb_gsec","imb_lostness_priority_index","imb_strategic_priority_index","has_photo","image_url","picture_credit","imb_people_description"];function ka({rowStore:e,rows:t,selectionSet:o,filterSet:n,FACET_ACC:r,dataOpts:s={},labelFor:a=null}){let l=null,i=null;function c(){return i||(i=(async()=>{var oe,K,W;const _=s.source||zt.activeSource,S=((oe=zt==null?void 0:zt.sources)==null?void 0:oe[_])||{},$=Array.isArray(S.exportFields)&&S.exportFields.length?S.exportFields:Wr,D=((K=S.endpoints)==null?void 0:K.bulk)||"/api/people-groups/list",I=((W=S.queryParams)==null?void 0:W.lang)||"en",H=`${wa()}${D}?fields=${$.join(",")}&lang=${I}`,Q=await fetch(H,{cache:"no-store"});if(!Q.ok)throw new Error(`export list HTTP ${Q.status}`);const se=await Q.json(),_e=Array.isArray(se)?se:se.posts||se.data||se.results||[],q=new Map;for(const T of _e){const B=T&&(T.slug||T.id);B&&q.set(B,T)}return l=q,q})().catch(_=>{throw i=null,_}),i)}function u(_){if(!l)return _;const S=l.get(_&&(_.slug||_.id));return S?{..._,...S}:_}function f(){if(o&&o.size)return[...o].map(S=>e.value.get(S)).filter(Boolean);const _=Object.keys(n);return _.length?(t.value||[]).filter(S=>_.every($=>{const D=r[$];return D?D(S)===n[$]:!0})):t.value||[]}function m(){return o&&o.size?`selection (${o.size})`:Object.keys(n).length?"filter result":"all"}function v(_){return _==null?_:Array.isArray(_)?_.map(S=>v(S)).filter(S=>S!==""&&S!==null&&S!==void 0).join(" | "):typeof _=="object"?_.label??_.value??_.text??_.name??_.link??JSON.stringify(_):_}function A(_){const S={};for(const $ of Object.keys(_))S[$]=v(_[$]);return S}function x(_){let S=_==null?"":String(_);return/^[=+\-@]/.test(S)&&(S="'"+S),/[",\n\r]/.test(S)&&(S='"'+S.replace(/"/g,'""')+'"'),S}function w(){const _=f().map(u).map(A),S=_.reduce((Q,se)=>(Object.keys(se).forEach(_e=>Q.add(_e)),Q),new Set),$=[...Wr.filter(Q=>S.has(Q)),...[...S].filter(Q=>!Wr.includes(Q))],D=Object.entries(n).map(([Q,se])=>`${Q}=${a?a(Q,se):se}`).join(" | ")||"none",I=`# Research Dashboard export — scope: ${m()}; filters: ${D}; rows: ${_.length}`;return[$.map(x).join(","),..._.map(Q=>$.map(se=>x(Q[se])).join(",")),I].join(`\r `)}const L={rows:0,clipboard:!1,downloaded:!1,at:0,fields:0,wide:!1};function y(){const _=w(),S=f().length,$=(_.split(`\r `)[0]||"").split(",").length;try{typeof window<"u"&&(window.__rdashLastCsv=_)}catch{}let D=!1,I=!1;try{typeof navigator<"u"&&navigator.clipboard&&navigator.clipboard.writeText&&(navigator.clipboard.writeText(_).catch(()=>{}),D=!0)}catch{}try{const H=new Blob([_],{type:"text/csv;charset=utf-8"}),Q=URL.createObjectURL(H),se=document.createElement("a");se.href=Q,se.download="research-dashboard.csv",se.style.display="none",document.body.appendChild(se),se.click(),I=!0,setTimeout(()=>{try{URL.revokeObjectURL(Q),se.remove()}catch{}},200)}catch{}Object.assign(L,{rows:S,clipboard:D,downloaded:I,fields:$,wide:!!l,at:typeof performance<"u"?performance.now():0});try{window.__rdashExportStatus={rows:S,clipboard:D,downloaded:I,fields:$,wide:!!l}}catch{}return{csv:_,rows:S,clipboard:D,downloaded:I,fields:$,wide:!!l}}async function p(){try{await c()}catch{}return y()}function g(){try{return c()}catch{return null}}return{exportCsv:y,exportCsvAsync:p,buildCsv:w,pickRows:f,scopeLabel:m,lastExport:L,prefetchExportFields:g,EXPORT_FIELDS:Wr}}const h_="#6b7280";function m_(){const e=Vr(mo.AFFINITY_BLOCK);return e&&e.propertyKey==="affinityBlock"&&e.palette?e.palette:{}}function b_(e,t){const o=m_();return e&&o[e]?o[e]:h_}function __(e){return(e==null?void 0:e.properties)||e||{}}function $a(e){return e&&typeof e=="object"&&"label"in e?e.label||e.value||"":e}function y_(e){var t;return String(e.affinityBlock||$a((t=e._raw)==null?void 0:t.rop1)||"").trim()}function v_(e){var t;return String(e.affinityBlockLabel||((t=e._raw)!=null&&t.rop1&&typeof e._raw.rop1=="object"?e._raw.rop1.label:"")||"").trim()}function x_(e){var t;return String(e.cluster||$a((t=e._raw)==null?void 0:t.imb_reg_of_people_2)||"").trim()}function w_(e){var t;return String(e.clusterLabel||((t=e._raw)!=null&&t.imb_reg_of_people_2&&typeof e._raw.imb_reg_of_people_2=="object"?e._raw.imb_reg_of_people_2.label:"")||"").trim()}function k_(e){var t;return String(e.peopleGroup||$a((t=e._raw)==null?void 0:t.imb_reg_of_people_25)||"").trim()}function $_(e){var t;return String(e.peopleGroupLabel||((t=e._raw)!=null&&t.imb_reg_of_people_25&&typeof e._raw.imb_reg_of_people_25=="object"?e._raw.imb_reg_of_people_25.label:"")||e.name||"").trim()}function S_(e){var t;return String(e.uniqueId||e.slug||((t=e._raw)==null?void 0:t.slug)||"").trim()}function E_(e){var t;return String(e.name||e.displayName||((t=e._raw)==null?void 0:t.name)||"").trim()}function A_(e){var o;const t=Number(e.population??e.populationNum??((o=e._raw)==null?void 0:o.population)??0);return Number.isFinite(t)?t:0}function C_(e){return String(e.countryName||e.country||e.countryIsoLabel||e.countryIso||"").trim()}function T_(e){const t=le(()=>{const s=e&&e.value||[],a=new Map;for(const l of s){const i=__(l),c=y_(i),u=v_(i)||c||"— Unknown —",f=x_(i),m=w_(i)||f||"— Unknown —",v=k_(i),A=$_(i)||v||"— Unknown —",x=S_(i),w=E_(i)||x,L=A_(i),y=C_(i);if(!x)continue;let p=a.get(c||"__unknown__");p||(p={code:c,label:u,count:0,pop:0,memberIds:[],clusters:new Map},a.set(c||"__unknown__",p)),p.count+=1,p.pop+=L,p.memberIds.push(x);let g=p.clusters.get(f||"__unknown__");g||(g={code:f,label:m,count:0,pop:0,memberIds:[],peopleGroups:new Map},p.clusters.set(f||"__unknown__",g)),g.count+=1,g.pop+=L,g.memberIds.push(x);let _=g.peopleGroups.get(v||"__unknown__");_||(_={code:v,label:A,count:0,pop:0,memberIds:[],instances:[]},g.peopleGroups.set(v||"__unknown__",_)),_.count+=1,_.pop+=L,_.memberIds.push(x),_.instances.push({id:x,name:w,country:y,pop:L})}return a}),o=s=>s&&s.length?["in",["get","uniqueId"],["literal",s]]:["==",["get","uniqueId"],"__none__"],n=le(()=>{const s=t.value,a=[];for(const l of s.values()){const i=b_(l.code,l.label),c={id:`bloc:${l.code||l.label}`,label:l.label,color:i,count:l.count,pop:l.pop,filter:o(l.memberIds),children:[]};for(const u of l.clusters.values()){const f={id:`cluster:${l.code}__${u.code||u.label}`,label:`${u.label} (Cluster)`,color:i,count:u.count,pop:u.pop,filter:o(u.memberIds),children:[]};for(const m of u.peopleGroups.values()){const v={id:`pg:${l.code}__${u.code}__${m.code||m.label}`,label:`${m.label} (PG)`,color:i,count:m.count,pop:m.pop,filter:o(m.memberIds),children:[]};m.instances.sort((A,x)=>x.pop-A.pop||A.country.localeCompare(x.country));for(const A of m.instances)v.children.push({id:`pgic:${A.id}`,label:`${A.country?`${A.name}, ${A.country}`:A.name} (PGIC)`,color:i,count:1,pop:A.pop,filter:["==",["get","uniqueId"],A.id],children:[]});f.children.push(v)}f.children.sort((m,v)=>v.count-m.count||v.pop-m.pop),c.children.push(f)}c.children.sort((u,f)=>f.count-u.count||f.pop-u.pop),a.push(c)}return a.sort((l,i)=>i.count-l.count||i.pop-l.pop),a});function r(s){if(typeof window>"u"||typeof window.CustomEvent!="function")return;if(!s){window.dispatchEvent(new CustomEvent("legend:highlight",{detail:{kind:null}}));return}const a=String(s.id||""),l={kind:null,label:s.label,filterExpr:s.filter};a.startsWith("bloc:")?l.kind="bloc":a.startsWith("cluster:")?l.kind="cluster":a.startsWith("pg:")?l.kind="people-group":a.startsWith("pgic:")&&(l.kind="people-group-in-country"),window.dispatchEvent(new CustomEvent("legend:highlight",{detail:l}))}return{aggregated:t,affinityTree:n,highlight:r}}function Wn(e,t,o){const n=le(()=>{const i=t&&o&&t.sources&&t.sources[o];return i&&i.features||[]}),{aggregated:r}=T_(n),s=le(()=>{const i=(e&&e.facetRail||[]).find(c=>c.tree==="affinity");return i&&i.drill||[]}),a=le(()=>{const[i,c,u]=s.value,f=new Map,m=new Map,v=new Map;for(const x of r.value.values()){x.code&&f.set(x.code,x.label);for(const w of x.clusters.values()){w.code&&m.set(w.code,w.label);for(const L of w.peopleGroups.values())L.code&&v.set(L.code,L.label)}}const A={};return i&&(A[i]=f),c&&(A[c]=m),u&&(A[u]=v),A});function l(i,c){const u=a.value[i];return u&&u.get(c)||c}return{normalizedFeatures:n,affinityAgg:r,affinityLabelMaps:a,treeFacetKeys:s,labelFor:l}}class mu{constructor(t={}){this.sourcesConfig=null,this.activeSource=null,this.rawData=[],this.normalizedData=[],this.dataByUniqueId=new Map,this.baseUrl=typeof window<"u"&&window.MAP_APP_BASE_URL||"./",this.locale=t.locale||null,this.cache=new Map,this.cacheEnabled=!0,this.cacheTTL=5*60*1e3}async init(){return this.sourcesConfig=zt,this.sourcesConfig}getActiveSourceId(){var t;return((t=this.sourcesConfig)==null?void 0:t.activeSource)||"doxa-csv"}getSourceConfig(t){var o,n;return(n=(o=this.sourcesConfig)==null?void 0:o.sources)==null?void 0:n[t]}async setActiveSource(t){const o=this.getSourceConfig(t);if(!o)throw new Error(`Source not found: ${t}`);if(this.activeSource=o,this.cacheEnabled&&this.cache.has(t)){const n=this.cache.get(t);return this.normalizedData=n.normalizedData,this.dataByUniqueId=n.dataByUniqueId,this.normalizedData}return o.type==="csv"?await this.loadCSVData(o):o.type==="api"?await this.loadAPIData(o):o.type==="rest-api"&&await this.loadRestApiData(o),this.cacheEnabled&&this.cache.set(t,{normalizedData:this.normalizedData,dataByUniqueId:this.dataByUniqueId,timestamp:Date.now()}),this.normalizedData}clearCache(t=null){t?this.cache.delete(t):this.cache.clear()}isCached(t){return this.cache.has(t)}async loadActiveSource(){return this.sourcesConfig||await this.init(),this.setActiveSource(this.getActiveSourceId())}parseCSV(t){const o=[],n=[];let r="",s=!1,a=[],l=!0;for(let i=0;iwindow.MAP_APP_API_URL = "https://pray.doxa.life"; - + - + - + - + + window.FORGE.manifest = {"schema":"doxa-maps-manifest@1","generatedFrom":"plugin-designs/*/*.vue","embedBase":".","bundleCount":21,"profileCount":32,"bundles":[{"bundle":"all-people-groups","scriptUrl":"./all-people-groups/all-people-groups.js","output":"doxa-maps/all-people-groups/all-people-groups.js","integrity":"sha384-ajyiOLGnsr8AOhrZpwopjFXwKGNk56IbWkBMD+2oYA+DSDjdtATeoF5muZoXhcEF","elements":["all-people-groups"],"profiles":[{"profile":"all-people-groups","file":"all-people-groups.vue","description":"All 12,379 people groups (peoplegroups.org) in four colors — reached,","element":"all-people-groups","type":"single","isMap":true,"iframeUrl":"./all-people-groups/all-people-groups/index.html","scriptUrl":"./all-people-groups/all-people-groups.js","embed":{"iframe":"\u003ciframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-ajyiOLGnsr8AOhrZpwopjFXwKGNk56IbWkBMD+2oYA+DSDjdtATeoF5muZoXhcEF\" crossorigin=\"anonymous\">\u003c/script>\n\u003call-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/all-people-groups>"},"bundle":"all-people-groups"}]},{"bundle":"big-picture","scriptUrl":"./big-picture/big-picture.js","output":"doxa-maps/big-picture/big-picture.js","integrity":"sha384-a9W2VPCO3zJ+1pqWQadGso72rNPTfmZgO4aoGtZN7RDFQpVQbeTvy8JBsGi9VH43","elements":["bp-big-picture","bp-research-header","people-groups-grid"],"composes":["bp-research-header","people-groups-grid"],"profiles":[{"profile":"big-picture","file":"big-picture.vue","description":"The Cat-4 composite that PAIRS the two real capability elements of the","element":"bp-big-picture","type":"nested-elements-mfe","isMap":false,"iframeUrl":"./big-picture/big-picture/index.html","scriptUrl":"./big-picture/big-picture.js","embed":{"iframe":"\u003ciframe src=\"./big-picture/big-picture/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./big-picture/big-picture.js\" integrity=\"sha384-a9W2VPCO3zJ+1pqWQadGso72rNPTfmZgO4aoGtZN7RDFQpVQbeTvy8JBsGi9VH43\" crossorigin=\"anonymous\">\u003c/script>\n\u003cbp-big-picture profile-config='{\"profile\":\"big-picture\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/bp-big-picture>"},"instances":[{"id":"big-picture","title":"Big Picture — research header ↔ people-groups grid (composite)","apiBaseUrl":"","props":{"profile":"big-picture","provider":"maplibre","instanceId":"bp-big-picture"},"element":"bp-big-picture","iframeUrl":"./big-picture/big-picture/big-picture/index.html","embed":{"iframe":"\u003ciframe src=\"./big-picture/big-picture/big-picture/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"frontier","title":"Big Picture — frontier accent","apiBaseUrl":"","props":{"profile":"big-picture","provider":"maplibre","instanceId":"bp-big-picture-frontier","accent":"#22d3ee","title":"Big Picture — Frontier Focus"},"element":"bp-big-picture","iframeUrl":"./big-picture/big-picture/frontier/index.html","embed":{"iframe":"\u003ciframe src=\"./big-picture/big-picture/frontier/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}],"bundle":"big-picture"}]},{"bundle":"cities-internet","scriptUrl":"./cities-internet/cities-internet.js","output":"doxa-maps/cities-internet/cities-internet.js","integrity":"sha384-fqVHxFNirz7+lNdo6RyMGcSABK6RIBNOw+iEQ/Ea6/c5UP+9dqS+Qt4I26HW5B7q","elements":["cities-internet-map"],"profiles":[{"profile":"connectivity-list","file":"connectivity-list.vue","description":"Countries where DX people groups live, grouped by region, showing measured internet penetration","element":"cities-internet-map","type":"single","isMap":false,"iframeUrl":"./cities-internet/connectivity-list/index.html","scriptUrl":"./cities-internet/cities-internet.js","embed":{"iframe":"\u003ciframe src=\"./cities-internet/connectivity-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-fqVHxFNirz7+lNdo6RyMGcSABK6RIBNOw+iEQ/Ea6/c5UP+9dqS+Qt4I26HW5B7q\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/cities-internet-map>"}},{"profile":"connectivity-map","file":"connectivity-map.vue","description":"Every country shaded by measured internet penetration, with its named carriers and dominant","element":"cities-internet-map","type":"single","isMap":true,"iframeUrl":"./cities-internet/connectivity-map/index.html","scriptUrl":"./cities-internet/cities-internet.js","embed":{"iframe":"\u003ciframe src=\"./cities-internet/connectivity-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-fqVHxFNirz7+lNdo6RyMGcSABK6RIBNOw+iEQ/Ea6/c5UP+9dqS+Qt4I26HW5B7q\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/cities-internet-map>"}},{"profile":"data-tables","file":"data-tables.vue","description":"Four validated research tables, one tab each, with sortable and filterable columns, CSV and JSON","element":"cities-internet-map","type":"single","isMap":false,"iframeUrl":"./cities-internet/data-tables/index.html","scriptUrl":"./cities-internet/cities-internet.js","embed":{"iframe":"\u003ciframe src=\"./cities-internet/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-fqVHxFNirz7+lNdo6RyMGcSABK6RIBNOw+iEQ/Ea6/c5UP+9dqS+Qt4I26HW5B7q\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/cities-internet-map>"}}]},{"bundle":"country-posters","scriptUrl":"./country-posters/country-posters.js","output":"doxa-maps/country-posters/country-posters.js","integrity":"sha384-11tC7IzM7DM66gTcAlLSb0bwA7TTkfKYmdrYdiGlBTy9eLVhYCjKgD+LmhZ+qLwO","elements":["country-posters-map"],"profiles":[{"profile":"countries-map","file":"countries-map.vue","description":"The researcher's workbench retargeted from people groups to COUNTRIES — region","element":"country-posters-map","type":"single","isMap":true,"iframeUrl":"./country-posters/countries-map/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-11tC7IzM7DM66gTcAlLSb0bwA7TTkfKYmdrYdiGlBTy9eLVhYCjKgD+LmhZ+qLwO\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/country-posters-map>"}},{"profile":"country-poster-wall","file":"country-poster-wall.vue","description":"One printable card per country, grouped into COLLAPSIBLE regional sections so the","element":"country-posters-map","type":"single","isMap":false,"iframeUrl":"./country-posters/country-poster-wall/index.html","scriptUrl":"./country-posters/country-posters.js","embed":{"iframe":"\u003ciframe src=\"./country-posters/country-poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./country-posters/country-posters.js\" integrity=\"sha384-11tC7IzM7DM66gTcAlLSb0bwA7TTkfKYmdrYdiGlBTy9eLVhYCjKgD+LmhZ+qLwO\" crossorigin=\"anonymous\">\u003c/script>\n\u003ccountry-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/country-posters-map>"}}]},{"bundle":"dashboard-plus-grid","scriptUrl":"./dashboard-plus-grid/dashboard-plus-grid.js","output":"doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js","integrity":"sha384-zUvuNNWNZdbjdsO1BJ6Wa+0mZ5HE4FEDpRRbWK2DFU52H9kh3zdY2SaQeY6HfeMD","elements":["dashboard-plus-grid"],"composes":["research-dashboard","people-groups-grid"],"profiles":[{"profile":"dashboard-plus-grid","file":"dashboard-plus-grid.vue","description":"Both children are IMPORTED DIRECTLY (compiled into this ONE bundle — no runtime bundle","element":"dashboard-plus-grid","type":"nested-elements-mfe","isMap":true,"iframeUrl":"./dashboard-plus-grid/dashboard-plus-grid/index.html","scriptUrl":"./dashboard-plus-grid/dashboard-plus-grid.js","embed":{"iframe":"\u003ciframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-zUvuNNWNZdbjdsO1BJ6Wa+0mZ5HE4FEDpRRbWK2DFU52H9kh3zdY2SaQeY6HfeMD\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/dashboard-plus-grid>"},"instances":[{"id":"default","title":"default","apiBaseUrl":"","props":{"profile":"dashboard-plus-grid"},"element":"dashboard-plus-grid","iframeUrl":"./dashboard-plus-grid/dashboard-plus-grid/default/index.html","embed":{"iframe":"\u003ciframe src=\"./dashboard-plus-grid/dashboard-plus-grid/default/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"demo-map","scriptUrl":"./demo-map/demo-map.js","output":"doxa-maps/demo-map/demo-map.js","integrity":"sha384-yLc6o2sikAUcTgqEszWaO9whzFZnBAZoO4gPXJhG3tzvfKaDpK2mhAW3qXwrycDO","elements":["demo-map"],"profiles":[{"profile":"demo-map","file":"demo-map.vue","description":"Simple two-tab demo map. Tab 1 colors pins by religion (shared","element":"demo-map","type":"parameterized","isMap":true,"iframeUrl":"./demo-map/demo-map/index.html","scriptUrl":"./demo-map/demo-map.js","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./demo-map/demo-map.js\" integrity=\"sha384-yLc6o2sikAUcTgqEszWaO9whzFZnBAZoO4gPXJhG3tzvfKaDpK2mhAW3qXwrycDO\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdemo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/demo-map>"},"instances":[{"id":"maplibre","title":"Demo map — MapLibre (token-free)","apiBaseUrl":"","props":{"profile":"demo-map","provider":"maplibre","instanceId":"demo-maplibre"},"element":"demo-map","iframeUrl":"./demo-map/demo-map/maplibre/index.html","embed":{"iframe":"\u003ciframe src=\"./demo-map/demo-map/maplibre/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}],"bundle":"demo-map"}]},{"bundle":"doxa-maps-spa","scriptUrl":"./doxa-maps-spa/doxa-maps-spa.js","output":"doxa-maps/doxa-maps-spa/doxa-maps-spa.js","integrity":"sha384-T+Vb+RHoAB76ZnZ0wbg5KMkKrxBKStUH+Faf9PHc+efE1CZPiiW1NlerC1V8KaU1","elements":["doxa-maps-spa"],"composes":["bp-big-picture","doxa-research-map","doxa-simple-map","cities-internet-map","gospel-resources-map","my-upg-100-list-map"],"profiles":[{"profile":"doxa-maps-spa","file":"doxa-maps-spa.vue","description":"The DX-maps app itself: one element whose vertical-tab rail nests every other","element":"doxa-maps-spa","type":"nested-mfe-spa","isMap":false,"iframeUrl":"./doxa-maps-spa/doxa-maps-spa/index.html","scriptUrl":"./doxa-maps-spa/doxa-maps-spa.js","embed":{"iframe":"\u003ciframe src=\"./doxa-maps-spa/doxa-maps-spa/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-T+Vb+RHoAB76ZnZ0wbg5KMkKrxBKStUH+Faf9PHc+efE1CZPiiW1NlerC1V8KaU1\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/doxa-maps-spa>"},"instances":[{"id":"app","title":"DX-Maps SPA — Big Picture + every research map (app-shell)","apiBaseUrl":"","props":{"profile":"doxa-maps-spa","provider":"maplibre","instanceId":"doxa-maps-spa-app","title":"DX-Maps"},"element":"doxa-maps-spa","iframeUrl":"./doxa-maps-spa/doxa-maps-spa/app/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-maps-spa/doxa-maps-spa/app/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"doxa-research-map","scriptUrl":"./doxa-research-map/doxa-research-map.js","output":"doxa-maps/doxa-research-map/doxa-research-map.js","integrity":"sha384-ugm8PXu3KYQmGJoQnOUaICqt07r17kQa1bINkKsrUgt89uENqvd87rxT2NBeyC9/","elements":["doxa-research-map"],"profiles":[{"profile":"research-map","file":"research-map.vue","description":"The researcher's workbench: every piece a missiologist, demographer or","element":"doxa-research-map","type":"monolithic","isMap":true,"iframeUrl":"./doxa-research-map/research-map/index.html","scriptUrl":"./doxa-research-map/doxa-research-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-ugm8PXu3KYQmGJoQnOUaICqt07r17kQa1bINkKsrUgt89uENqvd87rxT2NBeyC9/\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/doxa-research-map>"}}]},{"bundle":"doxa-simple-map","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","output":"doxa-maps/doxa-simple-map/doxa-simple-map.js","integrity":"sha384-fl3Eh//QzBhOEpF3OJcfZDXOdpyb/yxiQ5aEroT23Onjya6wvBlx+F2dUB6FiBZu","elements":["doxa-map","doxa-simple-map"],"profiles":[{"profile":"doxa-simple-map","file":"doxa-simple-map.vue","description":"The simple world map, shipped as three presets off ONE prop table —","element":"doxa-map","type":"parameterized","isMap":true,"iframeUrl":"./doxa-simple-map/doxa-simple-map/index.html","scriptUrl":"./doxa-simple-map/doxa-simple-map.js","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-fl3Eh//QzBhOEpF3OJcfZDXOdpyb/yxiQ5aEroT23Onjya6wvBlx+F2dUB6FiBZu\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/doxa-map>"},"instances":[{"id":"prayer","title":"Prayer Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-prayer","dataSource":"pray-tools","tabs":[{"id":"prayer","colorStrategy":"prayer","legend":"prayer","popup":"prayer"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/prayer/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/prayer/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"engagement","title":"Engagement Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-engagement","dataSource":"pray-tools","tabs":[{"id":"engagement","colorStrategy":"engagement","legend":"engagement","popup":"engagement"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/engagement/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/engagement/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"adoption","title":"Adoption Map","apiBaseUrl":"https://pray.doxa.life","props":{"profile":"doxa-simple-map","instanceId":"embed-adoption","dataSource":"pray-tools","tabs":[{"id":"adoption","colorStrategy":"adoption","legend":"adoption","popup":"adoption"}]},"element":"doxa-map","iframeUrl":"./doxa-simple-map/doxa-simple-map/adoption/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-simple-map/doxa-simple-map/adoption/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"doxa-vision-card","scriptUrl":"./doxa-vision-card/doxa-vision-card.js","output":"doxa-maps/doxa-vision-card/doxa-vision-card.js","integrity":"sha384-2mza3cltN5LQQIrlENG/IVL6Icd9zzcFve3E8R8VWuCdYOGW9uGKFvxcbu6eFfwn","elements":["doxa-vision-card"],"profiles":[{"profile":"doxa-vision-card","file":"doxa-vision-card.vue","description":"The Capability-1 example: ONE folder -> ONE bundle -> ONE element.","element":"doxa-vision-card","type":"parameterized","isMap":false,"iframeUrl":"./doxa-vision-card/doxa-vision-card/index.html","scriptUrl":"./doxa-vision-card/doxa-vision-card.js","embed":{"iframe":"\u003ciframe src=\"./doxa-vision-card/doxa-vision-card/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./doxa-vision-card/doxa-vision-card.js\" integrity=\"sha384-2mza3cltN5LQQIrlENG/IVL6Icd9zzcFve3E8R8VWuCdYOGW9uGKFvxcbu6eFfwn\" crossorigin=\"anonymous\">\u003c/script>\n\u003cdoxa-vision-card profile-config='{\"profile\":\"doxa-vision-card\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/doxa-vision-card>"},"instances":[{"id":"default","title":"Vision card — reach at a glance","apiBaseUrl":"","props":{"profile":"doxa-vision-card","provider":"maplibre","instanceId":"vision-card-default"},"element":"doxa-vision-card","iframeUrl":"./doxa-vision-card/doxa-vision-card/default/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-vision-card/doxa-vision-card/default/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"frontier","title":"Vision card — frontier accent","apiBaseUrl":"","props":{"profile":"doxa-vision-card","provider":"maplibre","instanceId":"vision-card-frontier","accent":"#22d3ee","title":"The last frontier of the gospel.","tagline":"Frontier people groups — where fewer than one in a thousand follow Jesus.","stats":[{"value":"1,910","label":"Frontier groups","note":"under 0.1% believers"},{"value":"2.1B","label":"People","note":"living in frontier settings"},{"value":"0.1%","label":"Christian","note":"or fewer, in each group"}]},"element":"doxa-vision-card","iframeUrl":"./doxa-vision-card/doxa-vision-card/frontier/index.html","embed":{"iframe":"\u003ciframe src=\"./doxa-vision-card/doxa-vision-card/frontier/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}],"bundle":"doxa-vision-card"}]},{"bundle":"golden-path-check","scriptUrl":"./golden-path-check/golden-path-check.js","output":"doxa-maps/golden-path-check/golden-path-check.js","integrity":"sha384-1V/sT5SkV0U9yTCK9ELIOFfU1ZIJkInIF6nG3UllJ4dxax3RsEAupSGLJEFK6e14","elements":["golden-path-check"],"profiles":[{"profile":"golden-path-check","file":"golden-path-check.vue","description":"A live self-test of the develop-a-plugin-and-see-it-live path: it reads the built","element":"golden-path-check","type":"single","isMap":false,"iframeUrl":"./golden-path-check/golden-path-check/index.html","scriptUrl":"./golden-path-check/golden-path-check.js","embed":{"iframe":"\u003ciframe src=\"./golden-path-check/golden-path-check/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./golden-path-check/golden-path-check.js\" integrity=\"sha384-1V/sT5SkV0U9yTCK9ELIOFfU1ZIJkInIF6nG3UllJ4dxax3RsEAupSGLJEFK6e14\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgolden-path-check profile-config='{\"profile\":\"golden-path-check\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/golden-path-check>"}}]},{"bundle":"gospel-resources","scriptUrl":"./gospel-resources/gospel-resources.js","output":"doxa-maps/gospel-resources/gospel-resources.js","integrity":"sha384-MBKsP+YZGmQ/TOcM1VDm7E0qB5EOP5W+MbUWVtfjiP1J0pIDSUi5SWbj1bgY74+X","elements":["gospel-resources-map"],"profiles":[{"profile":"charts","file":"charts.vue","description":"The gap by LANGUAGE (ISO 639-3) rather than by people group — because one translation serves every","element":"gospel-resources-map","type":"single","isMap":false,"iframeUrl":"./gospel-resources/charts/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-MBKsP+YZGmQ/TOcM1VDm7E0qB5EOP5W+MbUWVtfjiP1J0pIDSUi5SWbj1bgY74+X\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/gospel-resources-map>"}},{"profile":"data-tables","file":"data-tables.vue","description":"Two validated tables: what resources exist per people group, and whether that access is keeping","element":"gospel-resources-map","type":"single","isMap":false,"iframeUrl":"./gospel-resources/data-tables/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-MBKsP+YZGmQ/TOcM1VDm7E0qB5EOP5W+MbUWVtfjiP1J0pIDSUi5SWbj1bgY74+X\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-list","file":"resources-list.vue","description":"Which DX people groups have scripture in their own language, and which have none. The zero-resource","element":"gospel-resources-map","type":"single","isMap":false,"iframeUrl":"./gospel-resources/resources-list/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-MBKsP+YZGmQ/TOcM1VDm7E0qB5EOP5W+MbUWVtfjiP1J0pIDSUi5SWbj1bgY74+X\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/gospel-resources-map>"}},{"profile":"resources-map","file":"resources-map.vue","description":"Every country shaded by how much of its unengaged population has NO gospel resource in their own","element":"gospel-resources-map","type":"single","isMap":true,"iframeUrl":"./gospel-resources/resources-map/index.html","scriptUrl":"./gospel-resources/gospel-resources.js","embed":{"iframe":"\u003ciframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-MBKsP+YZGmQ/TOcM1VDm7E0qB5EOP5W+MbUWVtfjiP1J0pIDSUi5SWbj1bgY74+X\" crossorigin=\"anonymous\">\u003c/script>\n\u003cgospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/gospel-resources-map>"}}]},{"bundle":"my-upg-100-list","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","output":"doxa-maps/my-upg-100-list/my-upg-100-list.js","integrity":"sha384-Ejz1bj3BY55YwaQ/AbYYc/0E88rdhbvOUKs+ba2arx/UMufPkiDAcK5tcqyGF9AV","elements":["my-upg-100-list-map"],"composes":["my-upg-100-list/upg-100-list","my-upg-100-list/poster-wall"],"profiles":[{"profile":"poster-wall","file":"poster-wall.vue","description":"A wall of printable poster cards, one per 100-list entry, each with a \"Show on map\" action that","element":"my-upg-100-list-map","type":"single","isMap":true,"iframeUrl":"./my-upg-100-list/poster-wall/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe src=\"./my-upg-100-list/poster-wall/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-Ejz1bj3BY55YwaQ/AbYYc/0E88rdhbvOUKs+ba2arx/UMufPkiDAcK5tcqyGF9AV\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-list","file":"upg-100-list.vue","description":"A personal unreached-people-groups list painted as true boundary polygons —","element":"my-upg-100-list-map","type":"single","isMap":true,"iframeUrl":"./my-upg-100-list/upg-100-list/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe 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>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-Ejz1bj3BY55YwaQ/AbYYc/0E88rdhbvOUKs+ba2arx/UMufPkiDAcK5tcqyGF9AV\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/my-upg-100-list-map>"}},{"profile":"upg-100-mfe","file":"upg-100-mfe.vue","description":"The standalone, shareable and embeddable composite of the my-upg-100-list family — it nests the map","element":"my-upg-100-list-map","type":"nested-elements-mfe","isMap":true,"iframeUrl":"./my-upg-100-list/upg-100-mfe/index.html","scriptUrl":"./my-upg-100-list/my-upg-100-list.js","embed":{"iframe":"\u003ciframe 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>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-Ejz1bj3BY55YwaQ/AbYYc/0E88rdhbvOUKs+ba2arx/UMufPkiDAcK5tcqyGF9AV\" crossorigin=\"anonymous\">\u003c/script>\n\u003cmy-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/my-upg-100-list-map>"}}]},{"bundle":"people-groups-grid","scriptUrl":"./people-groups-grid/people-groups-grid.js","output":"doxa-maps/people-groups-grid/people-groups-grid.js","integrity":"sha384-M3RVF4r+s9KJ2YznjQ+g3BR4XjsA4n8uhfCk97dwyiuN1BxRdeQmmMnQILV0CwJg","elements":["people-groups-grid"],"profiles":[{"profile":"people-groups-grid","file":"people-groups-grid.vue","description":"The people-groups grid as an owned custom element: card list, search and four","element":"people-groups-grid","type":"parameterized","isMap":false,"iframeUrl":"./people-groups-grid/people-groups-grid/index.html","scriptUrl":"./people-groups-grid/people-groups-grid.js","embed":{"iframe":"\u003ciframe src=\"./people-groups-grid/people-groups-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./people-groups-grid/people-groups-grid.js\" integrity=\"sha384-M3RVF4r+s9KJ2YznjQ+g3BR4XjsA4n8uhfCk97dwyiuN1BxRdeQmmMnQILV0CwJg\" crossorigin=\"anonymous\">\u003c/script>\n\u003cpeople-groups-grid profile-config='{\"profile\":\"people-groups-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/people-groups-grid>"},"instances":[{"id":"people-groups-grid","title":"People Groups Grid — standalone (own search + 4 dropdowns)","apiBaseUrl":"","props":{"profile":"people-groups-grid","provider":"maplibre","instanceId":"people-groups-grid","pray-base-url":"https://pray.doxa.life"},"element":"people-groups-grid","iframeUrl":"./people-groups-grid/people-groups-grid/people-groups-grid/index.html","embed":{"iframe":"\u003ciframe src=\"./people-groups-grid/people-groups-grid/people-groups-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}},{"id":"driven","title":"People Groups Grid — externally driven (controls off, props/events)","apiBaseUrl":"","props":{"profile":"people-groups-grid","provider":"maplibre","instanceId":"people-groups-grid-driven","pray-base-url":"https://pray.doxa.life","show-search":"false","show-filters":"false"},"element":"people-groups-grid","iframeUrl":"./people-groups-grid/people-groups-grid/driven/index.html","embed":{"iframe":"\u003ciframe src=\"./people-groups-grid/people-groups-grid/driven/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"plugin-studio","scriptUrl":"./plugin-studio/plugin-studio.js","output":"doxa-maps/plugin-studio/plugin-studio.js","integrity":"sha384-VuTJ3Db517xAN7nyV6VKdM0YJH6ToDwxyCjjAEeK69x8KompgYFCHWs29Q0BkfJp","elements":["plugin-studio"],"composes":["bp-big-picture","people-groups-grid","doxa-research-map","doxa-simple-map","cities-internet-map","gospel-resources-map","my-upg-100-list-map","doxa-vision-card","all-people-groups","research-dashboard"],"profiles":[{"profile":"plugin-studio","file":"plugin-studio.vue","description":"The developer's viewing surface: a sidebar that is the composability ladder","element":"plugin-studio","type":"nested-mfe-spa","isMap":false,"iframeUrl":"./plugin-studio/plugin-studio/index.html","scriptUrl":"./plugin-studio/plugin-studio.js","embed":{"iframe":"\u003ciframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-VuTJ3Db517xAN7nyV6VKdM0YJH6ToDwxyCjjAEeK69x8KompgYFCHWs29Q0BkfJp\" crossorigin=\"anonymous\">\u003c/script>\n\u003cplugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/plugin-studio>"},"instances":[{"id":"studio","title":"Plugin Studio — every element by capability 5 -> 1 (developer studio)","apiBaseUrl":"","props":{"profile":"plugin-studio","provider":"maplibre","instanceId":"plugin-studio","title":"Plugin Studio"},"element":"plugin-studio","iframeUrl":"./plugin-studio/plugin-studio/studio/index.html","embed":{"iframe":"\u003ciframe src=\"./plugin-studio/plugin-studio/studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"prayer-walk-planner","scriptUrl":"./prayer-walk-planner/prayer-walk-planner.js","output":"doxa-maps/prayer-walk-planner/prayer-walk-planner.js","integrity":"sha384-+XBRYgeeX8JLpdYcc+oGtkQf+Zgc2JkFK6/tlMBh5qghF9rNAJLk1lwVxWkU0cKx","elements":["prayer-walk-planner"],"profiles":[{"profile":"prayer-walk-planner","file":"prayer-walk-planner.vue","description":"A simple polygon-drawing tool for planning prayer-walking routes.","element":"prayer-walk-planner","type":"single","isMap":true,"iframeUrl":"./prayer-walk-planner/prayer-walk-planner/index.html","scriptUrl":"./prayer-walk-planner/prayer-walk-planner.js","embed":{"iframe":"\u003ciframe src=\"./prayer-walk-planner/prayer-walk-planner/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./prayer-walk-planner/prayer-walk-planner.js\" integrity=\"sha384-+XBRYgeeX8JLpdYcc+oGtkQf+Zgc2JkFK6/tlMBh5qghF9rNAJLk1lwVxWkU0cKx\" crossorigin=\"anonymous\">\u003c/script>\n\u003cprayer-walk-planner profile-config='{\"profile\":\"prayer-walk-planner\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/prayer-walk-planner>"}}]},{"bundle":"regions-dashboard","scriptUrl":"./regions-dashboard/regions-dashboard.js","output":"doxa-maps/regions-dashboard/regions-dashboard.js","integrity":"sha384-5QpUDIMXiWozhCtGWtXmkcbZPjuqaGMDKU5RrudhFcbMMWxfTI+OhnNbbhHAlYxv","elements":["regions-dashboard"],"composes":["regions-dashboard/regions-list","regions-dashboard/region-dashboards"],"profiles":[{"profile":"region-dashboards","file":"region-dashboards.vue","description":"The dashboard half of the Driver's 2-tab Regions element: given a region (or a","element":"regions-dashboard","type":"single","isMap":false,"iframeUrl":"./regions-dashboard/region-dashboards/index.html","scriptUrl":"./regions-dashboard/regions-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-5QpUDIMXiWozhCtGWtXmkcbZPjuqaGMDKU5RrudhFcbMMWxfTI+OhnNbbhHAlYxv\" crossorigin=\"anonymous\">\u003c/script>\n\u003cregions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/regions-dashboard>"}},{"profile":"regions-list","file":"regions-list.vue","description":"A refactor of DX-life's /regions index page (app/pages/regions/index.vue) into","element":"regions-dashboard","type":"single","isMap":false,"iframeUrl":"./regions-dashboard/regions-list/index.html","scriptUrl":"./regions-dashboard/regions-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-5QpUDIMXiWozhCtGWtXmkcbZPjuqaGMDKU5RrudhFcbMMWxfTI+OhnNbbhHAlYxv\" crossorigin=\"anonymous\">\u003c/script>\n\u003cregions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/regions-dashboard>"}},{"profile":"regions-mfe","file":"regions-mfe.vue","description":"The composite the Driver asked for: ONE element carrying the SELECT VIEW switcher","element":"regions-dashboard","type":"nested-elements-mfe","isMap":false,"iframeUrl":"./regions-dashboard/regions-mfe/index.html","scriptUrl":"./regions-dashboard/regions-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-5QpUDIMXiWozhCtGWtXmkcbZPjuqaGMDKU5RrudhFcbMMWxfTI+OhnNbbhHAlYxv\" crossorigin=\"anonymous\">\u003c/script>\n\u003cregions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/regions-dashboard>"}}]},{"bundle":"research-dashboard","scriptUrl":"./research-dashboard/research-dashboard.js","output":"doxa-maps/research-dashboard/research-dashboard.js","integrity":"sha384-iS3PX4DbqpmhbOhuy/6w6PffVqdX+8S59w0FB/LSd4EK35EwAZJqek8HJsBJRo0+","elements":["research-dashboard-map"],"profiles":[{"profile":"research-dashboard","file":"research-dashboard.vue","description":"Coordinated-Multiple-Views research dashboard for 10/40-window UPGs (live pray.doxa.life): docked facet rail + map-as-hero + linked table/charts, brushing-and-linking over one in-memory store.","element":"research-dashboard-map","type":"monolithic","isMap":true,"iframeUrl":"./research-dashboard/research-dashboard/index.html","scriptUrl":"./research-dashboard/research-dashboard.js","embed":{"iframe":"\u003ciframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-iS3PX4DbqpmhbOhuy/6w6PffVqdX+8S59w0FB/LSd4EK35EwAZJqek8HJsBJRo0+\" crossorigin=\"anonymous\">\u003c/script>\n\u003cresearch-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/research-dashboard-map>"},"bundle":"research-dashboard"}]},{"bundle":"research-map-plus-grid","scriptUrl":"./research-map-plus-grid/research-map-plus-grid.js","output":"doxa-maps/research-map-plus-grid/research-map-plus-grid.js","integrity":"sha384-W3eI3zepAYbIa1bQfJTtvzU53KWPQEg8g4lVKmp3FtW7kNXOoKE2ny1JDjZ1L+MJ","elements":["research-map-plus-grid"],"composes":["doxa-research-map","people-groups-grid"],"profiles":[{"profile":"research-map-plus-grid","file":"research-map-plus-grid.vue","description":"The monolithic 7-tab research map (cap-3) on top, the People Groups grid beneath,","element":"research-map-plus-grid","type":"nested-elements-mfe","isMap":false,"iframeUrl":"./research-map-plus-grid/research-map-plus-grid/index.html","scriptUrl":"./research-map-plus-grid/research-map-plus-grid.js","embed":{"iframe":"\u003ciframe src=\"./research-map-plus-grid/research-map-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./research-map-plus-grid/research-map-plus-grid.js\" integrity=\"sha384-W3eI3zepAYbIa1bQfJTtvzU53KWPQEg8g4lVKmp3FtW7kNXOoKE2ny1JDjZ1L+MJ\" crossorigin=\"anonymous\">\u003c/script>\n\u003cresearch-map-plus-grid profile-config='{\"profile\":\"research-map-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/research-map-plus-grid>"},"instances":[{"id":"default","title":"default","apiBaseUrl":"","props":{"profile":"research-map-plus-grid"},"element":"research-map-plus-grid","iframeUrl":"./research-map-plus-grid/research-map-plus-grid/default/index.html","embed":{"iframe":"\u003ciframe src=\"./research-map-plus-grid/research-map-plus-grid/default/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"stack-demo","scriptUrl":"./stack-demo/stack-demo.js","output":"doxa-maps/stack-demo/stack-demo.js","integrity":"sha384-GQTUiygn0aS3lHIfW6HIYA1Ko8P2KZr0iUicOp+xDFLNw2gaGmLCZdwa5/cUYeUI","elements":["stack-demo"],"composes":["research-dashboard-map","people-groups-grid"],"profiles":[{"profile":"stack-demo","file":"stack-demo.vue","description":"Groups TWO independent elements TOP-TO-BOTTOM so you can embed the pair on a page and","element":"stack-demo","type":"nested-elements-mfe","isMap":false,"iframeUrl":"./stack-demo/stack-demo/index.html","scriptUrl":"./stack-demo/stack-demo.js","embed":{"iframe":"\u003ciframe src=\"./stack-demo/stack-demo/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./stack-demo/stack-demo.js\" integrity=\"sha384-GQTUiygn0aS3lHIfW6HIYA1Ko8P2KZr0iUicOp+xDFLNw2gaGmLCZdwa5/cUYeUI\" crossorigin=\"anonymous\">\u003c/script>\n\u003cstack-demo profile-config='{\"profile\":\"stack-demo\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/stack-demo>"},"instances":[{"id":"pair","title":"pair","apiBaseUrl":"","props":{"profile":"stack-demo"},"element":"stack-demo","iframeUrl":"./stack-demo/stack-demo/pair/index.html","embed":{"iframe":"\u003ciframe src=\"./stack-demo/stack-demo/pair/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>"}}]}]},{"bundle":"template-bundle","scriptUrl":"./template-bundle/template-bundle.js","output":"doxa-maps/template-bundle/template-bundle.js","integrity":"sha384-6BLnoGxxah2nBlYZe3+9dY5xquKg1exSyIUNazvQz7/0sJM4ROA4aHjRGjNMQL28","elements":["template-bundle"],"profiles":[{"profile":"template-map-a","file":"template-map-a.vue","description":"Minimal example profile A — a colored placeholder, no Mapbox or data.","element":"template-bundle","type":"single","isMap":false,"iframeUrl":"./template-bundle/template-map-a/index.html","scriptUrl":"./template-bundle/template-bundle.js","embed":{"iframe":"\u003ciframe src=\"./template-bundle/template-map-a/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./template-bundle/template-bundle.js\" integrity=\"sha384-6BLnoGxxah2nBlYZe3+9dY5xquKg1exSyIUNazvQz7/0sJM4ROA4aHjRGjNMQL28\" crossorigin=\"anonymous\">\u003c/script>\n\u003ctemplate-bundle profile-config='{\"profile\":\"template-map-a\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/template-bundle>"},"bundle":"template-bundle"},{"profile":"template-map-b","file":"template-map-b.vue","description":"Minimal example profile B — a second profile in the same bundle.","element":"template-bundle","type":"single","isMap":false,"iframeUrl":"./template-bundle/template-map-b/index.html","scriptUrl":"./template-bundle/template-bundle.js","embed":{"iframe":"\u003ciframe src=\"./template-bundle/template-map-b/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen>\u003c/iframe>","script":"\u003cscript>window.MAP_APP_API_URL=\"https://pray.doxa.life\";\u003c/script>\n\u003cscript src=\"./template-bundle/template-bundle.js\" integrity=\"sha384-6BLnoGxxah2nBlYZe3+9dY5xquKg1exSyIUNazvQz7/0sJM4ROA4aHjRGjNMQL28\" crossorigin=\"anonymous\">\u003c/script>\n\u003ctemplate-bundle profile-config='{\"profile\":\"template-map-b\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'>\u003c/template-bundle>"},"bundle":"template-bundle"}]}]}; \n\n" + "script": "\n\n" }, "instances": [ { @@ -280,7 +280,7 @@ "bundle": "doxa-maps-spa", "scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js", "output": "doxa-maps/doxa-maps-spa/doxa-maps-spa.js", - "integrity": "sha384-xBzg0WFQSdfa9tkQ9X2G6LOg3YURptleajqsly/Jyf+8edDiAgTkW1rUyv8QzFGv", + "integrity": "sha384-T+Vb+RHoAB76ZnZ0wbg5KMkKrxBKStUH+Faf9PHc+efE1CZPiiW1NlerC1V8KaU1", "elements": [ "doxa-maps-spa" ], @@ -304,7 +304,7 @@ "scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" }, "instances": [ { @@ -878,7 +878,7 @@ "bundle": "research-dashboard", "scriptUrl": "./research-dashboard/research-dashboard.js", "output": "doxa-maps/research-dashboard/research-dashboard.js", - "integrity": "sha384-vOGsI0iGbIPRWl0ic35cL7JoPk8KsOh9GrzIWTlUdZwUNA2hUabmDcv1h4pT3G2V", + "integrity": "sha384-iS3PX4DbqpmhbOhuy/6w6PffVqdX+8S59w0FB/LSd4EK35EwAZJqek8HJsBJRo0+", "elements": [ "research-dashboard-map" ], @@ -894,7 +894,7 @@ "scriptUrl": "./research-dashboard/research-dashboard.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" }, "bundle": "research-dashboard" } @@ -904,7 +904,7 @@ "bundle": "research-map-plus-grid", "scriptUrl": "./research-map-plus-grid/research-map-plus-grid.js", "output": "doxa-maps/research-map-plus-grid/research-map-plus-grid.js", - "integrity": "sha384-Dyh9E7k/YtwVCKP4lulQpWs9+oqKV5LJjxEnJMufru4zAzyZpbHyz0pja7hPwIwS", + "integrity": "sha384-W3eI3zepAYbIa1bQfJTtvzU53KWPQEg8g4lVKmp3FtW7kNXOoKE2ny1JDjZ1L+MJ", "elements": [ "research-map-plus-grid" ], @@ -924,7 +924,7 @@ "scriptUrl": "./research-map-plus-grid/research-map-plus-grid.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" }, "instances": [ { @@ -948,7 +948,7 @@ "bundle": "stack-demo", "scriptUrl": "./stack-demo/stack-demo.js", "output": "doxa-maps/stack-demo/stack-demo.js", - "integrity": "sha384-Wt5wtm3JMmbuKqXaBDYZ2Mrw3LF/q8LQ14d+qFPi958kH8aPJPAFGMvqHCD6BICy", + "integrity": "sha384-GQTUiygn0aS3lHIfW6HIYA1Ko8P2KZr0iUicOp+xDFLNw2gaGmLCZdwa5/cUYeUI", "elements": [ "stack-demo" ], @@ -968,7 +968,7 @@ "scriptUrl": "./stack-demo/stack-demo.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" }, "instances": [ { diff --git a/public/doxa-maps/research-dashboard/research-dashboard/index.html b/public/doxa-maps/research-dashboard/research-dashboard/index.html index 35865563f..c3745bada 100644 --- a/public/doxa-maps/research-dashboard/research-dashboard/index.html +++ b/public/doxa-maps/research-dashboard/research-dashboard/index.html @@ -29,7 +29,7 @@ - + - + - + - + - +