@tscircuit/runframe 0.0.1341 → 0.0.1342

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1615,7 +1615,7 @@ var package_default = {
1615
1615
  "chokidar-cli": "^3.0.0",
1616
1616
  "circuit-json": "0.0.303",
1617
1617
  "circuit-json-to-bom-csv": "^0.0.8",
1618
- "circuit-json-to-gerber": "^0.0.42",
1618
+ "circuit-json-to-gerber": "^0.0.43",
1619
1619
  "circuit-json-to-gltf": "^0.0.41",
1620
1620
  "circuit-json-to-kicad": "^0.0.25",
1621
1621
  "circuit-json-to-lbrn": "^0.0.4",
package/dist/preview.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  linkify,
9
9
  useOrderDialog,
10
10
  useOrderDialogCli
11
- } from "./chunk-G6WEH4O4.js";
11
+ } from "./chunk-EOZ7RHE3.js";
12
12
  export {
13
13
  BomTable,
14
14
  CadViewer,
package/dist/runner.js CHANGED
@@ -33,7 +33,7 @@ import {
33
33
  useRunFrameStore,
34
34
  useRunnerStore,
35
35
  useStyles
36
- } from "./chunk-G6WEH4O4.js";
36
+ } from "./chunk-EOZ7RHE3.js";
37
37
 
38
38
  // lib/components/RunFrame/RunFrame.tsx
39
39
  import { createCircuitWebWorker } from "@tscircuit/eval/worker";
@@ -6663,7 +6663,7 @@ ${A}%`}}),SDi=Ru({command_code:"TD",schema:_A({command_code:BA("TD").default("TD
6663
6663
  20,1,$1+$1,$4,$5,$6,$7,0*
6664
6664
  20,1,$1+$1,$6,$7,$8,$9,0*
6665
6665
  20,1,$1+$1,$8,$9,$2,$3,0*
6666
- `.trim()}).add("comment",{comment:"APERTURE MACROS END"}).build())};function s_i(e){const A=e.filter(i=>i.type==="pcb_trace"),t={};for(const i of A)for(const n of i.route)n.route_type==="wire"&&(t[n.layer]=t[n.layer]||new Set,t[n.layer].add(n.width));return{top:Array.from(t.top||[]),bottom:Array.from(t.bottom||[])}}function r_i({glayer:e,soup:A,glayer_name:t}){const i=()=>{const s=e.reduce((r,a)=>a.command_code==="ADD"?Math.max(r,a.aperture_number):r,0);return s===0?10:s+1};e.push(...BE().add("comment",{comment:"aperture START LIST"}).build());const n=s_i(A);for(const s of n[t.startsWith("F_")?"top":"bottom"])e.push(...BE().add("define_aperture_template",{aperture_number:i(),standard_template_code:"C",diameter:s}).build());const o=a_i(A,t.startsWith("F_")?"top":"bottom");for(const s of o)e.push(...BE().add("define_aperture_template",{aperture_number:i(),...s}).build());e.push(...BE().add("delete_attribute",{}).add("comment",{comment:"aperture END LIST"}).build())}var Hxt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};throw e.shape==="polygon"?new Error("Polygon SMT pads are drawn as regions, not apertures"):new Error(`Unsupported shape ${e.shape}`)},Yxt=e=>{if("stroke_width"in e)return{standard_template_code:"C",diameter:e.stroke_width};throw new Error(`Provide stroke_width for: ${e}`)},Jxt=e=>{if("font_size"in e)return{standard_template_code:"C",diameter:e.font_size/8};throw new Error(`Provide font_size for: ${e}`)},Txt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="pill"){if(!("width"in e&&"height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.width>=e.height?{macro_name:"HORZPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.width/2}:{macro_name:"VERTPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.height/2}}throw new Error(`Unsupported shape ${e.shape}`)},Kxt=e=>{if(e.shape==="circle"){if(!("outer_diameter"in e&&"hole_diameter"in e))throw new Error("Invalid circle shape in getApertureConfigFromPcbPlatedHole: missing diameters");return{standard_template_code:"C",diameter:e.outer_diameter}}if(e.shape==="pill"){if(!("outer_width"in e&&"outer_height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.outer_width>e.outer_height?{macro_name:"HORZPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_width/2}:{macro_name:"VERTPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_height/2}}const A=e.shape;if(A==="circular_hole_with_rect_pad"||A==="pill_hole_with_rect_pad"||A==="rotated_pill_hole_with_rect_pad"){if(!("rect_pad_width"in e&&"rect_pad_height"in e))throw new Error(`Invalid ${A} shape in getApertureConfigFromPcbPlatedHole: missing dimensions`);return{standard_template_code:"R",x_size:e.rect_pad_width,y_size:e.rect_pad_height}}throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHole: ${e.shape}`)},qxt=e=>{if(!("hole_diameter"in e))throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHole: ${e.hole_shape}`);return{standard_template_code:"C",diameter:e.hole_diameter}},Pxt=e=>{if(!("outer_diameter"in e))throw new Error("outer_diameter not specified in getApertureConfigFromPcbVia");return{standard_template_code:"C",diameter:e.outer_diameter}};function a_i(e,A){const t=[],i=new Set,n=o=>{const s=Vwi(o);i.has(s)||(t.push(o),i.add(s))};for(const o of e)o.type==="pcb_smtpad"?o.layer===A&&o.shape!=="polygon"&&n(Hxt(o)):o.type==="pcb_solder_paste"?o.layer===A&&n(Txt(o)):o.type==="pcb_plated_hole"?o.layers.includes(A)&&n(Kxt(o)):o.type==="pcb_hole"?o.hole_shape==="circle"?n(qxt(o)):console.warn("NOT IMPLEMENTED: drawing gerber for non circle holes"):o.type==="pcb_via"?n(Pxt(o)):o.type==="pcb_silkscreen_path"?n(Yxt(o)):o.type==="pcb_silkscreen_text"&&n(Jxt(o));return t}var hv=(e,A)=>{let t;if("trace_width"in A){const i=A.trace_width;t=e.find(n=>"standard_template_code"in n&&n.command_code==="ADD"&&n.standard_template_code==="C"&&n.diameter===i)}else("standard_template_code"in A||"macro_name"in A)&&(t=e.find(i=>i.command_code==="ADD"&&Object.keys(A).every(n=>i[n]===A[n])));if(!t)throw new Error(`Aperture not found for search params ${JSON.stringify(A)}`);return t.aperture_number},g_i={version:"0.0.41"},c_i={"top-copper":"Copper,L1,Top","bottom-copper":"Copper,L2,Bot","top-soldermask":"Soldermask,Top","bottom-soldermask":"Soldermask,Bot","top-silkscreen":"Legend,Top","bottom-silkscreen":"Legend,Bot","top-paste":"Paste,Top","bottom-paste":"Paste,Bot",edgecut:"Profile,NP"},Qv=e=>{const A=c_i[e.layer_type?`${e.layer}-${e.layer_type}`:e.layer];return BE().add("add_attribute_on_file",{attribute_name:"GenerationSoftware",attribute_value:`tscircuit,circuit-json-to-gerber,${g_i.version}`}).add("add_attribute_on_file",{attribute_name:"CreationDate",attribute_value:new Date().toISOString()}).add("add_attribute_on_file",{attribute_name:"SameCoordinates",attribute_value:"Original"}).add("add_attribute_on_file",{attribute_name:"FileFunction",attribute_value:A}).$if(e.layer!=="edgecut",t=>t.add("add_attribute_on_file",{attribute_name:"FilePolarity",attribute_value:e.layer_type==="soldermask"?"Negative":"Positive"})).add("format_specification",{}).add("set_unit",{unit:"MM"}).add("comment",{comment:"Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)"}).add("comment",{comment:`Created by tscircuit (builder) date ${new Date().toISOString()}`}).add("set_movement_mode_to_linear",{}).add("set_layer_polarity",{polarity:"D"}).add("create_arc",{}).build()},I_i={top:"F_",bottom:"B_"},l_i={copper:"Cu",silkscreen:"SilkScreen",soldermask:"Mask",mask:"Mask",paste:"Paste"},gw=(e,A)=>e==="edgecut"?"Edge_Cuts":`${I_i[e]}${l_i[A]}`,B_i=(e,A={})=>{A.flip_y_axis??=!1;const t={F_Cu:Qv({layer:"top",layer_type:"copper"}),F_SilkScreen:Qv({layer:"top",layer_type:"silkscreen"}),F_Mask:Qv({layer:"top",layer_type:"soldermask"}),F_Paste:Qv({layer:"top",layer_type:"paste"}),B_Cu:Qv({layer:"bottom",layer_type:"copper"}),B_SilkScreen:Qv({layer:"bottom",layer_type:"silkscreen"}),B_Mask:Qv({layer:"bottom",layer_type:"soldermask"}),B_Paste:Qv({layer:"bottom",layer_type:"paste"}),Edge_Cuts:Qv({layer:"edgecut"})};for(const o of["F_Cu","B_Cu","F_Mask","B_Mask","F_Paste","B_Paste","F_SilkScreen","B_SilkScreen"]){const s=t[o];o_i(s),r_i({soup:e,glayer:s,glayer_name:o})}t.Edge_Cuts.push(...BE().add("define_aperture_template",{aperture_number:10,standard_template_code:"C",diameter:.05}).build());const i=o=>A.flip_y_axis?-o:o,n=new Map;for(const o of e)if(o.type==="pcb_plated_hole"&&"x"in o&&typeof o.x=="number"&&"y"in o&&typeof o.y=="number"){const s="ccw_rotation"in o&&typeof o.ccw_rotation=="number"?o.ccw_rotation:0;n.set(`${o.x}:${o.y}`,s)}for(const o of["top","bottom","edgecut"])for(const s of e)if(s.type==="pcb_trace"){const{route:r}=s;for(const[a,g]of n_i(r))if(a.route_type==="wire"&&a.layer===o){const c=t[gw(o,"copper")];c.push(...BE().add("select_aperture",{aperture_number:hv(c,{trace_width:a.width})}).add("move_operation",{x:a.x,y:i(a.y)}).add("plot_operation",{x:g.x,y:i(g.y)}).build())}}else if(s.type==="pcb_silkscreen_path"){if(s.layer===o){const r=t[gw(o,"silkscreen")],a=Yxt(s),g=BE().add("select_aperture",{aperture_number:hv(r,a)});s.route.length>0&&g.add("move_operation",{x:s.route[0].x,y:i(s.route[0].y)});for(let c=1;c<s.route.length;c++)g.add("plot_operation",{x:s.route[c].x,y:i(s.route[c].y)});r.push(...g.build())}}else if(s.type==="pcb_silkscreen_text"){if(s.layer===o){const a=t[gw(o,"silkscreen")],g=Jxt(s),c=BE().add("select_aperture",{aperture_number:hv(a,g)});let I=s.anchor_position.x,l=s.anchor_position.y;const B=s.font_size*.7,C=B*.4,Q=B*.5,u=s.text.split("").reduce((k,b)=>b===" "?k+Q+C:k+B+C,0)-C,E=B;switch(s.anchor_alignment||(()=>{const k=s.anchor_side;if(k)switch(k){case"top":return"top_center";case"bottom":return"bottom_center";case"left":return"center_left";case"right":return"center_right"}})()||"center"){case"top_left":break;case"top_center":I-=u/2;break;case"top_right":I-=u;break;case"center_right":l-=E/2;break;case"center_left":I-=u,l-=E/2;break;case"bottom_left":l-=E;break;case"bottom_center":I-=u/2,l-=E;break;case"bottom_right":I-=u,l-=E;break;default:I-=u/2,l-=E/2;break}let f=I;const m=l;let S=s.ccw_rotation||0;const x=f+u/2,v=m+E/2,D=[];if(s.layer==="bottom"&&(D.push(XL(x,v),{a:-1,b:0,c:0,d:1,e:0,f:0},XL(-x,-v)),S=-S),S){const k=S*Math.PI/180;D.push(XL(x,v),u1A(k),XL(-x,-v))}for(const k of s.text.toUpperCase()){if(k===" "){f+=Q+C;continue}const b=h1A[k]||[];for(const L of b){const G=f+L.x1*B,T=m+L.y1*B,q=f+L.x2*B,P=m+L.y2*B;let V={x:G,y:T},z={x:q,y:P};if(D.length>0){const nA=Q1A(...D);V=Yk(nA,V),z=Yk(nA,z)}c.add("move_operation",{x:V.x,y:i(V.y)}),c.add("plot_operation",{x:z.x,y:i(z.y)})}f+=B+C}a.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape!=="polygon"){if(s.layer===o)for(const r of[t[gw(o,"copper")],t[gw(o,"soldermask")]]){const a=Hxt(s),g=hv(r,a),c=BE().add("select_aperture",{aperture_number:g});s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:s.ccw_rotation}),c.add("flash_operation",{x:s.x,y:i(s.y)}),s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape==="polygon"){if(s.layer===o){const r=[t[gw(o,"copper")]];(!("is_covered_with_solder_mask"in s)||s.is_covered_with_solder_mask!==!1)&&r.push(t[gw(o,"soldermask")]);for(const a of r){const g=BE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{}),{points:c}=s;if(c&&c.length>0){g.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)g.add("plot_operation",{x:c[I].x,y:i(c[I].y)});g.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}g.add("end_region_statement",{}),a.push(...g.build())}}}else if(s.type==="pcb_solder_paste"){if(s.layer===o){const r=t[gw(o,"paste")],a=hv(r,Txt(s)),g="ccw_rotation"in s&&typeof s.ccw_rotation=="number"?s.ccw_rotation:n.get(`${s.x}:${s.y}`)??0,c=BE().add("select_aperture",{aperture_number:a});g&&c.add("load_rotation",{rotation_degrees:g}),c.add("flash_operation",{x:s.x,y:i(s.y)}),g&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_plated_hole"){if(s.layers.includes(o))for(const r of[t[gw(o,"copper")],t[gw(o,"soldermask")]]){const a="hole_width"in s&&typeof s.hole_width=="number"?s.hole_width:0,g="hole_height"in s&&typeof s.hole_height=="number"?s.hole_height:0,c=[a];"outer_width"in s&&typeof s.outer_width=="number"&&c.push(s.outer_width),"rect_pad_width"in s&&typeof s.rect_pad_width=="number"&&c.push(s.rect_pad_width);const I=Math.max(...c),l=[g];"outer_height"in s&&typeof s.outer_height=="number"&&l.push(s.outer_height),"rect_pad_height"in s&&typeof s.rect_pad_height=="number"&&l.push(s.rect_pad_height);const B=Math.max(...l);if(s.shape==="pill"){const C={standard_template_code:"C",diameter:Math.min(I,B)};let Q;try{Q=hv(r,C)}catch{Q=Math.max(...r.filter(v=>"aperture_number"in v).map(v=>v.aperture_number),9)+1,r.push(...BE().add("define_aperture_template",{aperture_number:Q,...C}).build())}const u=BE().add("select_aperture",{aperture_number:Q}),E=(s.ccw_rotation??0)*Math.PI/180,p=Math.cos(E),f=Math.sin(E),m=(v,D)=>{const k=v*p-D*f,b=v*f+D*p;return{x:s.x+k,y:s.y+b}},S=I>=B,x=S?(I-B)/2:(B-I)/2;if(x<=0){const v=m(0,0);u.add("flash_operation",{x:v.x,y:i(v.y)})}else{const v=S?{x:-x,y:0}:{x:0,y:-x},D=S?{x,y:0}:{x:0,y:x},k=m(v.x,v.y),b=m(D.x,D.y);u.add("flash_operation",{x:k.x,y:i(k.y)}).add("move_operation",{x:k.x,y:i(k.y)}).add("plot_operation",{x:b.x,y:i(b.y)}).add("flash_operation",{x:b.x,y:i(b.y)})}r.push(...u.build())}else{const C=Kxt({...s,...s.shape!=="circle"?{outer_width:I,outer_height:B}:{}}),Q="rect_ccw_rotation"in s&&typeof s.rect_ccw_rotation=="number"?s.rect_ccw_rotation:void 0,u=BE().add("select_aperture",{aperture_number:hv(r,C)});Q&&u.add("load_rotation",{rotation_degrees:Q}),u.add("flash_operation",{x:s.x,y:i(s.y)}),Q&&u.add("load_rotation",{rotation_degrees:0}),r.push(...u.build())}}}else if(s.type==="pcb_hole"){if(o!=="edgecut")for(const r of[t[gw(o,"soldermask")]]){if(s.hole_shape!=="circle"){console.warn("NOT IMPLEMENTED: drawing gerber for non-round holes");continue}r.push(...BE().add("select_aperture",{aperture_number:hv(r,qxt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}}else if(s.type==="pcb_via"){if(s.layers.includes(o))for(const r of[t[gw(o,"copper")]])r.push(...BE().add("select_aperture",{aperture_number:hv(r,Pxt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}else if(s.type==="pcb_board"&&o==="edgecut"){if(s.pcb_panel_id)continue;const a=t.Edge_Cuts,{width:g,height:c,center:I,outline:l}=s,B=BE().add("select_aperture",{aperture_number:10});if(l&&l.length>2){const C=l.map(E=>({x:E.x,y:i(E.y)})),Q=C[0];B.add("move_operation",Q);for(let E=1;E<C.length;E++)B.add("plot_operation",C[E]);const u=C[C.length-1];(u.x!==Q.x||u.y!==Q.y)&&B.add("plot_operation",Q)}else B.add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});a.push(...B.build())}else if(s.type==="pcb_panel"&&o==="edgecut"){const r=t.Edge_Cuts,a=s,{width:g,height:c,center:I}=a,l=BE().add("select_aperture",{aperture_number:10}).add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});r.push(...l.build())}else if(s.type==="pcb_cutout"){if(o==="edgecut"){const r=t.Edge_Cuts,a=BE().add("select_aperture",{aperture_number:10}),g=s;if(g.shape==="rect"){const{center:c,width:I,height:l,rotation:B,corner_radius:C}=g,Q=I/2,u=l/2,E=Math.max(0,Math.min(C??0,Math.abs(Q),Math.abs(u))),f=(()=>{let m=Gxt();if(B){const S=B*Math.PI/180;m=u1A(S)}return Q1A(XL(c.x,c.y),m)})();if(E>0){const m={x:-Q+E,y:u};let S=Yk(f,m);a.add("move_operation",{x:S.x,y:i(S.y)});const x=D=>{const k=Yk(f,D);a.add("plot_operation",{x:k.x,y:i(k.y)}),S=k},v=D=>{const k=Yk(f,D.point),b=Yk(f,D.center);a.add("set_movement_mode_to_clockwise_circular",{}).add("plot_operation",{x:k.x,y:i(k.y),i:b.x-S.x,j:i(b.y)-i(S.y)}).add("set_movement_mode_to_linear",{}),S=k};x({x:Q-E,y:u}),v({point:{x:Q,y:u-E},center:{x:Q-E,y:u-E}}),x({x:Q,y:-u+E}),v({point:{x:Q-E,y:-u},center:{x:Q-E,y:-u+E}}),x({x:-Q+E,y:-u}),v({point:{x:-Q,y:-u+E},center:{x:-Q+E,y:-u+E}}),x({x:-Q,y:u-E}),v({point:{x:-Q+E,y:u},center:{x:-Q+E,y:u-E}})}else{const S=[{x:-Q,y:u},{x:Q,y:u},{x:Q,y:-u},{x:-Q,y:-u}].map(x=>Yk(f,x));a.add("move_operation",{x:S[0].x,y:i(S[0].y)});for(let x=1;x<S.length;x++)a.add("plot_operation",{x:S[x].x,y:i(S[x].y)});a.add("plot_operation",{x:S[0].x,y:i(S[0].y)})}}else if(g.shape==="circle"){const{center:c,radius:I}=g,l={x:c.x+I,y:c.y},B={x:c.x-I,y:c.y};a.add("move_operation",{x:l.x,y:i(l.y)}).add("set_movement_mode_to_counterclockwise_circular",{}).add("plot_operation",{x:B.x,y:i(B.y),i:-I,j:0}).add("plot_operation",{x:l.x,y:i(l.y),i:I,j:0}).add("set_movement_mode_to_linear",{})}else if(g.shape==="polygon"){const{points:c}=g;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}r.push(...a.build())}}else if(s.type==="pcb_copper_pour"&&o===s.layer){const r=t[gw(o,"copper")],a=BE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{});if(s.shape==="brep"){const{brep_shape:c}=s;if(!c)continue;const{outer_ring:I,inner_rings:l}=c,B=Q=>{if(!Q||Q.vertices.length===0)return;a.add("move_operation",{x:Q.vertices[0].x,y:i(Q.vertices[0].y)});const u=[...Q.vertices,Q.vertices[0]];for(let E=0;E<u.length-1;E++){const p=u[E],f=u[E+1];if(p.bulge&&Math.abs(p.bulge)>1e-9){const m=(A.flip_y_axis?-1:1)*p.bulge;m>0?a.add("set_movement_mode_to_counterclockwise_circular",{}):a.add("set_movement_mode_to_clockwise_circular",{});const S={x:p.x,y:p.y},x={x:f.x,y:f.y},v=x.x-S.x,D=x.y-S.y,k=Math.sqrt(v*v+D*D);if(k<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const b=Math.abs(m),L=4*Math.atan(b);if(Math.abs(Math.sin(L/2))<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const G=k/(2*Math.sin(L/2)),T=(Math.PI-L)/2,q=Math.atan2(D,v),P=m>0?T:-T,V=q+P,z=S.x+G*Math.cos(V),nA=S.y+G*Math.sin(V),rA=z-S.x,QA=nA-S.y;a.add("plot_operation",{x:f.x,y:i(f.y),i:rA,j:A.flip_y_axis?-QA:QA})}else a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)})}},C=Q=>{const{vertices:u}=Q;if(!u||u.length===0)return{vertices:[]};const E=u.length;return{vertices:[...u].reverse().map((m,S)=>{const x=(E-2-S+E)%E,v=u[x].bulge;return{...m,bulge:v?-v:void 0}})}};if(B(C(I)),l)for(const Q of l)B(C(Q))}else if(s.shape==="rect"){const{center:c,width:I,height:l,rotation:B}=s,C=I/2,Q=l/2,u=[{x:-C,y:Q},{x:C,y:Q},{x:C,y:-Q},{x:-C,y:-Q}];let E=Gxt();if(B){const f=B*Math.PI/180;E=u1A(f)}E=Q1A(XL(c.x,c.y),E);const p=u.map(f=>Yk(E,f));a.add("move_operation",{x:p[0].x,y:i(p[0].y)});for(let f=1;f<p.length;f++)a.add("plot_operation",{x:p[f].x,y:i(p[f].y)});a.add("plot_operation",{x:p[0].x,y:i(p[0].y)})}else if(s.shape==="polygon"){const{points:c}=s;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}a.add("end_region_statement",{});const g=a.build();r.push(...g),s.covered_with_solder_mask===!1&&t[gw(o,"soldermask")].push(...g)}for(const o of Object.keys(t))t[o].push(...BE().add("end_of_file",{}).build());return t},a3={},E1A={},Oxt;function C_i(){return Oxt||(Oxt=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0});var A=(function(){function o(s,r){var a=[],g=!0,c=!1,I=void 0;try{for(var l=s[Symbol.iterator](),B;!(g=(B=l.next()).done)&&(a.push(B.value),!(r&&a.length===r));g=!0);}catch(C){c=!0,I=C}finally{try{!g&&l.return&&l.return()}finally{if(c)throw I}}return a}return function(s,r){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return o(s,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();e.default=i,e.parseUnitObj=n;var t=/-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/;function i(o){var s=parseFloat(o),r=o.match(t)||[],a=r.length>0?o.substr(r[0].length).trim():"";return[s,a]}function n(o){var s=i(o),r=A(s,2),a=r[0],g=r[1];return{val:a,unit:g}}})(E1A)),E1A}var Wxt;function h_i(){if(Wxt)return a3;Wxt=1,Object.defineProperty(a3,"__esModule",{value:!0});var e=(function(){function a(g,c){var I=[],l=!0,B=!1,C=void 0;try{for(var Q=g[Symbol.iterator](),u;!(l=(u=Q.next()).done)&&(I.push(u.value),!(c&&I.length===c));l=!0);}catch(E){B=!0,C=E}finally{try{!l&&Q.return&&Q.return()}finally{if(B)throw C}}return I}return function(g,c){if(Array.isArray(g))return g;if(Symbol.iterator in Object(g))return a(g,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();a3.formatSI=o,a3.unformatSI=r;function A(a){return a&&a.__esModule?a:{default:a}}var t=C_i(),i=A(t),n={24:"Y",21:"Z",18:"E",15:"P",12:"T",9:"G",6:"M",3:"k",0:"","-3":"m","-6":"µ","-9":"n","-12":"p","-15":"f","-18":"a","-21":"z","-24":"y"};function o(a){if(a===0)return"0";for(var g=Math.abs(a),c=0;g>=1e3&&c<24;)g/=1e3,c+=3;for(;g<1&&c>-24;)g*=1e3,c-=3;var I=a<0?"-":"";return g>1e3?I+g.toFixed(0)+n[c]:I+parseFloat(g.toPrecision(3))+n[c]}var s={Y:1e24,Z:1e21,E:1e18,P:1e15,T:1e12,G:1e9,M:1e6,k:1e3,"":1,m:.001,µ:1e-6,u:1e-6,n:1e-9,p:1e-12,f:1e-15,a:1e-18,z:1e-21,y:1e-24};function r(a){if(a==null||a==="")return NaN;var g=(0,i.default)(a),c=e(g,2),I=c[0],l=c[1],B=s[l];return I*B}return a3}var Q_i=h_i(),u$={exports:{}};/* @license
6666
+ `.trim()}).add("comment",{comment:"APERTURE MACROS END"}).build())};function s_i(e){const A=e.filter(i=>i.type==="pcb_trace"),t={};for(const i of A)for(const n of i.route)n.route_type==="wire"&&(t[n.layer]=t[n.layer]||new Set,t[n.layer].add(n.width));return{top:Array.from(t.top||[]),bottom:Array.from(t.bottom||[])}}function r_i({glayer:e,soup:A,glayer_name:t}){const i=()=>{const s=e.reduce((r,a)=>a.command_code==="ADD"?Math.max(r,a.aperture_number):r,0);return s===0?10:s+1};e.push(...BE().add("comment",{comment:"aperture START LIST"}).build());const n=s_i(A);for(const s of n[t.startsWith("F_")?"top":"bottom"])e.push(...BE().add("define_aperture_template",{aperture_number:i(),standard_template_code:"C",diameter:s}).build());const o=a_i(A,t.startsWith("F_")?"top":"bottom");for(const s of o)e.push(...BE().add("define_aperture_template",{aperture_number:i(),...s}).build());e.push(...BE().add("delete_attribute",{}).add("comment",{comment:"aperture END LIST"}).build())}var Hxt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};throw e.shape==="polygon"?new Error("Polygon SMT pads are drawn as regions, not apertures"):new Error(`Unsupported shape ${e.shape}`)},Yxt=e=>{if("stroke_width"in e)return{standard_template_code:"C",diameter:e.stroke_width};throw new Error(`Provide stroke_width for: ${e}`)},Jxt=e=>{if("font_size"in e)return{standard_template_code:"C",diameter:e.font_size/8};throw new Error(`Provide font_size for: ${e}`)},Txt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="pill"){if(!("width"in e&&"height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.width>=e.height?{macro_name:"HORZPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.width/2}:{macro_name:"VERTPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.height/2}}throw new Error(`Unsupported shape ${e.shape}`)},Kxt=e=>{if(e.shape==="circle"){if(!("outer_diameter"in e&&"hole_diameter"in e))throw new Error("Invalid circle shape in getApertureConfigFromPcbPlatedHole: missing diameters");return{standard_template_code:"C",diameter:e.outer_diameter}}if(e.shape==="pill"){if(!("outer_width"in e&&"outer_height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.outer_width>e.outer_height?{macro_name:"HORZPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_width/2}:{macro_name:"VERTPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_height/2}}const A=e.shape;if(A==="circular_hole_with_rect_pad"||A==="pill_hole_with_rect_pad"||A==="rotated_pill_hole_with_rect_pad"){if(!("rect_pad_width"in e&&"rect_pad_height"in e))throw new Error(`Invalid ${A} shape in getApertureConfigFromPcbPlatedHole: missing dimensions`);return{standard_template_code:"R",x_size:e.rect_pad_width,y_size:e.rect_pad_height}}throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHole: ${e.shape}`)},qxt=e=>{if(!("hole_diameter"in e))throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHole: ${e.hole_shape}`);return{standard_template_code:"C",diameter:e.hole_diameter}},Pxt=e=>{if(!("outer_diameter"in e))throw new Error("outer_diameter not specified in getApertureConfigFromPcbVia");return{standard_template_code:"C",diameter:e.outer_diameter}};function a_i(e,A){const t=[],i=new Set,n=o=>{const s=Vwi(o);i.has(s)||(t.push(o),i.add(s))};for(const o of e)o.type==="pcb_smtpad"?o.layer===A&&o.shape!=="polygon"&&n(Hxt(o)):o.type==="pcb_solder_paste"?o.layer===A&&n(Txt(o)):o.type==="pcb_plated_hole"?o.layers.includes(A)&&n(Kxt(o)):o.type==="pcb_hole"?o.hole_shape==="circle"?n(qxt(o)):console.warn("NOT IMPLEMENTED: drawing gerber for non circle holes"):o.type==="pcb_via"?n(Pxt(o)):o.type==="pcb_silkscreen_path"?n(Yxt(o)):o.type==="pcb_silkscreen_text"&&n(Jxt(o));return t}var hv=(e,A)=>{let t;if("trace_width"in A){const i=A.trace_width;t=e.find(n=>"standard_template_code"in n&&n.command_code==="ADD"&&n.standard_template_code==="C"&&n.diameter===i)}else("standard_template_code"in A||"macro_name"in A)&&(t=e.find(i=>i.command_code==="ADD"&&Object.keys(A).every(n=>i[n]===A[n])));if(!t)throw new Error(`Aperture not found for search params ${JSON.stringify(A)}`);return t.aperture_number},g_i={version:"0.0.42"},c_i={"top-copper":"Copper,L1,Top","bottom-copper":"Copper,L2,Bot","top-soldermask":"Soldermask,Top","bottom-soldermask":"Soldermask,Bot","top-silkscreen":"Legend,Top","bottom-silkscreen":"Legend,Bot","top-paste":"Paste,Top","bottom-paste":"Paste,Bot",edgecut:"Profile,NP"},Qv=e=>{const A=c_i[e.layer_type?`${e.layer}-${e.layer_type}`:e.layer];return BE().add("add_attribute_on_file",{attribute_name:"GenerationSoftware",attribute_value:`tscircuit,circuit-json-to-gerber,${g_i.version}`}).add("add_attribute_on_file",{attribute_name:"CreationDate",attribute_value:new Date().toISOString()}).add("add_attribute_on_file",{attribute_name:"SameCoordinates",attribute_value:"Original"}).add("add_attribute_on_file",{attribute_name:"FileFunction",attribute_value:A}).$if(e.layer!=="edgecut",t=>t.add("add_attribute_on_file",{attribute_name:"FilePolarity",attribute_value:e.layer_type==="soldermask"?"Negative":"Positive"})).add("format_specification",{}).add("set_unit",{unit:"MM"}).add("comment",{comment:"Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)"}).add("comment",{comment:`Created by tscircuit (builder) date ${new Date().toISOString()}`}).add("set_movement_mode_to_linear",{}).add("set_layer_polarity",{polarity:"D"}).add("create_arc",{}).build()},I_i={top:"F_",bottom:"B_"},l_i={copper:"Cu",silkscreen:"SilkScreen",soldermask:"Mask",mask:"Mask",paste:"Paste"},gw=(e,A)=>e==="edgecut"?"Edge_Cuts":`${I_i[e]}${l_i[A]}`,B_i=(e,A={})=>{A.flip_y_axis??=!1;const t={F_Cu:Qv({layer:"top",layer_type:"copper"}),F_SilkScreen:Qv({layer:"top",layer_type:"silkscreen"}),F_Mask:Qv({layer:"top",layer_type:"soldermask"}),F_Paste:Qv({layer:"top",layer_type:"paste"}),B_Cu:Qv({layer:"bottom",layer_type:"copper"}),B_SilkScreen:Qv({layer:"bottom",layer_type:"silkscreen"}),B_Mask:Qv({layer:"bottom",layer_type:"soldermask"}),B_Paste:Qv({layer:"bottom",layer_type:"paste"}),Edge_Cuts:Qv({layer:"edgecut"})};for(const o of["F_Cu","B_Cu","F_Mask","B_Mask","F_Paste","B_Paste","F_SilkScreen","B_SilkScreen"]){const s=t[o];o_i(s),r_i({soup:e,glayer:s,glayer_name:o})}t.Edge_Cuts.push(...BE().add("define_aperture_template",{aperture_number:10,standard_template_code:"C",diameter:.05}).build());const i=o=>A.flip_y_axis?-o:o,n=new Map;for(const o of e)if(o.type==="pcb_plated_hole"&&"x"in o&&typeof o.x=="number"&&"y"in o&&typeof o.y=="number"){const s="ccw_rotation"in o&&typeof o.ccw_rotation=="number"?o.ccw_rotation:0;n.set(`${o.x}:${o.y}`,s)}for(const o of["top","bottom","edgecut"])for(const s of e)if(s.type==="pcb_trace"){const{route:r}=s;for(const[a,g]of n_i(r))if(a.route_type==="wire"&&a.layer===o){const c=t[gw(o,"copper")];c.push(...BE().add("select_aperture",{aperture_number:hv(c,{trace_width:a.width})}).add("move_operation",{x:a.x,y:i(a.y)}).add("plot_operation",{x:g.x,y:i(g.y)}).build())}}else if(s.type==="pcb_silkscreen_path"){if(s.layer===o){const r=t[gw(o,"silkscreen")],a=Yxt(s),g=BE().add("select_aperture",{aperture_number:hv(r,a)});s.route.length>0&&g.add("move_operation",{x:s.route[0].x,y:i(s.route[0].y)});for(let c=1;c<s.route.length;c++)g.add("plot_operation",{x:s.route[c].x,y:i(s.route[c].y)});r.push(...g.build())}}else if(s.type==="pcb_silkscreen_text"){if(s.layer===o){const a=t[gw(o,"silkscreen")],g=Jxt(s),c=BE().add("select_aperture",{aperture_number:hv(a,g)});let I=s.anchor_position.x,l=s.anchor_position.y;const B=s.font_size*.7,C=B*.4,Q=B*.5,u=s.text.split("").reduce((k,b)=>b===" "?k+Q+C:k+B+C,0)-C,E=B;switch(s.anchor_alignment||(()=>{const k=s.anchor_side;if(k)switch(k){case"top":return"top_center";case"bottom":return"bottom_center";case"left":return"center_left";case"right":return"center_right"}})()||"center"){case"top_left":break;case"top_center":I-=u/2;break;case"top_right":I-=u;break;case"center_right":l-=E/2;break;case"center_left":I-=u,l-=E/2;break;case"bottom_left":l-=E;break;case"bottom_center":I-=u/2,l-=E;break;case"bottom_right":I-=u,l-=E;break;default:I-=u/2,l-=E/2;break}let f=I;const m=l;let S=s.ccw_rotation||0;const x=f+u/2,v=m+E/2,D=[];if(s.layer==="bottom"&&(D.push(XL(x,v),{a:-1,b:0,c:0,d:1,e:0,f:0},XL(-x,-v)),S=-S),S){const k=S*Math.PI/180;D.push(XL(x,v),u1A(k),XL(-x,-v))}for(const k of s.text.toUpperCase()){if(k===" "){f+=Q+C;continue}const b=h1A[k]||[];for(const L of b){const G=f+L.x1*B,T=m+L.y1*B,q=f+L.x2*B,P=m+L.y2*B;let V={x:G,y:T},z={x:q,y:P};if(D.length>0){const nA=Q1A(...D);V=Yk(nA,V),z=Yk(nA,z)}c.add("move_operation",{x:V.x,y:i(V.y)}),c.add("plot_operation",{x:z.x,y:i(z.y)})}f+=B+C}a.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape!=="polygon"){if(s.layer===o)for(const r of[t[gw(o,"copper")],t[gw(o,"soldermask")]]){const a=Hxt(s),g=hv(r,a),c=BE().add("select_aperture",{aperture_number:g});s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:s.ccw_rotation}),c.add("flash_operation",{x:s.x,y:i(s.y)}),s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape==="polygon"){if(s.layer===o){const r=[t[gw(o,"copper")]];(!("is_covered_with_solder_mask"in s)||s.is_covered_with_solder_mask!==!1)&&r.push(t[gw(o,"soldermask")]);for(const a of r){const g=BE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{}),{points:c}=s;if(c&&c.length>0){g.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)g.add("plot_operation",{x:c[I].x,y:i(c[I].y)});g.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}g.add("end_region_statement",{}),a.push(...g.build())}}}else if(s.type==="pcb_solder_paste"){if(s.layer===o){const r=t[gw(o,"paste")],a=hv(r,Txt(s)),g="ccw_rotation"in s&&typeof s.ccw_rotation=="number"?s.ccw_rotation:n.get(`${s.x}:${s.y}`)??0,c=BE().add("select_aperture",{aperture_number:a});g&&c.add("load_rotation",{rotation_degrees:g}),c.add("flash_operation",{x:s.x,y:i(s.y)}),g&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_plated_hole"){if(s.layers.includes(o))for(const r of[t[gw(o,"copper")],t[gw(o,"soldermask")]]){const a="hole_width"in s&&typeof s.hole_width=="number"?s.hole_width:0,g="hole_height"in s&&typeof s.hole_height=="number"?s.hole_height:0,c=[a];"outer_width"in s&&typeof s.outer_width=="number"&&c.push(s.outer_width),"rect_pad_width"in s&&typeof s.rect_pad_width=="number"&&c.push(s.rect_pad_width);const I=Math.max(...c),l=[g];"outer_height"in s&&typeof s.outer_height=="number"&&l.push(s.outer_height),"rect_pad_height"in s&&typeof s.rect_pad_height=="number"&&l.push(s.rect_pad_height);const B=Math.max(...l);if(s.shape==="pill"){const C={standard_template_code:"C",diameter:Math.min(I,B)};let Q;try{Q=hv(r,C)}catch{Q=Math.max(...r.filter(v=>"aperture_number"in v).map(v=>v.aperture_number),9)+1,r.push(...BE().add("define_aperture_template",{aperture_number:Q,...C}).build())}const u=BE().add("select_aperture",{aperture_number:Q}),E=(s.ccw_rotation??0)*Math.PI/180,p=Math.cos(E),f=Math.sin(E),m=(v,D)=>{const k=v*p-D*f,b=v*f+D*p;return{x:s.x+k,y:s.y+b}},S=I>=B,x=S?(I-B)/2:(B-I)/2;if(x<=0){const v=m(0,0);u.add("flash_operation",{x:v.x,y:i(v.y)})}else{const v=S?{x:-x,y:0}:{x:0,y:-x},D=S?{x,y:0}:{x:0,y:x},k=m(v.x,v.y),b=m(D.x,D.y);u.add("flash_operation",{x:k.x,y:i(k.y)}).add("move_operation",{x:k.x,y:i(k.y)}).add("plot_operation",{x:b.x,y:i(b.y)}).add("flash_operation",{x:b.x,y:i(b.y)})}r.push(...u.build())}else{const C=Kxt({...s,...s.shape!=="circle"?{outer_width:I,outer_height:B}:{}}),Q="rect_ccw_rotation"in s&&typeof s.rect_ccw_rotation=="number"?s.rect_ccw_rotation:void 0,u=BE().add("select_aperture",{aperture_number:hv(r,C)});Q&&u.add("load_rotation",{rotation_degrees:Q}),u.add("flash_operation",{x:s.x,y:i(s.y)}),Q&&u.add("load_rotation",{rotation_degrees:0}),r.push(...u.build())}}}else if(s.type==="pcb_hole"){if(o!=="edgecut")for(const r of[t[gw(o,"soldermask")]]){if(s.hole_shape!=="circle"){console.warn("NOT IMPLEMENTED: drawing gerber for non-round holes");continue}r.push(...BE().add("select_aperture",{aperture_number:hv(r,qxt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}}else if(s.type==="pcb_via"){if(s.layers.includes(o))for(const r of[t[gw(o,"copper")]])r.push(...BE().add("select_aperture",{aperture_number:hv(r,Pxt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}else if(s.type==="pcb_board"&&o==="edgecut"){if(s.pcb_panel_id)continue;const a=t.Edge_Cuts,{width:g,height:c,center:I,outline:l}=s,B=BE().add("select_aperture",{aperture_number:10});if(l&&l.length>2){const C=l.map(E=>({x:E.x,y:i(E.y)})),Q=C[0];B.add("move_operation",Q);for(let E=1;E<C.length;E++)B.add("plot_operation",C[E]);const u=C[C.length-1];(u.x!==Q.x||u.y!==Q.y)&&B.add("plot_operation",Q)}else B.add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});a.push(...B.build())}else if(s.type==="pcb_panel"&&o==="edgecut"){const r=t.Edge_Cuts,a=s,{width:g,height:c,center:I}=a,l=BE().add("select_aperture",{aperture_number:10}).add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});r.push(...l.build())}else if(s.type==="pcb_cutout"){if(o==="edgecut"){const r=t.Edge_Cuts,a=BE().add("select_aperture",{aperture_number:10}),g=s;if(g.shape==="rect"){const{center:c,width:I,height:l,rotation:B,corner_radius:C}=g,Q=I/2,u=l/2,E=Math.max(0,Math.min(C??0,Math.abs(Q),Math.abs(u))),f=(()=>{let m=Gxt();if(B){const S=B*Math.PI/180;m=u1A(S)}return Q1A(XL(c.x,c.y),m)})();if(E>0){const m={x:-Q+E,y:u};let S=Yk(f,m);a.add("move_operation",{x:S.x,y:i(S.y)});const x=D=>{const k=Yk(f,D);a.add("plot_operation",{x:k.x,y:i(k.y)}),S=k},v=D=>{const k=Yk(f,D.point),b=Yk(f,D.center);a.add("set_movement_mode_to_clockwise_circular",{}).add("plot_operation",{x:k.x,y:i(k.y),i:b.x-S.x,j:i(b.y)-i(S.y)}).add("set_movement_mode_to_linear",{}),S=k};x({x:Q-E,y:u}),v({point:{x:Q,y:u-E},center:{x:Q-E,y:u-E}}),x({x:Q,y:-u+E}),v({point:{x:Q-E,y:-u},center:{x:Q-E,y:-u+E}}),x({x:-Q+E,y:-u}),v({point:{x:-Q,y:-u+E},center:{x:-Q+E,y:-u+E}}),x({x:-Q,y:u-E}),v({point:{x:-Q+E,y:u},center:{x:-Q+E,y:u-E}})}else{const S=[{x:-Q,y:u},{x:Q,y:u},{x:Q,y:-u},{x:-Q,y:-u}].map(x=>Yk(f,x));a.add("move_operation",{x:S[0].x,y:i(S[0].y)});for(let x=1;x<S.length;x++)a.add("plot_operation",{x:S[x].x,y:i(S[x].y)});a.add("plot_operation",{x:S[0].x,y:i(S[0].y)})}}else if(g.shape==="circle"){const{center:c,radius:I}=g,l={x:c.x+I,y:c.y},B={x:c.x-I,y:c.y};a.add("move_operation",{x:l.x,y:i(l.y)}).add("set_movement_mode_to_counterclockwise_circular",{}).add("plot_operation",{x:B.x,y:i(B.y),i:-I,j:0}).add("plot_operation",{x:l.x,y:i(l.y),i:I,j:0}).add("set_movement_mode_to_linear",{})}else if(g.shape==="polygon"){const{points:c}=g;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}r.push(...a.build())}}else if(s.type==="pcb_copper_pour"&&o===s.layer){const r=t[gw(o,"copper")],a=BE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{});if(s.shape==="brep"){const{brep_shape:c}=s;if(!c)continue;const{outer_ring:I,inner_rings:l}=c,B=Q=>{if(!Q||Q.vertices.length===0)return;a.add("move_operation",{x:Q.vertices[0].x,y:i(Q.vertices[0].y)});const u=[...Q.vertices,Q.vertices[0]];for(let E=0;E<u.length-1;E++){const p=u[E],f=u[E+1];if(p.bulge&&Math.abs(p.bulge)>1e-9){const m=(A.flip_y_axis?-1:1)*p.bulge;m>0?a.add("set_movement_mode_to_counterclockwise_circular",{}):a.add("set_movement_mode_to_clockwise_circular",{});const S={x:p.x,y:p.y},x={x:f.x,y:f.y},v=x.x-S.x,D=x.y-S.y,k=Math.sqrt(v*v+D*D);if(k<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const b=Math.abs(m),L=4*Math.atan(b);if(Math.abs(Math.sin(L/2))<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const G=k/(2*Math.sin(L/2)),T=(Math.PI-L)/2,q=Math.atan2(D,v),P=m>0?T:-T,V=q+P,z=S.x+G*Math.cos(V),nA=S.y+G*Math.sin(V),rA=z-S.x,QA=nA-S.y;a.add("plot_operation",{x:f.x,y:i(f.y),i:rA,j:A.flip_y_axis?-QA:QA})}else a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)})}},C=Q=>{const{vertices:u}=Q;if(!u||u.length===0)return{vertices:[]};const E=u.length;return{vertices:[...u].reverse().map((m,S)=>{const x=(E-2-S+E)%E,v=u[x].bulge;return{...m,bulge:v?-v:void 0}})}};if(B(C(I)),l)for(const Q of l)B(C(Q))}else if(s.shape==="rect"){const{center:c,width:I,height:l,rotation:B}=s,C=I/2,Q=l/2,u=[{x:-C,y:Q},{x:C,y:Q},{x:C,y:-Q},{x:-C,y:-Q}];let E=Gxt();if(B){const f=B*Math.PI/180;E=u1A(f)}E=Q1A(XL(c.x,c.y),E);const p=u.map(f=>Yk(E,f));a.add("move_operation",{x:p[0].x,y:i(p[0].y)});for(let f=1;f<p.length;f++)a.add("plot_operation",{x:p[f].x,y:i(p[f].y)});a.add("plot_operation",{x:p[0].x,y:i(p[0].y)})}else if(s.shape==="polygon"){const{points:c}=s;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}a.add("end_region_statement",{});const g=a.build();r.push(...g),s.covered_with_solder_mask===!1&&t[gw(o,"soldermask")].push(...g)}for(const o of Object.keys(t))t[o].push(...BE().add("end_of_file",{}).build());return t},a3={},E1A={},Oxt;function C_i(){return Oxt||(Oxt=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0});var A=(function(){function o(s,r){var a=[],g=!0,c=!1,I=void 0;try{for(var l=s[Symbol.iterator](),B;!(g=(B=l.next()).done)&&(a.push(B.value),!(r&&a.length===r));g=!0);}catch(C){c=!0,I=C}finally{try{!g&&l.return&&l.return()}finally{if(c)throw I}}return a}return function(s,r){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return o(s,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();e.default=i,e.parseUnitObj=n;var t=/-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/;function i(o){var s=parseFloat(o),r=o.match(t)||[],a=r.length>0?o.substr(r[0].length).trim():"";return[s,a]}function n(o){var s=i(o),r=A(s,2),a=r[0],g=r[1];return{val:a,unit:g}}})(E1A)),E1A}var Wxt;function h_i(){if(Wxt)return a3;Wxt=1,Object.defineProperty(a3,"__esModule",{value:!0});var e=(function(){function a(g,c){var I=[],l=!0,B=!1,C=void 0;try{for(var Q=g[Symbol.iterator](),u;!(l=(u=Q.next()).done)&&(I.push(u.value),!(c&&I.length===c));l=!0);}catch(E){B=!0,C=E}finally{try{!l&&Q.return&&Q.return()}finally{if(B)throw C}}return I}return function(g,c){if(Array.isArray(g))return g;if(Symbol.iterator in Object(g))return a(g,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();a3.formatSI=o,a3.unformatSI=r;function A(a){return a&&a.__esModule?a:{default:a}}var t=C_i(),i=A(t),n={24:"Y",21:"Z",18:"E",15:"P",12:"T",9:"G",6:"M",3:"k",0:"","-3":"m","-6":"µ","-9":"n","-12":"p","-15":"f","-18":"a","-21":"z","-24":"y"};function o(a){if(a===0)return"0";for(var g=Math.abs(a),c=0;g>=1e3&&c<24;)g/=1e3,c+=3;for(;g<1&&c>-24;)g*=1e3,c-=3;var I=a<0?"-":"";return g>1e3?I+g.toFixed(0)+n[c]:I+parseFloat(g.toPrecision(3))+n[c]}var s={Y:1e24,Z:1e21,E:1e18,P:1e15,T:1e12,G:1e9,M:1e6,k:1e3,"":1,m:.001,µ:1e-6,u:1e-6,n:1e-9,p:1e-12,f:1e-15,a:1e-18,z:1e-21,y:1e-24};function r(a){if(a==null||a==="")return NaN;var g=(0,i.default)(a),c=e(g,2),I=c[0],l=c[1],B=s[l];return I*B}return a3}var Q_i=h_i(),u$={exports:{}};/* @license
6667
6667
  Papa Parse
6668
6668
  v5.5.3
6669
6669
  https://github.com/mholt/PapaParse
@@ -6723,7 +6723,7 @@ ${A}%`}}),obi=Nu({command_code:"TD",schema:xA({command_code:CA("TD").default("TD
6723
6723
  20,1,$1+$1,$4,$5,$6,$7,0*
6724
6724
  20,1,$1+$1,$6,$7,$8,$9,0*
6725
6725
  20,1,$1+$1,$8,$9,$2,$3,0*
6726
- `.trim()}).add("comment",{comment:"APERTURE MACROS END"}).build())};function Mbi(e){const A=e.filter(i=>i.type==="pcb_trace"),t={};for(const i of A)for(const n of i.route)n.route_type==="wire"&&(t[n.layer]=t[n.layer]||new Set,t[n.layer].add(n.width));return{top:Array.from(t.top||[]),bottom:Array.from(t.bottom||[])}}function Lbi({glayer:e,soup:A,glayer_name:t}){const i=()=>{const s=e.reduce((r,a)=>a.command_code==="ADD"?Math.max(r,a.aperture_number):r,0);return s===0?10:s+1};e.push(...QE().add("comment",{comment:"aperture START LIST"}).build());const n=Mbi(A);for(const s of n[t.startsWith("F_")?"top":"bottom"])e.push(...QE().add("define_aperture_template",{aperture_number:i(),standard_template_code:"C",diameter:s}).build());const o=Ubi(A,t.startsWith("F_")?"top":"bottom");for(const s of o)e.push(...QE().add("define_aperture_template",{aperture_number:i(),...s}).build());e.push(...QE().add("delete_attribute",{}).add("comment",{comment:"aperture END LIST"}).build())}var Zbt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};throw e.shape==="polygon"?new Error("Polygon SMT pads are drawn as regions, not apertures"):new Error(`Unsupported shape ${e.shape}`)},Vbt=e=>{if("stroke_width"in e)return{standard_template_code:"C",diameter:e.stroke_width};throw new Error(`Provide stroke_width for: ${e}`)},jbt=e=>{if("font_size"in e)return{standard_template_code:"C",diameter:e.font_size/8};throw new Error(`Provide font_size for: ${e}`)},zbt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="pill"){if(!("width"in e&&"height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.width>=e.height?{macro_name:"HORZPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.width/2}:{macro_name:"VERTPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.height/2}}throw new Error(`Unsupported shape ${e.shape}`)},Xbt=e=>{if(e.shape==="circle"){if(!("outer_diameter"in e&&"hole_diameter"in e))throw new Error("Invalid circle shape in getApertureConfigFromPcbPlatedHole: missing diameters");return{standard_template_code:"C",diameter:e.outer_diameter}}if(e.shape==="pill"){if(!("outer_width"in e&&"outer_height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.outer_width>e.outer_height?{macro_name:"HORZPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_width/2}:{macro_name:"VERTPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_height/2}}const A=e.shape;if(A==="circular_hole_with_rect_pad"||A==="pill_hole_with_rect_pad"||A==="rotated_pill_hole_with_rect_pad"){if(!("rect_pad_width"in e&&"rect_pad_height"in e))throw new Error(`Invalid ${A} shape in getApertureConfigFromPcbPlatedHole: missing dimensions`);return{standard_template_code:"R",x_size:e.rect_pad_width,y_size:e.rect_pad_height}}throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHole: ${e.shape}`)},$bt=e=>{if(!("hole_diameter"in e))throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHole: ${e.hole_shape}`);return{standard_template_code:"C",diameter:e.hole_diameter}},ASt=e=>{if(!("outer_diameter"in e))throw new Error("outer_diameter not specified in getApertureConfigFromPcbVia");return{standard_template_code:"C",diameter:e.outer_diameter}};function Ubi(e,A){const t=[],i=new Set,n=o=>{const s=Dxi(o);i.has(s)||(t.push(o),i.add(s))};for(const o of e)o.type==="pcb_smtpad"?o.layer===A&&o.shape!=="polygon"&&n(Zbt(o)):o.type==="pcb_solder_paste"?o.layer===A&&n(zbt(o)):o.type==="pcb_plated_hole"?o.layers.includes(A)&&n(Xbt(o)):o.type==="pcb_hole"?o.hole_shape==="circle"?n($bt(o)):console.warn("NOT IMPLEMENTED: drawing gerber for non circle holes"):o.type==="pcb_via"?n(ASt(o)):o.type==="pcb_silkscreen_path"?n(Vbt(o)):o.type==="pcb_silkscreen_text"&&n(jbt(o));return t}var mv=(e,A)=>{let t;if("trace_width"in A){const i=A.trace_width;t=e.find(n=>"standard_template_code"in n&&n.command_code==="ADD"&&n.standard_template_code==="C"&&n.diameter===i)}else("standard_template_code"in A||"macro_name"in A)&&(t=e.find(i=>i.command_code==="ADD"&&Object.keys(A).every(n=>i[n]===A[n])));if(!t)throw new Error(`Aperture not found for search params ${JSON.stringify(A)}`);return t.aperture_number},Hbi={version:"0.0.41"},Ybi={"top-copper":"Copper,L1,Top","bottom-copper":"Copper,L2,Bot","top-soldermask":"Soldermask,Top","bottom-soldermask":"Soldermask,Bot","top-silkscreen":"Legend,Top","bottom-silkscreen":"Legend,Bot","top-paste":"Paste,Top","bottom-paste":"Paste,Bot",edgecut:"Profile,NP"},wv=e=>{const A=Ybi[e.layer_type?`${e.layer}-${e.layer_type}`:e.layer];return QE().add("add_attribute_on_file",{attribute_name:"GenerationSoftware",attribute_value:`tscircuit,circuit-json-to-gerber,${Hbi.version}`}).add("add_attribute_on_file",{attribute_name:"CreationDate",attribute_value:new Date().toISOString()}).add("add_attribute_on_file",{attribute_name:"SameCoordinates",attribute_value:"Original"}).add("add_attribute_on_file",{attribute_name:"FileFunction",attribute_value:A}).$if(e.layer!=="edgecut",t=>t.add("add_attribute_on_file",{attribute_name:"FilePolarity",attribute_value:e.layer_type==="soldermask"?"Negative":"Positive"})).add("format_specification",{}).add("set_unit",{unit:"MM"}).add("comment",{comment:"Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)"}).add("comment",{comment:`Created by tscircuit (builder) date ${new Date().toISOString()}`}).add("set_movement_mode_to_linear",{}).add("set_layer_polarity",{polarity:"D"}).add("create_arc",{}).build()},Jbi={top:"F_",bottom:"B_"},Tbi={copper:"Cu",silkscreen:"SilkScreen",soldermask:"Mask",mask:"Mask",paste:"Paste"},hw=(e,A)=>e==="edgecut"?"Edge_Cuts":`${Jbi[e]}${Tbi[A]}`,Kbi=(e,A={})=>{A.flip_y_axis??=!1;const t={F_Cu:wv({layer:"top",layer_type:"copper"}),F_SilkScreen:wv({layer:"top",layer_type:"silkscreen"}),F_Mask:wv({layer:"top",layer_type:"soldermask"}),F_Paste:wv({layer:"top",layer_type:"paste"}),B_Cu:wv({layer:"bottom",layer_type:"copper"}),B_SilkScreen:wv({layer:"bottom",layer_type:"silkscreen"}),B_Mask:wv({layer:"bottom",layer_type:"soldermask"}),B_Paste:wv({layer:"bottom",layer_type:"paste"}),Edge_Cuts:wv({layer:"edgecut"})};for(const o of["F_Cu","B_Cu","F_Mask","B_Mask","F_Paste","B_Paste","F_SilkScreen","B_SilkScreen"]){const s=t[o];Gbi(s),Lbi({soup:e,glayer:s,glayer_name:o})}t.Edge_Cuts.push(...QE().add("define_aperture_template",{aperture_number:10,standard_template_code:"C",diameter:.05}).build());const i=o=>A.flip_y_axis?-o:o,n=new Map;for(const o of e)if(o.type==="pcb_plated_hole"&&"x"in o&&typeof o.x=="number"&&"y"in o&&typeof o.y=="number"){const s="ccw_rotation"in o&&typeof o.ccw_rotation=="number"?o.ccw_rotation:0;n.set(`${o.x}:${o.y}`,s)}for(const o of["top","bottom","edgecut"])for(const s of e)if(s.type==="pcb_trace"){const{route:r}=s;for(const[a,g]of Nbi(r))if(a.route_type==="wire"&&a.layer===o){const c=t[hw(o,"copper")];c.push(...QE().add("select_aperture",{aperture_number:mv(c,{trace_width:a.width})}).add("move_operation",{x:a.x,y:i(a.y)}).add("plot_operation",{x:g.x,y:i(g.y)}).build())}}else if(s.type==="pcb_silkscreen_path"){if(s.layer===o){const r=t[hw(o,"silkscreen")],a=Vbt(s),g=QE().add("select_aperture",{aperture_number:mv(r,a)});s.route.length>0&&g.add("move_operation",{x:s.route[0].x,y:i(s.route[0].y)});for(let c=1;c<s.route.length;c++)g.add("plot_operation",{x:s.route[c].x,y:i(s.route[c].y)});r.push(...g.build())}}else if(s.type==="pcb_silkscreen_text"){if(s.layer===o){const a=t[hw(o,"silkscreen")],g=jbt(s),c=QE().add("select_aperture",{aperture_number:mv(a,g)});let I=s.anchor_position.x,l=s.anchor_position.y;const B=s.font_size*.7,C=B*.4,h=B*.5,u=s.text.split("").reduce((k,b)=>b===" "?k+h+C:k+B+C,0)-C,E=B;switch(s.anchor_alignment||(()=>{const k=s.anchor_side;if(k)switch(k){case"top":return"top_center";case"bottom":return"bottom_center";case"left":return"center_left";case"right":return"center_right"}})()||"center"){case"top_left":break;case"top_center":I-=u/2;break;case"top_right":I-=u;break;case"center_right":l-=E/2;break;case"center_left":I-=u,l-=E/2;break;case"bottom_left":l-=E;break;case"bottom_center":I-=u/2,l-=E;break;case"bottom_right":I-=u,l-=E;break;default:I-=u/2,l-=E/2;break}let f=I;const m=l;let S=s.ccw_rotation||0;const _=f+u/2,v=m+E/2,D=[];if(s.layer==="bottom"&&(D.push(QU(_,v),{a:-1,b:0,c:0,d:1,e:0,f:0},QU(-_,-v)),S=-S),S){const k=S*Math.PI/180;D.push(QU(_,v),gkA(k),QU(-_,-v))}for(const k of s.text.toUpperCase()){if(k===" "){f+=h+C;continue}const b=rkA[k]||[];for(const M of b){const N=f+M.x1*B,T=m+M.y1*B,K=f+M.x2*B,P=m+M.y2*B;let V={x:N,y:T},z={x:K,y:P};if(D.length>0){const nA=akA(...D);V=Vk(nA,V),z=Vk(nA,z)}c.add("move_operation",{x:V.x,y:i(V.y)}),c.add("plot_operation",{x:z.x,y:i(z.y)})}f+=B+C}a.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape!=="polygon"){if(s.layer===o)for(const r of[t[hw(o,"copper")],t[hw(o,"soldermask")]]){const a=Zbt(s),g=mv(r,a),c=QE().add("select_aperture",{aperture_number:g});s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:s.ccw_rotation}),c.add("flash_operation",{x:s.x,y:i(s.y)}),s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape==="polygon"){if(s.layer===o){const r=[t[hw(o,"copper")]];(!("is_covered_with_solder_mask"in s)||s.is_covered_with_solder_mask!==!1)&&r.push(t[hw(o,"soldermask")]);for(const a of r){const g=QE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{}),{points:c}=s;if(c&&c.length>0){g.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)g.add("plot_operation",{x:c[I].x,y:i(c[I].y)});g.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}g.add("end_region_statement",{}),a.push(...g.build())}}}else if(s.type==="pcb_solder_paste"){if(s.layer===o){const r=t[hw(o,"paste")],a=mv(r,zbt(s)),g="ccw_rotation"in s&&typeof s.ccw_rotation=="number"?s.ccw_rotation:n.get(`${s.x}:${s.y}`)??0,c=QE().add("select_aperture",{aperture_number:a});g&&c.add("load_rotation",{rotation_degrees:g}),c.add("flash_operation",{x:s.x,y:i(s.y)}),g&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_plated_hole"){if(s.layers.includes(o))for(const r of[t[hw(o,"copper")],t[hw(o,"soldermask")]]){const a="hole_width"in s&&typeof s.hole_width=="number"?s.hole_width:0,g="hole_height"in s&&typeof s.hole_height=="number"?s.hole_height:0,c=[a];"outer_width"in s&&typeof s.outer_width=="number"&&c.push(s.outer_width),"rect_pad_width"in s&&typeof s.rect_pad_width=="number"&&c.push(s.rect_pad_width);const I=Math.max(...c),l=[g];"outer_height"in s&&typeof s.outer_height=="number"&&l.push(s.outer_height),"rect_pad_height"in s&&typeof s.rect_pad_height=="number"&&l.push(s.rect_pad_height);const B=Math.max(...l);if(s.shape==="pill"){const C={standard_template_code:"C",diameter:Math.min(I,B)};let h;try{h=mv(r,C)}catch{h=Math.max(...r.filter(v=>"aperture_number"in v).map(v=>v.aperture_number),9)+1,r.push(...QE().add("define_aperture_template",{aperture_number:h,...C}).build())}const u=QE().add("select_aperture",{aperture_number:h}),E=(s.ccw_rotation??0)*Math.PI/180,p=Math.cos(E),f=Math.sin(E),m=(v,D)=>{const k=v*p-D*f,b=v*f+D*p;return{x:s.x+k,y:s.y+b}},S=I>=B,_=S?(I-B)/2:(B-I)/2;if(_<=0){const v=m(0,0);u.add("flash_operation",{x:v.x,y:i(v.y)})}else{const v=S?{x:-_,y:0}:{x:0,y:-_},D=S?{x:_,y:0}:{x:0,y:_},k=m(v.x,v.y),b=m(D.x,D.y);u.add("flash_operation",{x:k.x,y:i(k.y)}).add("move_operation",{x:k.x,y:i(k.y)}).add("plot_operation",{x:b.x,y:i(b.y)}).add("flash_operation",{x:b.x,y:i(b.y)})}r.push(...u.build())}else{const C=Xbt({...s,...s.shape!=="circle"?{outer_width:I,outer_height:B}:{}}),h="rect_ccw_rotation"in s&&typeof s.rect_ccw_rotation=="number"?s.rect_ccw_rotation:void 0,u=QE().add("select_aperture",{aperture_number:mv(r,C)});h&&u.add("load_rotation",{rotation_degrees:h}),u.add("flash_operation",{x:s.x,y:i(s.y)}),h&&u.add("load_rotation",{rotation_degrees:0}),r.push(...u.build())}}}else if(s.type==="pcb_hole"){if(o!=="edgecut")for(const r of[t[hw(o,"soldermask")]]){if(s.hole_shape!=="circle"){console.warn("NOT IMPLEMENTED: drawing gerber for non-round holes");continue}r.push(...QE().add("select_aperture",{aperture_number:mv(r,$bt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}}else if(s.type==="pcb_via"){if(s.layers.includes(o))for(const r of[t[hw(o,"copper")]])r.push(...QE().add("select_aperture",{aperture_number:mv(r,ASt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}else if(s.type==="pcb_board"&&o==="edgecut"){if(s.pcb_panel_id)continue;const a=t.Edge_Cuts,{width:g,height:c,center:I,outline:l}=s,B=QE().add("select_aperture",{aperture_number:10});if(l&&l.length>2){const C=l.map(E=>({x:E.x,y:i(E.y)})),h=C[0];B.add("move_operation",h);for(let E=1;E<C.length;E++)B.add("plot_operation",C[E]);const u=C[C.length-1];(u.x!==h.x||u.y!==h.y)&&B.add("plot_operation",h)}else B.add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});a.push(...B.build())}else if(s.type==="pcb_panel"&&o==="edgecut"){const r=t.Edge_Cuts,a=s,{width:g,height:c,center:I}=a,l=QE().add("select_aperture",{aperture_number:10}).add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});r.push(...l.build())}else if(s.type==="pcb_cutout"){if(o==="edgecut"){const r=t.Edge_Cuts,a=QE().add("select_aperture",{aperture_number:10}),g=s;if(g.shape==="rect"){const{center:c,width:I,height:l,rotation:B,corner_radius:C}=g,h=I/2,u=l/2,E=Math.max(0,Math.min(C??0,Math.abs(h),Math.abs(u))),f=(()=>{let m=Kbt();if(B){const S=B*Math.PI/180;m=gkA(S)}return akA(QU(c.x,c.y),m)})();if(E>0){const m={x:-h+E,y:u};let S=Vk(f,m);a.add("move_operation",{x:S.x,y:i(S.y)});const _=D=>{const k=Vk(f,D);a.add("plot_operation",{x:k.x,y:i(k.y)}),S=k},v=D=>{const k=Vk(f,D.point),b=Vk(f,D.center);a.add("set_movement_mode_to_clockwise_circular",{}).add("plot_operation",{x:k.x,y:i(k.y),i:b.x-S.x,j:i(b.y)-i(S.y)}).add("set_movement_mode_to_linear",{}),S=k};_({x:h-E,y:u}),v({point:{x:h,y:u-E},center:{x:h-E,y:u-E}}),_({x:h,y:-u+E}),v({point:{x:h-E,y:-u},center:{x:h-E,y:-u+E}}),_({x:-h+E,y:-u}),v({point:{x:-h,y:-u+E},center:{x:-h+E,y:-u+E}}),_({x:-h,y:u-E}),v({point:{x:-h+E,y:u},center:{x:-h+E,y:u-E}})}else{const S=[{x:-h,y:u},{x:h,y:u},{x:h,y:-u},{x:-h,y:-u}].map(_=>Vk(f,_));a.add("move_operation",{x:S[0].x,y:i(S[0].y)});for(let _=1;_<S.length;_++)a.add("plot_operation",{x:S[_].x,y:i(S[_].y)});a.add("plot_operation",{x:S[0].x,y:i(S[0].y)})}}else if(g.shape==="circle"){const{center:c,radius:I}=g,l={x:c.x+I,y:c.y},B={x:c.x-I,y:c.y};a.add("move_operation",{x:l.x,y:i(l.y)}).add("set_movement_mode_to_counterclockwise_circular",{}).add("plot_operation",{x:B.x,y:i(B.y),i:-I,j:0}).add("plot_operation",{x:l.x,y:i(l.y),i:I,j:0}).add("set_movement_mode_to_linear",{})}else if(g.shape==="polygon"){const{points:c}=g;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}r.push(...a.build())}}else if(s.type==="pcb_copper_pour"&&o===s.layer){const r=t[hw(o,"copper")],a=QE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{});if(s.shape==="brep"){const{brep_shape:c}=s;if(!c)continue;const{outer_ring:I,inner_rings:l}=c,B=h=>{if(!h||h.vertices.length===0)return;a.add("move_operation",{x:h.vertices[0].x,y:i(h.vertices[0].y)});const u=[...h.vertices,h.vertices[0]];for(let E=0;E<u.length-1;E++){const p=u[E],f=u[E+1];if(p.bulge&&Math.abs(p.bulge)>1e-9){const m=(A.flip_y_axis?-1:1)*p.bulge;m>0?a.add("set_movement_mode_to_counterclockwise_circular",{}):a.add("set_movement_mode_to_clockwise_circular",{});const S={x:p.x,y:p.y},_={x:f.x,y:f.y},v=_.x-S.x,D=_.y-S.y,k=Math.sqrt(v*v+D*D);if(k<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const b=Math.abs(m),M=4*Math.atan(b);if(Math.abs(Math.sin(M/2))<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const N=k/(2*Math.sin(M/2)),T=(Math.PI-M)/2,K=Math.atan2(D,v),P=m>0?T:-T,V=K+P,z=S.x+N*Math.cos(V),nA=S.y+N*Math.sin(V),cA=z-S.x,hA=nA-S.y;a.add("plot_operation",{x:f.x,y:i(f.y),i:cA,j:A.flip_y_axis?-hA:hA})}else a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)})}},C=h=>{const{vertices:u}=h;if(!u||u.length===0)return{vertices:[]};const E=u.length;return{vertices:[...u].reverse().map((m,S)=>{const _=(E-2-S+E)%E,v=u[_].bulge;return{...m,bulge:v?-v:void 0}})}};if(B(C(I)),l)for(const h of l)B(C(h))}else if(s.shape==="rect"){const{center:c,width:I,height:l,rotation:B}=s,C=I/2,h=l/2,u=[{x:-C,y:h},{x:C,y:h},{x:C,y:-h},{x:-C,y:-h}];let E=Kbt();if(B){const f=B*Math.PI/180;E=gkA(f)}E=akA(QU(c.x,c.y),E);const p=u.map(f=>Vk(E,f));a.add("move_operation",{x:p[0].x,y:i(p[0].y)});for(let f=1;f<p.length;f++)a.add("plot_operation",{x:p[f].x,y:i(p[f].y)});a.add("plot_operation",{x:p[0].x,y:i(p[0].y)})}else if(s.shape==="polygon"){const{points:c}=s;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}a.add("end_region_statement",{});const g=a.build();r.push(...g),s.covered_with_solder_mask===!1&&t[hw(o,"soldermask")].push(...g)}for(const o of Object.keys(t))t[o].push(...QE().add("end_of_file",{}).build());return t},b3={},ckA={},tSt;function qbi(){return tSt||(tSt=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0});var A=(function(){function o(s,r){var a=[],g=!0,c=!1,I=void 0;try{for(var l=s[Symbol.iterator](),B;!(g=(B=l.next()).done)&&(a.push(B.value),!(r&&a.length===r));g=!0);}catch(C){c=!0,I=C}finally{try{!g&&l.return&&l.return()}finally{if(c)throw I}}return a}return function(s,r){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return o(s,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();e.default=i,e.parseUnitObj=n;var t=/-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/;function i(o){var s=parseFloat(o),r=o.match(t)||[],a=r.length>0?o.substr(r[0].length).trim():"";return[s,a]}function n(o){var s=i(o),r=A(s,2),a=r[0],g=r[1];return{val:a,unit:g}}})(ckA)),ckA}var eSt;function Pbi(){if(eSt)return b3;eSt=1,Object.defineProperty(b3,"__esModule",{value:!0});var e=(function(){function a(g,c){var I=[],l=!0,B=!1,C=void 0;try{for(var h=g[Symbol.iterator](),u;!(l=(u=h.next()).done)&&(I.push(u.value),!(c&&I.length===c));l=!0);}catch(E){B=!0,C=E}finally{try{!l&&h.return&&h.return()}finally{if(B)throw C}}return I}return function(g,c){if(Array.isArray(g))return g;if(Symbol.iterator in Object(g))return a(g,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();b3.formatSI=o,b3.unformatSI=r;function A(a){return a&&a.__esModule?a:{default:a}}var t=qbi(),i=A(t),n={24:"Y",21:"Z",18:"E",15:"P",12:"T",9:"G",6:"M",3:"k",0:"","-3":"m","-6":"µ","-9":"n","-12":"p","-15":"f","-18":"a","-21":"z","-24":"y"};function o(a){if(a===0)return"0";for(var g=Math.abs(a),c=0;g>=1e3&&c<24;)g/=1e3,c+=3;for(;g<1&&c>-24;)g*=1e3,c-=3;var I=a<0?"-":"";return g>1e3?I+g.toFixed(0)+n[c]:I+parseFloat(g.toPrecision(3))+n[c]}var s={Y:1e24,Z:1e21,E:1e18,P:1e15,T:1e12,G:1e9,M:1e6,k:1e3,"":1,m:.001,µ:1e-6,u:1e-6,n:1e-9,p:1e-12,f:1e-15,a:1e-18,z:1e-21,y:1e-24};function r(a){if(a==null||a==="")return NaN;var g=(0,i.default)(a),c=e(g,2),I=c[0],l=c[1],B=s[l];return I*B}return b3}var Obi=Pbi(),tAA={exports:{}};/* @license
6726
+ `.trim()}).add("comment",{comment:"APERTURE MACROS END"}).build())};function Mbi(e){const A=e.filter(i=>i.type==="pcb_trace"),t={};for(const i of A)for(const n of i.route)n.route_type==="wire"&&(t[n.layer]=t[n.layer]||new Set,t[n.layer].add(n.width));return{top:Array.from(t.top||[]),bottom:Array.from(t.bottom||[])}}function Lbi({glayer:e,soup:A,glayer_name:t}){const i=()=>{const s=e.reduce((r,a)=>a.command_code==="ADD"?Math.max(r,a.aperture_number):r,0);return s===0?10:s+1};e.push(...QE().add("comment",{comment:"aperture START LIST"}).build());const n=Mbi(A);for(const s of n[t.startsWith("F_")?"top":"bottom"])e.push(...QE().add("define_aperture_template",{aperture_number:i(),standard_template_code:"C",diameter:s}).build());const o=Ubi(A,t.startsWith("F_")?"top":"bottom");for(const s of o)e.push(...QE().add("define_aperture_template",{aperture_number:i(),...s}).build());e.push(...QE().add("delete_attribute",{}).add("comment",{comment:"aperture END LIST"}).build())}var Zbt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};throw e.shape==="polygon"?new Error("Polygon SMT pads are drawn as regions, not apertures"):new Error(`Unsupported shape ${e.shape}`)},Vbt=e=>{if("stroke_width"in e)return{standard_template_code:"C",diameter:e.stroke_width};throw new Error(`Provide stroke_width for: ${e}`)},jbt=e=>{if("font_size"in e)return{standard_template_code:"C",diameter:e.font_size/8};throw new Error(`Provide font_size for: ${e}`)},zbt=e=>{if(e.shape==="rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="rotated_rect")return{standard_template_code:"R",x_size:e.width,y_size:e.height};if(e.shape==="circle")return{standard_template_code:"C",diameter:e.radius*2};if(e.shape==="pill"){if(!("width"in e&&"height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.width>=e.height?{macro_name:"HORZPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.width/2}:{macro_name:"VERTPILL",x_size:e.width,y_size:e.height,circle_diameter:Math.min(e.width,e.height),circle_center_offset:e.height/2}}throw new Error(`Unsupported shape ${e.shape}`)},Xbt=e=>{if(e.shape==="circle"){if(!("outer_diameter"in e&&"hole_diameter"in e))throw new Error("Invalid circle shape in getApertureConfigFromPcbPlatedHole: missing diameters");return{standard_template_code:"C",diameter:e.outer_diameter}}if(e.shape==="pill"){if(!("outer_width"in e&&"outer_height"in e))throw new Error("Invalid pill shape in getApertureConfigFromPcbPlatedHole: missing dimensions");return e.outer_width>e.outer_height?{macro_name:"HORZPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_width/2}:{macro_name:"VERTPILL",x_size:e.outer_width,y_size:e.outer_height,circle_diameter:Math.min(e.outer_width,e.outer_height),circle_center_offset:e.outer_height/2}}const A=e.shape;if(A==="circular_hole_with_rect_pad"||A==="pill_hole_with_rect_pad"||A==="rotated_pill_hole_with_rect_pad"){if(!("rect_pad_width"in e&&"rect_pad_height"in e))throw new Error(`Invalid ${A} shape in getApertureConfigFromPcbPlatedHole: missing dimensions`);return{standard_template_code:"R",x_size:e.rect_pad_width,y_size:e.rect_pad_height}}throw new Error(`Unsupported shape in getApertureConfigFromPcbPlatedHole: ${e.shape}`)},$bt=e=>{if(!("hole_diameter"in e))throw new Error(`Invalid shape called in getApertureConfigFromCirclePcbHole: ${e.hole_shape}`);return{standard_template_code:"C",diameter:e.hole_diameter}},ASt=e=>{if(!("outer_diameter"in e))throw new Error("outer_diameter not specified in getApertureConfigFromPcbVia");return{standard_template_code:"C",diameter:e.outer_diameter}};function Ubi(e,A){const t=[],i=new Set,n=o=>{const s=Dxi(o);i.has(s)||(t.push(o),i.add(s))};for(const o of e)o.type==="pcb_smtpad"?o.layer===A&&o.shape!=="polygon"&&n(Zbt(o)):o.type==="pcb_solder_paste"?o.layer===A&&n(zbt(o)):o.type==="pcb_plated_hole"?o.layers.includes(A)&&n(Xbt(o)):o.type==="pcb_hole"?o.hole_shape==="circle"?n($bt(o)):console.warn("NOT IMPLEMENTED: drawing gerber for non circle holes"):o.type==="pcb_via"?n(ASt(o)):o.type==="pcb_silkscreen_path"?n(Vbt(o)):o.type==="pcb_silkscreen_text"&&n(jbt(o));return t}var mv=(e,A)=>{let t;if("trace_width"in A){const i=A.trace_width;t=e.find(n=>"standard_template_code"in n&&n.command_code==="ADD"&&n.standard_template_code==="C"&&n.diameter===i)}else("standard_template_code"in A||"macro_name"in A)&&(t=e.find(i=>i.command_code==="ADD"&&Object.keys(A).every(n=>i[n]===A[n])));if(!t)throw new Error(`Aperture not found for search params ${JSON.stringify(A)}`);return t.aperture_number},Hbi={version:"0.0.42"},Ybi={"top-copper":"Copper,L1,Top","bottom-copper":"Copper,L2,Bot","top-soldermask":"Soldermask,Top","bottom-soldermask":"Soldermask,Bot","top-silkscreen":"Legend,Top","bottom-silkscreen":"Legend,Bot","top-paste":"Paste,Top","bottom-paste":"Paste,Bot",edgecut:"Profile,NP"},wv=e=>{const A=Ybi[e.layer_type?`${e.layer}-${e.layer_type}`:e.layer];return QE().add("add_attribute_on_file",{attribute_name:"GenerationSoftware",attribute_value:`tscircuit,circuit-json-to-gerber,${Hbi.version}`}).add("add_attribute_on_file",{attribute_name:"CreationDate",attribute_value:new Date().toISOString()}).add("add_attribute_on_file",{attribute_name:"SameCoordinates",attribute_value:"Original"}).add("add_attribute_on_file",{attribute_name:"FileFunction",attribute_value:A}).$if(e.layer!=="edgecut",t=>t.add("add_attribute_on_file",{attribute_name:"FilePolarity",attribute_value:e.layer_type==="soldermask"?"Negative":"Positive"})).add("format_specification",{}).add("set_unit",{unit:"MM"}).add("comment",{comment:"Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)"}).add("comment",{comment:`Created by tscircuit (builder) date ${new Date().toISOString()}`}).add("set_movement_mode_to_linear",{}).add("set_layer_polarity",{polarity:"D"}).add("create_arc",{}).build()},Jbi={top:"F_",bottom:"B_"},Tbi={copper:"Cu",silkscreen:"SilkScreen",soldermask:"Mask",mask:"Mask",paste:"Paste"},hw=(e,A)=>e==="edgecut"?"Edge_Cuts":`${Jbi[e]}${Tbi[A]}`,Kbi=(e,A={})=>{A.flip_y_axis??=!1;const t={F_Cu:wv({layer:"top",layer_type:"copper"}),F_SilkScreen:wv({layer:"top",layer_type:"silkscreen"}),F_Mask:wv({layer:"top",layer_type:"soldermask"}),F_Paste:wv({layer:"top",layer_type:"paste"}),B_Cu:wv({layer:"bottom",layer_type:"copper"}),B_SilkScreen:wv({layer:"bottom",layer_type:"silkscreen"}),B_Mask:wv({layer:"bottom",layer_type:"soldermask"}),B_Paste:wv({layer:"bottom",layer_type:"paste"}),Edge_Cuts:wv({layer:"edgecut"})};for(const o of["F_Cu","B_Cu","F_Mask","B_Mask","F_Paste","B_Paste","F_SilkScreen","B_SilkScreen"]){const s=t[o];Gbi(s),Lbi({soup:e,glayer:s,glayer_name:o})}t.Edge_Cuts.push(...QE().add("define_aperture_template",{aperture_number:10,standard_template_code:"C",diameter:.05}).build());const i=o=>A.flip_y_axis?-o:o,n=new Map;for(const o of e)if(o.type==="pcb_plated_hole"&&"x"in o&&typeof o.x=="number"&&"y"in o&&typeof o.y=="number"){const s="ccw_rotation"in o&&typeof o.ccw_rotation=="number"?o.ccw_rotation:0;n.set(`${o.x}:${o.y}`,s)}for(const o of["top","bottom","edgecut"])for(const s of e)if(s.type==="pcb_trace"){const{route:r}=s;for(const[a,g]of Nbi(r))if(a.route_type==="wire"&&a.layer===o){const c=t[hw(o,"copper")];c.push(...QE().add("select_aperture",{aperture_number:mv(c,{trace_width:a.width})}).add("move_operation",{x:a.x,y:i(a.y)}).add("plot_operation",{x:g.x,y:i(g.y)}).build())}}else if(s.type==="pcb_silkscreen_path"){if(s.layer===o){const r=t[hw(o,"silkscreen")],a=Vbt(s),g=QE().add("select_aperture",{aperture_number:mv(r,a)});s.route.length>0&&g.add("move_operation",{x:s.route[0].x,y:i(s.route[0].y)});for(let c=1;c<s.route.length;c++)g.add("plot_operation",{x:s.route[c].x,y:i(s.route[c].y)});r.push(...g.build())}}else if(s.type==="pcb_silkscreen_text"){if(s.layer===o){const a=t[hw(o,"silkscreen")],g=jbt(s),c=QE().add("select_aperture",{aperture_number:mv(a,g)});let I=s.anchor_position.x,l=s.anchor_position.y;const B=s.font_size*.7,C=B*.4,h=B*.5,u=s.text.split("").reduce((k,b)=>b===" "?k+h+C:k+B+C,0)-C,E=B;switch(s.anchor_alignment||(()=>{const k=s.anchor_side;if(k)switch(k){case"top":return"top_center";case"bottom":return"bottom_center";case"left":return"center_left";case"right":return"center_right"}})()||"center"){case"top_left":break;case"top_center":I-=u/2;break;case"top_right":I-=u;break;case"center_right":l-=E/2;break;case"center_left":I-=u,l-=E/2;break;case"bottom_left":l-=E;break;case"bottom_center":I-=u/2,l-=E;break;case"bottom_right":I-=u,l-=E;break;default:I-=u/2,l-=E/2;break}let f=I;const m=l;let S=s.ccw_rotation||0;const _=f+u/2,v=m+E/2,D=[];if(s.layer==="bottom"&&(D.push(QU(_,v),{a:-1,b:0,c:0,d:1,e:0,f:0},QU(-_,-v)),S=-S),S){const k=S*Math.PI/180;D.push(QU(_,v),gkA(k),QU(-_,-v))}for(const k of s.text.toUpperCase()){if(k===" "){f+=h+C;continue}const b=rkA[k]||[];for(const M of b){const N=f+M.x1*B,T=m+M.y1*B,K=f+M.x2*B,P=m+M.y2*B;let V={x:N,y:T},z={x:K,y:P};if(D.length>0){const nA=akA(...D);V=Vk(nA,V),z=Vk(nA,z)}c.add("move_operation",{x:V.x,y:i(V.y)}),c.add("plot_operation",{x:z.x,y:i(z.y)})}f+=B+C}a.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape!=="polygon"){if(s.layer===o)for(const r of[t[hw(o,"copper")],t[hw(o,"soldermask")]]){const a=Zbt(s),g=mv(r,a),c=QE().add("select_aperture",{aperture_number:g});s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:s.ccw_rotation}),c.add("flash_operation",{x:s.x,y:i(s.y)}),s.shape==="rotated_rect"&&s.ccw_rotation&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_smtpad"&&s.shape==="polygon"){if(s.layer===o){const r=[t[hw(o,"copper")]];(!("is_covered_with_solder_mask"in s)||s.is_covered_with_solder_mask!==!1)&&r.push(t[hw(o,"soldermask")]);for(const a of r){const g=QE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{}),{points:c}=s;if(c&&c.length>0){g.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)g.add("plot_operation",{x:c[I].x,y:i(c[I].y)});g.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}g.add("end_region_statement",{}),a.push(...g.build())}}}else if(s.type==="pcb_solder_paste"){if(s.layer===o){const r=t[hw(o,"paste")],a=mv(r,zbt(s)),g="ccw_rotation"in s&&typeof s.ccw_rotation=="number"?s.ccw_rotation:n.get(`${s.x}:${s.y}`)??0,c=QE().add("select_aperture",{aperture_number:a});g&&c.add("load_rotation",{rotation_degrees:g}),c.add("flash_operation",{x:s.x,y:i(s.y)}),g&&c.add("load_rotation",{rotation_degrees:0}),r.push(...c.build())}}else if(s.type==="pcb_plated_hole"){if(s.layers.includes(o))for(const r of[t[hw(o,"copper")],t[hw(o,"soldermask")]]){const a="hole_width"in s&&typeof s.hole_width=="number"?s.hole_width:0,g="hole_height"in s&&typeof s.hole_height=="number"?s.hole_height:0,c=[a];"outer_width"in s&&typeof s.outer_width=="number"&&c.push(s.outer_width),"rect_pad_width"in s&&typeof s.rect_pad_width=="number"&&c.push(s.rect_pad_width);const I=Math.max(...c),l=[g];"outer_height"in s&&typeof s.outer_height=="number"&&l.push(s.outer_height),"rect_pad_height"in s&&typeof s.rect_pad_height=="number"&&l.push(s.rect_pad_height);const B=Math.max(...l);if(s.shape==="pill"){const C={standard_template_code:"C",diameter:Math.min(I,B)};let h;try{h=mv(r,C)}catch{h=Math.max(...r.filter(v=>"aperture_number"in v).map(v=>v.aperture_number),9)+1,r.push(...QE().add("define_aperture_template",{aperture_number:h,...C}).build())}const u=QE().add("select_aperture",{aperture_number:h}),E=(s.ccw_rotation??0)*Math.PI/180,p=Math.cos(E),f=Math.sin(E),m=(v,D)=>{const k=v*p-D*f,b=v*f+D*p;return{x:s.x+k,y:s.y+b}},S=I>=B,_=S?(I-B)/2:(B-I)/2;if(_<=0){const v=m(0,0);u.add("flash_operation",{x:v.x,y:i(v.y)})}else{const v=S?{x:-_,y:0}:{x:0,y:-_},D=S?{x:_,y:0}:{x:0,y:_},k=m(v.x,v.y),b=m(D.x,D.y);u.add("flash_operation",{x:k.x,y:i(k.y)}).add("move_operation",{x:k.x,y:i(k.y)}).add("plot_operation",{x:b.x,y:i(b.y)}).add("flash_operation",{x:b.x,y:i(b.y)})}r.push(...u.build())}else{const C=Xbt({...s,...s.shape!=="circle"?{outer_width:I,outer_height:B}:{}}),h="rect_ccw_rotation"in s&&typeof s.rect_ccw_rotation=="number"?s.rect_ccw_rotation:void 0,u=QE().add("select_aperture",{aperture_number:mv(r,C)});h&&u.add("load_rotation",{rotation_degrees:h}),u.add("flash_operation",{x:s.x,y:i(s.y)}),h&&u.add("load_rotation",{rotation_degrees:0}),r.push(...u.build())}}}else if(s.type==="pcb_hole"){if(o!=="edgecut")for(const r of[t[hw(o,"soldermask")]]){if(s.hole_shape!=="circle"){console.warn("NOT IMPLEMENTED: drawing gerber for non-round holes");continue}r.push(...QE().add("select_aperture",{aperture_number:mv(r,$bt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}}else if(s.type==="pcb_via"){if(s.layers.includes(o))for(const r of[t[hw(o,"copper")]])r.push(...QE().add("select_aperture",{aperture_number:mv(r,ASt(s))}).add("flash_operation",{x:s.x,y:i(s.y)}).build())}else if(s.type==="pcb_board"&&o==="edgecut"){if(s.pcb_panel_id)continue;const a=t.Edge_Cuts,{width:g,height:c,center:I,outline:l}=s,B=QE().add("select_aperture",{aperture_number:10});if(l&&l.length>2){const C=l.map(E=>({x:E.x,y:i(E.y)})),h=C[0];B.add("move_operation",h);for(let E=1;E<C.length;E++)B.add("plot_operation",C[E]);const u=C[C.length-1];(u.x!==h.x||u.y!==h.y)&&B.add("plot_operation",h)}else B.add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});a.push(...B.build())}else if(s.type==="pcb_panel"&&o==="edgecut"){const r=t.Edge_Cuts,a=s,{width:g,height:c,center:I}=a,l=QE().add("select_aperture",{aperture_number:10}).add("move_operation",{x:I.x-g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y-c/2)}).add("plot_operation",{x:I.x+g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y+c/2)}).add("plot_operation",{x:I.x-g/2,y:i(I.y-c/2)});r.push(...l.build())}else if(s.type==="pcb_cutout"){if(o==="edgecut"){const r=t.Edge_Cuts,a=QE().add("select_aperture",{aperture_number:10}),g=s;if(g.shape==="rect"){const{center:c,width:I,height:l,rotation:B,corner_radius:C}=g,h=I/2,u=l/2,E=Math.max(0,Math.min(C??0,Math.abs(h),Math.abs(u))),f=(()=>{let m=Kbt();if(B){const S=B*Math.PI/180;m=gkA(S)}return akA(QU(c.x,c.y),m)})();if(E>0){const m={x:-h+E,y:u};let S=Vk(f,m);a.add("move_operation",{x:S.x,y:i(S.y)});const _=D=>{const k=Vk(f,D);a.add("plot_operation",{x:k.x,y:i(k.y)}),S=k},v=D=>{const k=Vk(f,D.point),b=Vk(f,D.center);a.add("set_movement_mode_to_clockwise_circular",{}).add("plot_operation",{x:k.x,y:i(k.y),i:b.x-S.x,j:i(b.y)-i(S.y)}).add("set_movement_mode_to_linear",{}),S=k};_({x:h-E,y:u}),v({point:{x:h,y:u-E},center:{x:h-E,y:u-E}}),_({x:h,y:-u+E}),v({point:{x:h-E,y:-u},center:{x:h-E,y:-u+E}}),_({x:-h+E,y:-u}),v({point:{x:-h,y:-u+E},center:{x:-h+E,y:-u+E}}),_({x:-h,y:u-E}),v({point:{x:-h+E,y:u},center:{x:-h+E,y:u-E}})}else{const S=[{x:-h,y:u},{x:h,y:u},{x:h,y:-u},{x:-h,y:-u}].map(_=>Vk(f,_));a.add("move_operation",{x:S[0].x,y:i(S[0].y)});for(let _=1;_<S.length;_++)a.add("plot_operation",{x:S[_].x,y:i(S[_].y)});a.add("plot_operation",{x:S[0].x,y:i(S[0].y)})}}else if(g.shape==="circle"){const{center:c,radius:I}=g,l={x:c.x+I,y:c.y},B={x:c.x-I,y:c.y};a.add("move_operation",{x:l.x,y:i(l.y)}).add("set_movement_mode_to_counterclockwise_circular",{}).add("plot_operation",{x:B.x,y:i(B.y),i:-I,j:0}).add("plot_operation",{x:l.x,y:i(l.y),i:I,j:0}).add("set_movement_mode_to_linear",{})}else if(g.shape==="polygon"){const{points:c}=g;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}r.push(...a.build())}}else if(s.type==="pcb_copper_pour"&&o===s.layer){const r=t[hw(o,"copper")],a=QE().add("select_aperture",{aperture_number:10}).add("start_region_statement",{});if(s.shape==="brep"){const{brep_shape:c}=s;if(!c)continue;const{outer_ring:I,inner_rings:l}=c,B=h=>{if(!h||h.vertices.length===0)return;a.add("move_operation",{x:h.vertices[0].x,y:i(h.vertices[0].y)});const u=[...h.vertices,h.vertices[0]];for(let E=0;E<u.length-1;E++){const p=u[E],f=u[E+1];if(p.bulge&&Math.abs(p.bulge)>1e-9){const m=(A.flip_y_axis?-1:1)*p.bulge;m>0?a.add("set_movement_mode_to_counterclockwise_circular",{}):a.add("set_movement_mode_to_clockwise_circular",{});const S={x:p.x,y:p.y},_={x:f.x,y:f.y},v=_.x-S.x,D=_.y-S.y,k=Math.sqrt(v*v+D*D);if(k<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const b=Math.abs(m),M=4*Math.atan(b);if(Math.abs(Math.sin(M/2))<1e-9){a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)});continue}const N=k/(2*Math.sin(M/2)),T=(Math.PI-M)/2,K=Math.atan2(D,v),P=m>0?T:-T,V=K+P,z=S.x+N*Math.cos(V),nA=S.y+N*Math.sin(V),cA=z-S.x,hA=nA-S.y;a.add("plot_operation",{x:f.x,y:i(f.y),i:cA,j:A.flip_y_axis?-hA:hA})}else a.add("set_movement_mode_to_linear",{}),a.add("plot_operation",{x:f.x,y:i(f.y)})}},C=h=>{const{vertices:u}=h;if(!u||u.length===0)return{vertices:[]};const E=u.length;return{vertices:[...u].reverse().map((m,S)=>{const _=(E-2-S+E)%E,v=u[_].bulge;return{...m,bulge:v?-v:void 0}})}};if(B(C(I)),l)for(const h of l)B(C(h))}else if(s.shape==="rect"){const{center:c,width:I,height:l,rotation:B}=s,C=I/2,h=l/2,u=[{x:-C,y:h},{x:C,y:h},{x:C,y:-h},{x:-C,y:-h}];let E=Kbt();if(B){const f=B*Math.PI/180;E=gkA(f)}E=akA(QU(c.x,c.y),E);const p=u.map(f=>Vk(E,f));a.add("move_operation",{x:p[0].x,y:i(p[0].y)});for(let f=1;f<p.length;f++)a.add("plot_operation",{x:p[f].x,y:i(p[f].y)});a.add("plot_operation",{x:p[0].x,y:i(p[0].y)})}else if(s.shape==="polygon"){const{points:c}=s;if(c.length>0){a.add("move_operation",{x:c[0].x,y:i(c[0].y)});for(let I=1;I<c.length;I++)a.add("plot_operation",{x:c[I].x,y:i(c[I].y)});a.add("plot_operation",{x:c[0].x,y:i(c[0].y)})}}a.add("end_region_statement",{});const g=a.build();r.push(...g),s.covered_with_solder_mask===!1&&t[hw(o,"soldermask")].push(...g)}for(const o of Object.keys(t))t[o].push(...QE().add("end_of_file",{}).build());return t},b3={},ckA={},tSt;function qbi(){return tSt||(tSt=1,(function(e){Object.defineProperty(e,"__esModule",{value:!0});var A=(function(){function o(s,r){var a=[],g=!0,c=!1,I=void 0;try{for(var l=s[Symbol.iterator](),B;!(g=(B=l.next()).done)&&(a.push(B.value),!(r&&a.length===r));g=!0);}catch(C){c=!0,I=C}finally{try{!g&&l.return&&l.return()}finally{if(c)throw I}}return a}return function(s,r){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return o(s,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();e.default=i,e.parseUnitObj=n;var t=/-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/;function i(o){var s=parseFloat(o),r=o.match(t)||[],a=r.length>0?o.substr(r[0].length).trim():"";return[s,a]}function n(o){var s=i(o),r=A(s,2),a=r[0],g=r[1];return{val:a,unit:g}}})(ckA)),ckA}var eSt;function Pbi(){if(eSt)return b3;eSt=1,Object.defineProperty(b3,"__esModule",{value:!0});var e=(function(){function a(g,c){var I=[],l=!0,B=!1,C=void 0;try{for(var h=g[Symbol.iterator](),u;!(l=(u=h.next()).done)&&(I.push(u.value),!(c&&I.length===c));l=!0);}catch(E){B=!0,C=E}finally{try{!l&&h.return&&h.return()}finally{if(B)throw C}}return I}return function(g,c){if(Array.isArray(g))return g;if(Symbol.iterator in Object(g))return a(g,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();b3.formatSI=o,b3.unformatSI=r;function A(a){return a&&a.__esModule?a:{default:a}}var t=qbi(),i=A(t),n={24:"Y",21:"Z",18:"E",15:"P",12:"T",9:"G",6:"M",3:"k",0:"","-3":"m","-6":"µ","-9":"n","-12":"p","-15":"f","-18":"a","-21":"z","-24":"y"};function o(a){if(a===0)return"0";for(var g=Math.abs(a),c=0;g>=1e3&&c<24;)g/=1e3,c+=3;for(;g<1&&c>-24;)g*=1e3,c-=3;var I=a<0?"-":"";return g>1e3?I+g.toFixed(0)+n[c]:I+parseFloat(g.toPrecision(3))+n[c]}var s={Y:1e24,Z:1e21,E:1e18,P:1e15,T:1e12,G:1e9,M:1e6,k:1e3,"":1,m:.001,µ:1e-6,u:1e-6,n:1e-9,p:1e-12,f:1e-15,a:1e-18,z:1e-21,y:1e-24};function r(a){if(a==null||a==="")return NaN;var g=(0,i.default)(a),c=e(g,2),I=c[0],l=c[1],B=s[l];return I*B}return b3}var Obi=Pbi(),tAA={exports:{}};/* @license
6727
6727
  Papa Parse
6728
6728
  v5.5.3
6729
6729
  https://github.com/mholt/PapaParse
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/runframe",
3
3
  "main": "dist/preview.js",
4
4
  "type": "module",
5
- "version": "0.0.1341",
5
+ "version": "0.0.1342",
6
6
  "exports": {
7
7
  ".": "./dist/preview.js",
8
8
  "./preview": "./dist/preview.js",
@@ -67,7 +67,7 @@
67
67
  "chokidar-cli": "^3.0.0",
68
68
  "circuit-json": "0.0.303",
69
69
  "circuit-json-to-bom-csv": "^0.0.8",
70
- "circuit-json-to-gerber": "^0.0.42",
70
+ "circuit-json-to-gerber": "^0.0.43",
71
71
  "circuit-json-to-gltf": "^0.0.41",
72
72
  "circuit-json-to-kicad": "^0.0.25",
73
73
  "circuit-json-to-lbrn": "^0.0.4",