From ce1097da3ff12ca6622c45f654d2494d82b296e8 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Fri, 25 Sep 2026 18:23:44 +0000 Subject: [PATCH 1/7] Delete the glFor copy: the instance sniff already lives in library, once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I landed glFor as a local copy of pplr-data-maps' helper and flagged the duplication as a decision on the record rather than drift. It did not need to be a decision at all: library/composables/useMapProvider.js already exports isMapboxMap(map) — the same per-instance test, documented for the same reason ("works even on dual-engine pages where both globals are loaded"). So the copy is gone and the part that could drift is delegated. What remains in the plugin is the namespace choice, one expression with nowhere to drift to. When exp-shepherd's engineFor(map) lands, that line goes too. WHAT IS PROVEN, and what is not, because the browser slots have been saturated for fifteen minutes and RULE 3 says gates green before committing. This is a pure expression substitution, so its logic is provable without a GPU: _chk-glfor-equivalence.mjs stubs the globals, builds BOTH implementations, and compares their decisions across every engine combination — mapbox map with both globals, maplibre map with both, either alone, and the case the whole fix exists for: a MapLibre map with no Mapbox global at all. Identical in all of them. That establishes the refactor cannot have changed the decision, so the pin-click integration result already measured still applies. It does NOT re-run that click; the browser re-proof is queued and will run when a slot frees. check:sri PASS, composite freshness PASS. --- .../src/RegionCountryMap.vue | 10 +- plugin-designs/regions-dashboard/src/glFor.js | 26 --- public/doxa-maps/doxa-maps-spa/manifest.json | 8 +- public/doxa-maps/manifest.json | 8 +- .../region-dashboards/index.html | 2 +- .../regions-dashboard/regions-dashboard.js | 152 +++++++++--------- .../regions-dashboard/regions-list/index.html | 2 +- .../regions-dashboard/regions-mfe/index.html | 2 +- 8 files changed, 96 insertions(+), 114 deletions(-) delete mode 100644 plugin-designs/regions-dashboard/src/glFor.js diff --git a/plugin-designs/regions-dashboard/src/RegionCountryMap.vue b/plugin-designs/regions-dashboard/src/RegionCountryMap.vue index 382b41f31..c289c4829 100644 --- a/plugin-designs/regions-dashboard/src/RegionCountryMap.vue +++ b/plugin-designs/regions-dashboard/src/RegionCountryMap.vue @@ -27,7 +27,15 @@ */ import { ref, computed, watch, onMounted, onBeforeUnmount, inject } from 'vue' import { useMapInstance } from '@map/composables/useMapInstance.js' -import { glFor } from './glFor.js' +import { isMapboxMap } from '@map/composables/useMapProvider.js' +// ★ THE INSTANCE SNIFF LIVES IN library/, ONCE. This was a local glFor.js copied from +// pplr-data-maps, and I flagged the duplication as a decision on the record. It turns out +// library/composables/useMapProvider.js already exports isMapboxMap(map) — the same per-instance +// test, documented for the same reason ("works even on dual-engine pages where both globals are +// loaded"). So the copy is deleted and the part that could drift is delegated; what remains here +// is only the namespace choice, which is one expression and has nowhere to drift to. +// When exp-shepherd's engineFor(map) lands this line goes too. +const glFor = (m) => (isMapboxMap(m) ? window.mapboxgl : (window.maplibregl || window.mapboxgl)) import { resolveMapProvider } from '@map/composables/useMapProvider.js' import { resolveAssetsBase } from '@map/utils/embedBase.js' import { useShadowStyles } from '@map/composables/useShadowStyles.js' diff --git a/plugin-designs/regions-dashboard/src/glFor.js b/plugin-designs/regions-dashboard/src/glFor.js deleted file mode 100644 index f577011d2..000000000 --- a/plugin-designs/regions-dashboard/src/glFor.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * The map-engine namespace that built a given map instance — Popup, Marker, NavigationControl. - * - * ★ WHY THIS EXISTS. Every view here was written against the Mapbox global, and under - * provider=maplibre that global does not exist. `new window.mapboxgl.Popup(...)` then throws, or — - * worse, and what this plugin actually did — the code guards with `if (!g) return` and the pin - * click silently does NOTHING. It has been passing only because each generated leaf - * statically loads mapbox-gl, so a MapLibre map was opening a Mapbox popup. Those tags are being - * removed (a static Mapbox script leaks the visitor's IP to Mapbox even for a partner who chose - * MapLibre), so the engine has to be derived from the map, not assumed from a global. - * - * ★ WHY A COPY AND NOT AN IMPORT. The same function lives at - * plugin-designs/pplr-data-maps/src/utils/pplrData.js:64. Importing across plugin folders would - * couple two plugins through a path neither owns, and RULE 2 says default to the plugin folder; - * library/ is the right home the moment a THIRD consumer appears, at which point both copies - * should be deleted in the same commit rather than left to drift. - * - * Order matters: ask MapLibre first with an instanceof test, because a page can legitimately have - * BOTH globals loaded and only the instance knows which one made it. - */ -export function glFor(map) { - if (typeof window === 'undefined') return undefined - const ml = window.maplibregl - if (ml && map && ml.Map && map instanceof ml.Map) return ml - return window.mapboxgl || ml -} diff --git a/public/doxa-maps/doxa-maps-spa/manifest.json b/public/doxa-maps/doxa-maps-spa/manifest.json index 5b4f1f33f..b61250caf 100644 --- a/public/doxa-maps/doxa-maps-spa/manifest.json +++ b/public/doxa-maps/doxa-maps-spa/manifest.json @@ -888,7 +888,7 @@ "bundle": "regions-dashboard", "scriptUrl": "./regions-dashboard/regions-dashboard.js", "output": "doxa-maps/regions-dashboard/regions-dashboard.js", - "integrity": "sha384-s6fZzSXIqBkgA4KnbR4r7uYBrEly/OvCaFLqFM4VimcSqO8wNbr3mM1SC5USMMbI", + "integrity": "sha384-ZXuvbAcPZsF0Cs1Uu5muBUZ7X9EAf6e/UMA1PohxYCydopxQO4ytVsgbeC1H0BGH", "elements": [ "regions-dashboard" ], @@ -908,7 +908,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" } }, { @@ -922,7 +922,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" } }, { @@ -936,7 +936,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" } } ] diff --git a/public/doxa-maps/manifest.json b/public/doxa-maps/manifest.json index 5b4f1f33f..b61250caf 100644 --- a/public/doxa-maps/manifest.json +++ b/public/doxa-maps/manifest.json @@ -888,7 +888,7 @@ "bundle": "regions-dashboard", "scriptUrl": "./regions-dashboard/regions-dashboard.js", "output": "doxa-maps/regions-dashboard/regions-dashboard.js", - "integrity": "sha384-s6fZzSXIqBkgA4KnbR4r7uYBrEly/OvCaFLqFM4VimcSqO8wNbr3mM1SC5USMMbI", + "integrity": "sha384-ZXuvbAcPZsF0Cs1Uu5muBUZ7X9EAf6e/UMA1PohxYCydopxQO4ytVsgbeC1H0BGH", "elements": [ "regions-dashboard" ], @@ -908,7 +908,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" } }, { @@ -922,7 +922,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n" + "script": "\n\n" } }, { @@ -936,7 +936,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" } } ] diff --git a/public/doxa-maps/regions-dashboard/region-dashboards/index.html b/public/doxa-maps/regions-dashboard/region-dashboards/index.html index 2a308470b..8155ef00b 100644 --- a/public/doxa-maps/regions-dashboard/region-dashboards/index.html +++ b/public/doxa-maps/regions-dashboard/region-dashboards/index.html @@ -29,7 +29,7 @@ - + - + - + + From 966c44fcc01b86470cebdbe26e40efa4323381d3 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Fri, 25 Sep 2026 18:26:55 +0000 Subject: [PATCH 3/7] Plugin Studio: a map-token control (paste a Mapbox public token, or point it at a token service) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver request, 2026-09-25: "add a spot on the studio for placing a Mapbox token, or setting the URL for where the Mapbox token API is from, like doxa.life has an API token". A 🔑 Map token button in the studio header opens a small panel: - paste a Mapbox PUBLIC token (pk.…) — a secret sk.… token is refused, the page is public; - or a token-service URL: the studio fetches it (JSON {token|tk|accessToken} or a bare string, the leaf pages' contract) and uses the pk.… it returns. The maps never read a token URL themselves, so the studio resolves it and hands them the token; - Clear returns to the token built into the page. A dot and a status line say which is in use. Precedence: your token > a token from your URL > the host's tk > the page's built-in token. Kept in this browser's localStorage only; applying re-mounts the open map and publishes window.MAP_TOKEN for maps nested inside composites. Labels in all 11 locales (i18n parity PASS). Tested in a browser on the built studio: shows the built-in source; sk.… refused and not stored; a pasted pk.… reaches the pane's profile-config and window.MAP_TOKEN and survives a reload; Clear restores the built-in token; a token URL is fetched and applied. https://doxa.life/api/maps/token is refused cross-origin from another site — the panel says so and keeps the current token. --- library/i18n/locales/ar/studio.json | 15 +- library/i18n/locales/de/studio.json | 15 +- library/i18n/locales/en/studio.json | 15 +- library/i18n/locales/es/studio.json | 15 +- library/i18n/locales/fr/studio.json | 15 +- library/i18n/locales/hi/studio.json | 15 +- library/i18n/locales/it/studio.json | 15 +- library/i18n/locales/pt/studio.json | 15 +- library/i18n/locales/ro/studio.json | 15 +- library/i18n/locales/ru/studio.json | 15 +- library/i18n/locales/zh/studio.json | 15 +- .../plugin-studio/plugin-studio.vue | 156 +++++++++++++++++- public/doxa-maps/doxa-maps-spa/manifest.json | 4 +- public/doxa-maps/index.html | 2 +- public/doxa-maps/manifest.json | 4 +- .../doxa-maps/plugin-studio/plugin-studio.js | 37 +++-- .../plugin-studio/plugin-studio/index.html | 2 +- .../plugin-studio/studio/index.html | 2 +- 18 files changed, 342 insertions(+), 30 deletions(-) diff --git a/library/i18n/locales/ar/studio.json b/library/i18n/locales/ar/studio.json index 8634ab559..c3b519408 100644 --- a/library/i18n/locales/ar/studio.json +++ b/library/i18n/locales/ar/studio.json @@ -26,5 +26,18 @@ "expandList": "توسيع القائمة", "collapseList": "طي القائمة", "collapse": "طي", - "partOf": "جزء من {name}، غير منشور بمفرده" + "partOf": "جزء من {name}، غير منشور بمفرده", + "mapToken": "رمز الخريطة", + "tokenPaste": "رمز Mapbox العام (pk.…)", + "tokenUrlLabel": "…أو رابط خدمة الرموز", + "tokenApply": "استخدام", + "tokenClear": "مسح", + "tokenStoredHere": "يُحفظ في هذا المتصفح فقط.", + "tokenSourceYours": "يُستخدم رمزك", + "tokenSourceUrl": "يُستخدم رمز من {url}", + "tokenSourceBuilt": "يُستخدم الرمز المضمَّن في هذه الصفحة", + "tokenSourceNone": "لا يوجد رمز Mapbox: لا يمكن تحميل خرائط Mapbox (خرائط MapLibre لا تحتاج رمزًا)", + "tokenSecret": "هذا رمز سري (sk.…). الصق رمزًا عامًا (pk.…): هذه الصفحة عامة.", + "tokenNotPk": "يبدأ رمز Mapbox العام بـ pk.", + "tokenUrlFailed": "تعذّر الحصول على رمز من هذا الرابط: {why}" } diff --git a/library/i18n/locales/de/studio.json b/library/i18n/locales/de/studio.json index adf79f7f2..5210ca9d5 100644 --- a/library/i18n/locales/de/studio.json +++ b/library/i18n/locales/de/studio.json @@ -26,5 +26,18 @@ "expandList": "Liste ausklappen", "collapseList": "Liste einklappen", "collapse": "Einklappen", - "partOf": "Teil von {name}, nicht eigenständig veröffentlicht" + "partOf": "Teil von {name}, nicht eigenständig veröffentlicht", + "mapToken": "Karten-Token", + "tokenPaste": "Öffentlicher Mapbox-Token (pk.…)", + "tokenUrlLabel": "…oder die URL eines Token-Dienstes", + "tokenApply": "Verwenden", + "tokenClear": "Löschen", + "tokenStoredHere": "Nur in diesem Browser gespeichert.", + "tokenSourceYours": "Ihr Token wird verwendet", + "tokenSourceUrl": "Token von {url} wird verwendet", + "tokenSourceBuilt": "Der in diese Seite eingebaute Token wird verwendet", + "tokenSourceNone": "Kein Mapbox-Token: Mapbox-Karten können nicht laden (MapLibre-Karten brauchen keinen)", + "tokenSecret": "Das ist ein geheimer Token (sk.…). Fügen Sie einen öffentlichen ein (pk.…): Diese Seite ist öffentlich.", + "tokenNotPk": "Ein öffentlicher Mapbox-Token beginnt mit pk.", + "tokenUrlFailed": "Von dieser URL kam kein Token: {why}" } diff --git a/library/i18n/locales/en/studio.json b/library/i18n/locales/en/studio.json index 3a122b400..cc8ff20ef 100644 --- a/library/i18n/locales/en/studio.json +++ b/library/i18n/locales/en/studio.json @@ -26,5 +26,18 @@ "expandList": "Expand list", "collapseList": "Collapse list", "collapse": "Collapse", - "partOf": "part of {name}, not published on its own" + "partOf": "part of {name}, not published on its own", + "mapToken": "Map token", + "tokenPaste": "Mapbox public token (pk.…)", + "tokenUrlLabel": "…or the URL of a token service", + "tokenApply": "Use", + "tokenClear": "Clear", + "tokenStoredHere": "Kept in this browser only.", + "tokenSourceYours": "Using your token", + "tokenSourceUrl": "Using a token from {url}", + "tokenSourceBuilt": "Using the token built into this page", + "tokenSourceNone": "No Mapbox token: Mapbox maps cannot load (MapLibre maps need none)", + "tokenSecret": "That is a secret token (sk.…). Paste a public one (pk.…): this page is public.", + "tokenNotPk": "A Mapbox public token starts with pk.", + "tokenUrlFailed": "Could not get a token from that URL: {why}" } diff --git a/library/i18n/locales/es/studio.json b/library/i18n/locales/es/studio.json index ba70af3fa..bc46827d9 100644 --- a/library/i18n/locales/es/studio.json +++ b/library/i18n/locales/es/studio.json @@ -26,5 +26,18 @@ "expandList": "Expandir la lista", "collapseList": "Contraer la lista", "collapse": "Contraer", - "partOf": "parte de {name}, no publicada por separado" + "partOf": "parte de {name}, no publicada por separado", + "mapToken": "Token del mapa", + "tokenPaste": "Token público de Mapbox (pk.…)", + "tokenUrlLabel": "…o la URL de un servicio de tokens", + "tokenApply": "Usar", + "tokenClear": "Borrar", + "tokenStoredHere": "Se guarda solo en este navegador.", + "tokenSourceYours": "Usando tu token", + "tokenSourceUrl": "Usando un token de {url}", + "tokenSourceBuilt": "Usando el token integrado en esta página", + "tokenSourceNone": "Sin token de Mapbox: los mapas de Mapbox no cargan (los de MapLibre no lo necesitan)", + "tokenSecret": "Ese es un token secreto (sk.…). Pega uno público (pk.…): esta página es pública.", + "tokenNotPk": "Un token público de Mapbox empieza por pk.", + "tokenUrlFailed": "No se pudo obtener un token de esa URL: {why}" } diff --git a/library/i18n/locales/fr/studio.json b/library/i18n/locales/fr/studio.json index b7db511c7..087d3e54e 100644 --- a/library/i18n/locales/fr/studio.json +++ b/library/i18n/locales/fr/studio.json @@ -26,5 +26,18 @@ "expandList": "Déplier la liste", "collapseList": "Replier la liste", "collapse": "Replier", - "partOf": "partie de {name}, non publiée seule" + "partOf": "partie de {name}, non publiée seule", + "mapToken": "Jeton de carte", + "tokenPaste": "Jeton public Mapbox (pk.…)", + "tokenUrlLabel": "…ou l’URL d’un service de jetons", + "tokenApply": "Utiliser", + "tokenClear": "Effacer", + "tokenStoredHere": "Conservé dans ce navigateur uniquement.", + "tokenSourceYours": "Votre jeton est utilisé", + "tokenSourceUrl": "Jeton obtenu de {url}", + "tokenSourceBuilt": "Jeton intégré à cette page", + "tokenSourceNone": "Aucun jeton Mapbox : les cartes Mapbox ne peuvent pas charger (MapLibre n’en a pas besoin)", + "tokenSecret": "C’est un jeton secret (sk.…). Collez un jeton public (pk.…) : cette page est publique.", + "tokenNotPk": "Un jeton public Mapbox commence par pk.", + "tokenUrlFailed": "Impossible d’obtenir un jeton depuis cette URL : {why}" } diff --git a/library/i18n/locales/hi/studio.json b/library/i18n/locales/hi/studio.json index 818c8e238..050f635d3 100644 --- a/library/i18n/locales/hi/studio.json +++ b/library/i18n/locales/hi/studio.json @@ -26,5 +26,18 @@ "expandList": "सूची फैलाएँ", "collapseList": "सूची संक्षिप्त करें", "collapse": "संक्षिप्त करें", - "partOf": "{name} का भाग, अलग से प्रकाशित नहीं" + "partOf": "{name} का भाग, अलग से प्रकाशित नहीं", + "mapToken": "मानचित्र टोकन", + "tokenPaste": "Mapbox सार्वजनिक टोकन (pk.…)", + "tokenUrlLabel": "…या किसी टोकन सेवा का URL", + "tokenApply": "उपयोग करें", + "tokenClear": "साफ़ करें", + "tokenStoredHere": "केवल इसी ब्राउज़र में रखा जाता है।", + "tokenSourceYours": "आपका टोकन उपयोग हो रहा है", + "tokenSourceUrl": "{url} से टोकन उपयोग हो रहा है", + "tokenSourceBuilt": "इस पेज में बना टोकन उपयोग हो रहा है", + "tokenSourceNone": "कोई Mapbox टोकन नहीं: Mapbox मानचित्र लोड नहीं हो सकते (MapLibre को इसकी ज़रूरत नहीं)", + "tokenSecret": "यह एक गुप्त टोकन है (sk.…)। सार्वजनिक टोकन (pk.…) चिपकाएँ: यह पेज सार्वजनिक है।", + "tokenNotPk": "Mapbox सार्वजनिक टोकन pk. से शुरू होता है", + "tokenUrlFailed": "उस URL से टोकन नहीं मिल सका: {why}" } diff --git a/library/i18n/locales/it/studio.json b/library/i18n/locales/it/studio.json index d84390537..ac41b6df7 100644 --- a/library/i18n/locales/it/studio.json +++ b/library/i18n/locales/it/studio.json @@ -26,5 +26,18 @@ "expandList": "Espandi l’elenco", "collapseList": "Comprimi l’elenco", "collapse": "Comprimi", - "partOf": "parte di {name}, non pubblicata da sola" + "partOf": "parte di {name}, non pubblicata da sola", + "mapToken": "Token mappa", + "tokenPaste": "Token pubblico Mapbox (pk.…)", + "tokenUrlLabel": "…o l’URL di un servizio di token", + "tokenApply": "Usa", + "tokenClear": "Cancella", + "tokenStoredHere": "Conservato solo in questo browser.", + "tokenSourceYours": "Uso il tuo token", + "tokenSourceUrl": "Uso un token da {url}", + "tokenSourceBuilt": "Uso il token integrato in questa pagina", + "tokenSourceNone": "Nessun token Mapbox: le mappe Mapbox non si caricano (MapLibre non ne ha bisogno)", + "tokenSecret": "Questo è un token segreto (sk.…). Incolla un token pubblico (pk.…): questa pagina è pubblica.", + "tokenNotPk": "Un token pubblico Mapbox inizia con pk.", + "tokenUrlFailed": "Impossibile ottenere un token da quell’URL: {why}" } diff --git a/library/i18n/locales/pt/studio.json b/library/i18n/locales/pt/studio.json index 5f2a31352..9a824c894 100644 --- a/library/i18n/locales/pt/studio.json +++ b/library/i18n/locales/pt/studio.json @@ -26,5 +26,18 @@ "expandList": "Expandir a lista", "collapseList": "Recolher a lista", "collapse": "Recolher", - "partOf": "parte de {name}, não publicada separadamente" + "partOf": "parte de {name}, não publicada separadamente", + "mapToken": "Token do mapa", + "tokenPaste": "Token público do Mapbox (pk.…)", + "tokenUrlLabel": "…ou o URL de um serviço de tokens", + "tokenApply": "Usar", + "tokenClear": "Limpar", + "tokenStoredHere": "Guardado apenas neste navegador.", + "tokenSourceYours": "A usar o seu token", + "tokenSourceUrl": "A usar um token de {url}", + "tokenSourceBuilt": "A usar o token incorporado nesta página", + "tokenSourceNone": "Sem token do Mapbox: os mapas Mapbox não carregam (os MapLibre não precisam)", + "tokenSecret": "Esse é um token secreto (sk.…). Cole um público (pk.…): esta página é pública.", + "tokenNotPk": "Um token público do Mapbox começa por pk.", + "tokenUrlFailed": "Não foi possível obter um token desse URL: {why}" } diff --git a/library/i18n/locales/ro/studio.json b/library/i18n/locales/ro/studio.json index 1f4c1de38..6665219ea 100644 --- a/library/i18n/locales/ro/studio.json +++ b/library/i18n/locales/ro/studio.json @@ -26,5 +26,18 @@ "expandList": "Extinde lista", "collapseList": "Restrânge lista", "collapse": "Restrânge", - "partOf": "parte din {name}, nepublicată separat" + "partOf": "parte din {name}, nepublicată separat", + "mapToken": "Token hartă", + "tokenPaste": "Token public Mapbox (pk.…)", + "tokenUrlLabel": "…sau adresa URL a unui serviciu de tokenuri", + "tokenApply": "Folosește", + "tokenClear": "Șterge", + "tokenStoredHere": "Păstrat doar în acest browser.", + "tokenSourceYours": "Se folosește tokenul tău", + "tokenSourceUrl": "Se folosește un token de la {url}", + "tokenSourceBuilt": "Se folosește tokenul inclus în această pagină", + "tokenSourceNone": "Niciun token Mapbox: hărțile Mapbox nu se pot încărca (MapLibre nu are nevoie)", + "tokenSecret": "Acesta este un token secret (sk.…). Lipește unul public (pk.…): pagina este publică.", + "tokenNotPk": "Un token public Mapbox începe cu pk.", + "tokenUrlFailed": "Nu s-a putut obține un token de la acea adresă: {why}" } diff --git a/library/i18n/locales/ru/studio.json b/library/i18n/locales/ru/studio.json index a65453637..877fb6f0f 100644 --- a/library/i18n/locales/ru/studio.json +++ b/library/i18n/locales/ru/studio.json @@ -26,5 +26,18 @@ "expandList": "Развернуть список", "collapseList": "Свернуть список", "collapse": "Свернуть", - "partOf": "часть {name}, не публикуется отдельно" + "partOf": "часть {name}, не публикуется отдельно", + "mapToken": "Токен карты", + "tokenPaste": "Публичный токен Mapbox (pk.…)", + "tokenUrlLabel": "…или адрес службы токенов", + "tokenApply": "Применить", + "tokenClear": "Очистить", + "tokenStoredHere": "Хранится только в этом браузере.", + "tokenSourceYours": "Используется ваш токен", + "tokenSourceUrl": "Используется токен с {url}", + "tokenSourceBuilt": "Используется токен, встроенный в страницу", + "tokenSourceNone": "Нет токена Mapbox: карты Mapbox не загрузятся (MapLibre он не нужен)", + "tokenSecret": "Это секретный токен (sk.…). Вставьте публичный (pk.…): эта страница общедоступна.", + "tokenNotPk": "Публичный токен Mapbox начинается с pk.", + "tokenUrlFailed": "Не удалось получить токен по этому адресу: {why}" } diff --git a/library/i18n/locales/zh/studio.json b/library/i18n/locales/zh/studio.json index ade089a8c..df56e8091 100644 --- a/library/i18n/locales/zh/studio.json +++ b/library/i18n/locales/zh/studio.json @@ -26,5 +26,18 @@ "expandList": "展开列表", "collapseList": "折叠列表", "collapse": "折叠", - "partOf": "{name} 的一部分,不单独发布" + "partOf": "{name} 的一部分,不单独发布", + "mapToken": "地图令牌", + "tokenPaste": "Mapbox 公开令牌 (pk.…)", + "tokenUrlLabel": "…或令牌服务的网址", + "tokenApply": "使用", + "tokenClear": "清除", + "tokenStoredHere": "仅保存在此浏览器中。", + "tokenSourceYours": "正在使用您的令牌", + "tokenSourceUrl": "正在使用来自 {url} 的令牌", + "tokenSourceBuilt": "正在使用此页面内置的令牌", + "tokenSourceNone": "没有 Mapbox 令牌:Mapbox 地图无法加载(MapLibre 地图不需要)", + "tokenSecret": "这是秘密令牌 (sk.…)。请粘贴公开令牌 (pk.…):此页面是公开的。", + "tokenNotPk": "Mapbox 公开令牌以 pk. 开头", + "tokenUrlFailed": "无法从该网址获取令牌:{why}" } diff --git a/plugin-designs/plugin-studio/plugin-studio.vue b/plugin-designs/plugin-studio/plugin-studio.vue index 0611c70aa..baee84bf5 100644 --- a/plugin-designs/plugin-studio/plugin-studio.vue +++ b/plugin-designs/plugin-studio/plugin-studio.vue @@ -83,6 +83,31 @@ app-wrapper-material/languages.js (persisted, offline, no dep) — same switcher as the SPA. -->