Packet: point 4's reference names what prints, Mark 5:18–20, in all 11 locales (the Gerasene reading keeps 5:12–20), re-pinned; the passage gets a 700-char ceiling beside its 250 floor, in the render gate and, headless, in the structure gate for every locale
This commit is contained in:
parent
b0c4ef1897
commit
3211236014
4 changed files with 45 additions and 14 deletions
|
|
@ -182,6 +182,29 @@ const box = (html) => {
|
|||
ok(/metacamp\.org/.test(page), 'the wheel lost its attribution (source and website)', 'twelve "5 minutes" badges and the source attribution')
|
||||
}
|
||||
|
||||
// ── D2. POINT 4 PRINTS MARK 5:18-20 ONLY, IN EVERY LOCALE ─────────────────────────────────────
|
||||
// The same 250..700 bound as check-packet-render, here because this gate runs in gates:pre with no
|
||||
// browser and no generated packets: check-packet-render only runs over packets someone generated
|
||||
// (check:packets-all SKIPs on a clean checkout) and the browser gate is not measured headless. The
|
||||
// floor catches a truncated or missing passage; the ceiling catches the full 1-20 passage coming back
|
||||
// (2,141 chars in English), which would also push the twelve points off their one page.
|
||||
{
|
||||
const P4_MIN = 250, P4_MAX = 700
|
||||
const text = (h) => h.replace(/<[^>]+>/g, '').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
||||
.replace(/'/g, "'").replace(/&/g, '&').trim()
|
||||
const bad = []
|
||||
const langs = Object.keys(strings).filter((k) => k !== '_meta')
|
||||
for (const lang of langs) {
|
||||
const page = createPacketRenderer({ strings, lang }).pointsPage()
|
||||
const at = page.indexOf('class="p4-passage"')
|
||||
const end = at < 0 ? -1 : page.indexOf('</div></div>', at)
|
||||
const len = end < 0 ? 0 : text(page.slice(page.indexOf('>', at) + 1, end)).length
|
||||
if (len < P4_MIN || len > P4_MAX) bad.push(`${lang} ${len}`)
|
||||
}
|
||||
ok(!bad.length, `point 4's passage is outside ${P4_MIN}..${P4_MAX} chars (Mark 5:18-20 only): ${bad.join(', ')}`,
|
||||
`point 4 prints Mark 5:18-20 only (${P4_MIN}..${P4_MAX} chars) in all ${langs.length} locales`)
|
||||
}
|
||||
|
||||
// ── E. EVERY ZONE A READER CAN PICK ────────────────────────────────────────────────────────────
|
||||
{
|
||||
const zones = zonesWithSelectors(clusters, { deafCount: 123 })
|
||||
|
|
|
|||
|
|
@ -542,11 +542,19 @@ if (r.rhythms !== r.rhythmsTotal) fails.push(`only ${r.rhythms}/${r.rhythmsTotal
|
|||
// ★ POINT 4 PRINTS MARK 5:18-20 (2026-09-30, the second revision: only those verses, so all twelve points fit
|
||||
// one page), with verse 19 in bold. English is 385 chars + the credit; 250 is a floor no truncation or
|
||||
// placeholder survives, with room for the more compact languages (Russian is 277).
|
||||
// ★ AND A CEILING: the floor alone also passes the full 1-20 passage (2,141 chars in English). The browser
|
||||
// gate's one-sheet fit refuses 1-20 too, but it is NOT MEASURED in a headless run, so this ceiling is the
|
||||
// only headless guard for "18-20 only". 18-20 measures 277-428 chars across the 11 locales; 1-20 is well
|
||||
// over 700 in every one of them.
|
||||
const MARK5_MIN = 250
|
||||
const MARK5_MAX = 700
|
||||
if (r.mark5Len < MARK5_MIN) {
|
||||
fails.push(r.mark5Len === 0
|
||||
? 'Mark 5:18-20 is NOT printed (a requirement for point 4): no .p4-passage block'
|
||||
: `Mark 5:18-20 looks truncated: ${r.mark5Len} chars, expected at least ${MARK5_MIN}`)
|
||||
} else if (r.mark5Len > MARK5_MAX) {
|
||||
fails.push(`point 4's passage is ${r.mark5Len} chars, over ${MARK5_MAX}: more than Mark 5:18-20 is printed `
|
||||
+ '(the full 1-20 passage is back?), and the twelve points no longer fit one page')
|
||||
}
|
||||
if (!r.v19Len) fails.push('Mark 5:19 is not in bold (no .p4-v19 inside the passage)')
|
||||
const HEART_ITEMS = 7
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ export const POSTER_RENDER_GLOBAL_SHA384 = 'sha384-DZa1KOOlRZMm17kxVEyMXNGafsBBt
|
|||
// The sha384 of library/scripts/posters/packet-strings.json, served at <assets>/lib/packet-strings.json. The
|
||||
// packet, list and card text in every language, fetched at print time (packet/packetStrings.js) and used only
|
||||
// when it matches; otherwise the print falls back to the bundled English block.
|
||||
export const PACKET_STRINGS_SHA384 = 'sha384-lkip1VHdPSdyL3xFpwtXyc+RqOqLeOpXsd+e0IIk5o150CXc7gWod2+GgC7EKbf1'
|
||||
export const PACKET_STRINGS_SHA384 = 'sha384-63CpJ25458CweIfy8slxoPsI78Mh+5XZCxvLmpcHjrKWSyhomObwqtvjEsURJj8f'
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
"_meta": {
|
||||
"purpose": "EVERY human-readable string in the UPG-100 prayer packet, in one file, so a new language is a new block here and NOT a code change. packet.mjs reads LANG (default 'en') and falls back to 'en' key-by-key, so a partial translation renders the translated keys and leaves the rest in English rather than blanking.",
|
||||
"how_to_translate": "Copy the \"en\" block, change the key to the ISO code, translate the values. Keep {placeholders} exactly as they are — they are substituted at render time. Do not translate scripture REFERENCES (book names are resolved by the reader's own Bible); DO translate the prayer text.",
|
||||
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:1-20, printed in full by product decision). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
|
||||
"note_on_references": "Scripture REFERENCES (Matthew 27:27, Mark 5:1-20) are deliberately left in English in every language block, so a reader can look them up in their own Bible regardless of the packet's language. ⚠ MEASURED TRADEOFF, not an oversight: on a rendered French page the English book names are visibly foreign next to fully-translated prayer text. If a language wants localised book names, add a `books` map to that block and teach the renderer to use it — do NOT translate the refs inline, because the same strings identify the passage for any future lookup.",
|
||||
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:18-20, printed in full by product decision). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
|
||||
"note_on_references": "Scripture REFERENCES (Matthew 27:27, Mark 5:18-20) are deliberately left in English in every language block, so a reader can look them up in their own Bible regardless of the packet's language. ⚠ MEASURED TRADEOFF, not an oversight: on a rendered French page the English book names are visibly foreign next to fully-translated prayer text. If a language wants localised book names, add a `books` map to that block and teach the renderer to use it — do NOT translate the refs inline, because the same strings identify the passage for any future lookup.",
|
||||
"note_on_scripts": "ALL 11 app locales now ship. Script coverage MEASURED by rendering at 48px and READING THE PIXELS: Latin, Cyrillic (ru), Arabic (ar) and CJK (zh) shape correctly with the system Georgia/Palatino/serif stack. DEVANAGARI (hi) does NOT — it renders as tofu boxes — so Noto Serif Devanagari is vendored (OFL) and base64-INLINED into hi packets by the renderer's SCRIPT_FONT map. Inlined, not linked, because a packet is a standalone file that must print offline; ~165KB on a 3.5MB packet, and only for that language. mr and ne map to the same face.\n⚠ TWO MEASUREMENTS LIED ABOUT THIS, so do not automate it cheaply: (1) comparing shaped width against a missing font reported ar and zh BROKEN and hi FINE — exactly backwards, because Devanagari tofu boxes match real glyph advance; (2) an ink-column-profile heuristic scored CORRECTLY-RENDERED Devanagari the same as tofu (3 vs 2 distinct heights), because its baseline bar gives a uniform profile. check:packet-render therefore asserts only that a DECLARED @font-face LOADED — the mechanical half — and leaves glyph correctness to a human reading a screenshot. A detector that blocks working packets is worse than none.",
|
||||
"note_on_rtl": "ar is right-to-left. The renderer emits dir on <html> from an RTL set (packet-render.js), and scripture REFERENCES are wrapped in dir=ltr + unicode-bidi:isolate. Without that isolation the bidi algorithm reorders a reference that STARTS WITH A DIGIT: '1 Peter 5:6-11' rendered as 'Peter 5:6-11 1'. Note the reference LIST then reads right-to-left on an RTL page (first item rightmost) — that is correct for an RTL reader, not a defect."
|
||||
},
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
"sub": "the Father's love",
|
||||
"text": "That they would be SAVED and KNOW their heavenly Father loves them — and that through them He would bring salvation to their family, friends, neighbours, coworkers, classmates, everyone they know personally.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -367,7 +367,7 @@
|
|||
"sub": "el amor del Padre",
|
||||
"text": "Que sean SALVOS y CONOZCAN que su Padre celestial los ama — y que a través de ellos Él lleve salvación a su familia, amigos, vecinos, compañeros de trabajo, compañeros de clase, a todos los que conocen personalmente.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -645,7 +645,7 @@
|
|||
"sub": "l'amour du Père",
|
||||
"text": "Qu'ils soient SAUVÉS et qu'ils SACHENT que leur Père céleste les aime — et qu'à travers eux Il apporte le salut à leur famille, leurs amis, leurs voisins, leurs collègues, leurs camarades, à tous ceux qu'ils connaissent personnellement.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -923,7 +923,7 @@
|
|||
"sub": "o amor do Pai",
|
||||
"text": "Que sejam SALVOS e SAIBAM que o seu Pai celestial os ama — e que através deles Ele leve salvação à sua família, amigos, vizinhos, colegas de trabalho, colegas de classe, a todos os que conhecem pessoalmente.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -1198,7 +1198,7 @@
|
|||
"sub": "die Liebe des Vaters",
|
||||
"text": "Dass sie GERETTET werden und WISSEN, dass ihr himmlischer Vater sie liebt — und dass Er durch sie Rettung zu ihrer Familie, ihren Freunden, Nachbarn, Kollegen, Mitschülern bringt, zu allen, die sie persönlich kennen.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -1476,7 +1476,7 @@
|
|||
"sub": "l'amore del Padre",
|
||||
"text": "Che siano SALVATI e SAPPIANO che il loro Padre celeste li ama — e che attraverso di loro Egli porti salvezza alla loro famiglia, agli amici, ai vicini, ai colleghi, ai compagni di classe, a tutti coloro che conoscono personalmente.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -1751,7 +1751,7 @@
|
|||
"sub": "dragostea Tatălui",
|
||||
"text": "Să fie MÂNTUIȚI și să ȘTIE că Tatăl lor ceresc îi iubește — și ca prin ei El să aducă mântuire familiei lor, prietenilor, vecinilor, colegilor de muncă, colegilor de clasă, tuturor celor pe care îi cunosc personal.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -2026,7 +2026,7 @@
|
|||
"sub": "любовь Отца",
|
||||
"text": "Чтобы они были СПАСЕНЫ и ЗНАЛИ, что их Небесный Отец любит их — и чтобы через них Он принёс спасение их семье, друзьям, соседям, сослуживцам, одноклассникам, всем, кого они знают лично.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -2304,7 +2304,7 @@
|
|||
"sub": "محبة الآب",
|
||||
"text": "أن يَخلُصوا ويَعرِفوا أن أباهم السماوي يحبهم — وأن يحمل بهم الخلاص إلى عائلاتهم وأصدقائهم وجيرانهم وزملائهم في العمل والدراسة، وكل من يعرفونهم شخصيًا.",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -2582,7 +2582,7 @@
|
|||
"sub": "पिता का प्रेम",
|
||||
"text": "कि वे उद्धार पाएँ और जानें कि उनका स्वर्गीय पिता उनसे प्रेम करता है — और उनके द्वारा वह उनके परिवार, मित्रों, पड़ोसियों, सहकर्मियों, सहपाठियों, उन सबके पास उद्धार पहुँचाए जिन्हें वे व्यक्तिगत रूप से जानते हैं।",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
@ -2857,7 +2857,7 @@
|
|||
"sub": "天父的爱",
|
||||
"text": "愿他们得救,并知道天父爱他们——也愿神借着他们,把救恩带给他们的家人、朋友、邻舍、同事、同学,以及他们所认识的每一个人。",
|
||||
"refs": [
|
||||
"Mark 5:1–20",
|
||||
"Mark 5:18–20",
|
||||
"Acts 16:31"
|
||||
],
|
||||
"print_passage": true
|
||||
|
|
|
|||
Loading…
Reference in a new issue