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 @@ - + - + - + - + - +