/** Author distinct document cover PNGs locally. Run with tsx from apps/waterfall-wiki. */ import {createRequire} from 'node:module';import {fileURLToPath} from 'node:url';import path from 'node:path';import {mkdir,writeFile} from 'node:fs/promises';import {createHash} from 'node:crypto'; const require=createRequire(import.meta.url),sharp=require('sharp'),root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..'); const {guidanceDocuments}=require('../apps/waterfall-wiki/src/content/skills/guidance.ts'),{pageId}=require('../apps/waterfall-wiki/src/content/page-links.ts'),{chapters}=require('../apps/waterfall-wiki/src/content/learning-skills/data.ts'); const out=process.env.PROMPT_COVER_OUTPUT||path.resolve(root,'../output/prompt-tags-upgrade');await mkdir(out,{recursive:true}); function stableId(name){const b=createHash('sha256').update('prompt:learning-series:'+name).digest().subarray(0,16);b[6]=(b[6]&15)|80;b[8]=(b[8]&63)|128;const h=b.toString('hex');return `${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20)}`} const notes=[...guidanceDocuments.filter(d=>d.path.includes('/')).map((d,i)=>({id:pageId('guidance:'+d.path),title:d.title,collection:d.collection,slug:'guide-'+d.path.replaceAll('/','-'),file:d.path.replaceAll('/','-')+'.png',theme:d.collection==='照片入皮影'?'chinese':'sticker',number:String(guidanceDocuments.filter(x=>x.collection===d.collection&&x.path.includes('/')).findIndex(x=>x.path===d.path)+1).padStart(2,'0')})),...chapters.map((c,i)=>({id:stableId(c.key),title:['复习资料整理','出题与教学资料','英语学习资料'][i],collection:['笔记复习','教学资料','英语学习'][i],file:c.slug+'.png',theme:['notes','teaching','english'][i],number:c.number})),{id:'9ebd8f78d54b4b9db741b4e8',title:'Studio 封面工具',collection:'同一母版 / 三种构图',file:'studio-tools.png',theme:'studio',number:'TOOL',rebrand:true}]; const xml=s=>s.replaceAll('&','&').replaceAll('<','<').replaceAll('>','>'); for(const [i,n] of notes.entries()){ const palettes={chinese:['#f5ead7','#7e322e','#b4835a'],sticker:['#f7f1e7','#334c46','#a6b9a1'],notes:['#edf0e5','#354b3b','#a7b48c'],teaching:['#f3e7da','#6c483b','#c99773'],english:['#e9edf1','#35485b','#9db1c4'],studio:['#efeee5','#334d43','#9cac9f']},[paper,ink,accent]=palettes[n.theme]; const lines=n.theme==='studio'?['Studio','封面工具']:Array.from(n.title).reduce((arr,c,j)=>(j%9===0?arr.push(c):arr[arr.length-1]+=c,arr),[]); const ornament=n.theme==='chinese'?`文档`:n.theme==='sticker'?`${['Make.','Share.','Check.'][i%3]}`:`${n.theme==='english'?'Aa':n.number}`; const svg=`PROMPT / DOCUMENTS${xml(n.collection)}${lines.map((l,j)=>`${xml(l)}`).join('')}${ornament}${n.theme==='chinese'?'阅读 · 理解 · 制作':'READ / MAKE / KEEP'}独立文档封面 · 参考素材见正文${n.number}`; await sharp(Buffer.from(svg)).png().toFile(path.join(out,n.file)); } await writeFile(path.join(out,'catalog.json'),JSON.stringify({notes,roots:['street-people','shadow-puppet'].map(p=>({id:pageId('guidance:'+p),topic:p==='street-people'?'贴纸':'中国风'})),entries:['8eb8c76500580f7a4b56ba3c','9ebd8f78d54b4b9db741b4e8'],references:['street-people-reference','street-people-original']},null,2));console.log('Prepared '+notes.length+' independent covers and an API publication catalogue.');