import sharp from 'sharp'; import assert from 'node:assert/strict'; import {readFileSync,writeFileSync} from 'node:fs'; const time=JSON.parse(readFileSync('public/notes/timezone-check-results.json','utf8')).cases.find(x=>x.id==='fall-repeat'); assert.equal(time.elapsed_minutes,60);assert.equal(time.wall_minutes,0); const text=(x,y,s,size=28,color='#243f32')=>`${s}`; const svg=`${text(65,65,'FORTUNELEAF / CLOCK CHECK',20)}${text(65,143,'01:30',64)}${text(765,143,'01:30',64)}${text(65,192,'UTC -04:00',28)}${text(765,192,'UTC -05:00',28)}${text(65,430,'05:30 UTC',36)}${text(765,430,'06:30 UTC',36)}${text(411,326,'60 min',38,'#fff')}${text(65,527,'SAME CLOCK LABEL. TWO DIFFERENT INSTANTS.',26)}${text(65,585,'GENERATED CASE / NEW YORK / 2026-11-01 / EXPLICIT OFFSETS',18)}`; writeFileSync('public/journal/timezone.svg',svg);await sharp(Buffer.from(svg)).png().toFile('public/journal/timezone.png');await sharp(Buffer.from(svg)).webp({quality:88}).toFile('public/journal/timezone.webp'); const obs=JSON.parse(readFileSync('public/notes/label-check-results.json','utf8'));const one=obs.observations.find(x=>x.id==='tuna_145g'),pack=obs.observations.find(x=>x.id==='tuna_4x145g'); const minor=s=>{assert(/^\d+\.\d{2}$/.test(s));return Number(s.replace('.',''));};const single=minor(one.price_gbp),bundle=minor(pack.price_gbp); const cases=[1,2,4].map(needed=>({needed_cans:needed,single_purchase_pence:single*needed,four_pack_purchase_pence:bundle,extra_cans_in_pack:4-needed,extra_pack_outlay_pence:bundle-single*needed})); assert.deepEqual(cases.map(x=>x.extra_pack_outlay_pence),[184,119,-11]); writeFileSync('public/notes/pack-decision-results.json',JSON.stringify({observed_on:obs.checked_on,scope:'Generated demand of1,2,4 cans applied to dated public displayed prices. No purchase, consumption, stock or food-safety test. Extra cans are inventory, not automatically waste.',source_snapshot:'/notes/label-check-results.json',single_price_pence:single,four_pack_price_pence:bundle,cases},null,2)+'\n'); console.log('PASS: timeline uses actual0/60 fixture; pack cases [184,119,-11] pence checked with integer arithmetic. Wrote original SVG/PNG/WebP and reproducible JSON.'); writeFileSync('public/notes/build-reader-visuals.mjs.txt',readFileSync(new URL(import.meta.url)));