diff --git a/internal/check-poster-browser-equiv.mjs b/internal/check-poster-browser-equiv.mjs index 2b8d8688f..31dad1e57 100644 --- a/internal/check-poster-browser-equiv.mjs +++ b/internal/check-poster-browser-equiv.mjs @@ -11,7 +11,7 @@ * ★ IT CALLS WHAT THE BROWSER CALLS. The first version rebuilt the feed itself and so could not see a * defect in the real entry points: generateCountrySheet passed no province boundaries, and a country * beside India or China printed without them — while this gate, feeding them by hand, stayed green. So: - * · a UPG-100 zone through makeZoneSheet (data/zone-sheet-print.js), the map-only packet sheet, an India + * · a UPG-100 zone through makeZoneSheet (data/zone-sheet-print.js), the packet's page 1 (the full letter poster), an India * zone so the ADM1 path runs; * · a country through generateCountrySheet, NEPAL, which sits between India and China; * both fetching the served boundaries exactly as the page does (file:// here, the asset URL there). @@ -110,7 +110,9 @@ const results = [] const { makeZoneSheet } = await import(join(REPO, 'plugin-designs/my-upg-100-list/data/zone-sheet-print.js')) const zoneSheet = makeZoneSheet({ allRecords: async () => records, assetsBase: () => assetsBase, profileConfig: null, date: DATE }) const id = 'asia-india-gujarat' - results.push({ what: `${id} (packet sheet, makeZoneSheet)`, browser: await zoneSheet({ id }, 'packet'), node: nodeSheet({ FORMAT: 'packet', ONLY: id }, `${id}.packet.html`) }) + // The UPG-100 packet's page 1 is the FULL letter poster (zone-sheet-print answers 'packet' with it), so the + // Node side is the letter format without SPARSE. + results.push({ what: `${id} (packet page 1 = the full letter poster, makeZoneSheet)`, browser: await zoneSheet({ id }, 'packet'), node: nodeSheet({ FORMAT: 'letter', ONLY: id }, `${id}.letter.html`) }) } { // a country, through the function the country wall calls — Nepal, between India and China const { generateCountrySheet } = await import(join(REPO, 'library/packet/posterSheets.js')) diff --git a/library/packet/posterSheets.js b/library/packet/posterSheets.js index 08fa60f70..6192779f1 100644 --- a/library/packet/posterSheets.js +++ b/library/packet/posterSheets.js @@ -117,13 +117,15 @@ function loadPlaces(assetsBase) { /** * @returns {Promise} the sheet's full HTML document ('' when the zone cannot be drawn). * format '3x4' | '3x3' | 'letter' | 'packet' (map-only, for a packet's page 1) + * sparse the poster's thumbnail layout (default: every format but 'packet'); false asks for the FULL + * poster — the facts, the two explainers and the networks — in any format * seriesId a key of series.json ('upg100', 'country'); decides the poster's text and networks * date the stamp printed on the sheet (default today) — pass one to reproduce a sheet exactly */ export async function generateSheet({ zone, pins = [], zoneFC = null, format = '3x4', seriesId = 'upg100', ISO3_NAME = {}, adm0 = null, adm1Ind = null, adm1Chn = null, series = { totalGroups: 0, totalLists: 0, index: 1 }, date = null, - assetsBase = null, nePlaces = null, + assetsBase = null, nePlaces = null, sparse = format !== 'packet', } = {}) { if (!zone || !zone.zoneKey) return '' const [{ seriesAll }, places, createPosterGenerator] = await Promise.all([ @@ -142,7 +144,9 @@ export async function generateSheet({ // stored UPG-100 thumbnails showed the bold row. A reader saw one header on the card and got // another on the print. 'packet' is the one packet format (FORMATS: 3x4, 3x3, letter, packet), // so it alone keeps the full layout its packet pages were designed around. - env: { FORMAT: format, ...(format !== 'packet' ? { SPARSE: '1' } : {}), ...(date ? { POSTER_DATE: date } : {}) }, + // `sparse` defaults to exactly that split; a caller may ask for the full poster in a poster format (the + // UPG-100 packet's page 1 is its full letter poster). + env: { FORMAT: format, ...(sparse ? { SPARSE: '1' } : {}), ...(date ? { POSTER_DATE: date } : {}) }, SERIES_DEF, ISO3_NAME, adm0, adm1Ind, adm1Chn, nePlaces: places, series: { totalGroups: 0, totalLists: 0, index: 1, ...series }, }) const fc = zoneFC || { type: 'FeatureCollection', features: [] } diff --git a/plugin-designs/my-upg-100-list/data/zone-sheet-print.js b/plugin-designs/my-upg-100-list/data/zone-sheet-print.js index 22597064a..19b29ef94 100644 --- a/plugin-designs/my-upg-100-list/data/zone-sheet-print.js +++ b/plugin-designs/my-upg-100-list/data/zone-sheet-print.js @@ -29,8 +29,12 @@ export function makeZoneSheet({ allRecords, assetsBase, profileConfig, date = nu if (!zone) return '' // a selection or an unknown id has no zone sheet; the caller falls through const pins = assignPins(zones, records).get(zone.zoneKey) || [] const zoneFC = resolveZoneGeometry(zone, { records, ...bounds }) + // ★ THE PACKET'S PAGE 1 IS THE FULL UPG-100 POSTER (2026-10-02), not the map-only sheet: the letter-size + // poster with its title, the scripture banner, the three-column header and the footer. The packet asks + // for 'packet'; this series answers with the full letter sheet, which is the same 1500x1941 page. + const page1 = format === 'packet' return generateSheet({ - zone, pins, zoneFC, format, seriesId: 'upg100', ISO3_NAME, adm0: bounds.adm0, adm1Ind: bounds.adm1Ind, adm1Chn: bounds.adm1Chn, + zone, pins, zoneFC, format: page1 ? 'letter' : format, ...(page1 ? { sparse: false } : {}), seriesId: 'upg100', ISO3_NAME, adm0: bounds.adm0, adm1Ind: bounds.adm1Ind, adm1Chn: bounds.adm1Chn, series: { ...seriesFacts(zones), index: zones.indexOf(zone) + 1 }, date, assetsBase: assetsBase(), }) }