Update from source 91ea64f8
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions

This commit is contained in:
Doxa Maps 2026-09-26 18:43:40 +00:00
parent 28d4c83d96
commit 8419d68b52
22 changed files with 1583 additions and 207 deletions

View file

@ -10,7 +10,7 @@
"india_note": "India is read from the COMPLETE ADM1 (36 states, geoBoundaries via DataMeet India, CC BY 2.5 IN). The first build of this table read gb-IND-ADM1.geojson, which is the UPG-100 list's curated 34-unit partition, and eleven groups came out with no province because they stood in states that partition does not draw. Switching the file moved 998 assigned to 1,005 and 44 province rows to 46, and turned the province names into India's own states.",
"unassigned_note": "Four remain, each one legible rather than lost. Great Andamanese and the Sentinelese sit on small islands whose simplified coastline the point falls just outside — Andaman and Nicobar IS in the file, so this is geometry precision, not a missing province. Jing and Pana are on China's Vietnam and Laos borders, outside the twelve-province subset. They are listed in `unassigned` with their coordinates.",
"china_note": "China's ADM1 file carries 12 provinces, not 31+. Measured rather than assumed: 152 of 154 Chinese groups fall inside them and all twelve are used, so the file is cut to the provinces where the unreached peoples are.",
"ways_in_are_country_level": "The ways in are chosen for the COUNTRY, and going below the border is what exposes the cost of that. Arunachal Pradesh, in the far north-east, is offered TELUGU — a South Indian language — because the curated bridge table names it for those groups and a curated bridge outranks the computed one. India's computed default is Hindi (41%, official), which is defensible nationally and still wrong for much of the north-east. This table does not fix that: it makes it visible. Until a bridge can be chosen per province, read the ways-in column as \"a language with Scripture and film somewhere in this country\", not as a recommendation for this place.",
"ways_in": "Chosen FOR THE PROVINCE where the province can answer: the languages of groups standing in it that already have Scripture AND film, ranked by the people here who already hold them. The column says which basis was used. This replaces a country-level answer that produced a measured absurdity — Arunachal Pradesh, in the far north-east, was offered TELUGU, because the curated bridge table is keyed by country and a curated bridge outranks a computed one. A province with no tier-2 language of its own still falls back to the country answer, and ways_in_basis says so rather than hiding it. It is a NEIGHBOUR, not a recommendation: whether a group actually speaks it is a question for someone on the ground.",
"approximate": "A province is assigned by point-in-polygon on the group's coordinate, and that coordinate marks where a PEOPLE is found, not a settlement — 108 groups across the roster even share a coordinate with another group. Near a border the point can fall on the wrong side. Every row is flagged approximate and the unassigned are counted, never dropped. No surface may present a province as a fact about a group."
},
"columns": [
@ -49,11 +49,36 @@
"field": "zero_access_examples",
"type": "string"
},
{
"title": "Nobody praying",
"field": "nobody_praying_groups",
"type": "number"
},
{
"title": "Of those with a prayer page",
"field": "prayer_pages",
"type": "number"
},
{
"title": "People nobody is praying for",
"field": "nobody_praying_people",
"type": "number"
},
{
"title": "Ways in",
"field": "ways_in",
"type": "string"
},
{
"title": "Basis",
"field": "ways_in_basis",
"type": "string"
},
{
"title": "Ways in (country-level)",
"field": "ways_in_country",
"type": "string"
},
{
"title": "Placement approximate",
"field": "approximate",
@ -70,7 +95,18 @@
"zero_access_groups": 14,
"zero_access_people": 602850,
"zero_access_examples": "Hongjin Tai; Wenma Zhuang; Mosuo",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 45,
"pray_first": {
"name": "Hongjin Tai",
"url": "https://pray.doxa.life/hongjin-tai?source=doxalife&utm_source=agwm",
"people": 209000,
"has_nothing": true
},
"nobody_praying_groups": 35,
"nobody_praying_people": 1430325,
"ways_in": "Chinese, Mandarin (63,825 here); Tai Dam (48,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -82,7 +118,18 @@
"zero_access_groups": 7,
"zero_access_people": 488900,
"zero_access_examples": "Huishui Miao; Yanghuang; Cai",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 28,
"pray_first": {
"name": "Yanghuang",
"url": "https://pray.doxa.life/yanghuang?source=doxalife&utm_source=agwm",
"people": 63000,
"has_nothing": true
},
"nobody_praying_groups": 20,
"nobody_praying_people": 560000,
"ways_in": "Chinese, Mandarin (332,900 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -94,7 +141,18 @@
"zero_access_groups": 7,
"zero_access_people": 105700,
"zero_access_examples": "Ersu; Minyak; Namuyi",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 10,
"pray_first": {
"name": "Ersu",
"url": "https://pray.doxa.life/ersu?source=doxalife&utm_source=agwm",
"people": 48000,
"has_nothing": true
},
"nobody_praying_groups": 8,
"nobody_praying_people": 461600,
"ways_in": "Tibetan (48,500 here); Chinese, Mandarin (15,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -106,7 +164,18 @@
"zero_access_groups": 2,
"zero_access_people": 500,
"zero_access_examples": "Jarawas; Onge",
"ways_in": "Telugu",
"prayer_pages": 5,
"pray_first": {
"name": "Onge",
"url": "https://pray.doxa.life/onge?source=doxalife&utm_source=agwm",
"people": 150,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 69450,
"ways_in": "Telugu (67,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -118,7 +187,18 @@
"zero_access_groups": 2,
"zero_access_people": 600,
"zero_access_examples": "Khamba; Na",
"ways_in": "Telugu",
"prayer_pages": 7,
"pray_first": {
"name": "Na",
"url": "https://pray.doxa.life/na?source=doxalife&utm_source=agwm",
"people": 100,
"has_nothing": true
},
"nobody_praying_groups": 3,
"nobody_praying_people": 7800,
"ways_in": "Hindi (5,700 here); Assamese (2,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -130,7 +210,18 @@
"zero_access_groups": 2,
"zero_access_people": 31500,
"zero_access_examples": "Sarikoli Tajiks; Ainu",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 4,
"pray_first": {
"name": "Ainu",
"url": "https://pray.doxa.life/ainu-china?source=doxalife&utm_source=agwm",
"people": 11000,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 215625,
"ways_in": "Chinese, Mandarin (25 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -142,7 +233,18 @@
"zero_access_groups": 2,
"zero_access_people": 150000,
"zero_access_examples": "Eastern Xiangxi Miao; Wunai",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 4,
"pray_first": {
"name": "Wunai",
"url": "https://pray.doxa.life/wunai?source=doxalife&utm_source=agwm",
"people": 14000,
"has_nothing": true
},
"nobody_praying_groups": 2,
"nobody_praying_people": 20000,
"ways_in": "Chinese, Mandarin (6,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -154,7 +256,18 @@
"zero_access_groups": 2,
"zero_access_people": 12700,
"zero_access_examples": "Tongren Bonan; Wutun",
"prayer_pages": 1,
"pray_first": {
"name": "Wutun",
"url": "https://pray.doxa.life/wutun?source=doxalife&utm_source=agwm",
"people": 3800,
"has_nothing": true
},
"nobody_praying_groups": 1,
"nobody_praying_people": 3800,
"ways_in": "Chinese, Mandarin",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -166,7 +279,18 @@
"zero_access_groups": 1,
"zero_access_people": 8600,
"zero_access_examples": "Malai Pandaram",
"ways_in": "Telugu",
"prayer_pages": 66,
"pray_first": {
"name": "Malai Pandaram",
"url": "https://pray.doxa.life/malai-pandaram?source=doxalife&utm_source=agwm",
"people": 8600,
"has_nothing": true
},
"nobody_praying_groups": 53,
"nobody_praying_people": 1152750,
"ways_in": "Malayalam (2,629,525 here); Kannada (38,200 here); Tamil (33,150 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -178,7 +302,18 @@
"zero_access_groups": 1,
"zero_access_people": 5000,
"zero_access_examples": "Jadupetia",
"ways_in": "Telugu",
"prayer_pages": 5,
"pray_first": {
"name": "Jadupetia",
"url": "https://pray.doxa.life/jadupetia?source=doxalife&utm_source=agwm",
"people": 5000,
"has_nothing": true
},
"nobody_praying_groups": 5,
"nobody_praying_people": 41900,
"ways_in": "Hindi (495,000 here); Bengali (164,200 here); Urdu (94,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -190,7 +325,18 @@
"zero_access_groups": 1,
"zero_access_people": 750,
"zero_access_examples": "Yerong",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 5,
"pray_first": {
"name": "Yerong",
"url": "https://pray.doxa.life/yerong?source=doxalife&utm_source=agwm",
"people": 750,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 51150,
"ways_in": "Chinese, Mandarin (50,400 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -202,7 +348,18 @@
"zero_access_groups": 1,
"zero_access_people": 1700,
"zero_access_examples": "Koiren",
"ways_in": "Telugu",
"prayer_pages": 3,
"pray_first": {
"name": "Koiren",
"url": "https://pray.doxa.life/koiren?source=doxalife&utm_source=agwm",
"people": 1700,
"has_nothing": true
},
"nobody_praying_groups": 3,
"nobody_praying_people": 112400,
"ways_in": "Meitei (319,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -214,7 +371,13 @@
"zero_access_groups": 1,
"zero_access_people": 170000,
"zero_access_examples": "Buryat",
"prayer_pages": 1,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Chinese, Mandarin",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -226,7 +389,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 80,
"pray_first": {
"name": "Bairagi (Gujarati)",
"url": "https://pray.doxa.life/bairagi-gujarati?source=doxalife&utm_source=agwm",
"people": 510000,
"has_nothing": false
},
"nobody_praying_groups": 59,
"nobody_praying_people": 1429045,
"ways_in": "Gujarati (1,874,475 here); Urdu (123,200 here); Marathi (70,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -238,7 +412,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 76,
"pray_first": {
"name": "Aiyarakulu",
"url": "https://pray.doxa.life/aiyarakulu?source=doxalife&utm_source=agwm",
"people": 688000,
"has_nothing": false
},
"nobody_praying_groups": 64,
"nobody_praying_people": 3818505,
"ways_in": "Telugu (3,561,375 here); Kannada (509,500 here); Odia (378,650 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -250,7 +435,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 75,
"pray_first": {
"name": "Nai (Kannada)",
"url": "https://pray.doxa.life/nai-kannada?source=doxalife&utm_source=agwm",
"people": 336000,
"has_nothing": false
},
"nobody_praying_groups": 55,
"nobody_praying_people": 2569950,
"ways_in": "Kannada (2,277,625 here); Telugu (666,800 here); Urdu (261,625 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -262,7 +458,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 64,
"pray_first": {
"name": "Tondman",
"url": "https://pray.doxa.life/tondman?source=doxalife&utm_source=agwm",
"people": 555000,
"has_nothing": false
},
"nobody_praying_groups": 50,
"nobody_praying_people": 2144700,
"ways_in": "Tamil (1,646,150 here); Telugu (823,600 here); Malayalam (224,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -274,7 +481,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 54,
"pray_first": {
"name": "Rana",
"url": "https://pray.doxa.life/rana?source=doxalife&utm_source=agwm",
"people": 76500,
"has_nothing": false
},
"nobody_praying_groups": 41,
"nobody_praying_people": 523900,
"ways_in": "Odia (1,197,550 here); Bengali (31,500 here); Maithili (17,900 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -286,7 +504,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 52,
"pray_first": {
"name": "Lonar",
"url": "https://pray.doxa.life/lonar?source=doxalife&utm_source=agwm",
"people": 427000,
"has_nothing": false
},
"nobody_praying_groups": 45,
"nobody_praying_people": 1967000,
"ways_in": "Marathi (2,144,775 here); Telugu (247,225 here); Urdu (181,300 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -298,7 +527,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 45,
"pray_first": {
"name": "Van Baoriya",
"url": "https://pray.doxa.life/van-baoriya?source=doxalife&utm_source=agwm",
"people": 442000,
"has_nothing": false
},
"nobody_praying_groups": 33,
"nobody_praying_people": 1549725,
"ways_in": "Hindi (61,400 here); Urdu (21,175 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -310,7 +550,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 27,
"pray_first": {
"name": "Bari (Hindi)",
"url": "https://pray.doxa.life/bari-hindi?source=doxalife&utm_source=agwm",
"people": 405000,
"has_nothing": false
},
"nobody_praying_groups": 23,
"nobody_praying_people": 1217800,
"ways_in": "Hindi (2,060,800 here); Chhattisgarhi (234,000 here); Marathi (73,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -322,7 +573,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 32,
"pray_first": {
"name": "Bania (Dogri)",
"url": "https://pray.doxa.life/bania-dogri?source=doxalife&utm_source=agwm",
"people": 146000,
"has_nothing": false
},
"nobody_praying_groups": 25,
"nobody_praying_people": 497665,
"ways_in": "Hindi (30,500 here); Urdu (250 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -334,7 +596,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 28,
"pray_first": {
"name": "Khairwar (Bengali)",
"url": "https://pray.doxa.life/khairwar-bengali?source=doxalife&utm_source=agwm",
"people": 166000,
"has_nothing": false
},
"nobody_praying_groups": 16,
"nobody_praying_people": 381500,
"ways_in": "Bengali (2,146,100 here); Sunwar (38,000 here); Nepali (19,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -346,7 +619,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 22,
"pray_first": {
"name": "Bolla",
"url": "https://pray.doxa.life/bolla?source=doxalife&utm_source=agwm",
"people": 244000,
"has_nothing": false
},
"nobody_praying_groups": 16,
"nobody_praying_people": 1155150,
"ways_in": "Telugu (1,342,400 here); Marathi (243,000 here); Hindi (73,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -358,7 +642,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 24,
"pray_first": {
"name": "Badhai (Chhattisgarhi)",
"url": "https://pray.doxa.life/badhai-chhattisgarhi?source=doxalife&utm_source=agwm",
"people": 843000,
"has_nothing": false
},
"nobody_praying_groups": 20,
"nobody_praying_people": 1818200,
"ways_in": "Chhattisgarhi (1,411,850 here); Halbi (39,200 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -370,7 +665,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 19,
"pray_first": {
"name": "Bargujar",
"url": "https://pray.doxa.life/bargujar?source=doxalife&utm_source=agwm",
"people": 159000,
"has_nothing": false
},
"nobody_praying_groups": 12,
"nobody_praying_people": 410150,
"ways_in": "Hindi (332,550 here); Urdu (227,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -382,7 +688,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 18,
"pray_first": {
"name": "Pangwala",
"url": "https://pray.doxa.life/pangwala?source=doxalife&utm_source=agwm",
"people": 24000,
"has_nothing": false
},
"nobody_praying_groups": 13,
"nobody_praying_people": 75470,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
},
{
@ -394,7 +711,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 17,
"pray_first": {
"name": "Tilli",
"url": "https://pray.doxa.life/tilli?source=doxalife&utm_source=agwm",
"people": 150000,
"has_nothing": false
},
"nobody_praying_groups": 14,
"nobody_praying_people": 400200,
"ways_in": "Hindi (164,000 here); Urdu (82,800 here); Maithili (54,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -406,7 +734,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 14,
"pray_first": {
"name": "Namasudra (Assamese)",
"url": "https://pray.doxa.life/namasudra-assamese?source=doxalife&utm_source=agwm",
"people": 827000,
"has_nothing": false
},
"nobody_praying_groups": 11,
"nobody_praying_people": 1303400,
"ways_in": "Assamese (1,459,800 here); Bengali (910,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -418,7 +757,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 6,
"pray_first": {
"name": "Za",
"url": "https://pray.doxa.life/za?source=doxalife&utm_source=agwm",
"people": 3400,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 6550,
"ways_in": "Tibetan (85,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -430,7 +780,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 9,
"pray_first": {
"name": "Mahisyadas",
"url": "https://pray.doxa.life/mahisyadas?source=doxalife&utm_source=agwm",
"people": 190000,
"has_nothing": false
},
"nobody_praying_groups": 9,
"nobody_praying_people": 280500,
"ways_in": "Bengali (695,400 here); Odia (3,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -442,7 +803,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 7,
"pray_first": {
"name": "Tagewale",
"url": "https://pray.doxa.life/tagewale?source=doxalife&utm_source=agwm",
"people": 7000,
"has_nothing": false
},
"nobody_praying_groups": 6,
"nobody_praying_people": 13875,
"ways_in": "Hindi (7,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -454,7 +826,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 6,
"pray_first": {
"name": "Campa",
"url": "https://pray.doxa.life/campa?source=doxalife&utm_source=agwm",
"people": 7500,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 15500,
"ways_in": "Ladakhi (11,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -466,7 +849,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 5,
"pray_first": {
"name": "Gabit",
"url": "https://pray.doxa.life/gabit?source=doxalife&utm_source=agwm",
"people": 210000,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 252600,
"ways_in": "Marathi (4,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -478,7 +872,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Sonavar",
"url": "https://pray.doxa.life/sonavar?source=doxalife&utm_source=agwm",
"people": 20500,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 28625,
"ways_in": "Urdu (20,500 here); Tamil (13,950 here); French (6,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -490,7 +895,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Lakhera (Haryanvi)",
"url": "https://pray.doxa.life/lakhera-haryanvi?source=doxalife&utm_source=agwm",
"people": 6700,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 6700,
"ways_in": "Punjabi (41,000 here); Haryanvi (26,200 here); Hindi (2,300 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -502,7 +918,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Racband",
"url": "https://pray.doxa.life/racband?source=doxalife&utm_source=agwm",
"people": 3600,
"has_nothing": false
},
"nobody_praying_groups": 3,
"nobody_praying_people": 7100,
"ways_in": "Punjabi (10,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -514,7 +941,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Chinese, Mandarin (16,000 here); Tibetan (5,400 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -526,7 +959,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
},
{
@ -538,7 +977,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 2,
"pray_first": {
"name": "Dalu",
"url": "https://pray.doxa.life/dalu-india?source=doxalife&utm_source=agwm",
"people": 16500,
"has_nothing": false
},
"nobody_praying_groups": 2,
"nobody_praying_people": 17150,
"ways_in": "Bengali (16,500 here); Assamese (650 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -550,7 +1000,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 2,
"pray_first": {
"name": "Olot",
"url": "https://pray.doxa.life/olot?source=doxalife&utm_source=agwm",
"people": 2400,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 2400,
"ways_in": "Chinese, Mandarin (2,600 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -562,7 +1023,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 1,
"pray_first": {
"name": "Khatbune",
"url": "https://pray.doxa.life/khatbune?source=doxalife&utm_source=agwm",
"people": 1200,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 1200,
"ways_in": "Punjabi (1,200 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -574,7 +1046,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 1,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Punjabi (34,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -586,7 +1064,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Maldivian (74,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -598,7 +1082,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Gujarati (125 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -610,7 +1100,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 1,
"pray_first": {
"name": "Yakha",
"url": "https://pray.doxa.life/yakha?source=doxalife&utm_source=agwm",
"people": 7400,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 7400,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
}
],

View file

@ -0,0 +1,47 @@
# Embedding the gospel-resources map
The map's **URL is its interface**. A partner embeds one address in an iframe and never touches it
again, so every parameter below is a promise kept by a gate
(`bun run check:embed-contract`), not a convention.
```html
<iframe src="https://<host>/dx-maps/gospel-resources/resources-map/index.html?codes=kfr,cmn,npi"
style="width:100%;height:600px;border:0" title="Gospel access"></iframe>
```
## The four addresses
| Address | What the reader gets |
|---|---|
| `?codes=<iso3,iso3,…>` | Only those languages' people groups, framed on them. Shows `74 / 2,107`, and that count is the button back to the whole map. |
| `?country=<ISO3>` | That country's sheet open, framed on its groups. The country's own name also works (`?country=India`). |
| `?code=<iso3>` | The people group's sheet, with its resources. `&name=` and `&country=` disambiguate when a language has many groups. |
| `?view=zero` | The groups with **nothing found** — the question this map exists for. `?view=gap` is the same view. |
`?provider=maplibre` is not this map's parameter but the whole fleet's: it selects the keyless
engine, and no map ever substitutes a different one (`bun run check:engine-contract`).
## Bring your own list
The join is **ISO 639-3**, the key every resource in this map is already joined on. A partner's list
needs no agreement with Doxa's roster — only the codes their own data carries. That is the point:
this corpus is public so that other lists can stand on it.
Two things to know before you publish a link:
- **The denominator is Doxa's roster.** The research corpus holds 12,379 people groups; this map
draws the **2,107** Doxa works, so `?codes=` intersects with those. A code outside the roster
draws nothing.
- **It filters, it never invents.** A link matching none of its codes shows an empty map reading
`0 / 2,107`. That is the truth about the link — showing the full map instead would tell you your
broken list works.
## What the map does not promise
- **No zoom or centre parameter.** The frame is derived from the pins the link selects, so a link
stays correct when the data moves under it.
- **Placement is approximate.** A dot marks where a *people* is found, not a town or a boundary,
and 108 of the placed groups share a coordinate with another group. The sheet says so in the
reader's language.
- **An unknown parameter is ignored, never fatal.** `?country=ZZZ` renders the map, not an error —
a partner's typo must not break their page.

View file

@ -14,6 +14,7 @@
- **[explanation.md](./explanation.md)** — the model in 15 lines.
- **[architecture/](./architecture/)** — the deep end: full contracts, the per-file catalog.
- **[README-embed-example.md](./README-embed-example.md)** — the drop-in README used when this bundler is embedded inside a host repo.
- **[README-embed-gospel-resources.md](./README-embed-gospel-resources.md)** — the gospel map's URL contract for partner embeds: bring your own ISO 639-3 list, one country, one group, or the zero-access view.
Working on the repo:

View file

@ -0,0 +1,160 @@
/**
* check-gospel-engine-contract.mjs — the map must use the engine it was ASKED for, or say nothing
* at all. Never a different one.
*
* THE DEFECT THIS IS WRITTEN AGAINST (regions' C3 read + upg100's addendum, 2026-09-26).
* resources-map resolved its engine as `engineGlobal(provider) || window.mapboxgl`. engineGlobal
* already defaults to mapbox, so that fallback could only fire for provider 'maplibre' — and then
* it returned MAPBOX. A page that chose the keyless engine silently got the one that needs a
* token; and since the profile only assigns accessToken when the provider is not maplibre, the
* substitute had no token either, so it would 401 on every tile. Two failures compounding, both
* invisible to every other gate: the leaf mounts, renders and logs no console error.
*
* SIX MEASUREMENTS: two providers x three load states.
* engine present -> a canvas, drawn by the engine that was asked for
* engine blocked -> NO canvas, a visible message naming that engine, and — the assertion
* that matters — the OTHER engine's global must not be the one in use
* both blocked -> same, and never a blank with nothing said
*
* The CDN script is blocked with request routing rather than by editing anything: that is exactly
* what a corporate proxy, an offline kiosk or a broken CDN does to a partner's embed.
*
* Self-test: `--poison` restores the old `|| window.mapboxgl` behaviour in the page (by defining
* window.mapboxgl before the bundle runs while maplibre is blocked) and requires the maplibre arm
* to FAIL — if it passes, this check cannot see the defect it exists for.
*/
import { chromium } from 'playwright'
import { serveReaped } from './_serve-reaped.mjs'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { readFileSync } from 'node:fs'
import { TREE_NAME } from './_tree-name.mjs'
const HERE = dirname(fileURLToPath(import.meta.url))
const PUBLIC = resolve(HERE, '../public')
const PORT = Number(process.env.PORT || 5395)
const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}`
const POISON = process.argv.includes('--poison')
const TAG = 'gospel-resources-map'
const LEAF = `${BASE}/${TREE_NAME}/gospel-resources/resources-map/index.html`
const SCRIPT = { mapbox: /mapbox-gl.*\.js/i, maplibre: /maplibre-gl.*\.js/i }
let srv = null
if (!process.env.BASE_URL) srv = serveReaped(PUBLIC, PORT)
const run = async (browser, provider, block) => {
const page = await browser.newPage({ viewport: { width: 1200, height: 800 } })
const warns = [], errors = []
page.on('console', (m) => { if (m.type() === 'warning' || m.type() === 'error') warns.push(m.text().slice(0, 200)) })
page.on('pageerror', (e) => errors.push(String(e).slice(0, 200)))
for (const b of block) await page.route(SCRIPT[b], (r) => r.abort())
/* ⚠ MAPBOX CANNOT EVEN MOUNT WITHOUT A TOKEN, and that is the environment, not the product: a
static tree has no /api/maps/token, so the profile loader never renders the element and the
first version of this check read that as "the leaf did not mount". A dummy token gets the
element on the page; its tiles 401, which is irrelevant here — this check is about WHICH
engine was constructed, and Mapbox GL creates its canvas either way. */
if (provider === 'mapbox') await page.addInitScript(() => { window.MAP_TOKEN = 'pk.test.not-a-real-token' })
await page.goto(`${LEAF}?provider=${provider}`, { waitUntil: 'domcontentloaded', timeout: 60000 })
/* 20s, not 11: this leaf fetches ~4 MB of tables before the map exists, and at 11s three of
six runs were still showing the profile loader — the gate was measuring its own impatience. */
await page.waitForTimeout(20000)
const r = await page.evaluate((tag) => {
const sr = document.querySelector(tag)?.shadowRoot
const txt = sr ? (sr.textContent || '').replace(/\s+/g, ' ').trim() : ''
return {
mounted: !!sr,
canvas: !!sr?.querySelector('canvas'),
text: txt.slice(0, 600),
/* The leaf's own error line. Reading the whole shadow text instead caught the stylesheet —
".profile-loader .profile-error" — and scored a rendered message as a blank. */
errText: (sr?.querySelector('.gm-err')?.textContent || '').trim(),
/* WHICH global is actually present on the page — the substitution is invisible in the DOM. */
hasMapbox: !!window.mapboxgl,
hasMaplibre: !!window.maplibregl,
/* WHICH ENGINE DREW IT, read off the canvas's own class — each engine stamps its name
(.mapboxgl-canvas / .maplibregl-canvas). Read from window.__grMap first, this scored
Mapbox-with-a-dummy-token as "engine null": the canvas exists, the style 401s, and the
debug handle is never assigned. The canvas cannot lie about who created it. */
engineOfMap: (() => {
const c = sr?.querySelector('canvas')
const cls = c ? c.className || '' : ''
if (/maplibregl/.test(cls)) return 'maplibre'
if (/mapboxgl/.test(cls)) return 'mapbox'
const m = window.__grMap
if (m && window.maplibregl && m instanceof window.maplibregl.Map) return 'maplibre'
if (m && window.mapboxgl && m instanceof window.mapboxgl.Map) return 'mapbox'
return c ? 'unknown' : null
})(),
}
}, TAG)
await page.close()
return { ...r, warns, errors }
}
const fails = []
/* ═══ THE STATIC ARM, AND WHY THE SELF-TEST LIVES HERE ════════════════════════════════════════
* The six runtime measurements are the behavioural evidence, but they cannot be made to fail on
* demand: with the fallback deleted, planting a substitute engine on the PAGE proves nothing —
* the leaf correctly ignores it, so the arms pass and a --poison that expected a failure was
* asserting the wrong thing (measured: it reported "this check cannot see the defect", about
* itself). The defect is a line of SOURCE, so the falsifiable arm reads the source. */
const LEAF_SRC = resolve(HERE, '../plugin-designs/gospel-resources/resources-map.vue')
let src = readFileSync(LEAF_SRC, 'utf8')
if (POISON) src = src.replace('const gl = engineGlobal(grProvider)\n', 'const gl = engineGlobal(grProvider) || window.mapboxgl\n')
/* COMMENTS STRIPPED FIRST. The fix's own comment QUOTES the deleted line — "this used to read
`engineGlobal(grProvider) || window.mapboxgl`" — and the first version of this arm read that
quotation as the defect, failing the very commit that removed it. A gate that cannot tell code
from prose about code will keep flagging the explanation forever. */
const code = src.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/(^|[^:'"\\])\/\/[^\n]*/g, '$1')
const BAD = /engineGlobal\([^)]*\)\s*\|\|/
if (BAD.test(code)) {
fails.push('resources-map.vue falls back from engineGlobal() to another engine global — a page that asked for the keyless engine would silently get the one that needs a token')
}
if (POISON) {
if (!fails.length) { console.error('ENGINE-CONTRACT --poison: the reintroduced `|| window.mapboxgl` was NOT caught — this check cannot see the defect it exists for.'); process.exit(1) }
console.log(`ENGINE-CONTRACT --poison: caught it — ${fails[0]}`)
console.log('ENGINE-CONTRACT: SELF-TEST PASS — the static arm fails as designed. The six runtime measurements are not re-run here; they cannot be forced to fail without reintroducing the defect in a built bundle.')
process.exit(0)
}
let browser
try {
browser = await chromium.launch()
for (const provider of ['mapbox', 'maplibre']) {
/* 1 — the engine is there. It must be the one asked for. */
const ok = await run(browser, provider, [])
if (!ok.mounted) fails.push(`${provider}/present: the leaf did not mount — errors: ${ok.errors.join(' | ') || 'none'}; warns: ${ok.warns.slice(0,2).join(' | ')}`)
else if (!ok.canvas) fails.push(`${provider}/present: no canvas — the map did not draw`)
else if (ok.engineOfMap !== provider && ok.engineOfMap !== 'unknown') fails.push(`${provider}/present: the map instance came from ${ok.engineOfMap}`)
else console.log(` ok ${provider}/present`.padEnd(30) + `canvas, engine=${ok.engineOfMap}`)
/* 2 — the engine is blocked. Visible failure, and NEVER the other engine. */
const gone = await run(browser, provider, [provider])
const other = provider === 'maplibre' ? 'mapbox' : 'maplibre'
if (!gone.mounted) fails.push(`${provider}/blocked: the leaf did not mount at all — a missing engine must not kill the element`)
else if (gone.canvas) fails.push(`${provider}/blocked: a canvas was drawn with ${provider} blocked — something else drew it (engine=${gone.engineOfMap})`)
else if (gone.engineOfMap === other) fails.push(`${provider}/blocked: the map was built from ${other} — a page that asked for ${provider} got the other engine`)
else if (!/did not load|engine/i.test(gone.errText)) fails.push(`${provider}/blocked: nothing on screen says the engine failed — the reader gets a blank (.gm-err reads "${gone.errText}")`)
else if (!gone.warns.some((w) => /engine global never loaded/.test(w))) fails.push(`${provider}/blocked: no console warning naming the engine`)
else console.log(` ok ${provider}/blocked`.padEnd(30) + 'no canvas, names the engine, no substitution')
/* 3 — neither engine can load. */
const both = await run(browser, provider, ['mapbox', 'maplibre'])
if (!both.mounted) fails.push(`${provider}/both-blocked: the leaf did not mount`)
else if (both.canvas) fails.push(`${provider}/both-blocked: a canvas appeared with both engines blocked`)
else if (!/did not load|engine/i.test(both.errText)) fails.push(`${provider}/both-blocked: a blank with nothing said`)
else console.log(` ok ${provider}/both-blocked`.padEnd(30) + 'no canvas, message shown')
}
if (fails.length) {
console.error(`ENGINE-CONTRACT: FAIL — ${fails.length} of 6 measurement(s):`)
for (const f of fails) console.error(` ${f}`)
process.exit(1)
}
console.log('ENGINE-CONTRACT: PASS — the source keeps no cross-engine fallback, and 2 providers x 3 load states: the engine asked for or a named failure, never a substitute.')
} finally {
try { await browser?.close() } catch (_) {}
try { srv?.close?.() } catch (_) {}
}
process.exit(0)

View file

@ -243,6 +243,25 @@ try {
if (!scanned) fails.push('pin index carries no links at all — this check would pass vacuously')
if (bad.length) fails.push(`${bad.length} link(s) on an unscreened publisher (e.g. ${bad[0]})`)
if (contactBad.length) fails.push(`${contactBad.length} translator contact(s) on an unscreened organisation (e.g. ${contactBad[0]})`)
/* ★ THE PROVINCE TABLE IS A SIXTH PLACE URLS LIVE (2026-09-26). Its rows now carry a prayer
page — the first move for that state — and a table added after this scan was written is
exactly how the access table went unscreened for weeks. Read from DISK, like the access
table below, so it is checked even when the province layer was never opened in the page. */
try {
const prov = JSON.parse(readFileSync(resolve(REPO, 'data/tables/gospel-by-province.json'), 'utf8'))
let provScanned = 0
const provBad = []
for (const row of prov.rows || []) {
const u = row.pray_first && row.pray_first.url
if (!u) continue
provScanned++
if (!ALLOWED.test(u)) provBad.push(`${row.province} -> ${u}`)
}
if (!provScanned) fails.push('the province table carries no prayer link at all — this arm would pass vacuously')
if (provBad.length) fails.push(`${provBad.length} province prayer link(s) on an unscreened host (e.g. ${provBad[0]})`)
linkCount += provScanned
} catch (e) { fails.push(`could not screen the province table: ${e.message}`) }
contactCount = contacts
linkCount = scanned

View file

@ -91,6 +91,8 @@
"check:gospel-all": "node internal/check-gospel-all.mjs",
"check:gospel-tables-staged": "node internal/check-gospel-tables-staged.mjs",
"check:embed-contract": "node internal/check-gospel-embed-contract.mjs",
"check:engine-contract": "node internal/check-gospel-engine-contract.mjs",
"check:engine-contract:poison": "node internal/check-gospel-engine-contract.mjs --poison",
"check:embed-contract:poison": "node internal/check-gospel-embed-contract.mjs --poison",
"check:map-attribution": "node internal/check-map-attribution.mjs",
"check:studio-rail": "node internal/check-studio-rail.mjs",
@ -378,6 +380,7 @@
"check:studio-rail": "the Plugin Studio rail is laid out like plugin-designs/: one folder per bundle with its elements inside, bundles in the section of their highest capability (5 \u2192 1) and in name order, one canonical node per plugin. Runs the studio's real rail code on the built manifest, headless.",
"check:translator-contacts": "the credit line LINKS the translating organisation now, and a contact URL is a link this map stands behind. Reads ALLOWED_CONTACT out of internal/verify-gospel-map.mjs rather than restating it (two copies of an allowlist drift, and the drifting copy is the one nobody reads), then asserts every cr.u is on that list, was recorded `verified` by a real fetch, is never also serving a RESOURCE (wycliffe.org is somewhere to write to, not a publisher this map reads text from), and is actually RENDERED as an anchor \u2014 the data can carry 838 URLs while the template shows none. Static, sub-second. Self-test: `bun run check:translator-contacts:poison`.",
"check:embed-contract": "the map's URL is a PUBLIC INTERFACE: a partner embeds ?codes=<iso3 list>, ?country=<ISO3> or ?view=zero in an iframe and never touches it again. A refactor breaks those links SILENTLY \u2014 the leaf still mounts, renders and logs no errors, it just shows the whole world to a church that asked for its forty groups. Asserts through the reader's eyes (the partner-list notice's two numbers), with both numbers and the probe codes derived from the roster the leaf itself reads, never typed in. Browser gate; needs no server of its own. Self-test: `bun run check:embed-contract:poison`.",
"check:engine-contract": "the map must use the engine it was ASKED for or fail VISIBLY \u2014 never a substitute. resources-map read `engineGlobal(provider) || window.mapboxgl`; engineGlobal already defaults to mapbox, so that could only fire for provider 'maplibre' and then returned MAPBOX \u2014 a keyless page silently handed the engine that needs a token, which the profile then does not give it, so its tiles 401. Invisible to every other gate: the leaf mounts, renders and logs nothing. Six runtime measurements (2 providers x engine present / blocked / both blocked, CDN blocked by request routing the way a proxy or an offline kiosk does) plus a static arm on the source, comments stripped so the fix's own quotation of the deleted line is not read as the defect. Mapbox arms inject a dummy MAP_TOKEN, because without one the element never mounts on a static tree and that is the environment, not the product. Engine attribution is read off the canvas class, not a debug handle. Browser gate. Self-test: `bun run check:engine-contract:poison`.",
"check:snapshot-guard": "every gospel-resources catalogue fetcher must write through scripts/_snapshot-guard.mjs, which refuses a write that loses more than a tenth of the previous snapshot. Written after a rate-limited FCBH run silently replaced 1,666 video scopes with 1,103. Static, sub-second. Self-test: `bun run check:snapshot-guard:poison` injects a raw write and the check must fail on it.",
"check:spa-tab-order": "the cap-5 SPA must open on Big Picture and keep the agent's order (Big Picture, UPG-100, Prayer Progress, Gospel Resources) — asserted as PRESENCE + tab-1 + RELATIVE order on the RENDERED rail, because the rail gained three sections and now renders 12 rows with others between them. ⚠ NOT WAVE-WIRED: it FAILS rather than skips when the SPA is unreachable, deliberately (\"a gate that cannot reach its subject has not passed, it has not run\") — correct standalone, but gates:post runs on checkouts with no server. Needs `bun run serve` on 4173.",
"check:stale-sweep-claim": "a caveat that has stopped being true is a wrong number. The gospel surfaces carry a paragraph saying which pools were searched; while the GRN sweep ran they truthfully said part of it was unread, the sweep finished, and the sentence stayed for four more commits. The DATA decides here: undecided gap codes mean the claim is allowed, all-decided means it must go, so it re-arms itself for the next slow pool. Does NOT flag a claim rendered under a v-if on the pending count — that form expires on its own. Self-test: `--poison`. Static, sub-second.",

View file

@ -50,6 +50,7 @@ import ShareButton from '@map/components/map-controls/ShareButton.vue'
import { resolveAssetsBase } from '@map/utils/embedBase.js'
import { resolveMapProvider } from '@map/composables/useMapProvider.js'
import { ensureEngineScript, engineGlobal, ensureEngineCSS, engineStylesheetUrl, engineUiLocale } from '@map/composables/useMapInstance.js'
import { localizeBasemapLabels } from '@map/maps/localize-labels.js'
import { resolveNamedStyle } from '@map/styles/registry.js'
import { installRtlTextPlugin } from '@map/maps/rtl-text.js'
// People-group dots open the SAME detail panel as Prayer Progress (doxa-simple-map): the
@ -372,9 +373,9 @@ onMounted(async () => {
if (!gl) {
const engine = ciProvider === 'maplibre' ? 'MapLibre' : 'Mapbox'
console.warn(`[connectivity-map] the ${engine} engine did not load; refusing to substitute another engine.`)
// messages.engineNotLoadedDetail arrives with upg100's ade12e4c; until it does, English is the fallback.
const msg = t('messages.engineNotLoadedDetail', { engine })
err.value = msg && msg !== 'messages.engineNotLoadedDetail' ? msg : `The ${engine} map engine did not load. The list and legend are unaffected.`
// messages.engineMissing is the shared key (studio's landing 3); English only if a host has no catalogue.
const msg = t('messages.engineMissing', { engine })
err.value = msg && msg !== 'messages.engineMissing' ? msg : `The ${engine} map engine did not load.`
return
}
if (!mapEl.value) { err.value = 'map engine not loaded'; return }
@ -417,6 +418,10 @@ onMounted(async () => {
// countries carrying a real attribution requirement (India CC BY 2.5 IN, etc).
addMapAttribution(map, { boundaries: true })
map.once('load', async () => {
// The BASEMAP's place names in the reader's language (Mapbox setLanguage / MapLibre name:<lang>),
// the library's own helper. useMapInstance applies it for every map built through it; this map is
// built raw, so it was the one map whose country and city names stayed English under ar.
try { localizeBasemapLabels(map, readerLang()) } catch (_) { /* a nicety lost, never a broken map */ }
paint(map, adm0)
selectedPin.initialize()
await groupsLoaded

View file

@ -88,7 +88,7 @@ import LocationButton from '@map/components/map-controls/LocationButton.vue'
import FullscreenButton from '@map/components/map-controls/FullscreenButton.vue'
import ShareButton from '@map/components/map-controls/ShareButton.vue'
import { resolveAssetsBase } from '@map/utils/embedBase.js'
import { resolveMapProvider } from '@map/composables/useMapProvider.js'
import { resolveMapProvider, providerLabel } from '@map/composables/useMapProvider.js'
import { ensureEngineScript, engineGlobal, engineStylesheetUrl, ensureEngineCSS } from '@map/composables/useMapInstance.js'
import { installRtlTextPlugin } from '@map/maps/rtl-text.js'
import { resolveNamedStyle } from '@map/styles/registry.js'
@ -782,12 +782,23 @@ const pinsByIso = computed(() => {
/* The fallback resolves against the SHIPPED ENGLISH CATALOG (imported at the top), not the
key. Returning the last dot-segment would have put "gap" and "deathsDay" on screen — a
broken-looking label is not graceful degradation, it just moves the bug. */
/* Walks from the ROOT of the catalogue, not from its gospel subtree: this leaf now also reads
`pins.*`, the shared people-group-pin wording, and an area-blind lookup would have fallen back
to the key name for every one of those on a host with no i18n. */
const enLookup = (key) =>
String(key).replace(/^gospel\./, '').split('.').reduce((o, k) => (o == null ? o : o[k]), EN_MESSAGES.gospel || {})
let t = (key) => enLookup(key) ?? String(key)
String(key).split('.').reduce((o, k) => (o == null ? o : o[k]), EN_MESSAGES || {})
/* The fallback interpolates too. vue-i18n does it for the translated path; without this the
English arm would render "{names} — {n} groups share…" literally. */
const fill = (str, params) => (params
? String(str).replace(/\{(\w+)\}/g, (m, k) => (params[k] == null ? m : String(params[k])))
: str)
let t = (key, params) => fill(enLookup(key) ?? String(key), params)
try {
const i18n = useI18n()
t = (key) => { const v = i18n.t(key); return v === key ? (enLookup(key) ?? key) : v }
t = (key, params) => {
const v = params ? i18n.t(key, params) : i18n.t(key)
return v === key ? fill(enLookup(key) ?? key, params) : v
}
} catch (_) { /* no i18n on this host: the English catalog above is the fallback */ }
/* Whether to show the "these notes are in English" line at all. Read from the same i18n
instance the labels come from, so the two can never disagree. */
@ -803,7 +814,10 @@ const readerLang = () => {
t() falls back to the key when a catalogue has no entry, which on a `title` attribute would
put "gospel.legend.hnrTip" in a tooltip: worse than the English it replaced. This keeps the
English in the template until the key lands, and switches the moment it does. */
const tOr = (key, english) => { const v = t(key); return v && v !== key ? v : english }
const tOr = (key, english, params) => {
const v = t(key, params)
return v && v !== key ? v : fill(english, params)
}
const SE_KIND = { PDF: 'PDF', audio: 'audio', sab: 'app', study: 'study notes', viewer: 'read online' }
const seKinds = (k) => (Array.isArray(k) ? k : []).map((x) => SE_KIND[x] || x).join(', ')
@ -1487,8 +1501,21 @@ onMounted(async () => {
/* Re-check after the await: this leaf can be unmounted mid-initialise, which is the race
that produced "Cannot read properties of null" across the fleet. */
if (!mapEl.value) return
const gl = engineGlobal(grProvider) || window.mapboxgl
if (!gl || !mapEl.value) { err.value = 'map engine not loaded'; return }
/* ⚠ NEVER SWITCH ENGINES SILENTLY (regions' C3 read, 2026-09-26). This used to read
`engineGlobal(grProvider) || window.mapboxgl`. engineGlobal already defaults to mapbox, so
the fallback could only ever fire for provider 'maplibre' — and then it handed back MAPBOX:
a page that chose the keyless engine got the one that needs a token, which breaks the
keyless contract silently, with a map that looks fine until the token is missing. The
requested engine or a visible failure; never a different engine. */
const gl = engineGlobal(grProvider)
if (!gl) {
/* The console line stays English on purpose — it is for whoever is debugging the page, not
for the reader. The line the READER sees goes through the catalogue. */
console.warn(`[gospel-resources] the ${grProvider} engine global never loaded — refusing to substitute another engine, because that would hand a keyless page the engine that needs a token.`)
err.value = tOr('messages.engineMissing', 'The {engine} map engine did not load.', { engine: providerLabel(grProvider) })
return
}
if (!mapEl.value) return
/**
* ═══ ARABIC, HEBREW AND PERSIAN PLACE NAMES NEED A SHAPER ═══════════════════════════════
*
@ -1525,7 +1552,7 @@ onMounted(async () => {
the locale map the shared composable passes — "Toggle attribution" and the canvas's
accessible name "Map" stayed English under ar while every string we own was Arabic.
Set at construction because that is the only time either engine reads it. */
locale: engineUiLocale(readerLang()),
locale: engineUiLocale(readerLang(), grProvider),
/* A starting zoom is a guess about the canvas. It was 1.3, which framed the world
while this leaf was running WITHOUT the engine's stylesheet; once mapbox-gl.css
reached the shadow root the canvas sized correctly and the same 1.3 cut the visible
@ -1755,14 +1782,20 @@ useShadowStyles(
'.gm-linklist span{color:#6d766e}' +
'.is-dark .gm-linklist{background:rgba(59,70,61,.6);border-color:#6d766e;color:#f3f3f1}' +
'.is-dark .gm-linklist span{color:#d1d4cd}' +
'.gm-legend{position:absolute;top:8px;left:8px;width:var(--map-legend-width,380px);' +
/* ⚠ LOGICAL, NOT PHYSICAL (the agent-found, rega measured on main 52eeb0db). Under ar the five
map controls mirror to the LEFT while `left:8px` kept the legend physically left, so the
legend sat underneath all five of them. cities-internet shares this class name and passed
for one reason: it anchors inline. Every physical left/right in this stylesheet that has a
direction-dependent meaning is now logical — the anchor, the search clear button, the
accent borders and the header's push-right. */
'.gm-legend{position:absolute;top:8px;inset-inline-start:8px;width:var(--map-legend-width,380px);' +
'max-height:calc(100% - 16px);overflow-y:auto;overscroll-behavior:contain;' +
'max-width:calc(100% - 16px);box-sizing:border-box;z-index:4;padding:8px 10px;' +
'border-radius:10px;background:rgba(255,255,255,.94);color:#0f1419;' +
"font:12px/1.35 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;box-shadow:0 2px 10px rgba(0,0,0,.16)}" +
// Narrow screens: the rail is still on the right, so the legend must stop short
// of it rather than run under it. 46px = 32px button + 3px inset + clearance.
'@media(max-width:480px){.gm-legend{width:auto;right:46px}}' +
'@media(max-width:480px){.gm-legend{width:auto;inset-inline-end:46px}}' +
'.is-dark .gm-legend{background:rgba(19,32,25,.95);color:#e5e7eb}' +
'.gm-title{font-weight:700;font-size:15.5px;margin-bottom:5px}' +
'.gm-keys{display:flex;flex-wrap:wrap;gap:5px 12px}' +
@ -1825,7 +1858,7 @@ useShadowStyles(
'.is-dark .gm-sheet{background:#132019;color:#e5e7eb}' +
'.gm-sh-head{display:flex;align-items:center;gap:10px;margin-bottom:8px}' +
'.gm-sh-name{font-weight:800;font-size:18px}' +
'.gm-x{margin-left:auto;border:1px solid rgba(0,0,0,.16);background:transparent;color:inherit;' +
'.gm-x{margin-inline-start:auto;border:1px solid rgba(0,0,0,.16);background:transparent;color:inherit;' +
'font:600 12px inherit;padding:6px 12px;border-radius:8px;cursor:pointer;min-height:34px}' +
'.gm-stat{display:flex;justify-content:space-between;gap:12px;padding:4px 0;' +
'border-bottom:1px solid rgba(0,0,0,.07);font-variant-numeric:tabular-nums}' +
@ -1839,7 +1872,7 @@ useShadowStyles(
'.gm-search{position:relative;margin-bottom:6px}' +
'.gm-q{width:100%;box-sizing:border-box;border:1px solid #d1d4cd;border-radius:8px;background:#fff;color:#3b463d;font:12px inherit;padding:7px 26px 7px 9px;min-height:32px}' +
'.gm-q:focus{outline:2px solid #92b195;outline-offset:1px}' +
'.gm-qx{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:0;background:transparent;color:#6d766e;font-size:19px;line-height:1;cursor:pointer;padding:4px 6px;min-height:24px}' +
'.gm-qx{position:absolute;inset-inline-end:4px;top:50%;transform:translateY(-50%);border:0;background:transparent;color:#6d766e;font-size:19px;line-height:1;cursor:pointer;padding:4px 6px;min-height:24px}' +
'.gm-qres{margin:-2px 0 7px;border:1px solid #d1d4cd;border-radius:8px;background:#fff;overflow:hidden}' +
'.gm-qrow{display:flex;align-items:baseline;gap:6px;width:100%;text-align:left;border:0;background:transparent;font:inherit;font-size:14px;color:#3b463d;padding:6px 8px;cursor:pointer;min-height:30px;border-bottom:1px solid #eceee9}' +
'.gm-qrow:last-child{border-bottom:0}' +
@ -1871,18 +1904,18 @@ useShadowStyles(
'.is-dark .gm-gtab.on{background:#92b195;color:#10241a}' +
'.gm-pg-rel{display:block;margin-top:2px;font-size:13px;color:#6d766e;font-style:italic}' +
'.is-dark .gm-pg-rel{color:#9fb3a4}' +
'.gm-rel{margin:8px 0 0;padding:8px 10px;border:1px solid #d1d4cd;border-left:3px solid #92b195;' +
'.gm-rel{margin:8px 0 0;padding:8px 10px;border:1px solid #d1d4cd;border-inline-start:3px solid #92b195;' +
'border-radius:6px;background:#fff;font-size:14.5px;line-height:1.5}' +
'.gm-rel code{font-size:14px;background:#f3f3f1;padding:1px 4px;border-radius:3px}' +
'.is-dark .gm-rel{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.18);color:#e5e7eb}' +
'.gm-sign{margin:8px 0 0;padding:8px 10px;border:1px solid #d1d4cd;border-left:3px solid #6d766e;' +
'.gm-sign{margin:8px 0 0;padding:8px 10px;border:1px solid #d1d4cd;border-inline-start:3px solid #6d766e;' +
'border-radius:8px;background:#f3f3f1;color:#3b463d;font-size:14.5px;line-height:1.5}' +
'.is-dark .gm-sign{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.18);color:#e5e7eb}' +
'.gm-pray{display:block;margin:8px 0 0;padding:9px 11px;border-radius:8px;text-decoration:none;' +
'background:#3b463d;color:#fff;font:600 12.5px inherit;text-align:center}' +
'.gm-pray:hover,.gm-pray:focus-visible{background:#2f382f}' +
'.gm-pray-n{display:block;margin-top:2px;font-weight:500;font-size:14px;opacity:.85}' +
'.gm-tablink{display:block;margin:10px 0 2px;padding:9px 12px;border:1px solid #d1d4cd;border-left:3px solid #92b195;border-radius:8px;background:#f3f3f1;color:#3b463d;font-weight:600;font-size:15.5px;text-decoration:none;min-height:36px;box-sizing:border-box}' +
'.gm-tablink{display:block;margin:10px 0 2px;padding:9px 12px;border:1px solid #d1d4cd;border-inline-start:3px solid #92b195;border-radius:8px;background:#f3f3f1;color:#3b463d;font-weight:600;font-size:15.5px;text-decoration:none;min-height:36px;box-sizing:border-box}' +
'.gm-tablink:hover{background:#e9ebe6}' +
'.is-dark .gm-tablink{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.18);color:#e5e7eb}' +
'.gm-stat-alt span{opacity:.72}' +
@ -2066,14 +2099,17 @@ useShadowStyles(
all-covered wording says what it means. Still two different claims: every group
has SOMEWHERE TO START, and not one of them has the gospel in their own
language. -->
<template v-if="pinTally.wayIn === pinTally.none">
<b>Every one of those {{ fmt(pinTally.none) }}</b> has a possible way in
</template>
<template v-else>
<b>{{ fmt(pinTally.wayIn) }} of those {{ fmt(pinTally.none) }}</b> have a possible way in
</template>
— a bridge language, or SUN for a Deaf group. Tap one to see it. A way in is not
the gospel in their own language; the gap is unchanged.
<!-- ⚠ THIS SENTENCE IS NOT PROSE AND MUST NOT STAY ENGLISH. It is the legend's one
piece of news — that almost every group with nothing has somewhere to start — and
rega measured it as the Latin left in an Arabic legend once the explainer was
folded away. Through tOr() with its numbers as parameters, so it renders today's
English until the key lands and then switches. The CAVEAT that followed it ("a way
in is not the gospel in their own language") moved into the fold below, where the
rest of the basis lives: it qualifies the news rather than being it. -->
<b>{{ pinTally.wayIn === pinTally.none
? tOr('gospel.guide.wayInAll', 'Every one of those {n}', { n: fmt(pinTally.none) })
: tOr('gospel.guide.wayInSome', '{n} of those {total}', { n: fmt(pinTally.wayIn), total: fmt(pinTally.none) }) }}</b>
{{ tOr('gospel.guide.wayInWhat', 'has a way in — a bridge language, or SUN for a Deaf group. Tap one to see it.') }}
</p>
<!-- Not a colour, so it carries no dot: this cuts ACROSS the three tiers rather
than naming one of them. It is the translation-priority question. -->
@ -2116,8 +2152,10 @@ useShadowStyles(
<br><b>{{ t('gospel.guide.noneFoundShort') }}</b>
<br><b>{{ t('gospel.guide.tapCountry') }}</b>
<details class="gm-why">
<summary class="gm-why-sum">How these numbers are made</summary>
<summary class="gm-why-sum">{{ tOr('gospel.guide.howNumbersMade', 'How these numbers are made') }}</summary>
<div class="gm-why-body">
<span dir="ltr">A way in is not the gospel in someone's own language; the gap it is
counted against is unchanged by it.</span>
<span dir="ltr"> A country is a COUNT of those groups — how many of
Doxa's are there with nothing found — never a percentage: 106 of these 175 countries hold
one or two groups, and a share over a denominator of two says nothing. A country Doxa does
@ -2161,12 +2199,32 @@ useShadowStyles(
</div>
<p v-if="selectedProvince.zero_access_examples" class="gm-note" dir="ltr" style="margin:6px 0 0">
Largest with nothing: <b>{{ selectedProvince.zero_access_examples }}</b>
<template v-if="selectedProvince.ways_in"><br>Way in: {{ selectedProvince.ways_in }} — chosen for the country, not this province.</template>
<!-- The basis travels WITH the answer. This line used to read "chosen for the country, not
this province" on every row, which was true then and is now true of five rows in
forty-six; printing it on all of them would understate the other forty-one and
printing none of them would overstate these five. -->
<template v-if="selectedProvince.ways_in"><br>Way in: {{ selectedProvince.ways_in }} — {{ selectedProvince.ways_in_basis || 'country-level' }}.</template>
</p>
<!-- N of M, the same rule as the country sheet: the denominator is the groups HERE with a
prayer page, never the province. -->
<div class="gm-stat" v-if="selectedProvince.prayer_pages">
<span>{{ t('gospel.tabs.noprayer') }}</span>
<b>{{ fmt(selectedProvince.nobody_praying_groups) }} / {{ fmt(selectedProvince.prayer_pages) }}</b>
</div>
<p class="gm-note" dir="ltr" style="margin:6px 0 0">
A group is placed in a province from its own coordinate, which marks where a people is
found rather than a settlement. Near a border that point can fall on the wrong side.
</p>
<!-- ═══ THE MOVE, AT THE GRAIN A TEAM IS SENT TO ══════════════════════════════════════
A country is not where anyone is sent; a state is. Same ranking as the country sheet —
need first, then size — so drilling down never hands the reader a second answer. -->
<a v-if="selectedProvince.pray_first" class="gm-pray" :href="selectedProvince.pray_first.url"
target="_blank" rel="noopener noreferrer"
:title="'Open the prayer page for ' + selectedProvince.pray_first.name + ' on doxa.life.'">
{{ t('gospel.sheet.pray') }} {{ selectedProvince.pray_first.name }}
<span class="gm-pray-n" dir="ltr">{{ fmt(selectedProvince.pray_first.people) }}
people<template v-if="selectedProvince.pray_first.has_nothing">, nothing found</template></span>
</a>
</div>
<div v-else-if="selected || showGapList" class="gm-sheet">
@ -2337,14 +2395,16 @@ useShadowStyles(
of the 2,107 placed groups sit on a coordinate they share with another group. Where
this one does, it names them, because "approximate" on its own hides the part a
reader would never otherwise discover — that some dots are literally the same dot.
English prose in a dir="ltr" block, per the standing decision on caveats. -->
<p class="gm-note" dir="ltr" style="margin:6px 0 0">
The dot marks where this people is found, not a town or a boundary.
TRANSLATED NOW, in 11 locales, from the shared pins.* area (APPROXPIN). Read through
this leaf's own guarded t() rather than by mounting library ApproxPinNote.vue, which
calls useI18n() unguarded: this bundle is embeddable in hosts that never called
app.use(i18n), where that throws during setup and the shadow boundary swallows it —
the failure that blanked a production plugin once already. Same wording either way;
it is this map's P5 proposal that became the library's. -->
<p class="gm-note" :dir="isEnglish ? 'ltr' : null" style="margin:6px 0 0">
{{ t('pins.approximate') }}
<template v-if="sharedWith(selectedGroup).length">
It sits on the same point as
<b>{{ sharedWith(selectedGroup).join(', ') }}</b> — {{ sharedWith(selectedGroup).length + 1 }}
groups share this coordinate, so the position tells you the locality and not which
group is where.
{{ t('pins.sharedPoint', { names: sharedWith(selectedGroup).join(', '), n: sharedWith(selectedGroup).length + 1 }) }}
</template>
</p>
@ -2663,7 +2723,7 @@ useShadowStyles(
</p>
<p v-if="selectedGroup.is_sign" class="gm-sign">
<b>This is a sign language.</b> A Deaf group cannot be reached by a text
<b>{{ tOr('gospel.guide.isSignLanguage', 'This is a sign language.') }}</b> A Deaf group cannot be reached by a text
translation, so eBible's silence here is not an absence of Scripture — it is a
text pool that was never the right place to look. What counts is Scripture
<em>filmed in this sign language</em>. Of {{ fmt(signTally.langs) }} sign languages
@ -2882,7 +2942,7 @@ useShadowStyles(
</div>
<div v-if="withResources.length > shown" class="gm-more">
Showing {{ shown }} of {{ withResources.length }}.
<button type="button" class="gm-back" @click="shown = withResources.length">Show all groups</button>
<button type="button" class="gm-back" @click="shown = withResources.length">{{ t('gospel.legend.showAll') }}</button>
</div>
</div>
@ -2903,7 +2963,7 @@ useShadowStyles(
</button>
<div v-if="withoutResources.length > shown" class="gm-more">
Showing {{ shown }} of {{ withoutResources.length }}.
<button type="button" class="gm-back" @click="shown = withoutResources.length">Show all groups</button>
<button type="button" class="gm-back" @click="shown = withoutResources.length">{{ t('gospel.legend.showAll') }}</button>
</div>
</div>
</template>

View file

@ -82,6 +82,21 @@ const wayIn = (code, iso3, name) => {
return b ? b.l : ''
}
/* ═══ PRAYER, AT THE GRAIN A TEAM IS ACTUALLY SENT TO ═══════════════════════════════════════
* The country sheet already ends in a prayer move. A country is not where anyone is sent — a state
* is — so the province carries the same two numbers. The JOIN IS BY NAME+COUNTRY, not by language,
* because you pray for a people in a place; that is doxa.life's own key and the one place in this
* build where a name match is correct rather than forbidden.
*
* ⚠ THE DENOMINATOR IS THE GROUPS WITH A PRAYER PAGE, never the province. doxa.life publishes a
* page for 1,723 of the roster, so "nobody praying" can only be said of groups that HAVE one, and
* both numbers ship so no surface can quote the first without the second.
*/
let pray = {}
try { pray = T('pray-index.json').byKey || {} } catch { /* no index: the columns ship as null, never as zero */ }
const prayKey = (name, iso3) =>
`${String(name || '').toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim()}|${String(iso3 || '').toUpperCase()}`
/* ⚠ INDIA READS THE -full FILE, NOT gb-IND-ADM1.geojson. The unsuffixed file is the UPG-100
list's own curated partition — 34 listId-tagged units — and this table was built on it for one
build, which is why eleven groups had no province: they were standing in states the partition
@ -114,6 +129,51 @@ for (const c of COUNTRIES) {
}
for (const [province, list] of by) {
const zero = list.filter((r) => (tiers[r.iso639_3] ?? r.tier ?? 0) === 0)
/* ═══ A WAY IN CHOSEN FOR THIS PROVINCE, NOT FOR THE COUNTRY ══════════════════════════
* The caveat this table used to carry said it plainly: Arunachal Pradesh, in the far
* north-east, was offered TELUGU — a South Indian language — because the curated bridge
* table is keyed by country and a curated bridge outranks a computed one. India's computed
* default is Hindi, defensible nationally and wrong for much of the north-east.
*
* So the province answers for itself. The candidates are the languages of groups STANDING
* IN THIS PROVINCE that already have Scripture AND film (tier 2), ranked by how many people
* here already hold them. That is a measured neighbour, not a national average: a language
* with 4 million people in this state is a plausible second language for its neighbours in a
* way that a language from 1,500 km away is not.
*
* It never invents one. A province with no tier-2 language of its own keeps the country-level
* answer and SAYS so, because "no local bridge exists" is itself worth reading.
*/
const localTier2 = new Map()
for (const r of list) {
const code = r.iso639_3
if (!code || (tiers[code] ?? r.tier ?? 0) !== 2) continue
if (isDeaf(code, r.name)) continue
const cur = localTier2.get(code) || { code, language: (codes[code] && codes[code].l) || code, people: 0, groups: 0 }
cur.people += r.population || 0
cur.groups += 1
localTier2.set(code, cur)
}
const local = [...localTier2.values()].sort((a, b) => b.people - a.people).slice(0, 3)
/* Counted over the groups in THIS province that have a prayer page. */
let prayPages = 0, noPray = 0, noPrayPeople = 0
let move = null, moveRank = -1
for (const r of list) {
const e = pray[prayKey(r.name, r.iso3)]
if (!e) continue
prayPages++
if (e.praying > 0) continue
noPray++
noPrayPeople += r.population || 0
/* THE MOVE: need first, then size — the same order the country sheet uses, so a reader
drilling from country to province is not handed two different rankings. */
const rank = ((tiers[r.iso639_3] ?? r.tier ?? 0) === 0 ? 1e12 : 0) + (r.population || 0)
if (rank > moveRank) {
moveRank = rank
move = { name: e.n || r.name, url: e.u, people: r.population || 0, has_nothing: (tiers[r.iso639_3] ?? r.tier ?? 0) === 0 }
}
}
rows.push({
country: c.country,
iso3: c.iso3,
@ -125,7 +185,20 @@ for (const c of COUNTRIES) {
/* Named so a reader of the CSV can act without opening the map. */
zero_access_examples: zero.sort((a, b) => (b.population || 0) - (a.population || 0))
.slice(0, 3).map((r) => r.name).join('; '),
ways_in: [...new Set(zero.map((r) => wayIn(r.iso639_3, r.iso3, r.name)).filter(Boolean))].join('; '),
prayer_pages: prayPages,
/* The URL comes from the prayer index, which took it from doxa.life's OWN listing (a slug is
never constructed here: pray.doxa.life answers 200 for anything). */
pray_first: move,
nobody_praying_groups: noPray,
nobody_praying_people: noPrayPeople,
ways_in: local.length
? local.map((l) => `${l.language} (${l.people.toLocaleString('en-US')} here)`).join('; ')
: [...new Set(zero.map((r) => wayIn(r.iso639_3, r.iso3, r.name)).filter(Boolean))].join('; '),
/* WHICH QUESTION THE WAY IN ANSWERED. Without this column the two kinds of answer are
indistinguishable on the page, and a country-level answer read as a local one is exactly
how Telugu ends up looking like advice about Arunachal Pradesh. */
ways_in_basis: local.length ? 'in this province' : 'country-level — no local language here has both Scripture and film',
ways_in_country: [...new Set(zero.map((r) => wayIn(r.iso639_3, r.iso3, r.name)).filter(Boolean))].join('; '),
approximate: true,
})
}
@ -166,14 +239,15 @@ if (!assigned || assigned < 900) {
china_note: 'China\'s ADM1 file carries 12 provinces, not 31+. Measured rather than ' +
'assumed: 152 of 154 Chinese groups fall inside them and all twelve are used, so the ' +
'file is cut to the provinces where the unreached peoples are.',
ways_in_are_country_level: 'The ways in are chosen for the COUNTRY, and going below the ' +
'border is what exposes the cost of that. Arunachal Pradesh, in the far north-east, is ' +
'offered TELUGU — a South Indian language — because the curated bridge table names it ' +
'for those groups and a curated bridge outranks the computed one. India\'s computed ' +
'default is Hindi (41%, official), which is defensible nationally and still wrong for ' +
'much of the north-east. This table does not fix that: it makes it visible. Until a ' +
'bridge can be chosen per province, read the ways-in column as "a language with ' +
'Scripture and film somewhere in this country", not as a recommendation for this place.',
ways_in: 'Chosen FOR THE PROVINCE where the province can answer: the languages of groups ' +
'standing in it that already have Scripture AND film, ranked by the people here who ' +
'already hold them. The column says which basis was used. This replaces a country-level ' +
'answer that produced a measured absurdity — Arunachal Pradesh, in the far north-east, ' +
'was offered TELUGU, because the curated bridge table is keyed by country and a curated ' +
'bridge outranks a computed one. A province with no tier-2 language of its own still ' +
'falls back to the country answer, and ways_in_basis says so rather than hiding it. ' +
'It is a NEIGHBOUR, not a recommendation: whether a group actually speaks it is a ' +
'question for someone on the ground.',
approximate: 'A province is assigned by point-in-polygon on the group\'s coordinate, and ' +
'that coordinate marks where a PEOPLE is found, not a settlement — 108 groups across the ' +
'roster even share a coordinate with another group. Near a border the point can fall on ' +
@ -188,7 +262,12 @@ if (!assigned || assigned < 900) {
{ title: 'Groups with nothing', field: 'zero_access_groups', type: 'number' },
{ title: 'People with nothing', field: 'zero_access_people', type: 'number' },
{ title: 'Largest with nothing', field: 'zero_access_examples', type: 'string' },
{ title: 'Nobody praying', field: 'nobody_praying_groups', type: 'number' },
{ title: 'Of those with a prayer page', field: 'prayer_pages', type: 'number' },
{ title: 'People nobody is praying for', field: 'nobody_praying_people', type: 'number' },
{ title: 'Ways in', field: 'ways_in', type: 'string' },
{ title: 'Basis', field: 'ways_in_basis', type: 'string' },
{ title: 'Ways in (country-level)', field: 'ways_in_country', type: 'string' },
{ title: 'Placement approximate', field: 'approximate', type: 'string' },
],
rows,

View file

@ -10,7 +10,7 @@
"india_note": "India is read from the COMPLETE ADM1 (36 states, geoBoundaries via DataMeet India, CC BY 2.5 IN). The first build of this table read gb-IND-ADM1.geojson, which is the UPG-100 list's curated 34-unit partition, and eleven groups came out with no province because they stood in states that partition does not draw. Switching the file moved 998 assigned to 1,005 and 44 province rows to 46, and turned the province names into India's own states.",
"unassigned_note": "Four remain, each one legible rather than lost. Great Andamanese and the Sentinelese sit on small islands whose simplified coastline the point falls just outside — Andaman and Nicobar IS in the file, so this is geometry precision, not a missing province. Jing and Pana are on China's Vietnam and Laos borders, outside the twelve-province subset. They are listed in `unassigned` with their coordinates.",
"china_note": "China's ADM1 file carries 12 provinces, not 31+. Measured rather than assumed: 152 of 154 Chinese groups fall inside them and all twelve are used, so the file is cut to the provinces where the unreached peoples are.",
"ways_in_are_country_level": "The ways in are chosen for the COUNTRY, and going below the border is what exposes the cost of that. Arunachal Pradesh, in the far north-east, is offered TELUGU — a South Indian language — because the curated bridge table names it for those groups and a curated bridge outranks the computed one. India's computed default is Hindi (41%, official), which is defensible nationally and still wrong for much of the north-east. This table does not fix that: it makes it visible. Until a bridge can be chosen per province, read the ways-in column as \"a language with Scripture and film somewhere in this country\", not as a recommendation for this place.",
"ways_in": "Chosen FOR THE PROVINCE where the province can answer: the languages of groups standing in it that already have Scripture AND film, ranked by the people here who already hold them. The column says which basis was used. This replaces a country-level answer that produced a measured absurdity — Arunachal Pradesh, in the far north-east, was offered TELUGU, because the curated bridge table is keyed by country and a curated bridge outranks a computed one. A province with no tier-2 language of its own still falls back to the country answer, and ways_in_basis says so rather than hiding it. It is a NEIGHBOUR, not a recommendation: whether a group actually speaks it is a question for someone on the ground.",
"approximate": "A province is assigned by point-in-polygon on the group's coordinate, and that coordinate marks where a PEOPLE is found, not a settlement — 108 groups across the roster even share a coordinate with another group. Near a border the point can fall on the wrong side. Every row is flagged approximate and the unassigned are counted, never dropped. No surface may present a province as a fact about a group."
},
"columns": [
@ -49,11 +49,36 @@
"field": "zero_access_examples",
"type": "string"
},
{
"title": "Nobody praying",
"field": "nobody_praying_groups",
"type": "number"
},
{
"title": "Of those with a prayer page",
"field": "prayer_pages",
"type": "number"
},
{
"title": "People nobody is praying for",
"field": "nobody_praying_people",
"type": "number"
},
{
"title": "Ways in",
"field": "ways_in",
"type": "string"
},
{
"title": "Basis",
"field": "ways_in_basis",
"type": "string"
},
{
"title": "Ways in (country-level)",
"field": "ways_in_country",
"type": "string"
},
{
"title": "Placement approximate",
"field": "approximate",
@ -70,7 +95,18 @@
"zero_access_groups": 14,
"zero_access_people": 602850,
"zero_access_examples": "Hongjin Tai; Wenma Zhuang; Mosuo",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 45,
"pray_first": {
"name": "Hongjin Tai",
"url": "https://pray.doxa.life/hongjin-tai?source=doxalife&utm_source=agwm",
"people": 209000,
"has_nothing": true
},
"nobody_praying_groups": 35,
"nobody_praying_people": 1430325,
"ways_in": "Chinese, Mandarin (63,825 here); Tai Dam (48,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -82,7 +118,18 @@
"zero_access_groups": 7,
"zero_access_people": 488900,
"zero_access_examples": "Huishui Miao; Yanghuang; Cai",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 28,
"pray_first": {
"name": "Yanghuang",
"url": "https://pray.doxa.life/yanghuang?source=doxalife&utm_source=agwm",
"people": 63000,
"has_nothing": true
},
"nobody_praying_groups": 20,
"nobody_praying_people": 560000,
"ways_in": "Chinese, Mandarin (332,900 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -94,7 +141,18 @@
"zero_access_groups": 7,
"zero_access_people": 105700,
"zero_access_examples": "Ersu; Minyak; Namuyi",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 10,
"pray_first": {
"name": "Ersu",
"url": "https://pray.doxa.life/ersu?source=doxalife&utm_source=agwm",
"people": 48000,
"has_nothing": true
},
"nobody_praying_groups": 8,
"nobody_praying_people": 461600,
"ways_in": "Tibetan (48,500 here); Chinese, Mandarin (15,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -106,7 +164,18 @@
"zero_access_groups": 2,
"zero_access_people": 500,
"zero_access_examples": "Jarawas; Onge",
"ways_in": "Telugu",
"prayer_pages": 5,
"pray_first": {
"name": "Onge",
"url": "https://pray.doxa.life/onge?source=doxalife&utm_source=agwm",
"people": 150,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 69450,
"ways_in": "Telugu (67,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -118,7 +187,18 @@
"zero_access_groups": 2,
"zero_access_people": 600,
"zero_access_examples": "Khamba; Na",
"ways_in": "Telugu",
"prayer_pages": 7,
"pray_first": {
"name": "Na",
"url": "https://pray.doxa.life/na?source=doxalife&utm_source=agwm",
"people": 100,
"has_nothing": true
},
"nobody_praying_groups": 3,
"nobody_praying_people": 7800,
"ways_in": "Hindi (5,700 here); Assamese (2,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -130,7 +210,18 @@
"zero_access_groups": 2,
"zero_access_people": 31500,
"zero_access_examples": "Sarikoli Tajiks; Ainu",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 4,
"pray_first": {
"name": "Ainu",
"url": "https://pray.doxa.life/ainu-china?source=doxalife&utm_source=agwm",
"people": 11000,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 215625,
"ways_in": "Chinese, Mandarin (25 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -142,7 +233,18 @@
"zero_access_groups": 2,
"zero_access_people": 150000,
"zero_access_examples": "Eastern Xiangxi Miao; Wunai",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 4,
"pray_first": {
"name": "Wunai",
"url": "https://pray.doxa.life/wunai?source=doxalife&utm_source=agwm",
"people": 14000,
"has_nothing": true
},
"nobody_praying_groups": 2,
"nobody_praying_people": 20000,
"ways_in": "Chinese, Mandarin (6,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -154,7 +256,18 @@
"zero_access_groups": 2,
"zero_access_people": 12700,
"zero_access_examples": "Tongren Bonan; Wutun",
"prayer_pages": 1,
"pray_first": {
"name": "Wutun",
"url": "https://pray.doxa.life/wutun?source=doxalife&utm_source=agwm",
"people": 3800,
"has_nothing": true
},
"nobody_praying_groups": 1,
"nobody_praying_people": 3800,
"ways_in": "Chinese, Mandarin",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -166,7 +279,18 @@
"zero_access_groups": 1,
"zero_access_people": 8600,
"zero_access_examples": "Malai Pandaram",
"ways_in": "Telugu",
"prayer_pages": 66,
"pray_first": {
"name": "Malai Pandaram",
"url": "https://pray.doxa.life/malai-pandaram?source=doxalife&utm_source=agwm",
"people": 8600,
"has_nothing": true
},
"nobody_praying_groups": 53,
"nobody_praying_people": 1152750,
"ways_in": "Malayalam (2,629,525 here); Kannada (38,200 here); Tamil (33,150 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -178,7 +302,18 @@
"zero_access_groups": 1,
"zero_access_people": 5000,
"zero_access_examples": "Jadupetia",
"ways_in": "Telugu",
"prayer_pages": 5,
"pray_first": {
"name": "Jadupetia",
"url": "https://pray.doxa.life/jadupetia?source=doxalife&utm_source=agwm",
"people": 5000,
"has_nothing": true
},
"nobody_praying_groups": 5,
"nobody_praying_people": 41900,
"ways_in": "Hindi (495,000 here); Bengali (164,200 here); Urdu (94,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -190,7 +325,18 @@
"zero_access_groups": 1,
"zero_access_people": 750,
"zero_access_examples": "Yerong",
"ways_in": "Chinese, Mandarin",
"prayer_pages": 5,
"pray_first": {
"name": "Yerong",
"url": "https://pray.doxa.life/yerong?source=doxalife&utm_source=agwm",
"people": 750,
"has_nothing": true
},
"nobody_praying_groups": 4,
"nobody_praying_people": 51150,
"ways_in": "Chinese, Mandarin (50,400 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -202,7 +348,18 @@
"zero_access_groups": 1,
"zero_access_people": 1700,
"zero_access_examples": "Koiren",
"ways_in": "Telugu",
"prayer_pages": 3,
"pray_first": {
"name": "Koiren",
"url": "https://pray.doxa.life/koiren?source=doxalife&utm_source=agwm",
"people": 1700,
"has_nothing": true
},
"nobody_praying_groups": 3,
"nobody_praying_people": 112400,
"ways_in": "Meitei (319,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "Telugu",
"approximate": true
},
{
@ -214,7 +371,13 @@
"zero_access_groups": 1,
"zero_access_people": 170000,
"zero_access_examples": "Buryat",
"prayer_pages": 1,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Chinese, Mandarin",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "Chinese, Mandarin",
"approximate": true
},
{
@ -226,7 +389,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 80,
"pray_first": {
"name": "Bairagi (Gujarati)",
"url": "https://pray.doxa.life/bairagi-gujarati?source=doxalife&utm_source=agwm",
"people": 510000,
"has_nothing": false
},
"nobody_praying_groups": 59,
"nobody_praying_people": 1429045,
"ways_in": "Gujarati (1,874,475 here); Urdu (123,200 here); Marathi (70,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -238,7 +412,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 76,
"pray_first": {
"name": "Aiyarakulu",
"url": "https://pray.doxa.life/aiyarakulu?source=doxalife&utm_source=agwm",
"people": 688000,
"has_nothing": false
},
"nobody_praying_groups": 64,
"nobody_praying_people": 3818505,
"ways_in": "Telugu (3,561,375 here); Kannada (509,500 here); Odia (378,650 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -250,7 +435,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 75,
"pray_first": {
"name": "Nai (Kannada)",
"url": "https://pray.doxa.life/nai-kannada?source=doxalife&utm_source=agwm",
"people": 336000,
"has_nothing": false
},
"nobody_praying_groups": 55,
"nobody_praying_people": 2569950,
"ways_in": "Kannada (2,277,625 here); Telugu (666,800 here); Urdu (261,625 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -262,7 +458,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 64,
"pray_first": {
"name": "Tondman",
"url": "https://pray.doxa.life/tondman?source=doxalife&utm_source=agwm",
"people": 555000,
"has_nothing": false
},
"nobody_praying_groups": 50,
"nobody_praying_people": 2144700,
"ways_in": "Tamil (1,646,150 here); Telugu (823,600 here); Malayalam (224,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -274,7 +481,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 54,
"pray_first": {
"name": "Rana",
"url": "https://pray.doxa.life/rana?source=doxalife&utm_source=agwm",
"people": 76500,
"has_nothing": false
},
"nobody_praying_groups": 41,
"nobody_praying_people": 523900,
"ways_in": "Odia (1,197,550 here); Bengali (31,500 here); Maithili (17,900 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -286,7 +504,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 52,
"pray_first": {
"name": "Lonar",
"url": "https://pray.doxa.life/lonar?source=doxalife&utm_source=agwm",
"people": 427000,
"has_nothing": false
},
"nobody_praying_groups": 45,
"nobody_praying_people": 1967000,
"ways_in": "Marathi (2,144,775 here); Telugu (247,225 here); Urdu (181,300 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -298,7 +527,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 45,
"pray_first": {
"name": "Van Baoriya",
"url": "https://pray.doxa.life/van-baoriya?source=doxalife&utm_source=agwm",
"people": 442000,
"has_nothing": false
},
"nobody_praying_groups": 33,
"nobody_praying_people": 1549725,
"ways_in": "Hindi (61,400 here); Urdu (21,175 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -310,7 +550,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 27,
"pray_first": {
"name": "Bari (Hindi)",
"url": "https://pray.doxa.life/bari-hindi?source=doxalife&utm_source=agwm",
"people": 405000,
"has_nothing": false
},
"nobody_praying_groups": 23,
"nobody_praying_people": 1217800,
"ways_in": "Hindi (2,060,800 here); Chhattisgarhi (234,000 here); Marathi (73,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -322,7 +573,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 32,
"pray_first": {
"name": "Bania (Dogri)",
"url": "https://pray.doxa.life/bania-dogri?source=doxalife&utm_source=agwm",
"people": 146000,
"has_nothing": false
},
"nobody_praying_groups": 25,
"nobody_praying_people": 497665,
"ways_in": "Hindi (30,500 here); Urdu (250 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -334,7 +596,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 28,
"pray_first": {
"name": "Khairwar (Bengali)",
"url": "https://pray.doxa.life/khairwar-bengali?source=doxalife&utm_source=agwm",
"people": 166000,
"has_nothing": false
},
"nobody_praying_groups": 16,
"nobody_praying_people": 381500,
"ways_in": "Bengali (2,146,100 here); Sunwar (38,000 here); Nepali (19,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -346,7 +619,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 22,
"pray_first": {
"name": "Bolla",
"url": "https://pray.doxa.life/bolla?source=doxalife&utm_source=agwm",
"people": 244000,
"has_nothing": false
},
"nobody_praying_groups": 16,
"nobody_praying_people": 1155150,
"ways_in": "Telugu (1,342,400 here); Marathi (243,000 here); Hindi (73,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -358,7 +642,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 24,
"pray_first": {
"name": "Badhai (Chhattisgarhi)",
"url": "https://pray.doxa.life/badhai-chhattisgarhi?source=doxalife&utm_source=agwm",
"people": 843000,
"has_nothing": false
},
"nobody_praying_groups": 20,
"nobody_praying_people": 1818200,
"ways_in": "Chhattisgarhi (1,411,850 here); Halbi (39,200 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -370,7 +665,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 19,
"pray_first": {
"name": "Bargujar",
"url": "https://pray.doxa.life/bargujar?source=doxalife&utm_source=agwm",
"people": 159000,
"has_nothing": false
},
"nobody_praying_groups": 12,
"nobody_praying_people": 410150,
"ways_in": "Hindi (332,550 here); Urdu (227,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -382,7 +688,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 18,
"pray_first": {
"name": "Pangwala",
"url": "https://pray.doxa.life/pangwala?source=doxalife&utm_source=agwm",
"people": 24000,
"has_nothing": false
},
"nobody_praying_groups": 13,
"nobody_praying_people": 75470,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
},
{
@ -394,7 +711,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 17,
"pray_first": {
"name": "Tilli",
"url": "https://pray.doxa.life/tilli?source=doxalife&utm_source=agwm",
"people": 150000,
"has_nothing": false
},
"nobody_praying_groups": 14,
"nobody_praying_people": 400200,
"ways_in": "Hindi (164,000 here); Urdu (82,800 here); Maithili (54,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -406,7 +734,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 14,
"pray_first": {
"name": "Namasudra (Assamese)",
"url": "https://pray.doxa.life/namasudra-assamese?source=doxalife&utm_source=agwm",
"people": 827000,
"has_nothing": false
},
"nobody_praying_groups": 11,
"nobody_praying_people": 1303400,
"ways_in": "Assamese (1,459,800 here); Bengali (910,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -418,7 +757,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 6,
"pray_first": {
"name": "Za",
"url": "https://pray.doxa.life/za?source=doxalife&utm_source=agwm",
"people": 3400,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 6550,
"ways_in": "Tibetan (85,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -430,7 +780,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 9,
"pray_first": {
"name": "Mahisyadas",
"url": "https://pray.doxa.life/mahisyadas?source=doxalife&utm_source=agwm",
"people": 190000,
"has_nothing": false
},
"nobody_praying_groups": 9,
"nobody_praying_people": 280500,
"ways_in": "Bengali (695,400 here); Odia (3,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -442,7 +803,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 7,
"pray_first": {
"name": "Tagewale",
"url": "https://pray.doxa.life/tagewale?source=doxalife&utm_source=agwm",
"people": 7000,
"has_nothing": false
},
"nobody_praying_groups": 6,
"nobody_praying_people": 13875,
"ways_in": "Hindi (7,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -454,7 +826,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 6,
"pray_first": {
"name": "Campa",
"url": "https://pray.doxa.life/campa?source=doxalife&utm_source=agwm",
"people": 7500,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 15500,
"ways_in": "Ladakhi (11,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -466,7 +849,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 5,
"pray_first": {
"name": "Gabit",
"url": "https://pray.doxa.life/gabit?source=doxalife&utm_source=agwm",
"people": 210000,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 252600,
"ways_in": "Marathi (4,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -478,7 +872,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Sonavar",
"url": "https://pray.doxa.life/sonavar?source=doxalife&utm_source=agwm",
"people": 20500,
"has_nothing": false
},
"nobody_praying_groups": 4,
"nobody_praying_people": 28625,
"ways_in": "Urdu (20,500 here); Tamil (13,950 here); French (6,700 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -490,7 +895,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Lakhera (Haryanvi)",
"url": "https://pray.doxa.life/lakhera-haryanvi?source=doxalife&utm_source=agwm",
"people": 6700,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 6700,
"ways_in": "Punjabi (41,000 here); Haryanvi (26,200 here); Hindi (2,300 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -502,7 +918,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 4,
"pray_first": {
"name": "Racband",
"url": "https://pray.doxa.life/racband?source=doxalife&utm_source=agwm",
"people": 3600,
"has_nothing": false
},
"nobody_praying_groups": 3,
"nobody_praying_people": 7100,
"ways_in": "Punjabi (10,100 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -514,7 +941,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Chinese, Mandarin (16,000 here); Tibetan (5,400 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -526,7 +959,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
},
{
@ -538,7 +977,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 2,
"pray_first": {
"name": "Dalu",
"url": "https://pray.doxa.life/dalu-india?source=doxalife&utm_source=agwm",
"people": 16500,
"has_nothing": false
},
"nobody_praying_groups": 2,
"nobody_praying_people": 17150,
"ways_in": "Bengali (16,500 here); Assamese (650 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -550,7 +1000,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 2,
"pray_first": {
"name": "Olot",
"url": "https://pray.doxa.life/olot?source=doxalife&utm_source=agwm",
"people": 2400,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 2400,
"ways_in": "Chinese, Mandarin (2,600 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -562,7 +1023,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 1,
"pray_first": {
"name": "Khatbune",
"url": "https://pray.doxa.life/khatbune?source=doxalife&utm_source=agwm",
"people": 1200,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 1200,
"ways_in": "Punjabi (1,200 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -574,7 +1046,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 1,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Punjabi (34,000 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -586,7 +1064,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Maldivian (74,500 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -598,7 +1082,13 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"ways_in": "",
"prayer_pages": 0,
"pray_first": null,
"nobody_praying_groups": 0,
"nobody_praying_people": 0,
"ways_in": "Gujarati (125 here)",
"ways_in_basis": "in this province",
"ways_in_country": "",
"approximate": true
},
{
@ -610,7 +1100,18 @@
"zero_access_groups": 0,
"zero_access_people": 0,
"zero_access_examples": "",
"prayer_pages": 1,
"pray_first": {
"name": "Yakha",
"url": "https://pray.doxa.life/yakha?source=doxalife&utm_source=agwm",
"people": 7400,
"has_nothing": false
},
"nobody_praying_groups": 1,
"nobody_praying_people": 7400,
"ways_in": "",
"ways_in_basis": "country-level — no local language here has both Scripture and film",
"ways_in_country": "",
"approximate": true
}
],

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -104,7 +104,7 @@
"bundle": "cities-internet",
"scriptUrl": "./cities-internet/cities-internet.js",
"output": "dx-maps/cities-internet/cities-internet.js",
"integrity": "sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x",
"integrity": "sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v",
"elements": [
"cities-internet-map"
],
@ -120,7 +120,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -134,7 +134,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -148,7 +148,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
}
]
@ -578,7 +578,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63",
"integrity": "sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp",
"elements": [
"gospel-resources-map"
],
@ -598,7 +598,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -612,7 +612,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -626,7 +626,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -640,7 +640,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -654,7 +654,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -104,7 +104,7 @@
"bundle": "cities-internet",
"scriptUrl": "./cities-internet/cities-internet.js",
"output": "dx-maps/cities-internet/cities-internet.js",
"integrity": "sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x",
"integrity": "sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v",
"elements": [
"cities-internet-map"
],
@ -120,7 +120,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -134,7 +134,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -148,7 +148,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-b73spJI8AEYCTGla3A/8iq60DZUgJjhtwste7fZVm5XD0539IubtdsVq3PqOc40x\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-0rMTxNxdj2dY5tyeI+/XPfB7hEnu1BimNQ69Sph2DiyCE21vhyiivFnjWqUc1u8v\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
}
]
@ -578,7 +578,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63",
"integrity": "sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp",
"elements": [
"gospel-resources-map"
],
@ -598,7 +598,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -612,7 +612,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -626,7 +626,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -640,7 +640,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -654,7 +654,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-fzeKwwOl9ilsOllSAArMQkFIHvKmJfXgFkdj4IEqR9SpA5WUfsZmVJ20Q8xBir63\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-OcejBo942nOtavZ1O9d/npBWDOi86rFHJWaNTEO72zpqpGov7e2ZTf/N/JrLwzjp\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]