AnasSarkiz/NEMA14_CH32X035G8U6

A NEMA stepper motor is shown with proposed M3 screws/spacers, four wired motor leads and splices, and a JST SHR-04V-S connector.

Version
1.12.2
License
ISC
Stars
0

scripts/audit-manufacturing.py

#!/usr/bin/env python3
"""Independent RS-274X/Excellon audit. No Circuit JSON renderer is used.
Gerbonara 1.5 aperture-rotation and split-line G85 compatibility are explicit.
PyGerber separately renders the original, unmodified Gerbers, including LR.
"""
import argparse,csv,hashlib,importlib.util,json,math,pathlib,re,warnings,zipfile
from collections import Counter,defaultdict
from shapely.geometry import Point,LineString,Polygon,box
from shapely.affinity import rotate
from shapely.ops import unary_union,polygonize
from shapely.strtree import STRtree
from gerbonara import GerberFile,ExcellonFile
from gerbonara.graphic_objects import Flash
from gerbonara.utils import MM
from pygerber.gerberx3.api import v2

def shape(e):
 if e.get('shape')=='polygon':return Polygon([(p['x'],p['y']) for p in e['points']]).buffer(0)
 x,y=e['x'],e['y'];w=e.get('width',e.get('outer_width',e.get('outer_diameter',e.get('radius',0)*2)));h=e.get('height',e.get('outer_height',w))
 if e.get('shape')=='polygon':return Polygon([(p['x'],p['y']) for p in e['points']]).buffer(0)
 if e.get('shape')=='circle' or e['type']=='pcb_via':g=Point(x,y).buffer(w/2,quad_segs=64)
 elif e.get('shape') in ('pill','rotated_pill'):
  dx,dy=((w-h)/2,0) if w>=h else (0,(h-w)/2);g=LineString([(x-dx,y-dy),(x+dx,y+dy)]).buffer(min(w,h)/2,quad_segs=64)
 else:g=box(x-w/2,y-h/2,x+w/2,y+h/2)
 return rotate(g,e.get('ccw_rotation',0),origin=(x,y))
def primitive(p):
 n=type(p).__name__
 if n=='Circle':return Point(p.x,p.y).buffer(p.r,quad_segs=64)
 if n=='Rectangle':return rotate(box(p.x-p.w/2,p.y-p.h/2,p.x+p.w/2,p.y+p.h/2),math.degrees(p.rotation),origin=(p.x,p.y))
 if n=='Line':return LineString([(p.x1,p.y1),(p.x2,p.y2)]).buffer(p.width/2,quad_segs=64)
 if n=='ArcPoly':
  if any(x is not None for x in p.arc_centers):raise ValueError('ArcPoly arc unsupported: explicit failure rather than silent polygon approximation')
  return Polygon(p.outline).buffer(0)
 if n=='Arc':
  r=math.hypot(p.x1-p.cx,p.y1-p.cy);a=math.atan2(p.y1-p.cy,p.x1-p.cx);b=math.atan2(p.y2-p.cy,p.x2-p.cx)
  sweep=((a-b)%(2*math.pi))*(-1) if p.clockwise else (b-a)%(2*math.pi)
  if abs(sweep)<1e-12:sweep=(-1 if p.clockwise else 1)*2*math.pi
  steps=max(8,math.ceil(abs(sweep)*max(r,1)/.001));pts=[(p.cx+r*math.cos(a+sweep*i/steps),p.cy+r*math.sin(a+sweep*i/steps)) for i in range(steps+1)]
  return LineString(pts).buffer(p.width/2,quad_segs=64)
 raise ValueError(f'Unsupported primitive {n}')
def gerber(path):
 raw=path.read_text();rot=0.;angles=[]
 for token in re.findall(r'%[^%]*%|[^*%]+\*',raw):
  m=re.search(r'%LR([+-]?[\d.]+)\*%',token)
  if m:rot=float(m[1]);continue
  if re.search(r'D0?3\*$',token.strip()):angles.append(rot)
 with warnings.catch_warnings(record=True) as ws:
  warnings.simplefilter('always');g=GerberFile.open(path)
 unknown=[str(w.message) for w in ws if not re.search(r'Unknown statement found: \"LR[+\-\d.]+\"',str(w.message))]
 if unknown:raise ValueError(f'{path.name} parser warnings: {unknown}')
 flashes=[o for o in g.objects if isinstance(o,Flash)]
 if len(flashes)!=len(angles):raise ValueError(f'Flash correspondence failure {path.name}: {len(flashes)} / {len(angles)}')
 for o,a in zip(flashes,angles):
  if a%360 not in (0,90,180,270):raise ValueError(f'Rotation {a} requires independently validated analytic support')
  if a%360:o.aperture=o.aperture.rotated(math.radians(a))
 result=Polygon();batch=[];last=True
 for o in g.objects:
  for p in o.to_primitives(unit=MM):
   dark=p.polarity_dark
   if dark!=last and batch:
    u=unary_union(batch);result=result.union(u) if last else result.difference(u);batch=[]
   batch.append(primitive(p));last=dark
 if batch:
  u=unary_union(batch);result=result.union(u) if last else result.difference(u)
 return result,len(g.objects),{'LR_applied':sum(bool(a%360) for a in angles),'warnings':unknown}
def drill(path):
 raw=path.read_text();lines=raw.splitlines();out=[];joined=0
 for l in lines:
  if l.startswith('G85'):
   if not out or not re.fullmatch(r'X[-+\d.]+Y[-+\d.]+',out[-1]):raise ValueError('Ambiguous G85 start')
   start=out.pop();out.extend(['G00'+start,'M15','G01'+l[3:],'M16','G05']);joined+=1;continue
  out.append(l)
 with warnings.catch_warnings(record=True) as ws:
  warnings.simplefilter('always');d=ExcellonFile.from_string('\n'.join(out)+'\n')
 unhandled=[str(w.message) for w in ws if 'G90 header statement found after end of header' not in str(w.message)]
 if unhandled:raise ValueError(f'{path.name} drill warnings: {unhandled}')
 gs=[primitive(p) for o in d.objects for p in o.to_primitives(unit=MM)]
 return unary_union(gs),gs,{'objects':len(d.objects),'G85_joined':joined,'parser_notices':[str(w.message) for w in ws],'tools_mm':dict(Counter(round(o.tool.diameter,6) for o in d.objects))}
def expected(j):
 layers=defaultdict(list)
 for e in j:
  typ=e['type']
  if typ in ('pcb_smtpad','pcb_plated_hole','pcb_via'):
   for l in e.get('layers',[e.get('layer','top')]):layers[l].append(shape(e))
  elif typ=='pcb_trace':
   for a,b in zip(e['route'],e['route'][1:]):
    if a['route_type']==b['route_type']=='wire' and a['layer']==b['layer']:layers[a['layer']].append(LineString([(a['x'],a['y']),(b['x'],b['y'])]).buffer(max(a['width'],b['width'])/2,quad_segs=64))
  elif typ=='pcb_copper_pour':
   q=e['brep_shape'];coords=lambda r:[(p['x'],p['y']) for p in r['vertices']];layers[e['layer']].append(Polygon(coords(q['outer_ring']),[coords(r) for r in q.get('inner_rings',[])]).buffer(0))
 return {k:unary_union(v) for k,v in layers.items()}
def main():
 ap=argparse.ArgumentParser();ap.add_argument('--directory',default='artifacts/manufacturing');ap.add_argument('--source',default='artifacts/board.circuit.json');ap.add_argument('--archive',help='Actual archive to compare byte-for-byte against parsed extracted files');ap.add_argument('--baseline',action='store_true');ap.add_argument('--render',action='store_true');args=ap.parse_args();root=pathlib.Path(__file__).resolve().parents[1];directory=root/args.directory;source_bytes=(root/args.source).read_bytes();j=json.loads(source_bytes);report={'source_sha256':hashlib.sha256(source_bytes).hexdigest(),'directory':args.directory,'parser_versions':{'gerbonara':'1.5.0','pygerber':'2.4.3','shapely':__import__('shapely').__version__},'parser_compatibility':'Only LR right-angle aperture transforms and unambiguous split-line G85 slots are converted to equivalent G00/M15/G01/M16/G05 routing analytically. Original Gerbers independently rendered by PyGerber. Input CAM bytes remain unchanged.','files':{},'issues':[]}
 archive=root/args.archive if args.archive else (root/'artifacts/nema14-gerbers.zip' if args.directory=='artifacts/manufacturing' else directory/'original-export.zip')
 if not archive.exists():raise ValueError(f'Actual archive missing: {archive}')
 archive_records={}
 with zipfile.ZipFile(archive) as z:
  seen=set()
  for member in z.namelist():
   if member.endswith('/'):continue
   name=pathlib.Path(member).name
   if name in seen:raise ValueError(f'Duplicate archive member {name}')
   seen.add(name);data=z.read(member);path=directory/name
   if not path.exists() or path.read_bytes()!=data:raise ValueError(f'Actual archive/extracted byte mismatch: {name}')
   archive_records[name]=hashlib.sha256(data).hexdigest()
 loose_cam={p.name for p in directory.iterdir() if p.suffix in ['.gbr','.drl','.csv']}
 if loose_cam-set(archive_records):raise ValueError(f'Parsed CAM files absent from actual archive: {sorted(loose_cam-set(archive_records))}')
 report['archive']={'path':str(archive),'sha256':hashlib.sha256(archive.read_bytes()).hexdigest(),'extracted_bytes_verified':True,'members':archive_records}
 geo={}
 for p in sorted(directory.glob('*.gbr')):
  geometry,count,compat=gerber(p);geo[p.stem]=geometry;report['files'][p.name]={'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'objects':count,'area_mm2':geometry.area,'bounds_mm':list(geometry.bounds) if not geometry.is_empty else [],**compat}
  if args.render and p.stem.endswith('_Cu'):
   out=directory/'independent-render';out.mkdir(exist_ok=True);v2.GerberFile.from_file(p).parse(on_parser_error=v2.OnParserErrorEnum.Raise).render_raster(out/(p.stem+'.png'),dpmm=80,color_scheme=v2.ColorScheme.SILK)
 drills=[];all_drill=[]
 for p in sorted(directory.glob('*.drl')):
  g,parts,stats=drill(p);report['files'][p.name]={'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),**stats};all_drill.extend(parts)
  if 'npth' not in p.name:drills.extend(parts)
 holes=unary_union(all_drill);expected_layers=expected(j);layer_names={'top':'F_Cu','bottom':'B_Cu','inner1':'In1_Cu','inner2':'In2_Cu'};actual={};delta={}
 for layer,name in layer_names.items():
  if name not in geo:continue
  a=geo[name].difference(holes);b=expected_layers.get(layer,Polygon()).difference(holes);actual[layer]=a
  missing=b.difference(a.buffer(.0002));extra=a.difference(b.buffer(.0002));delta[layer]={'missing_mm2':missing.area,'extra_mm2':extra.area,'tolerance_mm':.0002}
  if missing.area>1e-4 or extra.area>1e-4:report['issues'].append({'kind':'copper-source-mismatch','layer':layer,**delta[layer]})
 report['copper_comparison']=delta
 # Each connected polygon in the actual copper is an electrical island. Bridge
 # its layers only at drilled plated barrels. Assign names from native pads.
 nodes=[];trees={};indices={}
 for l,g in actual.items():
  ps=list(g.geoms) if hasattr(g,'geoms') else [g];ps=[p for p in ps if p.area>1e-9];indices[l]=list(range(len(nodes),len(nodes)+len(ps)));nodes.extend(ps);trees[l]=STRtree(ps)
 parent=list(range(len(nodes)))
 def find(i):
  while parent[i]!=i:parent[i]=parent[parent[i]];i=parent[i]
  return i
 def union(ids):
  if ids:
   r=find(ids[0])
   for i in ids[1:]:parent[find(i)]=r
 def hits(l,g):return [indices[l][int(i)] for i in trees[l].query(g,predicate='intersects') if nodes[indices[l][int(i)]].intersection(g).area>1e-8]
 for d in drills:
  ann=d.buffer(.03).difference(d.buffer(-.0001));union([i for l in actual for i in hits(l,ann)])
 src={e['source_component_id']:e for e in j if e['type']=='source_component'};pc={e['pcb_component_id']:e for e in j if e['type']=='pcb_component'};sp={e['source_port_id']:e for e in j if e['type']=='source_port'};pp={e['pcb_port_id']:e for e in j if e['type']=='pcb_port'};netnames={e['subcircuit_connectivity_map_key']:e['name'] for e in j if e['type']=='source_net'};assign=defaultdict(lambda:defaultdict(list));netroots=defaultdict(lambda:defaultdict(list));unconnected=[]
 for e in j:
  if e['type'] not in ('pcb_smtpad','pcb_plated_hole') or not e.get('pcb_port_id'):continue
  port=pp[e['pcb_port_id']];s=sp[port['source_port_id']];key=s.get('subcircuit_connectivity_map_key')
  if not key:continue
  ref=src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'];ids=[i for l in e.get('layers',[e.get('layer','top')]) if l in actual for i in hits(l,shape(e).difference(holes))]
  if not ids:unconnected.append(ref)
  for r in {find(i) for i in ids}:assign[r][key].append(ref);netroots[key][r].append(ref)
 shorts=[{'nets':[netnames.get(k,k) for k in v],'pads':dict(v)} for v in assign.values() if len(v)>1];opens=[{'net':netnames.get(k,k),'islands':list(v.values())} for k,v in netroots.items() if len(v)>1];report['connectivity']={'named_nets_checked':len(netroots),'shorts':shorts,'opens':opens,'unconnected_pads':unconnected,'actual_copper_islands':len(nodes),'unassigned_islands':len({find(i) for i in range(len(nodes))}-set(assign))}
 nc_contacts=[]
 for e in j:
  if e['type']!='pcb_smtpad' or not e.get('pcb_port_id'):continue
  port=pp[e['pcb_port_id']];s=sp[port['source_port_id']]
  if s.get('subcircuit_connectivity_map_key'):continue
  for r in {find(i) for i in hits(e['layer'],shape(e))}:
   if r in assign:nc_contacts.append({'pad':src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'],'nets':[netnames.get(k,k) for k in assign[r]]})
 report['connectivity']['no_connect_contacts']=nc_contacts
 if nc_contacts:report['issues'].append({'kind':'no-connect-pad-contact','contacts':nc_contacts})
 # Classify copper islands without named connected pads; expected NC pads
 # must not be mislabeled as floating routed copper.
 isolated=[]
 for r in {find(i) for i in range(len(nodes))}-set(assign):
  geometry=unary_union([nodes[i] for i in range(len(nodes)) if find(i)==r]);nc=[]
  for e in j:
   if e['type']!='pcb_smtpad' or not e.get('pcb_port_id'):continue
   port=pp[e['pcb_port_id']];s=sp[port['source_port_id']]
   if s.get('subcircuit_connectivity_map_key'):continue
   if e['layer'] in actual and r in {find(i) for i in hits(e['layer'],shape(e))}:nc.append(src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'])
  isolated.append({'area_mm2':geometry.area,'bounds_mm':list(geometry.bounds) if not geometry.is_empty else [],'layers':[l for l in indices if any(find(i)==r for i in indices[l])],'no_connect_pads':nc,'classification':'intentional native no-connect pad' if nc else 'unassigned copper: review'})
 report['connectivity']['unassigned_island_details']=isolated
 # Spacing is measured on the independently parsed, finished copper, not on
 # centerlines or bounding rectangles. Same physical barrel-connected nets
 # are exempt; native NC islands remain separate conductors for this screen.
 copper_spacing={}
 for layer,ids in indices.items():
  near=[]
  for local,i in enumerate(ids):
   for other in trees[layer].query(nodes[i].buffer(.5)):
    other=int(other)
    if other<=local:continue
    k=ids[other];ri,rk=find(i),find(k)
    if ri==rk:continue
    ai=set(assign.get(ri,{}));ak=set(assign.get(rk,{}))
    if ai and ai==ak:continue
    distance=nodes[i].distance(nodes[k])
    near.append({'clearance_mm':distance,'conductors':[[netnames.get(n,n) for n in assign.get(r,{})] or ['native NC/unassigned island'] for r in (ri,rk)],'island_indices':[i,k]})
  near.sort(key=lambda e:e['clearance_mm'])
  copper_spacing[layer]={'minimum_distinct_conductor_clearance_mm':near[0]['clearance_mm'] if near else None,'closest_pairs':near[:5],'screen_minimum_mm':.15,'geometry_tolerance_mm':.0002,'scope':'actual finished copper edges; pairs within 0.50 mm; same electrical net excluded'}
  failures=[p for p in near if p['clearance_mm']<.1498]
  if failures:report['issues'].append({'kind':'actual-copper-clearance','layer':layer,'pairs':failures})
 report['actual_copper_spacing']=copper_spacing
 unresolved=[i for i in isolated if not i['no_connect_pads'] and i['area_mm2']>1e-5]
 if unresolved:report['issues'].append({'kind':'unassigned-copper-islands','islands':unresolved})
 if shorts or opens or unconnected:report['issues'].append({'kind':'physical-netlist-failure','short_count':len(shorts),'open_count':len(opens),'unconnected_pads':unconnected})
 bare={s['name'] for s in src.values() if s['ftype']=='simple_test_point'} | {src[p['source_component_id']]['name'] for p in pc.values() if p.get('do_not_place')};bare_pc={p['pcb_component_id'] for p in pc.values() if src[p['source_component_id']]['name'] in bare};bare_pads=unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['pcb_component_id'] in bare_pc]);paste={};pth=unary_union([shape(e) for e in j if e['type']=='pcb_plated_hole'])
 for l in ['F_Paste','B_Paste']:
  bare_pads=unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['pcb_component_id'] in bare_pc and e['layer']==('top' if l=='F_Paste' else 'bottom')])
  g=geo.get(l,Polygon());paste[l]={'bare_interface_overlap_mm2':g.intersection(bare_pads).area,'manual_plated_joint_overlap_mm2':g.intersection(pth).area,'outside_smt_copper_mm2':g.difference(unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['layer']==('top' if l=='F_Paste' else 'bottom')]).buffer(.0002)).area}
  if g.intersection(bare_pads).area>1e-6 or g.intersection(pth).area>1e-6 or paste[l]['outside_smt_copper_mm2']>1e-6:report['issues'].append({'kind':'assembly-paste-policy','layer':l,**paste[l]})
 report['paste']=paste;table={}
 for filename in ['bom.csv','pick_and_place.csv']:
  rows=list(csv.DictReader((directory/filename).open()));refs={r['Designator'] for r in rows};fit={s['name'] for s in src.values() if s['name'] not in bare};table[filename]={'rows':len(rows),'bare_rows':sorted(refs&bare),'missing_fitted':sorted(fit-refs),'unexpected':sorted(refs-fit-bare)}
  duplicates=sorted(ref for ref,count in Counter(r['Designator'] for r in rows).items() if count>1)
  table[filename]['duplicate_refs']=duplicates
  if refs&bare or fit-refs or refs-fit-bare or duplicates:report['issues'].append({'kind':'assembly-table-policy','table':filename,**table[filename]})
  if filename=='bom.csv':
   errors=[]
   byref={e['name']:e for e in src.values()}
   for row in rows:
    component=byref.get(row['Designator'])
    if component is None or row['Designator'] in bare:continue
    mismatch={}
    if row.get('JLCPCB Part #') not in component.get('supplier_part_numbers',{}).get('jlcpcb',[]):mismatch['supplier_part_number']={'export':row.get('JLCPCB Part #'),'source':component.get('supplier_part_numbers',{}).get('jlcpcb',[])}
    if not args.baseline:
     mpn=component.get('manufacturer_part_number');value=component.get('display_resistance',component.get('display_capacitance',mpn))
     for field,expected_value in [('Manufacturer Part Number',mpn),('Comment',mpn),('Value',value)]:
      if not expected_value or row.get(field)!=expected_value:mismatch[field]={'export':row.get(field),'source':expected_value}
    if mismatch:errors.append({'ref':row['Designator'],'errors':mismatch})
   table[filename]['source_identity_errors']=errors
   if errors:report['issues'].append({'kind':'BOM-source-identity','errors':errors})
 report['assembly_tables']=table
 placement_errors=[]
 for row in csv.DictReader((directory/'pick_and_place.csv').open()):
  component=next((e for e in pc.values() if src[e['source_component_id']]['name']==row['Designator']),None)
  if component is None:continue
  errs={}
  for field,val in [('Mid X',component['center']['x']),('Mid Y',component['center']['y']),('Rotation',component.get('rotation',0))]:
   if abs(float(row[field])-val)>.00051:errs[field]={'export':float(row[field]),'source':val}
  if row['Layer'].lower()!=component['layer'].lower():errs['layer']=row['Layer']
  if errs:placement_errors.append({'ref':row['Designator'],'errors':errs})
 report['cpl_coordinate_comparison']={'errors':placement_errors,'origin':'board center; mm; unmirrored top coordinates','rotation':'native imported land-pattern orientation plus saved pcb_component rotation; supplier interpretation still needs placement-preview approval','status':'SOURCE CONVENTION CHECK ONLY; supplier pickup datum and rotation remain USER_REVIEW','USB_centers':[{'reference':src[e['source_component_id']]['name'],'CPL_land_pattern_center_mm':e['center'],'rotation_deg':e.get('rotation',0)} for e in pc.values() if src[e['source_component_id']]['name'] in {'J_PD','J_DATA'}],'USB_center_note':'Upright GCT USB4145 uses native land-pattern CPL datum; local CAD anchor correction X +0.1524952 mm aligns the native STEP centre. Manufacturer pickup datum and JLCPCB placement preview remain unverified.'}
 if placement_errors:report['issues'].append({'kind':'CPL-coordinate-mismatch','errors':placement_errors})
 native_holes=[]
 for e in j:
  if e['type'] not in ('pcb_plated_hole','pcb_via','pcb_hole'):continue
  q=dict(e)
  if e['type']=='pcb_hole':q.update(shape=e.get('hole_shape','circle'),width=e.get('hole_diameter',e.get('hole_width')),height=e.get('hole_diameter',e.get('hole_height')))
  elif e['type']=='pcb_via':q.update(shape='circle',width=e['hole_diameter'],height=e['hole_diameter'])
  else:q.update(width=e.get('hole_width',e.get('hole_diameter')),height=e.get('hole_height',e.get('hole_diameter')))
  native_holes.append(shape(q))
 native_drill=unary_union(native_holes);drill_missing=native_drill.difference(holes.buffer(.00055)).area;drill_extra=holes.difference(native_drill.buffer(.00055)).area
 report['drill_source_comparison']={'missing_mm2':drill_missing,'extra_mm2':drill_extra,'tolerance_mm':.00055,'tolerance_reason':'Exporter slot endpoints and CPL rounded to 3 decimal places; 0.55 micrometer envelope','nominal_mounting_holes':4,'nominal_USB_plated_slots':8}
 if drill_missing>1e-4 or drill_extra>1e-4:report['issues'].append({'kind':'drill-source-mismatch',**report['drill_source_comparison']})
 mask_errors=[]
 for e in j:
  if e['type'] not in ('pcb_smtpad','pcb_plated_hole') or e.get('is_covered_with_solder_mask'):continue
  for l in e.get('layers',[e.get('layer','top')]):
   name={'top':'F_Mask','bottom':'B_Mask'}.get(l)
   if not name:continue
   missing=shape(e).difference(geo[name].buffer(.0002)).area
   if missing>1e-4:mask_errors.append({'id':e.get('pcb_smtpad_id',e.get('pcb_plated_hole_id')),'layer':l,'missing_opening_mm2':missing})
 report['mask_opening_comparison']={'errors':mask_errors,'policy':'uncovered fitted/bare solder pads and plated slots remain open; filled/capped thermal via process required'}
 if mask_errors:report['issues'].append({'kind':'mask-opening-mismatch','errors':mask_errors})
 stencil=[]
 for e in j:
  if e['type']!='pcb_smtpad' or e.get('shape')!='rect' or e.get('width',0)<=2 or e.get('height',0)<=2:continue
  ref=src[pc[e['pcb_component_id']]['source_component_id']]['name']
  if ref in {'U_PD','U_MCU','U_DRV'}:stencil.append({'ref':ref,'pad':e['pcb_smtpad_id'],'coverage_fraction':geo.get('F_Paste',Polygon()).intersection(shape(e)).area/shape(e).area})
 aperture_screen=[]
 for paste_layer in ['F_Paste','B_Paste']:
  geometry=geo.get(paste_layer,Polygon())
  aperture_polygons=list(geometry.geoms) if hasattr(geometry,'geoms') else [geometry]
  for polygon in aperture_polygons:
   if polygon.is_empty:continue
   x1,y1,x2,y2=polygon.bounds;aspect=min(x2-x1,y2-y1)/.1;ratio=polygon.area/(polygon.length*.1)
   aperture_screen.append({'layer':paste_layer,'bounds_mm':list(polygon.bounds),'area_mm2':polygon.area,'perimeter_mm':polygon.length,'aspect_ratio_at_100um':aspect,'area_ratio_at_100um':ratio})
 poor=[e for e in aperture_screen if e['aspect_ratio_at_100um']<1.5-1e-4 or e['area_ratio_at_100um']<.66-1e-4]
 report['stencil_release_screen']={'candidate_thickness_mm':.10,'minimum_aspect_ratio':min((e['aspect_ratio_at_100um'] for e in aperture_screen),default=None),'minimum_area_ratio':min((e['area_ratio_at_100um'] for e in aperture_screen),default=None),'screen_limits':{'aspect_ratio':1.5,'area_ratio':.66},'failing_apertures':poor,'scope':'common geometric release screens only; physical paste/stencil/reflow process acceptance still pending'}
 if poor:report['issues'].append({'kind':'stencil-release-screen','apertures':poor})
 report['exposed_pad_stencil']=stencil
 outline=GerberFile.open(directory/'Edge_Cuts.gbr');segments=[]
 for o in outline.objects:
  for primitive_edge in o.to_primitives(unit=MM):
   if type(primitive_edge).__name__!='Line':raise ValueError('Unexpected outline primitive')
   segments.append(LineString([(primitive_edge.x1,primitive_edge.y1),(primitive_edge.x2,primitive_edge.y2)]))
 outlines=list(polygonize(segments));valid_outline=len(outlines)==1 and abs(outlines[0].area-1225)<1e-6 and outlines[0].bounds==(-17.5,-17.5,17.5,17.5)
 report['board_outline']={'bounds_including_stroke':list(geo['Edge_Cuts'].bounds),'centerline_bounds_mm':list(outlines[0].bounds) if outlines else None,'closed_contour_count':len(outlines),'centerline_length_mm':sum(s.length for s in segments),'centerline_area_mm2':outlines[0].area if outlines else None,'valid_35mm_square':valid_outline}
 if not valid_outline:report['issues'].append({'kind':'outline-failure'})
 measured_webs={}
 for name in ['F_Mask','B_Mask']:
  polygons=list(geo[name].geoms) if hasattr(geo[name],'geoms') else [geo[name]];tree=STRtree(polygons);near=[]
  for i,g in enumerate(polygons):
   for other in tree.query(g.buffer(.25)):
    other=int(other)
    if other>i:near.append(g.distance(polygons[other]))
  minimum=min(near) if near else None;measured_webs[name]={'minimum_web_mm':minimum,'opening_polygons':len(polygons),'scope':'nearest distinct mask openings within 0.25 mm'}
  if not args.baseline and minimum is not None and minimum<.09999:report['issues'].append({'kind':'solder-mask-web','layer':name,'minimum_mm':minimum})
 report['mask_webs']=measured_webs
 report['mask']={n:{'area_mm2':geo[n].area,'bounds_mm':list(geo[n].bounds) if not geo[n].is_empty else []} for n in ['F_Mask','B_Mask'] if n in geo};report['plated_annulus_source_min_mm']=min((min(e.get('outer_width',e.get('outer_diameter',0))-e.get('hole_width',e.get('hole_diameter',0)),e.get('outer_height',e.get('outer_diameter',0))-e.get('hole_height',e.get('hole_diameter',0)))/2 for e in j if e['type'] in ('pcb_plated_hole','pcb_via')),default=None)
 clearances={}
 for l,g in actual.items():
  # Mounting-hole clearance is measured to the physical drill boundary.
  mounts=unary_union([Point(e['x'],e['y']).buffer(e['hole_diameter']/2,quad_segs=64) for e in j if e['type']=='pcb_hole' and e.get('hole_diameter')==3.2])
  clearances[l]={'mount_hole_edge_clearance_mm':g.distance(mounts),'board_edge_clearance_mm':g.distance(box(-18,-18,18,18).difference(box(-17.5,-17.5,17.5,17.5)))}
 report['copper_clearances']=clearances
 keepout_checks=[]
 for e in j:
  if e['type']!='pcb_keepout':continue
  if e.get('shape') not in ('circle','rect'):raise ValueError(f"Unsupported keepout shape: {e.get('shape')}")
  region=shape({**e,'x':e['center']['x'],'y':e['center']['y']})
  for layer in e['layers']:
   if layer not in actual:raise ValueError(f"Declared keepout layer missing from actual CAM: {layer}")
   intrusion=actual[layer].intersection(region).area
   tolerated=actual[layer].intersection(region.buffer(-.0002)).area
   check={'keepout_id':e['pcb_keepout_id'],'shape':e['shape'],'center_mm':e['center'],'layer':layer,'clearance_mm':actual[layer].distance(region),'intrusion_area_mm2':intrusion,'intrusion_beyond_0_0002mm_tolerance_mm2':tolerated}
   keepout_checks.append(check)
   if tolerated>1e-5:report['issues'].append({'kind':'actual-copper-keepout-intrusion',**check})
 report['actual_keepout_checks']=keepout_checks
 silk={}
 for n,m in [('F_SilkScreen','F_Mask'),('B_SilkScreen','B_Mask')]:
  silk[n]={'overlap_mask_openings_mm2':geo[n].intersection(geo[m]).area,'inside_0_15mm_mask_guard_mm2':geo[n].intersection(geo[m].buffer(.1499)).area,'outside_board_0_10mm_inset_mm2':geo[n].difference(box(-17.4,-17.4,17.4,17.4)).area}
  if not args.baseline and (silk[n]['inside_0_15mm_mask_guard_mm2']>1e-5 or silk[n]['outside_board_0_10mm_inset_mm2']>1e-5):report['issues'].append({'kind':'silkscreen-clearance','layer':n,**silk[n]})
 report['silkscreen_clearances']=silk
 if not args.baseline:
  for pane in stencil:
   if abs(pane['coverage_fraction']-.60)>.001:report['issues'].append({'kind':'EP-stencil-coverage',**pane})
  unowned=[e['pcb_solder_paste_id'] for e in j if e['type']=='pcb_solder_paste' and e.get('pcb_component_id') not in pc]
  if unowned:report['issues'].append({'kind':'unowned-source-paste','paste_ids':unowned,'reason':'No component ownership is present in saved source; apertures remain included in full CAM comparison.'})
  comparisons={}
  for source_layer,cam_layer in [('top','F_Paste'),('bottom','B_Paste')]:
   explicit_paste=unary_union([shape(e) for e in j if e['type']=='pcb_solder_paste' and e['layer']==source_layer and (e.get('pcb_component_id') not in pc or src[pc[e['pcb_component_id']]['source_component_id']]['name'] not in bare)])
   actual_paste=geo.get(cam_layer,Polygon())
   comparisons[cam_layer]={'missing_mm2':explicit_paste.difference(actual_paste.buffer(.0002)).area,'extra_mm2':actual_paste.difference(explicit_paste.buffer(.0002)).area}
   if any(v>1e-4 for v in comparisons[cam_layer].values()):report['issues'].append({'kind':'paste-source-mismatch','layer':cam_layer,**comparisons[cam_layer]})
  report['paste_source_comparison']=comparisons
 if (root/args.source).read_bytes()!=source_bytes:raise ValueError('Frozen source changed during independent CAM audit; regenerate and repeat')
 report['status']='FAIL' if report['issues'] else 'PASS';out=directory/'audit.json';out.write_text(json.dumps(report,indent=2,allow_nan=False)+'\n');print(json.dumps({'status':report['status'],'issues':report['issues'],'connectivity':{k:report['connectivity'][k] for k in ['named_nets_checked','actual_copper_islands','unassigned_islands']},'report':str(out)},indent=2));return 0 if args.baseline else bool(report['issues'])
if __name__=='__main__':raise SystemExit(main())
,token.strip()):angles.append(rot)\n with warnings.catch_warnings(record=True) as ws:\n warnings.simplefilter('always');g=GerberFile.open(path)\n unknown=[str(w.message) for w in ws if not re.search(r'Unknown statement found: \\\"LR[+\\-\\d.]+\\\"',str(w.message))]\n if unknown:raise ValueError(f'{path.name} parser warnings: {unknown}')\n flashes=[o for o in g.objects if isinstance(o,Flash)]\n if len(flashes)!=len(angles):raise ValueError(f'Flash correspondence failure {path.name}: {len(flashes)} / {len(angles)}')\n for o,a in zip(flashes,angles):\n if a%360 not in (0,90,180,270):raise ValueError(f'Rotation {a} requires independently validated analytic support')\n if a%360:o.aperture=o.aperture.rotated(math.radians(a))\n result=Polygon();batch=[];last=True\n for o in g.objects:\n for p in o.to_primitives(unit=MM):\n dark=p.polarity_dark\n if dark!=last and batch:\n u=unary_union(batch);result=result.union(u) if last else result.difference(u);batch=[]\n batch.append(primitive(p));last=dark\n if batch:\n u=unary_union(batch);result=result.union(u) if last else result.difference(u)\n return result,len(g.objects),{'LR_applied':sum(bool(a%360) for a in angles),'warnings':unknown}\ndef drill(path):\n raw=path.read_text();lines=raw.splitlines();out=[];joined=0\n for l in lines:\n if l.startswith('G85'):\n if not out or not re.fullmatch(r'X[-+\\d.]+Y[-+\\d.]+',out[-1]):raise ValueError('Ambiguous G85 start')\n start=out.pop();out.extend(['G00'+start,'M15','G01'+l[3:],'M16','G05']);joined+=1;continue\n out.append(l)\n with warnings.catch_warnings(record=True) as ws:\n warnings.simplefilter('always');d=ExcellonFile.from_string('\\n'.join(out)+'\\n')\n unhandled=[str(w.message) for w in ws if 'G90 header statement found after end of header' not in str(w.message)]\n if unhandled:raise ValueError(f'{path.name} drill warnings: {unhandled}')\n gs=[primitive(p) for o in d.objects for p in o.to_primitives(unit=MM)]\n return unary_union(gs),gs,{'objects':len(d.objects),'G85_joined':joined,'parser_notices':[str(w.message) for w in ws],'tools_mm':dict(Counter(round(o.tool.diameter,6) for o in d.objects))}\ndef expected(j):\n layers=defaultdict(list)\n for e in j:\n typ=e['type']\n if typ in ('pcb_smtpad','pcb_plated_hole','pcb_via'):\n for l in e.get('layers',[e.get('layer','top')]):layers[l].append(shape(e))\n elif typ=='pcb_trace':\n for a,b in zip(e['route'],e['route'][1:]):\n if a['route_type']==b['route_type']=='wire' and a['layer']==b['layer']:layers[a['layer']].append(LineString([(a['x'],a['y']),(b['x'],b['y'])]).buffer(max(a['width'],b['width'])/2,quad_segs=64))\n elif typ=='pcb_copper_pour':\n q=e['brep_shape'];coords=lambda r:[(p['x'],p['y']) for p in r['vertices']];layers[e['layer']].append(Polygon(coords(q['outer_ring']),[coords(r) for r in q.get('inner_rings',[])]).buffer(0))\n return {k:unary_union(v) for k,v in layers.items()}\ndef main():\n ap=argparse.ArgumentParser();ap.add_argument('--directory',default='artifacts/manufacturing');ap.add_argument('--source',default='artifacts/board.circuit.json');ap.add_argument('--archive',help='Actual archive to compare byte-for-byte against parsed extracted files');ap.add_argument('--baseline',action='store_true');ap.add_argument('--render',action='store_true');args=ap.parse_args();root=pathlib.Path(__file__).resolve().parents[1];directory=root/args.directory;source_bytes=(root/args.source).read_bytes();j=json.loads(source_bytes);report={'source_sha256':hashlib.sha256(source_bytes).hexdigest(),'directory':args.directory,'parser_versions':{'gerbonara':'1.5.0','pygerber':'2.4.3','shapely':__import__('shapely').__version__},'parser_compatibility':'Only LR right-angle aperture transforms and unambiguous split-line G85 slots are converted to equivalent G00/M15/G01/M16/G05 routing analytically. Original Gerbers independently rendered by PyGerber. Input CAM bytes remain unchanged.','files':{},'issues':[]}\n archive=root/args.archive if args.archive else (root/'artifacts/nema14-gerbers.zip' if args.directory=='artifacts/manufacturing' else directory/'original-export.zip')\n if not archive.exists():raise ValueError(f'Actual archive missing: {archive}')\n archive_records={}\n with zipfile.ZipFile(archive) as z:\n seen=set()\n for member in z.namelist():\n if member.endswith('/'):continue\n name=pathlib.Path(member).name\n if name in seen:raise ValueError(f'Duplicate archive member {name}')\n seen.add(name);data=z.read(member);path=directory/name\n if not path.exists() or path.read_bytes()!=data:raise ValueError(f'Actual archive/extracted byte mismatch: {name}')\n archive_records[name]=hashlib.sha256(data).hexdigest()\n loose_cam={p.name for p in directory.iterdir() if p.suffix in ['.gbr','.drl','.csv']}\n if loose_cam-set(archive_records):raise ValueError(f'Parsed CAM files absent from actual archive: {sorted(loose_cam-set(archive_records))}')\n report['archive']={'path':str(archive),'sha256':hashlib.sha256(archive.read_bytes()).hexdigest(),'extracted_bytes_verified':True,'members':archive_records}\n geo={}\n for p in sorted(directory.glob('*.gbr')):\n geometry,count,compat=gerber(p);geo[p.stem]=geometry;report['files'][p.name]={'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'objects':count,'area_mm2':geometry.area,'bounds_mm':list(geometry.bounds) if not geometry.is_empty else [],**compat}\n if args.render and p.stem.endswith('_Cu'):\n out=directory/'independent-render';out.mkdir(exist_ok=True);v2.GerberFile.from_file(p).parse(on_parser_error=v2.OnParserErrorEnum.Raise).render_raster(out/(p.stem+'.png'),dpmm=80,color_scheme=v2.ColorScheme.SILK)\n drills=[];all_drill=[]\n for p in sorted(directory.glob('*.drl')):\n g,parts,stats=drill(p);report['files'][p.name]={'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),**stats};all_drill.extend(parts)\n if 'npth' not in p.name:drills.extend(parts)\n holes=unary_union(all_drill);expected_layers=expected(j);layer_names={'top':'F_Cu','bottom':'B_Cu','inner1':'In1_Cu','inner2':'In2_Cu'};actual={};delta={}\n for layer,name in layer_names.items():\n if name not in geo:continue\n a=geo[name].difference(holes);b=expected_layers.get(layer,Polygon()).difference(holes);actual[layer]=a\n missing=b.difference(a.buffer(.0002));extra=a.difference(b.buffer(.0002));delta[layer]={'missing_mm2':missing.area,'extra_mm2':extra.area,'tolerance_mm':.0002}\n if missing.area\u003e1e-4 or extra.area\u003e1e-4:report['issues'].append({'kind':'copper-source-mismatch','layer':layer,**delta[layer]})\n report['copper_comparison']=delta\n # Each connected polygon in the actual copper is an electrical island. Bridge\n # its layers only at drilled plated barrels. Assign names from native pads.\n nodes=[];trees={};indices={}\n for l,g in actual.items():\n ps=list(g.geoms) if hasattr(g,'geoms') else [g];ps=[p for p in ps if p.area\u003e1e-9];indices[l]=list(range(len(nodes),len(nodes)+len(ps)));nodes.extend(ps);trees[l]=STRtree(ps)\n parent=list(range(len(nodes)))\n def find(i):\n while parent[i]!=i:parent[i]=parent[parent[i]];i=parent[i]\n return i\n def union(ids):\n if ids:\n r=find(ids[0])\n for i in ids[1:]:parent[find(i)]=r\n def hits(l,g):return [indices[l][int(i)] for i in trees[l].query(g,predicate='intersects') if nodes[indices[l][int(i)]].intersection(g).area\u003e1e-8]\n for d in drills:\n ann=d.buffer(.03).difference(d.buffer(-.0001));union([i for l in actual for i in hits(l,ann)])\n src={e['source_component_id']:e for e in j if e['type']=='source_component'};pc={e['pcb_component_id']:e for e in j if e['type']=='pcb_component'};sp={e['source_port_id']:e for e in j if e['type']=='source_port'};pp={e['pcb_port_id']:e for e in j if e['type']=='pcb_port'};netnames={e['subcircuit_connectivity_map_key']:e['name'] for e in j if e['type']=='source_net'};assign=defaultdict(lambda:defaultdict(list));netroots=defaultdict(lambda:defaultdict(list));unconnected=[]\n for e in j:\n if e['type'] not in ('pcb_smtpad','pcb_plated_hole') or not e.get('pcb_port_id'):continue\n port=pp[e['pcb_port_id']];s=sp[port['source_port_id']];key=s.get('subcircuit_connectivity_map_key')\n if not key:continue\n ref=src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'];ids=[i for l in e.get('layers',[e.get('layer','top')]) if l in actual for i in hits(l,shape(e).difference(holes))]\n if not ids:unconnected.append(ref)\n for r in {find(i) for i in ids}:assign[r][key].append(ref);netroots[key][r].append(ref)\n shorts=[{'nets':[netnames.get(k,k) for k in v],'pads':dict(v)} for v in assign.values() if len(v)\u003e1];opens=[{'net':netnames.get(k,k),'islands':list(v.values())} for k,v in netroots.items() if len(v)\u003e1];report['connectivity']={'named_nets_checked':len(netroots),'shorts':shorts,'opens':opens,'unconnected_pads':unconnected,'actual_copper_islands':len(nodes),'unassigned_islands':len({find(i) for i in range(len(nodes))}-set(assign))}\n nc_contacts=[]\n for e in j:\n if e['type']!='pcb_smtpad' or not e.get('pcb_port_id'):continue\n port=pp[e['pcb_port_id']];s=sp[port['source_port_id']]\n if s.get('subcircuit_connectivity_map_key'):continue\n for r in {find(i) for i in hits(e['layer'],shape(e))}:\n if r in assign:nc_contacts.append({'pad':src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'],'nets':[netnames.get(k,k) for k in assign[r]]})\n report['connectivity']['no_connect_contacts']=nc_contacts\n if nc_contacts:report['issues'].append({'kind':'no-connect-pad-contact','contacts':nc_contacts})\n # Classify copper islands without named connected pads; expected NC pads\n # must not be mislabeled as floating routed copper.\n isolated=[]\n for r in {find(i) for i in range(len(nodes))}-set(assign):\n geometry=unary_union([nodes[i] for i in range(len(nodes)) if find(i)==r]);nc=[]\n for e in j:\n if e['type']!='pcb_smtpad' or not e.get('pcb_port_id'):continue\n port=pp[e['pcb_port_id']];s=sp[port['source_port_id']]\n if s.get('subcircuit_connectivity_map_key'):continue\n if e['layer'] in actual and r in {find(i) for i in hits(e['layer'],shape(e))}:nc.append(src[pc[e['pcb_component_id']]['source_component_id']]['name']+'.'+s['name'])\n isolated.append({'area_mm2':geometry.area,'bounds_mm':list(geometry.bounds) if not geometry.is_empty else [],'layers':[l for l in indices if any(find(i)==r for i in indices[l])],'no_connect_pads':nc,'classification':'intentional native no-connect pad' if nc else 'unassigned copper: review'})\n report['connectivity']['unassigned_island_details']=isolated\n # Spacing is measured on the independently parsed, finished copper, not on\n # centerlines or bounding rectangles. Same physical barrel-connected nets\n # are exempt; native NC islands remain separate conductors for this screen.\n copper_spacing={}\n for layer,ids in indices.items():\n near=[]\n for local,i in enumerate(ids):\n for other in trees[layer].query(nodes[i].buffer(.5)):\n other=int(other)\n if other\u003c=local:continue\n k=ids[other];ri,rk=find(i),find(k)\n if ri==rk:continue\n ai=set(assign.get(ri,{}));ak=set(assign.get(rk,{}))\n if ai and ai==ak:continue\n distance=nodes[i].distance(nodes[k])\n near.append({'clearance_mm':distance,'conductors':[[netnames.get(n,n) for n in assign.get(r,{})] or ['native NC/unassigned island'] for r in (ri,rk)],'island_indices':[i,k]})\n near.sort(key=lambda e:e['clearance_mm'])\n copper_spacing[layer]={'minimum_distinct_conductor_clearance_mm':near[0]['clearance_mm'] if near else None,'closest_pairs':near[:5],'screen_minimum_mm':.15,'geometry_tolerance_mm':.0002,'scope':'actual finished copper edges; pairs within 0.50 mm; same electrical net excluded'}\n failures=[p for p in near if p['clearance_mm']\u003c.1498]\n if failures:report['issues'].append({'kind':'actual-copper-clearance','layer':layer,'pairs':failures})\n report['actual_copper_spacing']=copper_spacing\n unresolved=[i for i in isolated if not i['no_connect_pads'] and i['area_mm2']\u003e1e-5]\n if unresolved:report['issues'].append({'kind':'unassigned-copper-islands','islands':unresolved})\n if shorts or opens or unconnected:report['issues'].append({'kind':'physical-netlist-failure','short_count':len(shorts),'open_count':len(opens),'unconnected_pads':unconnected})\n bare={s['name'] for s in src.values() if s['ftype']=='simple_test_point'} | {src[p['source_component_id']]['name'] for p in pc.values() if p.get('do_not_place')};bare_pc={p['pcb_component_id'] for p in pc.values() if src[p['source_component_id']]['name'] in bare};bare_pads=unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['pcb_component_id'] in bare_pc]);paste={};pth=unary_union([shape(e) for e in j if e['type']=='pcb_plated_hole'])\n for l in ['F_Paste','B_Paste']:\n bare_pads=unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['pcb_component_id'] in bare_pc and e['layer']==('top' if l=='F_Paste' else 'bottom')])\n g=geo.get(l,Polygon());paste[l]={'bare_interface_overlap_mm2':g.intersection(bare_pads).area,'manual_plated_joint_overlap_mm2':g.intersection(pth).area,'outside_smt_copper_mm2':g.difference(unary_union([shape(e) for e in j if e['type']=='pcb_smtpad' and e['layer']==('top' if l=='F_Paste' else 'bottom')]).buffer(.0002)).area}\n if g.intersection(bare_pads).area\u003e1e-6 or g.intersection(pth).area\u003e1e-6 or paste[l]['outside_smt_copper_mm2']\u003e1e-6:report['issues'].append({'kind':'assembly-paste-policy','layer':l,**paste[l]})\n report['paste']=paste;table={}\n for filename in ['bom.csv','pick_and_place.csv']:\n rows=list(csv.DictReader((directory/filename).open()));refs={r['Designator'] for r in rows};fit={s['name'] for s in src.values() if s['name'] not in bare};table[filename]={'rows':len(rows),'bare_rows':sorted(refs\u0026bare),'missing_fitted':sorted(fit-refs),'unexpected':sorted(refs-fit-bare)}\n duplicates=sorted(ref for ref,count in Counter(r['Designator'] for r in rows).items() if count\u003e1)\n table[filename]['duplicate_refs']=duplicates\n if refs\u0026bare or fit-refs or refs-fit-bare or duplicates:report['issues'].append({'kind':'assembly-table-policy','table':filename,**table[filename]})\n if filename=='bom.csv':\n errors=[]\n byref={e['name']:e for e in src.values()}\n for row in rows:\n component=byref.get(row['Designator'])\n if component is None or row['Designator'] in bare:continue\n mismatch={}\n if row.get('JLCPCB Part #') not in component.get('supplier_part_numbers',{}).get('jlcpcb',[]):mismatch['supplier_part_number']={'export':row.get('JLCPCB Part #'),'source':component.get('supplier_part_numbers',{}).get('jlcpcb',[])}\n if not args.baseline:\n mpn=component.get('manufacturer_part_number');value=component.get('display_resistance',component.get('display_capacitance',mpn))\n for field,expected_value in [('Manufacturer Part Number',mpn),('Comment',mpn),('Value',value)]:\n if not expected_value or row.get(field)!=expected_value:mismatch[field]={'export':row.get(field),'source':expected_value}\n if mismatch:errors.append({'ref':row['Designator'],'errors':mismatch})\n table[filename]['source_identity_errors']=errors\n if errors:report['issues'].append({'kind':'BOM-source-identity','errors':errors})\n report['assembly_tables']=table\n placement_errors=[]\n for row in csv.DictReader((directory/'pick_and_place.csv').open()):\n component=next((e for e in pc.values() if src[e['source_component_id']]['name']==row['Designator']),None)\n if component is None:continue\n errs={}\n for field,val in [('Mid X',component['center']['x']),('Mid Y',component['center']['y']),('Rotation',component.get('rotation',0))]:\n if abs(float(row[field])-val)\u003e.00051:errs[field]={'export':float(row[field]),'source':val}\n if row['Layer'].lower()!=component['layer'].lower():errs['layer']=row['Layer']\n if errs:placement_errors.append({'ref':row['Designator'],'errors':errs})\n report['cpl_coordinate_comparison']={'errors':placement_errors,'origin':'board center; mm; unmirrored top coordinates','rotation':'native imported land-pattern orientation plus saved pcb_component rotation; supplier interpretation still needs placement-preview approval','status':'SOURCE CONVENTION CHECK ONLY; supplier pickup datum and rotation remain USER_REVIEW','USB_centers':[{'reference':src[e['source_component_id']]['name'],'CPL_land_pattern_center_mm':e['center'],'rotation_deg':e.get('rotation',0)} for e in pc.values() if src[e['source_component_id']]['name'] in {'J_PD','J_DATA'}],'USB_center_note':'Upright GCT USB4145 uses native land-pattern CPL datum; local CAD anchor correction X +0.1524952 mm aligns the native STEP centre. Manufacturer pickup datum and JLCPCB placement preview remain unverified.'}\n if placement_errors:report['issues'].append({'kind':'CPL-coordinate-mismatch','errors':placement_errors})\n native_holes=[]\n for e in j:\n if e['type'] not in ('pcb_plated_hole','pcb_via','pcb_hole'):continue\n q=dict(e)\n if e['type']=='pcb_hole':q.update(shape=e.get('hole_shape','circle'),width=e.get('hole_diameter',e.get('hole_width')),height=e.get('hole_diameter',e.get('hole_height')))\n elif e['type']=='pcb_via':q.update(shape='circle',width=e['hole_diameter'],height=e['hole_diameter'])\n else:q.update(width=e.get('hole_width',e.get('hole_diameter')),height=e.get('hole_height',e.get('hole_diameter')))\n native_holes.append(shape(q))\n native_drill=unary_union(native_holes);drill_missing=native_drill.difference(holes.buffer(.00055)).area;drill_extra=holes.difference(native_drill.buffer(.00055)).area\n report['drill_source_comparison']={'missing_mm2':drill_missing,'extra_mm2':drill_extra,'tolerance_mm':.00055,'tolerance_reason':'Exporter slot endpoints and CPL rounded to 3 decimal places; 0.55 micrometer envelope','nominal_mounting_holes':4,'nominal_USB_plated_slots':8}\n if drill_missing\u003e1e-4 or drill_extra\u003e1e-4:report['issues'].append({'kind':'drill-source-mismatch',**report['drill_source_comparison']})\n mask_errors=[]\n for e in j:\n if e['type'] not in ('pcb_smtpad','pcb_plated_hole') or e.get('is_covered_with_solder_mask'):continue\n for l in e.get('layers',[e.get('layer','top')]):\n name={'top':'F_Mask','bottom':'B_Mask'}.get(l)\n if not name:continue\n missing=shape(e).difference(geo[name].buffer(.0002)).area\n if missing\u003e1e-4:mask_errors.append({'id':e.get('pcb_smtpad_id',e.get('pcb_plated_hole_id')),'layer':l,'missing_opening_mm2':missing})\n report['mask_opening_comparison']={'errors':mask_errors,'policy':'uncovered fitted/bare solder pads and plated slots remain open; filled/capped thermal via process required'}\n if mask_errors:report['issues'].append({'kind':'mask-opening-mismatch','errors':mask_errors})\n stencil=[]\n for e in j:\n if e['type']!='pcb_smtpad' or e.get('shape')!='rect' or e.get('width',0)\u003c=2 or e.get('height',0)\u003c=2:continue\n ref=src[pc[e['pcb_component_id']]['source_component_id']]['name']\n if ref in {'U_PD','U_MCU','U_DRV'}:stencil.append({'ref':ref,'pad':e['pcb_smtpad_id'],'coverage_fraction':geo.get('F_Paste',Polygon()).intersection(shape(e)).area/shape(e).area})\n aperture_screen=[]\n for paste_layer in ['F_Paste','B_Paste']:\n geometry=geo.get(paste_layer,Polygon())\n aperture_polygons=list(geometry.geoms) if hasattr(geometry,'geoms') else [geometry]\n for polygon in aperture_polygons:\n if polygon.is_empty:continue\n x1,y1,x2,y2=polygon.bounds;aspect=min(x2-x1,y2-y1)/.1;ratio=polygon.area/(polygon.length*.1)\n aperture_screen.append({'layer':paste_layer,'bounds_mm':list(polygon.bounds),'area_mm2':polygon.area,'perimeter_mm':polygon.length,'aspect_ratio_at_100um':aspect,'area_ratio_at_100um':ratio})\n poor=[e for e in aperture_screen if e['aspect_ratio_at_100um']\u003c1.5-1e-4 or e['area_ratio_at_100um']\u003c.66-1e-4]\n report['stencil_release_screen']={'candidate_thickness_mm':.10,'minimum_aspect_ratio':min((e['aspect_ratio_at_100um'] for e in aperture_screen),default=None),'minimum_area_ratio':min((e['area_ratio_at_100um'] for e in aperture_screen),default=None),'screen_limits':{'aspect_ratio':1.5,'area_ratio':.66},'failing_apertures':poor,'scope':'common geometric release screens only; physical paste/stencil/reflow process acceptance still pending'}\n if poor:report['issues'].append({'kind':'stencil-release-screen','apertures':poor})\n report['exposed_pad_stencil']=stencil\n outline=GerberFile.open(directory/'Edge_Cuts.gbr');segments=[]\n for o in outline.objects:\n for primitive_edge in o.to_primitives(unit=MM):\n if type(primitive_edge).__name__!='Line':raise ValueError('Unexpected outline primitive')\n segments.append(LineString([(primitive_edge.x1,primitive_edge.y1),(primitive_edge.x2,primitive_edge.y2)]))\n outlines=list(polygonize(segments));valid_outline=len(outlines)==1 and abs(outlines[0].area-1225)\u003c1e-6 and outlines[0].bounds==(-17.5,-17.5,17.5,17.5)\n report['board_outline']={'bounds_including_stroke':list(geo['Edge_Cuts'].bounds),'centerline_bounds_mm':list(outlines[0].bounds) if outlines else None,'closed_contour_count':len(outlines),'centerline_length_mm':sum(s.length for s in segments),'centerline_area_mm2':outlines[0].area if outlines else None,'valid_35mm_square':valid_outline}\n if not valid_outline:report['issues'].append({'kind':'outline-failure'})\n measured_webs={}\n for name in ['F_Mask','B_Mask']:\n polygons=list(geo[name].geoms) if hasattr(geo[name],'geoms') else [geo[name]];tree=STRtree(polygons);near=[]\n for i,g in enumerate(polygons):\n for other in tree.query(g.buffer(.25)):\n other=int(other)\n if other\u003ei:near.append(g.distance(polygons[other]))\n minimum=min(near) if near else None;measured_webs[name]={'minimum_web_mm':minimum,'opening_polygons':len(polygons),'scope':'nearest distinct mask openings within 0.25 mm'}\n if not args.baseline and minimum is not None and minimum\u003c.09999:report['issues'].append({'kind':'solder-mask-web','layer':name,'minimum_mm':minimum})\n report['mask_webs']=measured_webs\n report['mask']={n:{'area_mm2':geo[n].area,'bounds_mm':list(geo[n].bounds) if not geo[n].is_empty else []} for n in ['F_Mask','B_Mask'] if n in geo};report['plated_annulus_source_min_mm']=min((min(e.get('outer_width',e.get('outer_diameter',0))-e.get('hole_width',e.get('hole_diameter',0)),e.get('outer_height',e.get('outer_diameter',0))-e.get('hole_height',e.get('hole_diameter',0)))/2 for e in j if e['type'] in ('pcb_plated_hole','pcb_via')),default=None)\n clearances={}\n for l,g in actual.items():\n # Mounting-hole clearance is measured to the physical drill boundary.\n mounts=unary_union([Point(e['x'],e['y']).buffer(e['hole_diameter']/2,quad_segs=64) for e in j if e['type']=='pcb_hole' and e.get('hole_diameter')==3.2])\n clearances[l]={'mount_hole_edge_clearance_mm':g.distance(mounts),'board_edge_clearance_mm':g.distance(box(-18,-18,18,18).difference(box(-17.5,-17.5,17.5,17.5)))}\n report['copper_clearances']=clearances\n keepout_checks=[]\n for e in j:\n if e['type']!='pcb_keepout':continue\n if e.get('shape') not in ('circle','rect'):raise ValueError(f\"Unsupported keepout shape: {e.get('shape')}\")\n region=shape({**e,'x':e['center']['x'],'y':e['center']['y']})\n for layer in e['layers']:\n if layer not in actual:raise ValueError(f\"Declared keepout layer missing from actual CAM: {layer}\")\n intrusion=actual[layer].intersection(region).area\n tolerated=actual[layer].intersection(region.buffer(-.0002)).area\n check={'keepout_id':e['pcb_keepout_id'],'shape':e['shape'],'center_mm':e['center'],'layer':layer,'clearance_mm':actual[layer].distance(region),'intrusion_area_mm2':intrusion,'intrusion_beyond_0_0002mm_tolerance_mm2':tolerated}\n keepout_checks.append(check)\n if tolerated\u003e1e-5:report['issues'].append({'kind':'actual-copper-keepout-intrusion',**check})\n report['actual_keepout_checks']=keepout_checks\n silk={}\n for n,m in [('F_SilkScreen','F_Mask'),('B_SilkScreen','B_Mask')]:\n silk[n]={'overlap_mask_openings_mm2':geo[n].intersection(geo[m]).area,'inside_0_15mm_mask_guard_mm2':geo[n].intersection(geo[m].buffer(.1499)).area,'outside_board_0_10mm_inset_mm2':geo[n].difference(box(-17.4,-17.4,17.4,17.4)).area}\n if not args.baseline and (silk[n]['inside_0_15mm_mask_guard_mm2']\u003e1e-5 or silk[n]['outside_board_0_10mm_inset_mm2']\u003e1e-5):report['issues'].append({'kind':'silkscreen-clearance','layer':n,**silk[n]})\n report['silkscreen_clearances']=silk\n if not args.baseline:\n for pane in stencil:\n if abs(pane['coverage_fraction']-.60)\u003e.001:report['issues'].append({'kind':'EP-stencil-coverage',**pane})\n unowned=[e['pcb_solder_paste_id'] for e in j if e['type']=='pcb_solder_paste' and e.get('pcb_component_id') not in pc]\n if unowned:report['issues'].append({'kind':'unowned-source-paste','paste_ids':unowned,'reason':'No component ownership is present in saved source; apertures remain included in full CAM comparison.'})\n comparisons={}\n for source_layer,cam_layer in [('top','F_Paste'),('bottom','B_Paste')]:\n explicit_paste=unary_union([shape(e) for e in j if e['type']=='pcb_solder_paste' and e['layer']==source_layer and (e.get('pcb_component_id') not in pc or src[pc[e['pcb_component_id']]['source_component_id']]['name'] not in bare)])\n actual_paste=geo.get(cam_layer,Polygon())\n comparisons[cam_layer]={'missing_mm2':explicit_paste.difference(actual_paste.buffer(.0002)).area,'extra_mm2':actual_paste.difference(explicit_paste.buffer(.0002)).area}\n if any(v\u003e1e-4 for v in comparisons[cam_layer].values()):report['issues'].append({'kind':'paste-source-mismatch','layer':cam_layer,**comparisons[cam_layer]})\n report['paste_source_comparison']=comparisons\n if (root/args.source).read_bytes()!=source_bytes:raise ValueError('Frozen source changed during independent CAM audit; regenerate and repeat')\n report['status']='FAIL' if report['issues'] else 'PASS';out=directory/'audit.json';out.write_text(json.dumps(report,indent=2,allow_nan=False)+'\\n');print(json.dumps({'status':report['status'],'issues':report['issues'],'connectivity':{k:report['connectivity'][k] for k in ['named_nets_checked','actual_copper_islands','unassigned_islands']},'report':str(out)},indent=2));return 0 if args.baseline else bool(report['issues'])\nif __name__=='__main__':raise SystemExit(main())\n","content_mimetype":"application/octet-stream","created_at":"2026-10-16T18:38:27.354Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"37e98b52-0b1d-4f91-8f06-8e5e321f5e45","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.12.2","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-16T18:34:09.247Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a234ce80dacb6ff214fc7c28c619fd53","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=37e98b52-0b1d-4f91-8f06-8e5e321f5e45\u0026file_path=dist%2Fassembly%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=37e98b52-0b1d-4f91-8f06-8e5e321f5e45\u0026file_path=dist%2Fassembly%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=37e98b52-0b1d-4f91-8f06-8e5e321f5e45\u0026file_path=dist%2Fassembly%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"77e1bbb0-f396-4288-91fe-37df764769c5","user_code_job_started_at":"2026-10-16T18:41:51.869Z","user_code_job_completed_at":"2026-10-16T19:03:14.960Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=b4d82ed09ecf2145ebf5367144ee5c949590a6ac3bcdaf14ccf32ab1d1ac0116","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"72324e94-d02f-46eb-b9c7-178503c804e7","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.12.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-15T20:09:52.954Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-e000137c4ac77f268f6c0562bf53f164","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72324e94-d02f-46eb-b9c7-178503c804e7\u0026file_path=dist%2Fassembly%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72324e94-d02f-46eb-b9c7-178503c804e7\u0026file_path=dist%2Fassembly%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72324e94-d02f-46eb-b9c7-178503c804e7\u0026file_path=dist%2Fassembly%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"078956f9-425b-4b10-9e6d-5a740e82b3a3","user_code_job_started_at":"2026-10-15T20:25:40.668Z","user_code_job_completed_at":"2026-10-15T20:38:06.241Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=12573a943f9397e50996b1bccd80890dc1be81bb6f1212a8201b6651530902ca","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"d2289b5f-055b-4f8e-8006-3f73509e1e4c","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.12.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-15T00:39:27.918Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-84611c750372845560ac2f9fdecdce28","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"0b670ed4-6879-4a0c-8747-53aa756b69b5","user_code_job_started_at":"2026-10-15T00:45:25.661Z","user_code_job_completed_at":"2026-10-15T01:15:33.807Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=ce0e9bf7adedcf7ddfb28c9b9a29aa62122ab3b80473c25ffc68f7bda0c484ce","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6ec63093-0f87-47f7-acc2-35835d09ecce","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.11.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-14T23:28:04.585Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-00bc5d36969659cf88d403c90bd6cbed","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6ec63093-0f87-47f7-acc2-35835d09ecce\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6ec63093-0f87-47f7-acc2-35835d09ecce\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6ec63093-0f87-47f7-acc2-35835d09ecce\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"022c14b3-831b-4f43-960d-d7a758b6e1e4","user_code_job_started_at":"2026-10-14T23:29:37.626Z","user_code_job_completed_at":"2026-10-14T23:39:00.990Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=c071518daed4d4b3642d275adc20ec40263c27b633777e4dde329e474dc38c3b","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b27af104-a452-4037-a9a4-dd015dabfcfc","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.11.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-10-14T23:24:04.657Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-678a35b926bfdafc913d38a47aeb82b6","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1521c528-ed34-4b95-9fe1-185e0a6bbe8a","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.11.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-14T18:25:45.981Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-9831935f17b7550883f201536e502417","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b6652bf1-1241-43c8-af2d-459954b50d04","user_code_job_started_at":"2026-10-14T18:29:51.172Z","user_code_job_completed_at":"2026-10-14T18:33:24.908Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=3efba8de65c39b4ef5985be7eb28759e10fa98be35a31e1618564b3b38ff1f41","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"51d83a2e-8891-4717-a20e-007bb3aabec7","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.10.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-14T05:35:46.173Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c10ceb2f662aae8664cf837728d7a747","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=51d83a2e-8891-4717-a20e-007bb3aabec7\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=51d83a2e-8891-4717-a20e-007bb3aabec7\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=51d83a2e-8891-4717-a20e-007bb3aabec7\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"084c9b13-f3be-43d6-b35d-e1cf290b51c6","user_code_job_started_at":"2026-10-14T05:41:09.764Z","user_code_job_completed_at":"2026-10-14T05:50:46.254Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=efdf7d12aa6f8332f1aedbf9221af7aef6940790a655f69ade1325de13478f94","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"f9bbc494-95d6-4fab-a098-022bff916049","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.10.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-14T04:44:10.233Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-bb5458e3a025963c5559c98aaac625ff","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f9bbc494-95d6-4fab-a098-022bff916049\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f9bbc494-95d6-4fab-a098-022bff916049\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f9bbc494-95d6-4fab-a098-022bff916049\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"74a822b3-75ab-4d04-9cac-0b01eb962811","user_code_job_started_at":"2026-10-14T04:47:15.435Z","user_code_job_completed_at":"2026-10-14T04:57:33.466Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=8f6c78f921469463eb71f97ed604229f242c60162ef7968a88cbc0b3b8baca02","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"f24fa34f-f33f-45b3-b0fd-5c1dd076bdfc","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.10.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-14T03:25:52.440Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a265f7ab43928dc98b847de48a71a802","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f24fa34f-f33f-45b3-b0fd-5c1dd076bdfc\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f24fa34f-f33f-45b3-b0fd-5c1dd076bdfc\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f24fa34f-f33f-45b3-b0fd-5c1dd076bdfc\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"fe2477b7-8943-4617-b3d8-d097c3b1754e","user_code_job_started_at":"2026-10-14T03:31:31.760Z","user_code_job_completed_at":"2026-10-14T03:40:50.617Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=fa151878be60b0a5510816a312014bf73c07561840ef9be3901c449cd4824468","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"3909c193-43b1-4db7-9a2d-3a855bc8484e","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.9.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T18:40:48.329Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-282ab02da5be4cdfe498ece838d17845","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3909c193-43b1-4db7-9a2d-3a855bc8484e\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3909c193-43b1-4db7-9a2d-3a855bc8484e\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3909c193-43b1-4db7-9a2d-3a855bc8484e\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"8d09edd7-75a6-4874-820e-99ad40b38af1","user_code_job_started_at":"2026-10-13T18:44:05.309Z","user_code_job_completed_at":"2026-10-13T18:54:32.741Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=d68c8da0089678e41a16c99d1e26cb3d94cd5a20f3d4ab0740b877583a4e4e86","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"3b5950f7-ebcd-4a14-8855-44161705fd9c","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.8.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T12:48:53.363Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-7e6302b1acadd1f6603c5052a3c619cb","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b5950f7-ebcd-4a14-8855-44161705fd9c\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b5950f7-ebcd-4a14-8855-44161705fd9c\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b5950f7-ebcd-4a14-8855-44161705fd9c\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"e2b38c1f-a2a9-48ef-ba1a-81552102c38d","user_code_job_started_at":"2026-10-13T12:53:29.933Z","user_code_job_completed_at":"2026-10-13T12:59:47.198Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=916709f73c82d32f8e2a96c9459990e39b8da1e1439ec646fe41f4f003f16bd5","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b538d937-c018-4d98-b3e8-e32e76a9b280","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.8.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T12:30:02.679Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-30646a2f0d4055e222bac835b6c08a0a","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b538d937-c018-4d98-b3e8-e32e76a9b280\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b538d937-c018-4d98-b3e8-e32e76a9b280\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b538d937-c018-4d98-b3e8-e32e76a9b280\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"2d1afeef-9837-4ff1-b542-94d13ca982be","user_code_job_started_at":"2026-10-13T12:33:58.171Z","user_code_job_completed_at":"2026-10-13T12:41:12.246Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=4ca0ee084f43e954fea31cc2bc08c76a2ec27d675a611d22cda0ccdd48aed65f","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"4dec2d64-2196-4721-b0c6-64d541a6bcb0","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.8.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T12:22:10.251Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-c55892260b3718e762e02a05b2dcf57e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=4dec2d64-2196-4721-b0c6-64d541a6bcb0\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=4dec2d64-2196-4721-b0c6-64d541a6bcb0\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=4dec2d64-2196-4721-b0c6-64d541a6bcb0\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"96d61b7f-762b-4246-aeb1-e2ef6d684c90","user_code_job_started_at":"2026-10-13T12:23:54.126Z","user_code_job_completed_at":"2026-10-13T12:30:10.042Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=fad73d5f7ed470e282b619be23ce24d2d9946a64700668210d956d12a550ca76","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"72cba361-522d-4755-94e9-3de7d070f12b","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.7.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T06:06:09.980Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-006547227a1182d95d91791d9f16bb70","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72cba361-522d-4755-94e9-3de7d070f12b\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72cba361-522d-4755-94e9-3de7d070f12b\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=72cba361-522d-4755-94e9-3de7d070f12b\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"5902c551-9159-4da8-98e6-a7422b747377","user_code_job_started_at":"2026-10-13T06:07:39.299Z","user_code_job_completed_at":"2026-10-13T06:11:12.462Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=555ab44c0f07447fc1f54a574635589f0793abf98a8f36d3225cb30997ba2743","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"23dd8434-bf70-49b4-9a5e-ed52cfdbe2f5","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.7.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-13T05:48:27.982Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-04ec64ecf0e9448bbe4cfe1ee2831a7e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=23dd8434-bf70-49b4-9a5e-ed52cfdbe2f5\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=23dd8434-bf70-49b4-9a5e-ed52cfdbe2f5\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=23dd8434-bf70-49b4-9a5e-ed52cfdbe2f5\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"0856090b-318d-4245-830f-b07803f5e87d","user_code_job_started_at":"2026-10-13T05:52:04.776Z","user_code_job_completed_at":"2026-10-13T06:01:01.941Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=02573a988e7c38528e50e7b34f745d0864ec914863ffb8483751bfed40170560","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8912a5e2-2a92-4b82-bfc6-157f09a6ba0d","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.7.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-12T20:41:27.395Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-e8bc6c69f6eaa441991986835d59f2cd","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8912a5e2-2a92-4b82-bfc6-157f09a6ba0d\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8912a5e2-2a92-4b82-bfc6-157f09a6ba0d\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8912a5e2-2a92-4b82-bfc6-157f09a6ba0d\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"21bfddaf-9fc2-4dc6-8d7b-310457ff5dd8","user_code_job_started_at":"2026-10-12T20:41:37.714Z","user_code_job_completed_at":"2026-10-12T20:47:08.672Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=df13b575bcba9ee76bae84e6ccb9bb1ee5f5615976fca399a978824fd41b150e","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2fef6bb9-712f-4bae-848f-9281aebbb415","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.6.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-12T18:59:52.431Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-4768901600e352024ca8e3857e4efb4b","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2fef6bb9-712f-4bae-848f-9281aebbb415\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2fef6bb9-712f-4bae-848f-9281aebbb415\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2fef6bb9-712f-4bae-848f-9281aebbb415\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"29eb912a-3afd-4b36-a6f2-0fb59fdbcfc4","user_code_job_started_at":"2026-10-12T19:03:02.935Z","user_code_job_completed_at":"2026-10-12T19:06:42.383Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=00d896bcca149dc07b611f76f54693fb30f103c695b4795ea6ea8708c56f5e2e","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"5fff5a1b-e87c-4186-9a91-4d9b31db7eeb","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.5.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-12T17:00:40.865Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a8d8360df9725b5e948a2da50263db16","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5fff5a1b-e87c-4186-9a91-4d9b31db7eeb\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5fff5a1b-e87c-4186-9a91-4d9b31db7eeb\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5fff5a1b-e87c-4186-9a91-4d9b31db7eeb\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"18ba8b38-59d5-4923-8510-fbf7ccee5e37","user_code_job_started_at":"2026-10-12T17:03:28.429Z","user_code_job_completed_at":"2026-10-12T17:11:42.883Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=422332973af089dfad09b93b1083b6ed5c8d0439347b92ed71f2b75e8afc9003","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"fb792f22-230f-4959-b90f-5ee4266b36ea","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.5.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-12T16:23:32.936Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-2ccc01a47ece280209f83c5c1d14195e","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=fb792f22-230f-4959-b90f-5ee4266b36ea\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=fb792f22-230f-4959-b90f-5ee4266b36ea\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=fb792f22-230f-4959-b90f-5ee4266b36ea\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"02c67f49-d493-4ddb-a351-4ba99fda1b8a","user_code_job_started_at":"2026-10-12T16:24:44.529Z","user_code_job_completed_at":"2026-10-12T16:41:59.749Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=e9f6dc29a23046546f2de452d1b4a77387d75acf2b9ddf1d5834703dc61010c3","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"206e1acb-9472-4afa-9d63-d2544c408ce7","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.4.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-11T20:38:15.199Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a18c6da278ecdd70207fa06dfd42361a","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=206e1acb-9472-4afa-9d63-d2544c408ce7\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=206e1acb-9472-4afa-9d63-d2544c408ce7\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=206e1acb-9472-4afa-9d63-d2544c408ce7\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"a78828f6-0456-497e-826c-55486a99a135","user_code_job_started_at":"2026-10-11T20:38:24.115Z","user_code_job_completed_at":"2026-10-11T20:40:55.494Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=499cd6865618cba284fff561975ff8461cc4a1e7953d13045448af7cdbcb1db3","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"a940d82c-ed34-4d1d-aa3d-c4c39f2f7296","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.3.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-11T19:56:16.964Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-ca20f1382e4dfc4ae7f5f95e1ed6ec6b","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a940d82c-ed34-4d1d-aa3d-c4c39f2f7296\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a940d82c-ed34-4d1d-aa3d-c4c39f2f7296\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a940d82c-ed34-4d1d-aa3d-c4c39f2f7296\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b7735516-6303-4844-90aa-8a3f297d0d78","user_code_job_started_at":"2026-10-11T19:56:22.159Z","user_code_job_completed_at":"2026-10-11T19:58:59.215Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=727dbb24942b2f5b50a9a73bbfb5ce3275abf623bded63393f3654bebb4c5fce","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"453b5046-d421-4e7f-986d-52a715ecae3a","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.2.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-11T18:22:54.676Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-afa7adc007831fc613c95d90b556cfbc","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"442a7791-4075-449f-8943-8defbee3a7fc","user_code_job_started_at":"2026-10-11T18:24:26.179Z","user_code_job_completed_at":"2026-10-11T18:28:56.566Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a9063319ce9c27ceabdaae204589a3bd04c206e05d47d1cba140d7559c735d38","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ed8b998e-34ee-4e0b-9eb0-1f5093d0c5ad","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.16","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-11T12:52:09.610Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-51248f38d938f3bb82a6d7581363430f","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"6104c472-988b-4b93-8953-6f21a5b33fdf","user_code_job_started_at":"2026-10-11T13:22:09.651Z","user_code_job_completed_at":"2026-10-11T13:52:12.259Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=f5d5f53a8385fc9b57e4cdc3871354eed6d4449ca24797312b02cc95b74a0c77","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"42a042be-c8b9-45ef-b0c0-3d07751f14b6","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.15","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-11T08:33:04.295Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a35026189dbe98ecb774dafb34640340","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"fd1f51cb-5daf-47b0-8edd-eadad7a26cbc","user_code_job_started_at":"2026-10-11T08:55:04.254Z","user_code_job_completed_at":"2026-10-11T09:02:35.414Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=327c5032b8e3bbdfeab097b83b4d124aa9f62db4738c7dbaeab0c4ccf17a337e","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"f814607f-05f5-4c87-bf59-91339d4019ef","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.14","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-10T08:13:06.267Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-4a98b8c2718548ca039f0e69c4a24b35","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f814607f-05f5-4c87-bf59-91339d4019ef\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f814607f-05f5-4c87-bf59-91339d4019ef\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f814607f-05f5-4c87-bf59-91339d4019ef\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"076e7f37-2ff7-48f8-a6ce-89432507df70","user_code_job_started_at":"2026-10-10T08:13:26.522Z","user_code_job_completed_at":"2026-10-10T08:15:53.205Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9bec42f30f58d07820046f2d3a66c3ee9ae3dc89d86f303fe5f9932b40fc98b2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ca84643e-8c70-4791-9f72-80b3a29e29ff","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.13","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-10T08:00:45.327Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-b87a402b6b3777ad64f9f773081c4682","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca84643e-8c70-4791-9f72-80b3a29e29ff\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca84643e-8c70-4791-9f72-80b3a29e29ff\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca84643e-8c70-4791-9f72-80b3a29e29ff\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"b36cb277-2718-43d1-be70-8dcd80641e7c","user_code_job_started_at":"2026-10-10T08:00:52.091Z","user_code_job_completed_at":"2026-10-10T08:03:27.323Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=c568dbb7a0c94029027024aa211a96a24544de0e173b575805faf6436a7a228e","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8c3898c0-fdb1-4f8c-ba38-2052593c8251","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.12","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-10T01:30:12.502Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-18881f9e2549c9a02115fae322d72bd7","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8c3898c0-fdb1-4f8c-ba38-2052593c8251\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8c3898c0-fdb1-4f8c-ba38-2052593c8251\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8c3898c0-fdb1-4f8c-ba38-2052593c8251\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"47b4f302-7675-4db9-bd2c-dfee246ed2fe","user_code_job_started_at":"2026-10-10T01:30:20.618Z","user_code_job_completed_at":"2026-10-10T01:33:49.353Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=f9c8ecab368cacc8066ef692f42ecd07849ca3bdfb7169918fe9dbb56962e234","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"35404778-1f1c-401d-94e1-564743f1ec3a","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.11","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-09T22:26:21.964Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a37c7c3d3bcf93c212634ebb549d947d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=35404778-1f1c-401d-94e1-564743f1ec3a\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=35404778-1f1c-401d-94e1-564743f1ec3a\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=35404778-1f1c-401d-94e1-564743f1ec3a\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"6634aaf0-5b4c-469e-b3e2-1d75b87ab419","user_code_job_started_at":"2026-10-09T22:26:30.079Z","user_code_job_completed_at":"2026-10-09T22:29:23.159Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=dde2cbef8378024bbe9521cc5ba85f9cdf78a331c1923cd247234f2837af8788","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"760da6cd-c4b2-493b-a233-4e13dc3f68f2","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.10","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-09T22:25:24.169Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-ce1afdc4f3216caabb332f7106a227ee","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"c73cbb30-9b6a-4d0e-a618-b15cb463d965","user_code_job_started_at":"2026-10-09T22:25:29.093Z","user_code_job_completed_at":"2026-10-09T22:27:12.072Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=428c66580af3d2fd31361d9fe63f860a403f93ccbdffeea14a4215f6f972f510","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"0866edf9-ff90-4a36-8cfa-65fb53f9e179","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.9","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-09T22:21:49.438Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-a4b0b8674ad747a3594d0fb797d0aa19","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0866edf9-ff90-4a36-8cfa-65fb53f9e179\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0866edf9-ff90-4a36-8cfa-65fb53f9e179\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0866edf9-ff90-4a36-8cfa-65fb53f9e179\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"bd7335a8-3e96-4051-9570-2dcf2fa0caaf","user_code_job_started_at":"2026-10-09T22:21:54.996Z","user_code_job_completed_at":"2026-10-09T22:24:39.958Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=6dca801fd1b6241cce7e436ed0c85911e22dc4973d77eb393127427daad829ab","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"7799fe34-cc8b-4ea1-9dab-0aa77fab1207","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.8","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-09T19:51:29.683Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-4536867f4df7cd012f15f959e6ed893c","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=7799fe34-cc8b-4ea1-9dab-0aa77fab1207\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=7799fe34-cc8b-4ea1-9dab-0aa77fab1207\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=7799fe34-cc8b-4ea1-9dab-0aa77fab1207\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"0f64d4f7-54a0-475b-9faa-034d34104976","user_code_job_started_at":"2026-10-09T19:52:51.330Z","user_code_job_completed_at":"2026-10-09T19:55:54.753Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=8d502b60147db571873ee1df306abd4c8daa336e1454878ef668e2c99a104b22","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"62e60735-69e6-445e-b69d-194485aaf934","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.7","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-09T05:50:37.942Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-5edf9a21b89692fd4296e5e8ae0836fc","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=62e60735-69e6-445e-b69d-194485aaf934\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=62e60735-69e6-445e-b69d-194485aaf934\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=62e60735-69e6-445e-b69d-194485aaf934\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"0d5f5175-9b90-4146-9a80-4b1922a71a9a","user_code_job_started_at":"2026-10-09T05:51:03.540Z","user_code_job_completed_at":"2026-10-09T05:57:47.230Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=b2b3196009bcb0d23f3f878a6f155a1e172369d309b8db106358fc377710fdcc","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"71ff847d-00c4-4927-808d-d7afc33fd32d","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":false,"is_pr_preview":false,"created_at":"2026-10-09T05:47:48.574Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-edfbc736fc292a7b86496812a466fcfd","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":null,"user_code_job_started_at":null,"user_code_job_completed_at":null,"user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":null,"ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"19f09a2b-a1dc-4316-a7a6-4fd959aee71a","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:56:52.849Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-50f9483ec58bc917bd66dd90714c8ace","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=19f09a2b-a1dc-4316-a7a6-4fd959aee71a\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=19f09a2b-a1dc-4316-a7a6-4fd959aee71a\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=19f09a2b-a1dc-4316-a7a6-4fd959aee71a\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"c9a37637-c5e4-478e-9c0e-48e0663fa353","user_code_job_started_at":"2026-10-07T23:57:05.274Z","user_code_job_completed_at":"2026-10-07T23:59:27.674Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=3a77639ff3fe4ae48dbec0b77d6108c9782d251c9387d029ef3dfb94d1526db9","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"4332ff6d-42ac-4b06-bc4d-405b10e3e3f0","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:34:03.210Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-81848bcff11436d56258c98537f5ad34","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"0e9d8171-3b87-45ca-b26a-dcd154142b07","user_code_job_started_at":"2026-10-07T23:36:16.274Z","user_code_job_completed_at":"2026-10-08T00:06:16.310Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=1cb4019a065d017ea2a41f66ac25753ea5425c1ed0a22de7e8c9fbf09afeb5b2","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1c70fee6-f2ca-4a04-9091-58fb90774d35","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:32:09.035Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-61a2ca0f804b6f3cfc9a5fd57a84e6df","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1c70fee6-f2ca-4a04-9091-58fb90774d35\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1c70fee6-f2ca-4a04-9091-58fb90774d35\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=1c70fee6-f2ca-4a04-9091-58fb90774d35\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"1324b3ab-bcab-45f4-af4b-de7eca18a69f","user_code_job_started_at":"2026-10-07T23:32:59.615Z","user_code_job_completed_at":"2026-10-07T23:36:17.324Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a995a2ce8eb6c32ce889c0abeeb542ed26a4b25564690f193e790606398c6de5","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8469abe1-b349-4e41-898c-9b6e1dc2e584","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:26:31.470Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-e5c2aa762b669a22cca8db77c6e741a7","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"2235e0bd-d618-4366-af82-4d8e1a7a529c","user_code_job_started_at":"2026-10-07T23:26:49.527Z","user_code_job_completed_at":"2026-10-07T23:56:54.911Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=213aeb53447b791208523e5b27f4cd9084cd5f9f782905df1a3d0c5c546fc68e","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"1a446442-30d6-4043-9c60-29f632d78f34","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:25:34.251Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-788d6706ebeb83f754169c4ebe6477e2","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"3ce356e4-46a5-480b-a125-9941835a1d5e","user_code_job_started_at":"2026-10-07T23:26:36.108Z","user_code_job_completed_at":"2026-10-07T23:56:44.872Z","user_code_job_error":{"message":"Build timed out after 30 minutes","error_code":"user_code_job_timeout"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=57858d9f4cacfd38e16e01aac75b320c5dffbb4e924cc332bcaf614d4d9cd07d","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"c154cdc5-b9fb-4124-afd7-12e95055d414","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.1.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T23:16:55.801Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-ffe01ed2f849fd28975c19bbb61ebf09","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":null,"package_release_website_url":null,"display_status":"pending","latest_package_build_id":"dd8c4b40-7e6b-450e-980f-8ec2086866ed","user_code_job_started_at":"2026-10-07T23:17:04.687Z","user_code_job_completed_at":"2026-10-07T23:21:18.414Z","user_code_job_error":{"message":"There was an error running the job on our infrastructure, this is probably not your code, see build logs","error_code":"user_code_job_infrastructure_error"},"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=c2510ff79ebf54ea05e54d32a42dfed8d23ac9c6c4106a03af1b65607fa8a775","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"3b02857b-2dfc-4eff-a59a-1a7b78367105","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T22:07:11.575Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-88482e374f204d6a994bf69c9e88c0e0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b02857b-2dfc-4eff-a59a-1a7b78367105\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b02857b-2dfc-4eff-a59a-1a7b78367105\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=3b02857b-2dfc-4eff-a59a-1a7b78367105\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"c2eb512e-fb71-4199-887f-029c5f9684cd","user_code_job_started_at":"2026-10-07T22:07:15.863Z","user_code_job_completed_at":"2026-10-07T22:09:47.766Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=5520ad13d06db060e03318fa7ba0eff2e88c9cf0cc3823eda6592ed7879e437d","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"6f21b3b1-8b4b-4b67-b0fa-9655f98f2756","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T21:27:10.605Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-be242ac7476bf4e820c2be061eeb7c00","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6f21b3b1-8b4b-4b67-b0fa-9655f98f2756\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6f21b3b1-8b4b-4b67-b0fa-9655f98f2756\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=6f21b3b1-8b4b-4b67-b0fa-9655f98f2756\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"d25c1dd7-b19c-49e9-809f-9d53f6b6e43d","user_code_job_started_at":"2026-10-07T21:27:18.467Z","user_code_job_completed_at":"2026-10-07T21:28:49.665Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=ec73b51fe7d796386f569ed8b7c039e4636ad2fc7ffd0a0bf8187a8558b91d51","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"ca604a13-b5b5-43be-b300-4a02c76e28e8","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T21:20:47.472Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-44385db4497f70f28fd2f433b0af0766","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca604a13-b5b5-43be-b300-4a02c76e28e8\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca604a13-b5b5-43be-b300-4a02c76e28e8\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ca604a13-b5b5-43be-b300-4a02c76e28e8\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"7a3de1e4-8f51-4338-83e2-75dc31402f04","user_code_job_started_at":"2026-10-07T21:20:55.048Z","user_code_job_completed_at":"2026-10-07T21:23:34.752Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=aa037cd31e00ae60895dc98a113ab4af6a4768824134b099502da620b3ac7c33","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"e9746b58-03b9-4424-a4e9-6757d9df36c2","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T21:16:39.111Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-4ed02721952abf2e52f35cf7935c9bc8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=e9746b58-03b9-4424-a4e9-6757d9df36c2\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=e9746b58-03b9-4424-a4e9-6757d9df36c2\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=e9746b58-03b9-4424-a4e9-6757d9df36c2\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"9b70fe41-2eb2-417d-89b0-12b7db7f350c","user_code_job_started_at":"2026-10-07T21:16:48.914Z","user_code_job_completed_at":"2026-10-07T21:18:29.897Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=1e6aa9ad672eb2e9b48dd62560b43edda0ed15820c55c1e4bdb427dbe73891ca","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"f51c239e-cdfe-4a8c-bcaf-96c8d2c9ff61","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T21:15:20.227Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-73f26f8faf83ad45978261804eca4e0d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f51c239e-cdfe-4a8c-bcaf-96c8d2c9ff61\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f51c239e-cdfe-4a8c-bcaf-96c8d2c9ff61\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=f51c239e-cdfe-4a8c-bcaf-96c8d2c9ff61\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"525c08f2-a1f6-4fd2-806a-ab93cc6d5b46","user_code_job_started_at":"2026-10-07T21:15:28.828Z","user_code_job_completed_at":"2026-10-07T21:17:06.642Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a95a0d4735da0dcbe91ab7edcffd54214361e42657c01f42542c7f372765e904","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"a55a575d-5800-4156-a056-dfed3de59dfd","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T17:54:33.914Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-fe2751dbeb29328b83a8c5fd67ea51b0","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a55a575d-5800-4156-a056-dfed3de59dfd\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a55a575d-5800-4156-a056-dfed3de59dfd\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=a55a575d-5800-4156-a056-dfed3de59dfd\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"566b9937-8235-4c23-9903-f14795f75a6b","user_code_job_started_at":"2026-10-07T17:54:38.547Z","user_code_job_completed_at":"2026-10-07T17:56:37.651Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=0480f964b62a38c078f955fdb86f416050d3dbad8920cae0e64e0fd8b6fc7f90","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"2a1a0b3c-a7e4-4de9-882c-93d531402acd","package_id":"1a688437-24fc-4e9f-921c-1ddc4fc53cf5","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-10-07T17:53:39.718Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-017da5464afeb64e1aadfdcf204b29a8","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2a1a0b3c-a7e4-4de9-882c-93d531402acd\u0026file_path=dist%2Fartifacts%2Fboard%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2a1a0b3c-a7e4-4de9-882c-93d531402acd\u0026file_path=dist%2Fartifacts%2Fboard%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2a1a0b3c-a7e4-4de9-882c-93d531402acd\u0026file_path=dist%2Fartifacts%2Fboard%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"27f78426-dfa5-4125-b6fa-0d7c42b13b4d","user_code_job_started_at":"2026-10-07T17:53:49.713Z","user_code_job_completed_at":"2026-10-07T17:55:35.358Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=79990377e7cde1bebf46bd5dbdb269b64cf82874fad435e8d9792d2aa30566b6","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"aa00927f-c266-46f3-8767-63e987da3236","creator_account_id":"84198f66-bb86-4dc1-97f0-cdf2cf2c843a","latest_package_release_id":"84cb520f-0021-479c-aa52-1395bb3b8ede","last_built_release_id":"84cb520f-0021-479c-aa52-1395bb3b8ede","latest_package_release_fs_sha":"md5-4deef1765b850c0779346bb02a875a80","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=84cb520f-0021-479c-aa52-1395bb3b8ede\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=84cb520f-0021-479c-aa52-1395bb3b8ede\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=84cb520f-0021-479c-aa52-1395bb3b8ede\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.0","license":"unset","owner_org_id":"07e44f25-c5d3-4583-9c34-2c7bb568f85b","org_owner_tscircuit_handle":"AnasSarkiz","owner_github_username":"AnasSarkiz","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"AnasSarkiz/vibe_Goblin","unscoped_name":"vibe_Goblin","star_count":0,"created_at":"2026-06-15T13:43:56.334Z","updated_at":"2026-06-15T13:46:52.686Z","ai_description":"These code snippets define various physical electronic components such as ICs, connectors, sensors, LEDs, and chips, specifying their pin layouts, footprint pads, silkscreen markings, courtyard outlines, and 3D CAD models for placement on PCB boards.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":"https://tscircuit.com/AnasSarkiz/vibe_Goblin","github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=84cb520f-0021-479c-aa52-1395bb3b8ede\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"b556e552-3bd8-4abb-8ce9-2d91d4e0d90d","creator_account_id":"63586009-ac32-446c-b5aa-a60ea81a44bf","latest_package_release_id":"2543e306-01e3-4d9f-ab5c-c94a17f8dc00","last_built_release_id":"2543e306-01e3-4d9f-ab5c-c94a17f8dc00","latest_package_release_fs_sha":"md5-87f801ac5a8e4f3339615839916f3878","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2543e306-01e3-4d9f-ab5c-c94a17f8dc00\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2543e306-01e3-4d9f-ab5c-c94a17f8dc00\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=2543e306-01e3-4d9f-ab5c-c94a17f8dc00\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.34","license":"unset","owner_org_id":"e4b51b30-273d-4e29-92ed-981078150dff","org_owner_tscircuit_handle":"ShiboSoftwareDev","owner_github_username":"ShiboSoftwareDev","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"ShiboSoftwareDev/nema8-20mm-dual-usbc-stepper-controller","unscoped_name":"nema8-20mm-dual-usbc-stepper-controller","star_count":0,"created_at":"2026-10-01T15:24:45.573Z","updated_at":"2026-10-11T17:46:50.170Z","ai_description":"A compact 20 mm four-layer USB‑C stepper-controller PCB combining CH32X035 MCU control, TMC2209 motor driving, USB‑C PD/data interfaces, protection/power regulation, temperature/LED status hardware, and NEMA8 motor connectivity.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=2543e306-01e3-4d9f-ab5c-c94a17f8dc00\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"f091b0b4-6338-4040-8ade-34937cb30f2e","creator_account_id":"96f144ef-7dfe-4068-aac0-8753c8ab5f62","latest_package_release_id":"ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd","last_built_release_id":"ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd","latest_package_release_fs_sha":"md5-f1485ef7f753c4cea2634724d9b86021","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.3.2","license":"unset","owner_org_id":"719473db-1754-470b-a747-20148ebb82aa","org_owner_tscircuit_handle":"imrishabh18","owner_github_username":"imrishabh18","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"imrishabh18/nema-23-stepper-controller","unscoped_name":"nema-23-stepper-controller","star_count":1,"created_at":"2026-09-16T14:50:21.318Z","updated_at":"2026-10-06T21:28:53.177Z","ai_description":"A four-layer NEMA23 stepper motor controller PCB featuring an RP2040 MCU, DRV8452 dual-phase driver, USB‑C PD power input/protection, current and temperature sensing, status LED/buzzer, and optional magnetic encoder.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=ce2edb82-bc7a-4eb3-9cbd-280f173e6dcd\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"AnasSarkiz","packageName":"NEMA14_CH32X035G8U6","packageNameWithScope":"AnasSarkiz/NEMA14_CH32X035G8U6","version":null,"isLegacyRoute":false,"kind":"file","filePath":"scripts/audit-manufacturing.py"};