import json,subprocess,pathlib,textwrap,math,time,hashlib
root=pathlib.Path(__file__).parent
for side,sha in [('before','31eea883c7'),('after','ec24de611d')]:
 run=sorted(root.glob(side+'-*'))[-1]; events=json.loads((run/'timeline.json').read_text()); frames=run/'frames';frames.mkdir(exist_ok=True)
 def render(t,path):
  lines=['BOOTSTRAP PIPE | '+side.upper()+' | '+sha,'Linux x86_64 | real bundled server | fresh synthetic state','Timestamped runtime transcript, rendered at original timing','Scope: server only; native Windows and Electron supervisor unverified','Elapsed: %05.1fs'%t,'']
  for e in events:
   if e['t']<=t:
    parts=textwrap.wrap('%6.2fs  %s'%(e['t'],e['text']),width=114,subsequent_indent='         ');lines.extend(parts)
  subprocess.run(['convert','-size','1600x1100','xc:#10151d','-font','DejaVu-Sans-Mono','-pointsize','20','-fill','#e3eaf3','-interline-spacing','5','-annotate','+35+45','\n'.join(lines),str(path)],check=True)
 end=math.ceil(events[-1]['t'])
 for t in range(end+5):render(t,frames/('%04d.png'%t))
 final=run/(side+'.png');render(end,final);time.sleep(.5);render(end,run/'stability.png')
 assert subprocess.check_output(['convert',str(final),'rgba:-'])==subprocess.check_output(['convert',str(run/'stability.png'),'rgba:-'])
 subprocess.run(['ffmpeg','-v','error','-y','-framerate','1','-i',str(frames/'%04d.png'),'-c:v','libx264','-pix_fmt','yuv420p','-movflags','+faststart',str(run/(side+'.mp4'))],check=True)
 print(run,flush=True)
