On a phone, India's Prayer List (Full detail, Lightweight) reported "that list has no people groups to print" on a
card of 855: its rows resolved [] and the print path read that as an empty list. Now, in the wall and the Regions
list alike, a desktop-only card's rows REJECT with the notice before any record is fetched, and the card shows the
same words: a new poster.phoneLimitAll ("This needs a desktop or laptop computer.", all eleven locales). The
existing "the largest sizes are off" stays for cards that are only partly blocked.
check:country-sheet-one-path arm F asserts it for both callers, with a poison for each.
Measured on the 60x96 print: every photo beside a name rasterised as the browser's broken-image glyph. An SVG
rasterised through <img> is an isolated document that fetches no external resource, and none of the people-group
photo hosts (media.joshuaproject.net, joshuaproject.net, images.peoplegroups.org and its resizer,
peoplegroupspublic.blob.core.windows.net, s3.doxa.life) sends CORS, so a photo cannot be inlined as data: in the
browser either.
- poster-raster.js: rasterPoster drops every <image> whose href is not data: (the basemap tiles are data: and stay),
so a download shows the paper, never the glyph. hasExternalImages() says when a sheet carries such photos.
- PosterWall: printing a generated sheet that carries photos prints THE SHEET ITSELF through printDocument, where
the photos load, on its own @page (60in 96in), instead of a raster shrunk onto letter. Same HUD steps.
- check:side-lanes: photo arms (0 external images reach the raster; the wall prints such a sheet as a document),
each with a poison in its self-test.
- check:side-lane-photo-pixels: the pixel side, a browser gate (a data: photo draws red; 99/99 external slots stay
flat; without the strip 0/99 do). Declared on-demand until its first browser-seat run.
- library/components/WARNING.md, library/dashboards/README.md and
documentation/contributing/README.md taught "graduate into the library at the second
consumer". They now teach the plugin-designer skill's rule (section 3): a component that
could serve more than one map is built once in library/, driven by props, and landed through
the build owner; one-off or experimental pieces stay in a map's folder; a new pattern is a
pilot, then approved, then rolled out. The contributing guide's "full reasoning" link pointed
to an index without it; it now points to the skill.
- The app shell doxa-maps-spa is labelled Deep Research. Ten docs still called it the Research
Gallery (15 mentions): DEPLOY.md, the desktop how-to, embeddability, develop-a-plugin,
reference-universal-props, reference.md, the shell's EMBED.md, and the plugin-designer skill
with two of its references. Identifiers (doxa-maps-spa, branch and route names) are unchanged;
README.md is not touched.
DX Life's /pray at 1440 kept the pill at the viewport's bottom until the map's bottom came into view: the page
scrolls a container, not the document, so the document-only test saw a full-screen page and kept the fold.
pageScrolls now also walks out from the pill, across shadow roots, for an ancestor scroller whose content is
taller than it; a map wholly below or above the viewport is treated as on a scrolling page; and a lift is
cleared when the pill goes off screen, so a lift set while the map was half visible does not survive into the
next view. check:pin-hint-floor adds the inner-scroller, shadow-crossing and map-below-the-fold fixtures; its
self-test refuses 9 planted defects.
countrySheet.js now lets a requested side-lane format win over a large
country's default sheet, so the shared path draws India at 66x66 and
36x60 as well as 60x96. The two cards that were listed but not drawn now
draw the real whole-India poster at their own size, and the note that
said no country printed at those sizes (missing.largeFormat, 11 locales)
is removed: nothing refers to it.
India can print at 60x96 (the default), 66x66 or 36x60. makeCountrySheet used to map any non-packet request to the
default, so a 66x66 or 36x60 request drew the 60x96 sheet. sheetFormatFor(item, format) (exported, pure) now keeps
a requested size the country can print at, falls back to its default otherwise, keeps a packet page a page, and
returns exactly what was asked for every other country.
check:country-sheet-one-path asserts that table (India 66x66/36x60/60x96/letter/3x4/packet; Nepal 3x3/letter;
China 3x4), with two poisons: India ignoring a requested 66x66, and a packet page turned into a large sheet.
poster-render gains three side-lane formats (60x96, 66x66, 36x60), and
check:poster-design-catalogue requires SHEET_FORMATS to list exactly what
FORMATS defines, so it failed on those three. They are now listed, near
the top after the 3 x 3 sheet, with India as their sample: India is the
one country countrySheet.js prints on a large sheet (LARGE_SHEETS).
map-sheet.country.60x96 draws through makeCountrySheet, the one country
sheet path, so its card shows the real whole-India poster. 66x66 and
36x60 are listed but not drawn: no country prints at those sizes yet, and
the shared path would hand back India's 5 x 8 ft sheet under their label.
Their details say so (posterDesign.missing.largeFormat, 11 locales).
The check fails on the three formats without this commit and passes with
it.
5B fixes on the side-lane mode:
- The side-lane styles' template slot sat on its own line, so every OTHER format's page gained one newline. It is
now joined onto </style>, emitting nothing at all off side lanes.
- A photo is drawn only over https from the hosts that serve people-group photos (media.joshuaproject.net,
joshuaproject.net, images.peoplegroups.org, peoplegroupspublic.blob.core.windows.net), never the generic
placeholder; anything else is dropped. Re-pinned.
check:side-lanes' seeded data now also carries photos on a host that is NOT allowed; none may be drawn.
The packet and card-deck title named the selection's zones and countries only.
Since India's states bring people, a selection of states alone had no names, and
reduce() threw "Reduce of empty array with no initial value" at the reader.
selectionTitleNames (data/selection-export.js, pure) adds the states and union
territories that brought people. A province with no table is not named. A
selection that brought nobody (Mizoram or Nagaland alone) gives the keyed
"no people groups to print" instead.
check:batch-selection-export arm A6 tests it on the real served table: Gujarāt
alone is titled "Gujarāt", a state + a country names both, a province beside it is
not named, and Mizoram alone reads the keyed text. Its negative control shows the
old naming is empty and reduce() throws. The call site is pinned in arm C. Four
mutants each fail.
CORRECTS the previous commit's "no prayer list, packet or cards for whole India": the current direction is that
whole India's poster, list, packet and cards (about a thousand pages) are offered DESKTOP-ONLY, and a phone shows
the existing poster.phoneLimit sentence instead of failing.
countrySheet.js now exports LARGE_SHEETS ({ IND: 60x96, desktopOnly }) and largeSheet(item), and makeCountrySheet
itself prints such a country in its large format (a packet page stays a page) with its "Administrative Areas"
cell from the shared state table ("36 states and union territories"). So every caller gets the same sheet: the
Regions list's India no longer has to disagree with Country Posters (regions-list's own lines follow, from regions).
The wall drops its India-only code and follows the same rule.
India's card is no longer "too many to fit": it prints as the 60x96 side-lane sheet (all 855 groups named beside
the map, crossing-free leaders, real photos), whatever paper the wall asks for, until the shared size picker
offers 66x66 and 36x60 too. Its facts row reads "36 states and union territories" (English, from the wall
head's plural key). As ruled, the whole-India card offers no prayer list, packet or cards; the state cards keep
theirs. Its card preview is the real sheet.
check:side-lanes (+ :self-test, gates:pre): the three side-lane formats on a seeded worst case (855 groups,
stacked and clustered) through the real renderer: every name once, 0 crossings re-measured from the SVG, no
overflow, photos only where real; without the lane clamp the same data crosses 36 times, and the arm fails.
pinsFrom carries image_url (only side-lane sheets draw it; every other sheet ignores it). countryZone and makeCountrySheet accept an optional adminAreas for the facts row (India: "36 states and union territories"); without it the cell shows the country's name as before.
A new layout mode, ADDITIVE: three new FORMATS with `sideLanes`; every existing format takes exactly its old path.
Every name horizontal, on the left and right of the map in two staggered columns per side (rows alternate, so each
column keeps a full line pitch and each row holds one name). Co-located groups form a cluster with one leader and
a bracketed block. Crossing-free by construction: one vertical split sends each cluster to the nearer side; each
leader is a short stub to its own lane, a horizontal run to the map edge, and a fan to its block, with lanes placed
farthest-from-the-edge first and clamped between their neighbours, and fans in the lanes' order. The renderer
measures and returns its crossing count. A real photo (never the placeholder) sits outside its name where the
format allows. The type is the largest that fits the rows and columns, capped per format (nameMaxPt).
On these sheets only: pins stay at their true positions (no settle pass), the map frame takes the country's own
shape centred in the band with a thin margin, and the side-lane styles are emitted.
India (855 groups, live data): 60x96 20.7 pt names + 7.9 mm photos; 66x66 14.6 pt + 5.5 mm; 36x60 12.6 pt, no
photos; 0 crossings on all three; 4 s per render where the numbered path took 65 s. Re-pinned.