Full detail: the question no longer repeats under every tally cell; the heads stand once per page over the cells' own columns, and each cell is all tally room (96px columns, taller boxes). The worksheet's boxes get a little more room too. Both lists' first page: the intro and the blessing (Numbers 6:24-26, its credit, one line of references, the wheel pointer) at full width, then ONE band like the poster's (ruled above and below, three columns between short rules): the pace table (strongest to slower, weekly marked, each load computed from the list), what the three columns ask, and an EXAMPLE row of tally cells under the table's own heads, exactly as wide as the tally block and directly over it. One code path (explainTop, explainBand) for both packets. Measured with a 100-group list in all 11 languages: the worksheet's first page holds 10 rows (the tallest, ru, keeps 67px), Full detail's 12 under a 640px block (the tallest uses 612); the example sits over the real cells to the pixel. Gates: packet-variants checks the band in BOTH packets (once, before the first row, computed paces, one example row, heads once per page); packet-render reads the page sizes from the renderer, fails a clipped first-page block, and measures text direction against the content box (a padded cell is still pinned left). New strings x11: howto_bless_col, example_title, example_note. |
||
|---|---|---|
| .. | ||
| scripts | ||
| card-render.js | ||
| circularLayout.js | ||
| countrySheet.js | ||
| evangelicalShare.js | ||
| fork-leaders.js | ||
| mapLabels.js | ||
| packet-render.js | ||
| packetSets.js | ||
| packetStrings.js | ||
| pins-in-state.js | ||
| poster-fetch.js | ||
| poster-raster.js | ||
| poster-render.integrity.js | ||
| poster-render.js | ||
| posterSheets.js | ||
| qr.js | ||
| README.md | ||
| sha384.js | ||
The print standard — prayer resources for any set of people groups
Any map in this library can print four prayer resources for whatever its reader picked — a UPG-100 list, a country, a region, a selection on the map:
| Resource | What it is |
|---|---|
| Poster | the set's map sheet, printed on letter paper as a vector page |
| Card deck | one prayer card per people group, in five card stocks |
| Prayer list | the prayer packet: full detail (map, triangle, life calendar, % evangelical, profiles, bounded + centered sets, prayer wheel, prayer points) or lightweight (map, triangle, a worksheet of every group, wheel, points) |
Everything is generated at the click, in the reader's language. Nothing a reader prints is stored; only the previews on a poster wall are stored files, because a wall shows many at once.
Where it is production, where it is experimental
Production (always on): the UPG 100 list (its legend exports, selection HUD and poster wall), the Regions dashboard's country posters, and the Country Posters wall.
Experimental (one switch, library/print/experimentalExports.js): any other map whose legend already
has an Export menu may offer the same exports — the card deck, the packet — only while
experimentalExportsOn(profileConfig) is true. Turn it off per page (experimentalExports: false in
profile-config), per visit (?exports=off), per site (window.DOXA_EXPERIMENTAL_EXPORTS = false) or
everywhere (EXPERIMENTAL_EXPORTS_DEFAULT); off restores the menu the map had before. The legend shows
the Card Deck item only when told to (:export-cards, or provide('legendExportCards', …) for the
mobile sheet), so a map that does not handle it never shows a dead button.
Adopting it in a map — three pieces
import { usePosterPrints } from '@map/composables/usePosterPrints.js'
import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js'
import { getApiBaseUrl } from '@map/api/apiBaseUrl.js'
// 1. RECORDS — the people of a set, by selector (one fetch per language, shared by every item)
const recordsFor = createPeopleGroupRecords({ apiBase: () => getApiBaseUrl(), lang: () => locale, profileConfig })
// 2. THE PRINTS — an item is { id, label } plus whatever your records/sheet functions need
const prints = usePosterPrints({
records: (item) => recordsFor({ type: 'country', values: [item.iso3] }),
lang: () => locale,
assetsBase: () => assetsBase,
sheet: (item, format) => mySheet(item, format), // 3. optional: the generated map sheet
})
prints.printPacket(item, { variant: 'full' }) // or 'lightweight'
prints.printCardDeck(item)
prints.printPoster(item)
Or hand the same options to <PosterWall> as props (:records, :sheet, item-count-key, …) and the
wall renders every card's Poster / Prayer list / Cards buttons itself. A wall that passes no records
shows only the poster, rather than buttons that fail.
Selectors (peopleGroupRecords.js)
| Selector | Picks |
|---|---|
{ type: 'country', values: ['TCD'] } |
the groups of those countries (ISO3) |
{ type: 'pg_slugs', values: [...] } |
exactly those groups — a selection, a custom list |
{ type: 'field', field: 'wagf_region', values: ['africa'] } |
any field's value |
| anything else | your evaluate(selector, records) (the UPG-100 selector language) |
An unknown selector selects nothing, never everything.
The map sheet (posterSheets.js)
generateSheet({ zone, pins, zoneFC, format, seriesId, ISO3_NAME, adm0, adm1Ind, adm1Chn, series })
draws a sheet with the same generator the Node script runs (poster-render.js). Formats: 3x4,
3x3 (wall posters), letter (the poster print), packet (the map-only sheet for a packet's page 1).
loadBoundaries(assetsBase) fetches the full-resolution boundaries it draws from.
generateCountrySheet({ country, records, assetsBase, ISO3_NAME, format, series }) does all of it for
one country. A UPG-100 zone: plugin-designs/my-upg-100-list/data/zone-sheet-print.js.
Page 1 of a packet takes the first of: an explicit mapSvg, sheet(item, 'packet'), mapImage(item)
(a raster of a live map), a stored sheet under assetsBase. With none, it says the map is missing.
What proves it
| Gate | Asserts |
|---|---|
check:people-group-records |
a selector picks exactly its set, two-sided |
check:poster-browser-equiv |
a sheet generated in the browser is byte-identical to the Node generator's |
check:packet-a1-structure, check:packet-variants |
both packets' page order and contents |
check:map-labels, check:plural-forms, check:i18n-* |
every word in the reader's language |