"""Build an offline, single-file deck with no package install or network.""" from pathlib import Path import base64, hashlib, json, re R=Path(__file__).resolve().parents[1] def build(): vendor=R/'assets/vendor'; s=(R/'assets/starter.html').read_text() manifest=R/'vendor-manifest.json' if manifest.exists(): for entry in json.loads(manifest.read_text()): assert hashlib.sha256((R/entry['path']).read_bytes()).hexdigest()==entry['sha256'], entry['path'] nodes=[] labels=['People','Process','Platform','Quality','Cost','Risk'] details=['People: who owns the decision?','Process: how does work move?','Platform: what enables delivery?','Quality: what evidence proves fitness?','Cost: what constraint shapes the choice?','Risk: what could invalidate the plan?'] for i,(label,detail) in enumerate(zip(labels,details)): x=[250,550,850][i%3];y=65 if i<3 else 305 nodes.append(f'{label}') s=s.replace('','\n'.join(nodes)) for marker,file in [('REVEAL_CSS','reveal.css'),('REVEAL_JS','reveal.js'),('ANIME_JS','anime.umd.min.js')]: text=(vendor/file).read_text();text=re.sub(r'//# sourceMappingURL=.*','',text) s=s.replace('/* '+marker+' */',text) fonts='' for file,weight in [('work-sans.woff2',400),('work-sans-bold.woff2',700)]: fonts+=f"@font-face{{font-family:'Work Sans';font-weight:{weight};font-style:normal;font-display:block;src:url(data:font/woff2;base64,{base64.b64encode((vendor/file).read_bytes()).decode()}) format('woff2');}}" s=s.replace('/* FONT_CSS */',fonts).replace('/* APP_JS */',(R/'assets/app.js').read_text()) licenses='\n'.join((vendor/f).read_text() for f in ['reveal-LICENSE','anime-LICENSE.md','work-sans-LICENSE']) s=s.replace('','') out=R/'dist';out.mkdir(exist_ok=True);p=out/'presentation-html-demo-0.1.0.html';p.write_text(s) report={'file':p.name,'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'bytes':p.stat().st_size,'slides':6,'interactive_nodes':6,'reveal':'6.0.2','anime':'4.5.0'} (out/'manifest.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(report)) if __name__=='__main__':build()