app
AI Flow: Reverse Engineering
Public Made by Adomby adom
Photos of a PCB to a tagged KiCad copy: parts placed, copper and nets with their evidence, a schematic, a measured confidence score, bench tests and a video of the run.
main
Caleb
Version 0.3.0: new copper reader, dome via filter, every layer read from the photos, net evidence, measured confidence;…
e874d7d
const p=require(process.env.HOME+'/.cache/hero-studio/node_modules/puppeteer-core'),fs=require('fs'),cp=require('child_process'),http=require('http'),path=require('path');
const F=process.env.FF,T=JSON.parse(fs.readFileSync('a/data.json')).timing,MODE=process.argv[2]||'still',ONLY=process.argv[3]?process.argv[3].split(','):null;
const INTRO=5,VO_IN=1.8,LEAD=.1,TAIL=.3;
const durOf=s=>s.id==='board'?Math.max(4,s.speech[1]+VO_IN-INTRO+TAIL):s.id==='cost'?s.speech[1]+LEAD-1.2:s.speech[1]+LEAD+TAIL;
const leadOf=s=>s.id==='board'?(VO_IN-INTRO):LEAD;
const srv=http.createServer((q,r)=>{const f=path.join('a',decodeURIComponent(q.url.split('?')[0]));fs.readFile(f,(e,b)=>{if(e){r.writeHead(404);return r.end()}r.writeHead(200,{'content-type':f.endsWith('.html')?'text/html':f.endsWith('.json')?'application/json':f.endsWith('.woff2')?'font/woff2':'image/jpeg'});r.end(b)})}).listen(0,'127.0.0.1',async()=>{const port=srv.address().port;
const b=await p.launch({headless:'new',executablePath:process.env.HOME+'/.cache/puppeteer/chrome/linux-150.0.7871.24/chrome-linux64/chrome',args:['--no-sandbox','--disable-gpu'],protocolTimeout:3600000});
const list=T.filter(s=>!ONLY||ONLY.includes(s.id));
const one=async s=>{const pg=await b.newPage();pg.on('pageerror',e=>console.error('ERR',s.id,e.message));await pg.setViewport({width:1920,height:1080});await pg.goto(`http://127.0.0.1:${port}/composer.html?s=${s.id}`);await pg.evaluate(()=>window.ready);
const d=durOf(s),lead=leadOf(s),C=s.starts.map(v=>v+lead);
if(MODE==='still'){const ts=[...C.map((c,i)=>Math.min(d-.3,(c+(C[i+1]??d))/2)),...(C.length>1?[Math.min(d-.4,C[C.length-1]+Math.max(1,(d-C[C.length-1])*.85))]:[])];
for(let i=0;i<ts.length;i++){await pg.evaluate((id,t,d,l)=>window.draw(id,t,d,l),s.id,ts[i],d,lead);const j=await pg.evaluate(()=>window.grab());fs.writeFileSync(`shots/st_${s.id}_${i}.jpg`,Buffer.from(j,'base64'))}}
else{const n=Math.round(d*30),ff=cp.spawn(F,['-y','-v','error','-f','image2pipe','-c:v','mjpeg','-r','30','-i','-','-c:v','libx264','-preset','medium','-crf','17','-pix_fmt','yuv420p','-r','30',`clips/${s.id}.mp4`],{stdio:['pipe','inherit','inherit']});
for(let i=0;i<n;i++){const j=await pg.evaluate((id,t,d,l)=>{window.draw(id,t,d,l);return window.grab()},s.id,i/30,d,lead);if(!ff.stdin.write(Buffer.from(j,'base64')))await new Promise(r=>ff.stdin.once('drain',r))}
ff.stdin.end();await new Promise(r=>ff.on('close',r));console.log('done',s.id,n)}
await pg.close()};
await Promise.all(list.map(one));await b.close();srv.close();
fs.writeFileSync('clips/durs.json',JSON.stringify(T.map(s=>({id:s.id,title:s.title,d:Math.round(durOf(s)*30)/30}))));
});