@tscircuit/3d-viewer 0.0.429 → 0.0.431

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.
Files changed (2) hide show
  1. package/dist/index.js +1674 -188
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1129,13 +1129,13 @@ var require_squaredLength = __commonJS({
1129
1129
  var require_subtract = __commonJS({
1130
1130
  "node_modules/@jscad/modeling/src/maths/vec3/subtract.js"(exports, module) {
1131
1131
  "use strict";
1132
- var subtract5 = (out, a, b) => {
1132
+ var subtract6 = (out, a, b) => {
1133
1133
  out[0] = a[0] - b[0];
1134
1134
  out[1] = a[1] - b[1];
1135
1135
  out[2] = a[2] - b[2];
1136
1136
  return out;
1137
1137
  };
1138
- module.exports = subtract5;
1138
+ module.exports = subtract6;
1139
1139
  }
1140
1140
  });
1141
1141
 
@@ -1676,7 +1676,7 @@ var require_scale2 = __commonJS({
1676
1676
  var require_subtract2 = __commonJS({
1677
1677
  "node_modules/@jscad/modeling/src/maths/mat4/subtract.js"(exports, module) {
1678
1678
  "use strict";
1679
- var subtract5 = (out, a, b) => {
1679
+ var subtract6 = (out, a, b) => {
1680
1680
  out[0] = a[0] - b[0];
1681
1681
  out[1] = a[1] - b[1];
1682
1682
  out[2] = a[2] - b[2];
@@ -1695,7 +1695,7 @@ var require_subtract2 = __commonJS({
1695
1695
  out[15] = a[15] - b[15];
1696
1696
  return out;
1697
1697
  };
1698
- module.exports = subtract5;
1698
+ module.exports = subtract6;
1699
1699
  }
1700
1700
  });
1701
1701
 
@@ -1712,7 +1712,7 @@ var require_toString2 = __commonJS({
1712
1712
  var require_translate = __commonJS({
1713
1713
  "node_modules/@jscad/modeling/src/maths/mat4/translate.js"(exports, module) {
1714
1714
  "use strict";
1715
- var translate8 = (out, matrix, offsets) => {
1715
+ var translate9 = (out, matrix, offsets) => {
1716
1716
  const x = offsets[0];
1717
1717
  const y = offsets[1];
1718
1718
  const z133 = offsets[2];
@@ -1765,7 +1765,7 @@ var require_translate = __commonJS({
1765
1765
  }
1766
1766
  return out;
1767
1767
  };
1768
- module.exports = translate8;
1768
+ module.exports = translate9;
1769
1769
  }
1770
1770
  });
1771
1771
 
@@ -2205,12 +2205,12 @@ var require_squaredLength2 = __commonJS({
2205
2205
  var require_subtract3 = __commonJS({
2206
2206
  "node_modules/@jscad/modeling/src/maths/vec2/subtract.js"(exports, module) {
2207
2207
  "use strict";
2208
- var subtract5 = (out, a, b) => {
2208
+ var subtract6 = (out, a, b) => {
2209
2209
  out[0] = a[0] - b[0];
2210
2210
  out[1] = a[1] - b[1];
2211
2211
  return out;
2212
2212
  };
2213
- module.exports = subtract5;
2213
+ module.exports = subtract6;
2214
2214
  }
2215
2215
  });
2216
2216
 
@@ -2671,14 +2671,14 @@ var require_point_line_distance = __commonJS({
2671
2671
  "node_modules/@jscad/modeling/src/operations/hulls/quickhull/point-line-distance.js"(exports, module) {
2672
2672
  "use strict";
2673
2673
  var cross = require_cross();
2674
- var subtract5 = require_subtract();
2674
+ var subtract6 = require_subtract();
2675
2675
  var squaredLength = require_squaredLength();
2676
2676
  var distanceSquared = (p, a, b) => {
2677
2677
  const ab = [];
2678
2678
  const ap = [];
2679
2679
  const cr = [];
2680
- subtract5(ab, b, a);
2681
- subtract5(ap, p, a);
2680
+ subtract6(ab, b, a);
2681
+ subtract6(ap, p, a);
2682
2682
  const area = squaredLength(cross(cr, ap, ab));
2683
2683
  const s = squaredLength(ab);
2684
2684
  if (s === 0) {
@@ -2697,11 +2697,11 @@ var require_get_plane_normal = __commonJS({
2697
2697
  "use strict";
2698
2698
  var cross = require_cross();
2699
2699
  var normalize = require_normalize();
2700
- var subtract5 = require_subtract();
2700
+ var subtract6 = require_subtract();
2701
2701
  var planeNormal = (out, point1, point2, point32) => {
2702
2702
  const tmp = [0, 0, 0];
2703
- subtract5(out, point1, point2);
2704
- subtract5(tmp, point2, point32);
2703
+ subtract6(out, point1, point2);
2704
+ subtract6(tmp, point2, point32);
2705
2705
  cross(out, out, tmp);
2706
2706
  return normalize(out, out);
2707
2707
  };
@@ -2915,7 +2915,7 @@ var require_Face = __commonJS({
2915
2915
  var length2 = require_length();
2916
2916
  var normalize = require_normalize();
2917
2917
  var scale2 = require_scale();
2918
- var subtract5 = require_subtract();
2918
+ var subtract6 = require_subtract();
2919
2919
  var HalfEdge = require_HalfEdge();
2920
2920
  var VISIBLE = 0;
2921
2921
  var NON_CONVEX = 1;
@@ -2949,14 +2949,14 @@ var require_Face = __commonJS({
2949
2949
  const e0 = this.edge;
2950
2950
  const e1 = e0.next;
2951
2951
  let e2 = e1.next;
2952
- const v2 = subtract5([], e1.head().point, e0.head().point);
2952
+ const v2 = subtract6([], e1.head().point, e0.head().point);
2953
2953
  const t = [];
2954
2954
  const v1 = [];
2955
2955
  this.nVertices = 2;
2956
2956
  this.normal = [0, 0, 0];
2957
2957
  while (e2 !== e0) {
2958
2958
  copy(v1, v2);
2959
- subtract5(v2, e2.head().point, e0.head().point);
2959
+ subtract6(v2, e2.head().point, e0.head().point);
2960
2960
  add(this.normal, this.normal, cross(t, v1, v2));
2961
2961
  e2 = e2.next;
2962
2962
  this.nVertices += 1;
@@ -2980,7 +2980,7 @@ var require_Face = __commonJS({
2980
2980
  } while (edge !== this.edge);
2981
2981
  const p1 = maxEdge.tail().point;
2982
2982
  const p2 = maxEdge.head().point;
2983
- const maxVector = subtract5([], p2, p1);
2983
+ const maxVector = subtract6([], p2, p1);
2984
2984
  const maxLength = Math.sqrt(maxSquaredLength);
2985
2985
  scale2(maxVector, maxVector, 1 / maxLength);
2986
2986
  const maxProjection = dot(this.normal, maxVector);
@@ -5426,7 +5426,7 @@ var require_colorize = __commonJS({
5426
5426
  newpoly.color = color;
5427
5427
  return newpoly;
5428
5428
  };
5429
- var colorize7 = (color, ...objects) => {
5429
+ var colorize8 = (color, ...objects) => {
5430
5430
  if (!Array.isArray(color)) throw new Error("color must be an array");
5431
5431
  if (color.length < 3) throw new Error("color must contain R, G and B values");
5432
5432
  if (color.length === 3) color = [color[0], color[1], color[2], 1];
@@ -5442,7 +5442,7 @@ var require_colorize = __commonJS({
5442
5442
  });
5443
5443
  return results.length === 1 ? results[0] : results;
5444
5444
  };
5445
- module.exports = colorize7;
5445
+ module.exports = colorize8;
5446
5446
  }
5447
5447
  });
5448
5448
 
@@ -7555,7 +7555,7 @@ var require_circle = __commonJS({
7555
7555
  var { TAU } = require_constants();
7556
7556
  var ellipse = require_ellipse();
7557
7557
  var { isGTE } = require_commonChecks();
7558
- var circle = (options) => {
7558
+ var circle2 = (options) => {
7559
7559
  const defaults = {
7560
7560
  center: [0, 0],
7561
7561
  radius: 1,
@@ -7568,7 +7568,7 @@ var require_circle = __commonJS({
7568
7568
  radius = [radius, radius];
7569
7569
  return ellipse({ center, radius, startAngle, endAngle, segments });
7570
7570
  };
7571
- module.exports = circle;
7571
+ module.exports = circle2;
7572
7572
  }
7573
7573
  });
7574
7574
 
@@ -9746,7 +9746,7 @@ var require_translate2 = __commonJS({
9746
9746
  var geom2 = require_geom2();
9747
9747
  var geom3 = require_geom3();
9748
9748
  var path2 = require_path2();
9749
- var translate8 = (offset4, ...objects) => {
9749
+ var translate9 = (offset4, ...objects) => {
9750
9750
  if (!Array.isArray(offset4)) throw new Error("offset must be an array");
9751
9751
  objects = flatten(objects);
9752
9752
  if (objects.length === 0) throw new Error("wrong number of arguments");
@@ -9761,11 +9761,11 @@ var require_translate2 = __commonJS({
9761
9761
  });
9762
9762
  return results.length === 1 ? results[0] : results;
9763
9763
  };
9764
- var translateX = (offset4, ...objects) => translate8([offset4, 0, 0], objects);
9765
- var translateY = (offset4, ...objects) => translate8([0, offset4, 0], objects);
9766
- var translateZ = (offset4, ...objects) => translate8([0, 0, offset4], objects);
9764
+ var translateX = (offset4, ...objects) => translate9([offset4, 0, 0], objects);
9765
+ var translateY = (offset4, ...objects) => translate9([0, offset4, 0], objects);
9766
+ var translateZ = (offset4, ...objects) => translate9([0, 0, offset4], objects);
9767
9767
  module.exports = {
9768
- translate: translate8,
9768
+ translate: translate9,
9769
9769
  translateX,
9770
9770
  translateY,
9771
9771
  translateZ
@@ -9780,8 +9780,8 @@ var require_torus = __commonJS({
9780
9780
  var { TAU } = require_constants();
9781
9781
  var extrudeRotate = require_extrudeRotate();
9782
9782
  var { rotate: rotate2 } = require_rotate3();
9783
- var { translate: translate8 } = require_translate2();
9784
- var circle = require_circle();
9783
+ var { translate: translate9 } = require_translate2();
9784
+ var circle2 = require_circle();
9785
9785
  var { isGT, isGTE } = require_commonChecks();
9786
9786
  var torus = (options) => {
9787
9787
  const defaults = {
@@ -9801,11 +9801,11 @@ var require_torus = __commonJS({
9801
9801
  if (!isGTE(startAngle, 0)) throw new Error("startAngle must be positive");
9802
9802
  if (!isGT(outerRotation, 0)) throw new Error("outerRotation must be greater than zero");
9803
9803
  if (innerRadius >= outerRadius) throw new Error("inner circle is too large to rotate about the outer circle");
9804
- let innerCircle = circle({ radius: innerRadius, segments: innerSegments });
9804
+ let innerCircle = circle2({ radius: innerRadius, segments: innerSegments });
9805
9805
  if (innerRotation !== 0) {
9806
9806
  innerCircle = rotate2([0, 0, innerRotation], innerCircle);
9807
9807
  }
9808
- innerCircle = translate8([outerRadius, 0], innerCircle);
9808
+ innerCircle = translate9([outerRadius, 0], innerCircle);
9809
9809
  const extrudeOptions = {
9810
9810
  startAngle,
9811
9811
  angle: outerRotation,
@@ -11612,7 +11612,7 @@ var require_subtractGeom3 = __commonJS({
11612
11612
  var flatten = require_flatten();
11613
11613
  var retessellate = require_retessellate();
11614
11614
  var subtractSub = require_subtractGeom3Sub();
11615
- var subtract5 = (...geometries) => {
11615
+ var subtract6 = (...geometries) => {
11616
11616
  geometries = flatten(geometries);
11617
11617
  let newgeometry = geometries.shift();
11618
11618
  geometries.forEach((geometry) => {
@@ -11621,7 +11621,7 @@ var require_subtractGeom3 = __commonJS({
11621
11621
  newgeometry = retessellate(newgeometry);
11622
11622
  return newgeometry;
11623
11623
  };
11624
- module.exports = subtract5;
11624
+ module.exports = subtract6;
11625
11625
  }
11626
11626
  });
11627
11627
 
@@ -11635,14 +11635,14 @@ var require_subtractGeom2 = __commonJS({
11635
11635
  var fromFakePolygons = require_fromFakePolygons();
11636
11636
  var to3DWalls = require_to3DWalls();
11637
11637
  var subtractGeom3 = require_subtractGeom3();
11638
- var subtract5 = (...geometries) => {
11638
+ var subtract6 = (...geometries) => {
11639
11639
  geometries = flatten(geometries);
11640
11640
  const newgeometries = geometries.map((geometry) => to3DWalls({ z0: -1, z1: 1 }, geometry));
11641
11641
  const newgeom3 = subtractGeom3(newgeometries);
11642
11642
  const epsilon = measureEpsilon(newgeom3);
11643
11643
  return fromFakePolygons(epsilon, geom3.toPolygons(newgeom3));
11644
11644
  };
11645
- module.exports = subtract5;
11645
+ module.exports = subtract6;
11646
11646
  }
11647
11647
  });
11648
11648
 
@@ -11656,7 +11656,7 @@ var require_subtract4 = __commonJS({
11656
11656
  var geom3 = require_geom3();
11657
11657
  var subtractGeom2 = require_subtractGeom2();
11658
11658
  var subtractGeom3 = require_subtractGeom3();
11659
- var subtract5 = (...geometries) => {
11659
+ var subtract6 = (...geometries) => {
11660
11660
  geometries = flatten(geometries);
11661
11661
  if (geometries.length === 0) throw new Error("wrong number of arguments");
11662
11662
  if (!areAllShapesTheSameType(geometries)) {
@@ -11667,7 +11667,7 @@ var require_subtract4 = __commonJS({
11667
11667
  if (geom3.isA(geometry)) return subtractGeom3(geometries);
11668
11668
  return geometry;
11669
11669
  };
11670
- module.exports = subtract5;
11670
+ module.exports = subtract6;
11671
11671
  }
11672
11672
  });
11673
11673
 
@@ -12451,7 +12451,7 @@ var require_extrudeLinear = __commonJS({
12451
12451
  var path2 = require_path2();
12452
12452
  var extrudeLinearGeom2 = require_extrudeLinearGeom2();
12453
12453
  var extrudeLinearPath2 = require_extrudeLinearPath2();
12454
- var extrudeLinear7 = (options, ...objects) => {
12454
+ var extrudeLinear8 = (options, ...objects) => {
12455
12455
  const defaults = {
12456
12456
  height: 1,
12457
12457
  twistAngle: 0,
@@ -12469,7 +12469,7 @@ var require_extrudeLinear = __commonJS({
12469
12469
  });
12470
12470
  return results.length === 1 ? results[0] : results;
12471
12471
  };
12472
- module.exports = extrudeLinear7;
12472
+ module.exports = extrudeLinear8;
12473
12473
  }
12474
12474
  });
12475
12475
 
@@ -13528,7 +13528,7 @@ var require_align = __commonJS({
13528
13528
  var flatten = require_flatten();
13529
13529
  var padArrayToLength = require_padArrayToLength();
13530
13530
  var measureAggregateBoundingBox = require_measureAggregateBoundingBox();
13531
- var { translate: translate8 } = require_translate2();
13531
+ var { translate: translate9 } = require_translate2();
13532
13532
  var validateOptions = (options) => {
13533
13533
  if (!Array.isArray(options.modes) || options.modes.length > 3) throw new Error("align(): modes must be an array of length <= 3");
13534
13534
  options.modes = padArrayToLength(options.modes, "none", 3);
@@ -13565,7 +13565,7 @@ var require_align = __commonJS({
13565
13565
  translation[i] = relativeTo[i] - bounds[0][i];
13566
13566
  }
13567
13567
  }
13568
- return translate8(translation, geometry);
13568
+ return translate9(translation, geometry);
13569
13569
  };
13570
13570
  var align = (options, ...geometries) => {
13571
13571
  const defaults = {
@@ -13602,7 +13602,7 @@ var require_center = __commonJS({
13602
13602
  var geom3 = require_geom3();
13603
13603
  var path2 = require_path2();
13604
13604
  var measureBoundingBox = require_measureBoundingBox2();
13605
- var { translate: translate8 } = require_translate2();
13605
+ var { translate: translate9 } = require_translate2();
13606
13606
  var centerGeometry = (options, object) => {
13607
13607
  const defaults = {
13608
13608
  axes: [true, true, true],
@@ -13614,7 +13614,7 @@ var require_center = __commonJS({
13614
13614
  if (axes[0]) offset4[0] = relativeTo[0] - (bounds[0][0] + (bounds[1][0] - bounds[0][0]) / 2);
13615
13615
  if (axes[1]) offset4[1] = relativeTo[1] - (bounds[0][1] + (bounds[1][1] - bounds[0][1]) / 2);
13616
13616
  if (axes[2]) offset4[2] = relativeTo[2] - (bounds[0][2] + (bounds[1][2] - bounds[0][2]) / 2);
13617
- return translate8(offset4, object);
13617
+ return translate9(offset4, object);
13618
13618
  };
13619
13619
  var center = (options, ...objects) => {
13620
13620
  const defaults = {
@@ -15959,6 +15959,8 @@ var pcb_component = z69.object({
15959
15959
  do_not_place: z69.boolean().optional(),
15960
15960
  subcircuit_id: z69.string().optional(),
15961
15961
  pcb_group_id: z69.string().optional(),
15962
+ position_mode: z69.enum(["packed", "relative_to_group_anchor", "none"]).optional(),
15963
+ positioned_relative_to_pcb_group_id: z69.string().optional(),
15962
15964
  obstructs_within_bounds: z69.boolean().default(true).describe(
15963
15965
  "Does this component take up all the space within its bounds on a layer. This is generally true except for when separated pin headers are being represented by a single component (in which case, chips can be placed between the pin headers) or for tall modules where chips fit underneath"
15964
15966
  )
@@ -16488,12 +16490,13 @@ var pcb_board = z83.object({
16488
16490
  pcb_panel_id: z83.string().optional(),
16489
16491
  is_subcircuit: z83.boolean().optional(),
16490
16492
  subcircuit_id: z83.string().optional(),
16491
- width: length,
16492
- height: length,
16493
+ width: length.optional(),
16494
+ height: length.optional(),
16493
16495
  center: point,
16494
16496
  thickness: length.optional().default(1.4),
16495
16497
  num_layers: z83.number().optional().default(4),
16496
16498
  outline: z83.array(point).optional(),
16499
+ shape: z83.enum(["rect", "polygon"]).optional(),
16497
16500
  material: z83.enum(["fr4", "fr1"]).default("fr4")
16498
16501
  }).describe("Defines the board outline of the PCB");
16499
16502
  expectTypesMatch(true);
@@ -16939,6 +16942,7 @@ var pcb_group = z109.object({
16939
16942
  anchor_position: point.optional(),
16940
16943
  anchor_alignment: z109.enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]).optional(),
16941
16944
  pcb_component_ids: z109.array(z109.string()),
16945
+ child_layout_mode: z109.enum(["packed", "none"]).optional(),
16942
16946
  name: z109.string().optional(),
16943
16947
  description: z109.string().optional(),
16944
16948
  layout_mode: z109.string().optional(),
@@ -24319,7 +24323,7 @@ var m2host = (raw_params) => {
24319
24323
  }
24320
24324
  const centerX = (minX + maxX) / 2;
24321
24325
  const centerY = (minY + maxY) / 2;
24322
- const translate8 = (el) => {
24326
+ const translate9 = (el) => {
24323
24327
  if (typeof el.x === "number") el.x -= centerX;
24324
24328
  if (typeof el.y === "number") el.y -= centerY;
24325
24329
  if (el.center) {
@@ -24333,9 +24337,9 @@ var m2host = (raw_params) => {
24333
24337
  }));
24334
24338
  }
24335
24339
  };
24336
- for (const pad2 of pads) translate8(pad2);
24337
- translate8(cutout);
24338
- translate8(pin1Marker);
24340
+ for (const pad2 of pads) translate9(pad2);
24341
+ translate9(cutout);
24342
+ translate9(pin1Marker);
24339
24343
  return {
24340
24344
  circuitJson: [
24341
24345
  ...pads,
@@ -24576,6 +24580,7 @@ var Hull = Symbol("Hull");
24576
24580
  var Colorize = Symbol("Colorize");
24577
24581
  var Polygon = Symbol("Polygon");
24578
24582
  var ExtrudeLinear = Symbol("ExtrudeLinear");
24583
+ var RoundedCylinder = Symbol("RoundedCylinder");
24579
24584
  var Fragment22 = Fragment2;
24580
24585
  var jsx5 = (type, props, _key) => h(type, props);
24581
24586
  var jsxs = (type, props, _key) => h(type, props);
@@ -24584,31 +24589,68 @@ var ChipBody = ({
24584
24589
  width: width10,
24585
24590
  length: length2,
24586
24591
  height: height10,
24587
- heightAboveSurface: heightAboveSurface2 = 0.15
24592
+ heightAboveSurface: heightAboveSurface2 = 0.15,
24593
+ color = "#555",
24594
+ taperRatio = 0.12,
24595
+ faceRatio = 0.75,
24596
+ straightHeightRatio = 0.5,
24597
+ includeNotch = true,
24598
+ notchRadius,
24599
+ notchPosition,
24600
+ notchRotation = [0, 0, 0],
24601
+ notchLength = 0.5,
24602
+ notchWidth = 0.25,
24603
+ chamferSize = 0
24588
24604
  }) => {
24589
- const straightHeight = height10 * 0.5;
24605
+ const straightHeight = height10 * straightHeightRatio;
24590
24606
  const taperHeight = height10 - straightHeight;
24591
- const taperInset = Math.min(width10, length2) * 0.12;
24592
- const faceWidth = Math.max(width10 - taperInset, width10 * 0.75);
24593
- const faceLength = Math.max(length2 - taperInset, length2 * 0.75);
24594
- const notchRadius = Math.min(width10, length2) * 0.12;
24595
- const notchCenterZ = height10 - notchRadius * 0.6;
24596
- const notchCenterY = length2 / 2 - notchRadius * 0.25;
24597
- const notchLength = faceLength / 8;
24598
- const notchWidth = height10 / 4;
24599
- return /* @__PURE__ */ jsx5(Colorize, { color: "#555", children: /* @__PURE__ */ jsx5(Translate, { offset: center, children: /* @__PURE__ */ jsx5(Translate, { offset: { x: 0, y: 0, z: heightAboveSurface2 }, children: /* @__PURE__ */ jsxs(Subtract, { children: [
24600
- /* @__PURE__ */ jsxs(Union, { children: [
24601
- /* @__PURE__ */ jsxs(Hull, { children: [
24602
- /* @__PURE__ */ jsx5(Translate, { z: 5e-3, children: /* @__PURE__ */ jsx5(Cuboid, { size: [faceWidth, faceLength, 0.01] }) }),
24603
- /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [width10, length2, 0.01] }) })
24604
- ] }),
24605
- /* @__PURE__ */ jsxs(Hull, { children: [
24606
- /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [width10, length2, 0.01] }) }),
24607
- /* @__PURE__ */ jsx5(Translate, { z: straightHeight + taperHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [faceWidth, faceLength, 0.01] }) })
24608
- ] })
24607
+ const taperInset = Math.min(width10, length2) * taperRatio;
24608
+ const faceWidth = Math.max(width10 - taperInset, width10 * faceRatio);
24609
+ const faceLength = Math.max(length2 - taperInset, length2 * faceRatio);
24610
+ const defaultNotchRadius = Math.min(width10, length2) * 0.12;
24611
+ const actualNotchRadius = notchRadius ?? defaultNotchRadius;
24612
+ const defaultNotchPosition = {
24613
+ x: 0,
24614
+ y: length2 / 2 - actualNotchRadius * 0.25,
24615
+ z: height10
24616
+ };
24617
+ const actualNotchPosition = notchPosition ?? defaultNotchPosition;
24618
+ const body = /* @__PURE__ */ jsxs(Union, { children: [
24619
+ /* @__PURE__ */ jsxs(Hull, { children: [
24620
+ /* @__PURE__ */ jsx5(Translate, { z: 5e-3, children: /* @__PURE__ */ jsx5(Cuboid, { size: [faceWidth, faceLength, 0.01] }) }),
24621
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [width10, length2, 0.01] }) })
24609
24622
  ] }),
24610
- /* @__PURE__ */ jsx5(Translate, { offset: { x: 0, y: notchCenterY, z: height10 }, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, 0, 0], children: /* @__PURE__ */ jsx5(Cylinder, { radius: notchLength, height: notchWidth }) }) })
24611
- ] }) }) }) });
24623
+ /* @__PURE__ */ jsxs(Hull, { children: [
24624
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [width10, length2, 0.01] }) }),
24625
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight + taperHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [faceWidth, faceLength, 0.01] }) })
24626
+ ] })
24627
+ ] });
24628
+ const chamferCutout = (xPos, yPos) => /* @__PURE__ */ jsx5(Translate, { offset: { x: xPos, y: yPos, z: 0 }, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, 0, Math.PI / 4], children: /* @__PURE__ */ jsx5(
24629
+ Cuboid,
24630
+ {
24631
+ size: [
24632
+ chamferSize * Math.SQRT2,
24633
+ chamferSize * Math.SQRT2,
24634
+ height10 * 3
24635
+ ]
24636
+ }
24637
+ ) }) });
24638
+ let finalBody = body;
24639
+ if (chamferSize > 0) {
24640
+ const xOffset = width10 / 2;
24641
+ const yOffset = length2 / 2;
24642
+ finalBody = /* @__PURE__ */ jsxs(Subtract, { children: [
24643
+ body,
24644
+ chamferCutout(xOffset, yOffset),
24645
+ chamferCutout(-xOffset, yOffset),
24646
+ chamferCutout(xOffset, -yOffset),
24647
+ chamferCutout(-xOffset, -yOffset)
24648
+ ] });
24649
+ }
24650
+ return /* @__PURE__ */ jsx5(Colorize, { color, children: /* @__PURE__ */ jsx5(Translate, { offset: center, children: /* @__PURE__ */ jsx5(Translate, { offset: { x: 0, y: 0, z: heightAboveSurface2 }, children: includeNotch ? /* @__PURE__ */ jsxs(Subtract, { children: [
24651
+ finalBody,
24652
+ /* @__PURE__ */ jsx5(Translate, { offset: actualNotchPosition, children: /* @__PURE__ */ jsx5(Rotate, { rotation: notchRotation, children: /* @__PURE__ */ jsx5(Cylinder, { radius: actualNotchRadius, height: notchWidth }) }) })
24653
+ ] }) : finalBody }) }) });
24612
24654
  };
24613
24655
  var range = (end) => Array.from({ length: end }, (_, i) => i);
24614
24656
  function getExpandedStroke(strokeInput, width10) {
@@ -24697,7 +24739,12 @@ var heightAboveSurface = 0.5;
24697
24739
  var DipPinLeg = ({ x, y, z: z133 }) => {
24698
24740
  const isRotated = x > 0;
24699
24741
  return /* @__PURE__ */ jsxs(Fragment22, { children: [
24700
- /* @__PURE__ */ jsx5(Translate, { offset: { x: x + 0.25 / 2, y, z: z133 }, children: /* @__PURE__ */ jsx5(Rotate, { rotation: ["-90deg", 0, "90deg"], children: /* @__PURE__ */ jsx5(ExtrudeLinear, { height: 0.25, children: /* @__PURE__ */ jsx5(Polygon, { points: svgPathPoints.map((p) => [p.x, p.y]) }) }) }) }),
24742
+ /* @__PURE__ */ jsx5(Translate, { offset: { x: x + 0.25 / 2, y, z: z133 }, children: /* @__PURE__ */ jsx5(Rotate, { rotation: ["-90deg", 0, "90deg"], children: /* @__PURE__ */ jsx5(ExtrudeLinear, { height: 0.25, children: /* @__PURE__ */ jsx5(
24743
+ Polygon,
24744
+ {
24745
+ points: svgPathPoints.slice().reverse().map((p) => [p.x, p.y])
24746
+ }
24747
+ ) }) }) }),
24701
24748
  /* @__PURE__ */ jsx5(
24702
24749
  Translate,
24703
24750
  {
@@ -24839,6 +24886,64 @@ var Tssop = ({
24839
24886
  )
24840
24887
  ] });
24841
24888
  };
24889
+ var MSOP = ({
24890
+ pinCount,
24891
+ padContactLength = 0.4,
24892
+ leadWidth = 0.2,
24893
+ pitch = 0.65,
24894
+ bodyWidth = 3
24895
+ }) => {
24896
+ const sidePinCount = Math.ceil(pinCount / 2);
24897
+ const pinOffsetToCenter = (sidePinCount - 1) * pitch / 2;
24898
+ const leadThickness = 0.2;
24899
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
24900
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
24901
+ SmdChipLead,
24902
+ {
24903
+ position: {
24904
+ x: -bodyWidth / 2 - padContactLength - 0.3,
24905
+ y: i * pitch - pinOffsetToCenter,
24906
+ z: leadThickness / 2
24907
+ },
24908
+ width: leadWidth,
24909
+ thickness: leadThickness,
24910
+ padContactLength,
24911
+ bodyDistance: padContactLength + 0.4,
24912
+ height: 0.6
24913
+ },
24914
+ i
24915
+ )),
24916
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
24917
+ SmdChipLead,
24918
+ {
24919
+ rotation: Math.PI,
24920
+ position: {
24921
+ x: bodyWidth / 2 + padContactLength + 0.3,
24922
+ y: i * pitch - pinOffsetToCenter,
24923
+ z: leadThickness / 2
24924
+ },
24925
+ width: leadWidth,
24926
+ thickness: leadThickness,
24927
+ padContactLength,
24928
+ bodyDistance: padContactLength + 0.4,
24929
+ height: 0.6
24930
+ },
24931
+ i
24932
+ )),
24933
+ /* @__PURE__ */ jsx5(
24934
+ ChipBody,
24935
+ {
24936
+ center: { x: 0, y: 0, z: leadThickness / 2 },
24937
+ width: bodyWidth,
24938
+ length: bodyWidth,
24939
+ height: 1.1,
24940
+ notchRadius: 0.35,
24941
+ heightAboveSurface: 0.1,
24942
+ taperRatio: 0.09
24943
+ }
24944
+ )
24945
+ ] });
24946
+ };
24842
24947
  var fullLength = 1;
24843
24948
  var width = 0.5;
24844
24949
  var height = 0.5;
@@ -24956,13 +25061,13 @@ var QFP = ({
24956
25061
  const fullWidth = fullLength10;
24957
25062
  const leadHeight = 0.8;
24958
25063
  const leadThickness = 0.15;
24959
- const bodyDistance = (fullWidth - bodyWidth) / 2;
25064
+ const bodyDistance = (fullWidth - bodyWidth) / 2 + 0.5;
24960
25065
  return /* @__PURE__ */ jsxs(Fragment22, { children: [
24961
25066
  Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
24962
25067
  SmdChipLead,
24963
25068
  {
24964
25069
  position: {
24965
- x: -fullWidth / 2,
25070
+ x: -fullWidth / 2 - 0.4,
24966
25071
  y: i * pitch - pinOffsetToCenter,
24967
25072
  z: leadThickness / 2
24968
25073
  },
@@ -24979,7 +25084,7 @@ var QFP = ({
24979
25084
  {
24980
25085
  rotation: Math.PI,
24981
25086
  position: {
24982
- x: fullWidth / 2,
25087
+ x: fullWidth / 2 + 0.4,
24983
25088
  y: i * pitch - pinOffsetToCenter,
24984
25089
  z: leadThickness / 2
24985
25090
  },
@@ -24997,7 +25102,7 @@ var QFP = ({
24997
25102
  rotation: Math.PI / 2,
24998
25103
  position: {
24999
25104
  x: i * pitch - pinOffsetToCenter,
25000
- y: -fullLength10 / 2,
25105
+ y: -fullLength10 / 2 - 0.4,
25001
25106
  z: leadThickness / 2
25002
25107
  },
25003
25108
  width: leadWidth,
@@ -25014,7 +25119,7 @@ var QFP = ({
25014
25119
  rotation: -Math.PI / 2,
25015
25120
  position: {
25016
25121
  x: i * pitch - pinOffsetToCenter,
25017
- y: fullLength10 / 2,
25122
+ y: fullLength10 / 2 + 0.4,
25018
25123
  z: leadThickness / 2
25019
25124
  },
25020
25125
  width: leadWidth,
@@ -25028,10 +25133,18 @@ var QFP = ({
25028
25133
  /* @__PURE__ */ jsx5(
25029
25134
  ChipBody,
25030
25135
  {
25031
- center: { x: 0, y: 0, z: leadThickness / 2 },
25136
+ center: { x: 0, y: 0, z: 0 },
25032
25137
  width: bodyWidth,
25033
25138
  length: bodyLength10,
25034
- height: 1.5
25139
+ height: 1.5,
25140
+ taperRatio: 0.03,
25141
+ chamferSize: 0.7,
25142
+ notchPosition: {
25143
+ x: bodyLength10 / 2 - 1.5,
25144
+ y: bodyWidth / 2 - 1.5,
25145
+ z: 1.5
25146
+ },
25147
+ notchRadius: 1.5 / 2
25035
25148
  }
25036
25149
  )
25037
25150
  ] });
@@ -25051,14 +25164,17 @@ var getPitch = (pinCount, width10) => {
25051
25164
  };
25052
25165
  var getPadContactLength = (pinCount) => {
25053
25166
  switch (pinCount) {
25054
- case 44:
25167
+ case 32:
25168
+ return 0.6;
25169
+ case 40:
25170
+ return 0.6;
25055
25171
  case 52:
25056
25172
  case 64:
25057
- return 2.25;
25173
+ return 0.65;
25058
25174
  case 208:
25059
25175
  return 1.65;
25060
25176
  default:
25061
- return 1;
25177
+ return 0.6;
25062
25178
  }
25063
25179
  };
25064
25180
  var getLeadWidth = (pinCount, width10) => {
@@ -25878,7 +25994,7 @@ var SOIC = ({
25878
25994
  width: leadWidth,
25879
25995
  thickness: leadThickness,
25880
25996
  padContactLength: leadLength / 2,
25881
- bodyDistance: leadLength + 0.2,
25997
+ bodyDistance: leadLength + 0.3,
25882
25998
  height: leadHeight
25883
25999
  },
25884
26000
  i
@@ -25895,7 +26011,7 @@ var SOIC = ({
25895
26011
  width: leadWidth,
25896
26012
  thickness: leadThickness,
25897
26013
  padContactLength: leadLength / 2,
25898
- bodyDistance: leadLength + 0.2,
26014
+ bodyDistance: leadLength + 0.3,
25899
26015
  height: leadHeight
25900
26016
  },
25901
26017
  i
@@ -25952,7 +26068,7 @@ var VSSOP = ({
25952
26068
  width: _leadWidth,
25953
26069
  thickness: leadThickness,
25954
26070
  padContactLength: padContactLength + 0.05,
25955
- bodyDistance: leadBodyDistance + 0.05,
26071
+ bodyDistance: leadBodyDistance + 0.1,
25956
26072
  height: leadHeight
25957
26073
  },
25958
26074
  `left-${i}`
@@ -25969,7 +26085,7 @@ var VSSOP = ({
25969
26085
  width: _leadWidth,
25970
26086
  thickness: leadThickness,
25971
26087
  padContactLength: padContactLength + 0.05,
25972
- bodyDistance: leadBodyDistance + 0.05,
26088
+ bodyDistance: leadBodyDistance + 0.1,
25973
26089
  height: leadHeight
25974
26090
  },
25975
26091
  `right-${i}`
@@ -25997,6 +26113,315 @@ var SOD523 = () => {
25997
26113
  const rightPadCenterX = bodyWidth / 2 - padLength / 2 + 0.15;
25998
26114
  const taperOffset = 0.2;
25999
26115
  const straightHeight = bodyHeight * 0.5;
26116
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26117
+ /* @__PURE__ */ jsx5(
26118
+ Cuboid,
26119
+ {
26120
+ color: "#ccc",
26121
+ size: [padLength, padWidth, padThickness],
26122
+ center: [leftPadCenterX, 0, padThickness / 2]
26123
+ }
26124
+ ),
26125
+ /* @__PURE__ */ jsx5(
26126
+ Cuboid,
26127
+ {
26128
+ color: "#ccc",
26129
+ size: [padLength, padWidth, padThickness],
26130
+ center: [rightPadCenterX, 0, padThickness / 2]
26131
+ }
26132
+ ),
26133
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
26134
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight / 2, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, straightHeight] }) }),
26135
+ /* @__PURE__ */ jsxs(Hull, { children: [
26136
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) }),
26137
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26138
+ Cuboid,
26139
+ {
26140
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26141
+ }
26142
+ ) })
26143
+ ] })
26144
+ ] }) })
26145
+ ] });
26146
+ };
26147
+ var SOD882 = () => {
26148
+ const bodyLength10 = 0.98;
26149
+ const bodyHeight = 0.47;
26150
+ const pitch = 0.65;
26151
+ const padWidth = 0.51;
26152
+ const padLength = 0.26;
26153
+ const padThickness = 0.12;
26154
+ const bodyWidth = 0.58;
26155
+ const leftPadCenterX = -pitch / 2;
26156
+ const rightPadCenterX = pitch / 2;
26157
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26158
+ /* @__PURE__ */ jsx5(
26159
+ Cuboid,
26160
+ {
26161
+ color: "#ccc",
26162
+ size: [padLength, padWidth, padThickness],
26163
+ center: [leftPadCenterX, 0, padThickness / 2]
26164
+ }
26165
+ ),
26166
+ /* @__PURE__ */ jsx5(
26167
+ Cuboid,
26168
+ {
26169
+ color: "#ccc",
26170
+ size: [padLength, padWidth, padThickness],
26171
+ center: [rightPadCenterX, 0, padThickness / 2]
26172
+ }
26173
+ ),
26174
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsx5(Translate, { z: bodyHeight / 2 + 0.02, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyLength10, bodyWidth, bodyHeight] }) }) }),
26175
+ /* @__PURE__ */ jsx5(
26176
+ Cuboid,
26177
+ {
26178
+ color: "#ccc",
26179
+ size: [bodyLength10 + 1e-3, padLength / 2, padLength / 4],
26180
+ center: [0, padLength / 2, bodyHeight / 4]
26181
+ }
26182
+ ),
26183
+ /* @__PURE__ */ jsx5(
26184
+ Cuboid,
26185
+ {
26186
+ color: "#ccc",
26187
+ size: [bodyLength10 + 1e-3, padLength / 2, padLength / 4],
26188
+ center: [0, -padLength / 2, bodyHeight / 4]
26189
+ }
26190
+ ),
26191
+ /* @__PURE__ */ jsx5(
26192
+ Cuboid,
26193
+ {
26194
+ color: "#ccc",
26195
+ size: [padLength / 1.5, bodyWidth + 1e-3, padLength / 4],
26196
+ center: [pitch / 2, 0, bodyHeight / 4]
26197
+ }
26198
+ ),
26199
+ /* @__PURE__ */ jsx5(
26200
+ Cuboid,
26201
+ {
26202
+ color: "#ccc",
26203
+ size: [padLength / 1.5, bodyWidth + 1e-3, padLength / 4],
26204
+ center: [-pitch / 2, 0, bodyHeight / 4]
26205
+ }
26206
+ )
26207
+ ] });
26208
+ };
26209
+ var SMA = () => {
26210
+ const bodyWidth = 4.4;
26211
+ const bodyLength10 = 3.4;
26212
+ const bodyHeight = 2.3;
26213
+ const padWidth = 1.45;
26214
+ const padThickness = 0.12;
26215
+ const leadThickness = 0.2;
26216
+ const leadHeight = 1.14;
26217
+ const taperOffset = 0.4;
26218
+ const straightHeight = bodyHeight * 0.5;
26219
+ const Body = /* @__PURE__ */ jsx5(Colorize, { color: "#1a1a1a", children: /* @__PURE__ */ jsxs(Union, { children: [
26220
+ /* @__PURE__ */ jsxs(Hull, { children: [
26221
+ /* @__PURE__ */ jsx5(Translate, { z: padThickness + 0.01, children: /* @__PURE__ */ jsx5(
26222
+ Cuboid,
26223
+ {
26224
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.03]
26225
+ }
26226
+ ) }),
26227
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) })
26228
+ ] }),
26229
+ /* @__PURE__ */ jsxs(Hull, { children: [
26230
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) }),
26231
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26232
+ Cuboid,
26233
+ {
26234
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26235
+ }
26236
+ ) })
26237
+ ] })
26238
+ ] }) });
26239
+ const Lead = ({ xDir }) => {
26240
+ const verticalGap = 1;
26241
+ const lowerPadGap = 1;
26242
+ const lowerPadX = xDir * (bodyLength10 / 2 - bodyHeight * 0.8 / 2 + lowerPadGap);
26243
+ const verticalLeadX = xDir * (bodyLength10 / 2 - leadThickness / 2 + verticalGap);
26244
+ const bodyEdgeX = xDir * (bodyLength10 / 2 - leadThickness / 2);
26245
+ const bridgeLength = Math.abs(bodyEdgeX - verticalLeadX);
26246
+ const bridgeCenterX = (verticalLeadX + bodyEdgeX) / 2;
26247
+ return /* @__PURE__ */ jsx5(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsxs(Union, { children: [
26248
+ /* @__PURE__ */ jsx5(
26249
+ Cuboid,
26250
+ {
26251
+ size: [bodyHeight * 0.8, padWidth, leadThickness],
26252
+ center: [lowerPadX, 0, leadThickness / 2]
26253
+ }
26254
+ ),
26255
+ /* @__PURE__ */ jsx5(
26256
+ Cuboid,
26257
+ {
26258
+ size: [leadThickness, padWidth, leadHeight],
26259
+ center: [verticalLeadX, 0, leadHeight / 2 + leadThickness]
26260
+ }
26261
+ ),
26262
+ /* @__PURE__ */ jsx5(
26263
+ Cuboid,
26264
+ {
26265
+ size: [bridgeLength, padWidth, leadThickness],
26266
+ center: [bridgeCenterX, 0, leadThickness / 2 + leadHeight]
26267
+ }
26268
+ )
26269
+ ] }) });
26270
+ };
26271
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26272
+ /* @__PURE__ */ jsx5(Lead, { xDir: 1 }),
26273
+ /* @__PURE__ */ jsx5(Lead, { xDir: -1 }),
26274
+ Body
26275
+ ] });
26276
+ };
26277
+ var SMB = () => {
26278
+ const bodyWidth = 4.4;
26279
+ const bodyLength10 = 3.4;
26280
+ const bodyHeight = 2.3;
26281
+ const padWidth = 1.45;
26282
+ const padThickness = 0.12;
26283
+ const leadThickness = 0.2;
26284
+ const leadHeight = 1.14;
26285
+ const taperOffset = 0.4;
26286
+ const straightHeight = bodyHeight * 0.5;
26287
+ const Body = /* @__PURE__ */ jsx5(Colorize, { color: "#1a1a1a", children: /* @__PURE__ */ jsxs(Union, { children: [
26288
+ /* @__PURE__ */ jsxs(Hull, { children: [
26289
+ /* @__PURE__ */ jsx5(Translate, { z: padThickness + 0.01, children: /* @__PURE__ */ jsx5(
26290
+ Cuboid,
26291
+ {
26292
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.03]
26293
+ }
26294
+ ) }),
26295
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) })
26296
+ ] }),
26297
+ /* @__PURE__ */ jsxs(Hull, { children: [
26298
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) }),
26299
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26300
+ Cuboid,
26301
+ {
26302
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26303
+ }
26304
+ ) })
26305
+ ] })
26306
+ ] }) });
26307
+ const Lead = ({ xDir }) => {
26308
+ const verticalGap = 1;
26309
+ const lowerPadGap = 1;
26310
+ const lowerPadX = xDir * (bodyLength10 / 2 - bodyHeight * 0.8 / 2 + lowerPadGap);
26311
+ const verticalLeadX = xDir * (bodyLength10 / 2 - leadThickness / 2 + verticalGap);
26312
+ const bodyEdgeX = xDir * (bodyLength10 / 2 - leadThickness / 2);
26313
+ const bridgeLength = Math.abs(bodyEdgeX - verticalLeadX);
26314
+ const bridgeCenterX = (verticalLeadX + bodyEdgeX) / 2;
26315
+ return /* @__PURE__ */ jsx5(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsxs(Union, { children: [
26316
+ /* @__PURE__ */ jsx5(
26317
+ Cuboid,
26318
+ {
26319
+ size: [bodyHeight * 0.8, padWidth, leadThickness],
26320
+ center: [lowerPadX, 0, leadThickness / 2]
26321
+ }
26322
+ ),
26323
+ /* @__PURE__ */ jsx5(
26324
+ Cuboid,
26325
+ {
26326
+ size: [leadThickness, padWidth, leadHeight],
26327
+ center: [verticalLeadX, 0, leadHeight / 2 + leadThickness]
26328
+ }
26329
+ ),
26330
+ /* @__PURE__ */ jsx5(
26331
+ Cuboid,
26332
+ {
26333
+ size: [bridgeLength, padWidth, leadThickness],
26334
+ center: [bridgeCenterX, 0, leadThickness / 2 + leadHeight]
26335
+ }
26336
+ )
26337
+ ] }) });
26338
+ };
26339
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26340
+ /* @__PURE__ */ jsx5(Lead, { xDir: 1 }),
26341
+ /* @__PURE__ */ jsx5(Lead, { xDir: -1 }),
26342
+ Body
26343
+ ] });
26344
+ };
26345
+ var SMC = () => {
26346
+ const bodyWidth = 6.8;
26347
+ const bodyLength10 = 6;
26348
+ const bodyHeight = 2.3;
26349
+ const padWidth = 2.95;
26350
+ const padThickness = 0.2;
26351
+ const leadThickness = 0.2;
26352
+ const leadHeight = 1.14;
26353
+ const taperOffset = 0.4;
26354
+ const straightHeight = bodyHeight * 0.5;
26355
+ const Body = /* @__PURE__ */ jsx5(Colorize, { color: "#1a1a1a", children: /* @__PURE__ */ jsxs(Union, { children: [
26356
+ /* @__PURE__ */ jsxs(Hull, { children: [
26357
+ /* @__PURE__ */ jsx5(Translate, { z: padThickness + 0.01, children: /* @__PURE__ */ jsx5(
26358
+ Cuboid,
26359
+ {
26360
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.03]
26361
+ }
26362
+ ) }),
26363
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) })
26364
+ ] }),
26365
+ /* @__PURE__ */ jsxs(Hull, { children: [
26366
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, 0.01] }) }),
26367
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26368
+ Cuboid,
26369
+ {
26370
+ size: [bodyWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26371
+ }
26372
+ ) })
26373
+ ] })
26374
+ ] }) });
26375
+ const Lead = ({ xDir }) => {
26376
+ const verticalGap = 1;
26377
+ const lowerPadGap = 1;
26378
+ const lowerPadX = xDir * (bodyLength10 / 2 - bodyHeight * 0.8 / 2 + lowerPadGap);
26379
+ const verticalLeadX = xDir * (bodyLength10 / 2 - leadThickness / 2 + verticalGap);
26380
+ const bodyEdgeX = xDir * (bodyLength10 / 2 - leadThickness / 2);
26381
+ const bridgeLength = Math.abs(bodyEdgeX - verticalLeadX);
26382
+ const bridgeCenterX = (verticalLeadX + bodyEdgeX) / 2;
26383
+ return /* @__PURE__ */ jsx5(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsxs(Union, { children: [
26384
+ /* @__PURE__ */ jsx5(
26385
+ Cuboid,
26386
+ {
26387
+ size: [bodyHeight * 0.8, padWidth, leadThickness],
26388
+ center: [lowerPadX, 0, leadThickness / 2]
26389
+ }
26390
+ ),
26391
+ /* @__PURE__ */ jsx5(
26392
+ Cuboid,
26393
+ {
26394
+ size: [leadThickness, padWidth, leadHeight],
26395
+ center: [verticalLeadX, 0, leadHeight / 2 + leadThickness]
26396
+ }
26397
+ ),
26398
+ /* @__PURE__ */ jsx5(
26399
+ Cuboid,
26400
+ {
26401
+ size: [bridgeLength, padWidth, leadThickness],
26402
+ center: [bridgeCenterX, 0, leadThickness / 2 + leadHeight]
26403
+ }
26404
+ )
26405
+ ] }) });
26406
+ };
26407
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26408
+ /* @__PURE__ */ jsx5(Lead, { xDir: 1 }),
26409
+ /* @__PURE__ */ jsx5(Lead, { xDir: -1 }),
26410
+ Body
26411
+ ] });
26412
+ };
26413
+ var SMF = () => {
26414
+ const fullWidth = 2.9;
26415
+ const bodyLength10 = 1.9;
26416
+ const bodyHeight = 1.08;
26417
+ const padWidth = 1.2;
26418
+ const padLength = 1;
26419
+ const padThickness = 0.25;
26420
+ const bodyWidth = fullWidth;
26421
+ const leftPadCenterX = -1.3;
26422
+ const rightPadCenterX = 1.3;
26423
+ const taperOffset = 0.2;
26424
+ const straightHeight = bodyHeight * 0.5;
26000
26425
  const Body = /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
26001
26426
  /* @__PURE__ */ jsx5(Translate, { z: straightHeight / 2, children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, straightHeight] }) }),
26002
26427
  /* @__PURE__ */ jsxs(Hull, { children: [
@@ -26029,10 +26454,889 @@ var SOD523 = () => {
26029
26454
  Body
26030
26455
  ] });
26031
26456
  };
26032
- var Footprinter3d = ({ footprint }) => {
26033
- const fpJson = fp.string(footprint).json();
26034
- switch (fpJson.fn) {
26035
- case "dip":
26457
+ var SOD123F = () => {
26458
+ const fullWidth = 2.7;
26459
+ const bodyLength10 = 1.6;
26460
+ const bodyHeight = 1.1;
26461
+ const padWidth = 0.6;
26462
+ const padLength = 1;
26463
+ const padThickness = 0.12;
26464
+ const leftPadCenterX = -1.3;
26465
+ const rightPadCenterX = 1.3;
26466
+ const taperOffset = 0.2;
26467
+ const straightHeight = bodyHeight * 0.5;
26468
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26469
+ /* @__PURE__ */ jsx5(
26470
+ Cuboid,
26471
+ {
26472
+ color: "#ccc",
26473
+ size: [padLength, padWidth, padThickness],
26474
+ center: [leftPadCenterX, 0, padThickness / 2]
26475
+ }
26476
+ ),
26477
+ /* @__PURE__ */ jsx5(
26478
+ Cuboid,
26479
+ {
26480
+ color: "#ccc",
26481
+ size: [padLength, padWidth, padThickness],
26482
+ center: [rightPadCenterX, 0, padThickness / 2]
26483
+ }
26484
+ ),
26485
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
26486
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight / 2, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, straightHeight] }) }),
26487
+ /* @__PURE__ */ jsxs(Hull, { children: [
26488
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, 0.01] }) }),
26489
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26490
+ Cuboid,
26491
+ {
26492
+ size: [fullWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26493
+ }
26494
+ ) })
26495
+ ] })
26496
+ ] }) })
26497
+ ] });
26498
+ };
26499
+ var SOD123FL = () => {
26500
+ const fullWidth = 2.75;
26501
+ const bodyLength10 = 1.8;
26502
+ const bodyHeight = 1;
26503
+ const padWidth = 0.9;
26504
+ const padLength = 1;
26505
+ const padThickness = 0.2;
26506
+ const leftPadCenterX = -(fullWidth / 2 - 0.075);
26507
+ const rightPadCenterX = fullWidth / 2 - 0.075;
26508
+ const taperOffset = 0.4;
26509
+ const straightHeight = bodyHeight * 0.2;
26510
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26511
+ /* @__PURE__ */ jsx5(
26512
+ Cuboid,
26513
+ {
26514
+ color: "#ccc",
26515
+ size: [padLength, padWidth, padThickness],
26516
+ center: [leftPadCenterX, 0, padThickness / 2]
26517
+ }
26518
+ ),
26519
+ /* @__PURE__ */ jsx5(
26520
+ Cuboid,
26521
+ {
26522
+ color: "#ccc",
26523
+ size: [padLength, padWidth, padThickness],
26524
+ center: [rightPadCenterX, 0, padThickness / 2]
26525
+ }
26526
+ ),
26527
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
26528
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight / 2, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, straightHeight] }) }),
26529
+ /* @__PURE__ */ jsxs(Hull, { children: [
26530
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, 0.01] }) }),
26531
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26532
+ Cuboid,
26533
+ {
26534
+ size: [fullWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26535
+ }
26536
+ ) })
26537
+ ] })
26538
+ ] }) }),
26539
+ /* @__PURE__ */ jsx5(
26540
+ Cuboid,
26541
+ {
26542
+ color: "#777",
26543
+ size: [padThickness, bodyLength10 - taperOffset, 0.01],
26544
+ center: [leftPadCenterX + taperOffset, 0, bodyHeight]
26545
+ }
26546
+ )
26547
+ ] });
26548
+ };
26549
+ var SOD923 = () => {
26550
+ const fullWidth = 0.8;
26551
+ const bodyLength10 = 0.6;
26552
+ const bodyHeight = 0.37;
26553
+ const padWidth = 0.25;
26554
+ const padLength = 0.4;
26555
+ const padThickness = 0.14;
26556
+ const leftPadCenterX = -(fullWidth / 2);
26557
+ const rightPadCenterX = fullWidth / 2;
26558
+ const taperOffset = 0.1;
26559
+ const straightHeight = padThickness;
26560
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26561
+ /* @__PURE__ */ jsx5(
26562
+ Cuboid,
26563
+ {
26564
+ color: "#ccc",
26565
+ size: [padLength, padWidth, padThickness],
26566
+ center: [leftPadCenterX, 0, padThickness / 2]
26567
+ }
26568
+ ),
26569
+ /* @__PURE__ */ jsx5(
26570
+ Cuboid,
26571
+ {
26572
+ color: "#ccc",
26573
+ size: [padLength, padWidth, padThickness],
26574
+ center: [rightPadCenterX, 0, padThickness / 2]
26575
+ }
26576
+ ),
26577
+ /* @__PURE__ */ jsx5(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
26578
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight / 2, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, straightHeight] }) }),
26579
+ /* @__PURE__ */ jsxs(Hull, { children: [
26580
+ /* @__PURE__ */ jsx5(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx5(Cuboid, { size: [fullWidth, bodyLength10, 0.01] }) }),
26581
+ /* @__PURE__ */ jsx5(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx5(
26582
+ Cuboid,
26583
+ {
26584
+ size: [fullWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
26585
+ }
26586
+ ) })
26587
+ ] })
26588
+ ] }) })
26589
+ ] });
26590
+ };
26591
+ var SOT223 = () => {
26592
+ const fullWidth = 6.6;
26593
+ const bodyWidth = 3.5;
26594
+ const bodyLength10 = 6.5;
26595
+ const bodyHeight = 1.7;
26596
+ const leadWidth = 0.7;
26597
+ const leftLeadWidth = 3;
26598
+ const leadThickness = 0.25;
26599
+ const leadHeight = 0.75;
26600
+ const padContactLength = 0.5;
26601
+ const padPitch = 2.3;
26602
+ const extendedBodyDistance = fullWidth - bodyWidth;
26603
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26604
+ /* @__PURE__ */ jsx5(
26605
+ SmdChipLead,
26606
+ {
26607
+ rotation: Math.PI,
26608
+ position: {
26609
+ x: fullWidth / 2 + extendedBodyDistance / 4,
26610
+ y: 0,
26611
+ z: leadThickness / 2
26612
+ },
26613
+ width: leftLeadWidth,
26614
+ thickness: leadThickness,
26615
+ padContactLength,
26616
+ bodyDistance: extendedBodyDistance,
26617
+ height: leadHeight
26618
+ },
26619
+ 4
26620
+ ),
26621
+ /* @__PURE__ */ jsx5(
26622
+ SmdChipLead,
26623
+ {
26624
+ position: {
26625
+ x: -fullWidth / 2 - extendedBodyDistance / 4,
26626
+ y: 0,
26627
+ z: leadThickness / 2
26628
+ },
26629
+ width: leadWidth,
26630
+ thickness: leadThickness,
26631
+ padContactLength,
26632
+ bodyDistance: extendedBodyDistance,
26633
+ height: leadHeight
26634
+ },
26635
+ 3
26636
+ ),
26637
+ /* @__PURE__ */ jsx5(
26638
+ SmdChipLead,
26639
+ {
26640
+ position: {
26641
+ x: -fullWidth / 2 - extendedBodyDistance / 4,
26642
+ y: -padPitch,
26643
+ z: leadThickness / 2
26644
+ },
26645
+ width: leadWidth,
26646
+ thickness: leadThickness,
26647
+ padContactLength,
26648
+ bodyDistance: extendedBodyDistance,
26649
+ height: leadHeight
26650
+ },
26651
+ 1
26652
+ ),
26653
+ /* @__PURE__ */ jsx5(
26654
+ SmdChipLead,
26655
+ {
26656
+ position: {
26657
+ x: -fullWidth / 2 - extendedBodyDistance / 4,
26658
+ y: padPitch,
26659
+ z: leadThickness / 2
26660
+ },
26661
+ width: leadWidth,
26662
+ thickness: leadThickness,
26663
+ padContactLength,
26664
+ bodyDistance: extendedBodyDistance,
26665
+ height: leadHeight
26666
+ },
26667
+ 2
26668
+ ),
26669
+ /* @__PURE__ */ jsx5(
26670
+ ChipBody,
26671
+ {
26672
+ center: { x: 0, y: 0, z: 0 },
26673
+ width: bodyWidth,
26674
+ length: bodyLength10,
26675
+ height: bodyHeight,
26676
+ includeNotch: false,
26677
+ taperRatio: 0.06,
26678
+ straightHeightRatio: 0.45
26679
+ }
26680
+ )
26681
+ ] });
26682
+ };
26683
+ var TQFP = () => {
26684
+ const pinCount = 64;
26685
+ const pitch = 0.5;
26686
+ const leadWidth = 0.2;
26687
+ const padContactLength = 0.45;
26688
+ const bodyWidth = 9;
26689
+ const sidePinCount = pinCount / 4;
26690
+ const bodyLength10 = bodyWidth;
26691
+ const pinOffsetToCenter = (sidePinCount - 1) * pitch / 2;
26692
+ const fullLength10 = bodyLength10 + 2 * padContactLength + 0.6;
26693
+ const fullWidth = fullLength10;
26694
+ const leadHeight = 0.65;
26695
+ const leadThickness = 0.25;
26696
+ const bodyDistance = (fullWidth - bodyWidth) / 2 + 0.2;
26697
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26698
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26699
+ SmdChipLead,
26700
+ {
26701
+ position: {
26702
+ x: -fullWidth / 2,
26703
+ y: i * pitch - pinOffsetToCenter,
26704
+ z: leadThickness / 2
26705
+ },
26706
+ width: leadWidth,
26707
+ thickness: leadThickness,
26708
+ padContactLength,
26709
+ bodyDistance,
26710
+ height: leadHeight
26711
+ },
26712
+ `left-${i}`
26713
+ )),
26714
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26715
+ SmdChipLead,
26716
+ {
26717
+ rotation: Math.PI,
26718
+ position: {
26719
+ x: fullWidth / 2,
26720
+ y: i * pitch - pinOffsetToCenter,
26721
+ z: leadThickness / 2
26722
+ },
26723
+ width: leadWidth,
26724
+ thickness: leadThickness,
26725
+ padContactLength,
26726
+ bodyDistance,
26727
+ height: leadHeight
26728
+ },
26729
+ `right-${i}`
26730
+ )),
26731
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26732
+ SmdChipLead,
26733
+ {
26734
+ rotation: Math.PI / 2,
26735
+ position: {
26736
+ x: i * pitch - pinOffsetToCenter,
26737
+ y: -fullLength10 / 2,
26738
+ z: leadThickness / 2
26739
+ },
26740
+ width: leadWidth,
26741
+ thickness: leadThickness,
26742
+ padContactLength,
26743
+ bodyDistance,
26744
+ height: leadHeight
26745
+ },
26746
+ `bottom-${i}`
26747
+ )),
26748
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26749
+ SmdChipLead,
26750
+ {
26751
+ rotation: -Math.PI / 2,
26752
+ position: {
26753
+ x: i * pitch - pinOffsetToCenter,
26754
+ y: fullLength10 / 2,
26755
+ z: leadThickness / 2
26756
+ },
26757
+ width: leadWidth,
26758
+ thickness: leadThickness,
26759
+ padContactLength,
26760
+ bodyDistance,
26761
+ height: leadHeight
26762
+ },
26763
+ `top-${i}`
26764
+ )),
26765
+ /* @__PURE__ */ jsx5(
26766
+ ChipBody,
26767
+ {
26768
+ center: { x: 0, y: 0, z: 0 },
26769
+ width: bodyWidth,
26770
+ length: bodyLength10,
26771
+ height: 1.2,
26772
+ chamferSize: 0.7,
26773
+ taperRatio: 0.05,
26774
+ notchPosition: { x: 3.5, y: 3.5, z: 1.2 },
26775
+ notchRadius: 1.2 / 2
26776
+ }
26777
+ )
26778
+ ] });
26779
+ };
26780
+ var tqfp_default = TQFP;
26781
+ var SOT323 = () => {
26782
+ const fullWidth = 2.05;
26783
+ const bodyWidth = 1.25;
26784
+ const bodyLength10 = 2;
26785
+ const bodyHeight = 0.9;
26786
+ const leadWidth = 0.3;
26787
+ const leadThickness = 0.18;
26788
+ const leadHeight = 0.65;
26789
+ const padContactLength = 0.2;
26790
+ const padPitch = 0.65;
26791
+ const extendedBodyDistance = fullWidth - bodyWidth;
26792
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26793
+ /* @__PURE__ */ jsx5(
26794
+ SmdChipLead,
26795
+ {
26796
+ rotation: Math.PI,
26797
+ position: {
26798
+ x: fullWidth / 2 + extendedBodyDistance / 4,
26799
+ y: 0,
26800
+ z: leadThickness / 2
26801
+ },
26802
+ width: leadWidth,
26803
+ thickness: leadThickness,
26804
+ padContactLength,
26805
+ bodyDistance: extendedBodyDistance,
26806
+ height: leadHeight
26807
+ },
26808
+ 4
26809
+ ),
26810
+ /* @__PURE__ */ jsx5(
26811
+ SmdChipLead,
26812
+ {
26813
+ position: {
26814
+ x: -fullWidth / 2 - extendedBodyDistance / 4,
26815
+ y: -padPitch,
26816
+ z: leadThickness / 2
26817
+ },
26818
+ width: leadWidth,
26819
+ thickness: leadThickness,
26820
+ padContactLength,
26821
+ bodyDistance: extendedBodyDistance,
26822
+ height: leadHeight
26823
+ },
26824
+ 1
26825
+ ),
26826
+ /* @__PURE__ */ jsx5(
26827
+ SmdChipLead,
26828
+ {
26829
+ position: {
26830
+ x: -fullWidth / 2 - extendedBodyDistance / 4,
26831
+ y: padPitch,
26832
+ z: leadThickness / 2
26833
+ },
26834
+ width: leadWidth,
26835
+ thickness: leadThickness,
26836
+ padContactLength,
26837
+ bodyDistance: extendedBodyDistance,
26838
+ height: leadHeight
26839
+ },
26840
+ 2
26841
+ ),
26842
+ /* @__PURE__ */ jsx5(
26843
+ ChipBody,
26844
+ {
26845
+ center: { x: 0, y: 0, z: 0 },
26846
+ width: bodyWidth,
26847
+ length: bodyLength10,
26848
+ height: bodyHeight,
26849
+ includeNotch: false,
26850
+ taperRatio: 0.06,
26851
+ straightHeightRatio: 0.7,
26852
+ heightAboveSurface: 0.05
26853
+ }
26854
+ )
26855
+ ] });
26856
+ };
26857
+ var LQFP = ({
26858
+ pinCount,
26859
+ pitch,
26860
+ leadWidth,
26861
+ padContactLength,
26862
+ bodyWidth
26863
+ }) => {
26864
+ const sidePinCount = pinCount / 4;
26865
+ if (sidePinCount !== Math.floor(sidePinCount)) {
26866
+ throw new Error(`LQFP pinCount must be divisible by 4, got ${pinCount}`);
26867
+ }
26868
+ if (!pitch) pitch = 0.5;
26869
+ if (!padContactLength) padContactLength = 0.6;
26870
+ if (!leadWidth) leadWidth = 0.22;
26871
+ if (!bodyWidth) bodyWidth = pitch * (sidePinCount + 4);
26872
+ const bodyLength10 = bodyWidth;
26873
+ const pinOffsetToCenter = (sidePinCount - 1) * pitch / 2;
26874
+ const fullLength10 = bodyLength10 + 3.3 * padContactLength;
26875
+ const fullWidth = fullLength10;
26876
+ const leadHeight = 0.8;
26877
+ const leadThickness = 0.2;
26878
+ const bodyDistance = (fullWidth - bodyWidth) / 2 + 0.4;
26879
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26880
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26881
+ SmdChipLead,
26882
+ {
26883
+ position: {
26884
+ x: -fullWidth / 2 - 0.36,
26885
+ y: i * pitch - pinOffsetToCenter,
26886
+ z: leadThickness / 2
26887
+ },
26888
+ width: leadWidth,
26889
+ thickness: leadThickness,
26890
+ padContactLength,
26891
+ bodyDistance,
26892
+ height: leadHeight
26893
+ },
26894
+ `left-${i}`
26895
+ )),
26896
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26897
+ SmdChipLead,
26898
+ {
26899
+ rotation: Math.PI,
26900
+ position: {
26901
+ x: fullWidth / 2 + 0.36,
26902
+ y: i * pitch - pinOffsetToCenter,
26903
+ z: leadThickness / 2
26904
+ },
26905
+ width: leadWidth,
26906
+ thickness: leadThickness,
26907
+ padContactLength,
26908
+ bodyDistance,
26909
+ height: leadHeight
26910
+ },
26911
+ `right-${i}`
26912
+ )),
26913
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26914
+ SmdChipLead,
26915
+ {
26916
+ rotation: Math.PI / 2,
26917
+ position: {
26918
+ x: i * pitch - pinOffsetToCenter,
26919
+ y: -fullLength10 / 2 - 0.36,
26920
+ z: leadThickness / 2
26921
+ },
26922
+ width: leadWidth,
26923
+ thickness: leadThickness,
26924
+ padContactLength,
26925
+ bodyDistance,
26926
+ height: leadHeight
26927
+ },
26928
+ `bottom-${i}`
26929
+ )),
26930
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
26931
+ SmdChipLead,
26932
+ {
26933
+ rotation: -Math.PI / 2,
26934
+ position: {
26935
+ x: i * pitch - pinOffsetToCenter,
26936
+ y: fullLength10 / 2 + 0.36,
26937
+ z: leadThickness / 2
26938
+ },
26939
+ width: leadWidth,
26940
+ thickness: leadThickness,
26941
+ padContactLength,
26942
+ bodyDistance,
26943
+ height: leadHeight
26944
+ },
26945
+ `top-${i}`
26946
+ )),
26947
+ /* @__PURE__ */ jsx5(
26948
+ ChipBody,
26949
+ {
26950
+ center: { x: 0, y: 0, z: 0 },
26951
+ width: bodyWidth,
26952
+ length: bodyLength10,
26953
+ height: 1.5,
26954
+ heightAboveSurface: 0.1,
26955
+ taperRatio: 0.04,
26956
+ chamferSize: 0.7,
26957
+ notchPosition: {
26958
+ x: bodyLength10 / 2 - 1.5,
26959
+ y: bodyLength10 / 2 - 1.5,
26960
+ z: 1.5
26961
+ },
26962
+ notchRadius: 1.5 / 2
26963
+ }
26964
+ )
26965
+ ] });
26966
+ };
26967
+ var getCcwSot723Coords2 = (pn) => {
26968
+ if (pn === 1) {
26969
+ return { x: 0, y: 0 };
26970
+ } else if (pn === 2) {
26971
+ return { x: 1, y: -0.4 };
26972
+ } else {
26973
+ return { x: 1, y: 0.4 };
26974
+ }
26975
+ };
26976
+ var SOT723 = () => {
26977
+ const bodyWidth = 0.8;
26978
+ const bodyLength10 = 1.2;
26979
+ const bodyHeight = 0.5;
26980
+ const leadWidth = 0.32;
26981
+ const leadLength = 0.3;
26982
+ const leadHeight = 0.1;
26983
+ const centerLeadWidth = 0.42;
26984
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
26985
+ /* @__PURE__ */ jsx5(Rotate, { rotation: [45 * Math.PI, 0, 0], children: /* @__PURE__ */ jsx5(Translate, { center: [0.475, leadHeight / 2, -0.25], children: /* @__PURE__ */ jsx5(Colorize, { color: "grey", children: /* @__PURE__ */ jsx5(Cuboid, { size: [bodyWidth, bodyLength10, bodyHeight] }) }) }) }),
26986
+ [1, 2, 3].map((pn) => {
26987
+ const { x, y } = getCcwSot723Coords2(pn);
26988
+ return /* @__PURE__ */ jsx5(Translate, { center: [x, y, 0.05], children: /* @__PURE__ */ jsx5(
26989
+ Cuboid,
26990
+ {
26991
+ size: [
26992
+ leadLength,
26993
+ pn === 1 ? centerLeadWidth : leadWidth,
26994
+ leadHeight
26995
+ ]
26996
+ }
26997
+ ) }, `lead-${pn}`);
26998
+ })
26999
+ ] });
27000
+ };
27001
+ var DFN = ({
27002
+ num_pins,
27003
+ bodyWidth = 5.3,
27004
+ bodyLength: bodyLength10 = 5.3,
27005
+ bodyThickness = 1,
27006
+ thermalPadSize,
27007
+ // For a body length of 5 the typical pad width/length are 0.6 and 1.
27008
+ // Scale those values proportionally when `bodyLength` changes.
27009
+ padWidth = bodyLength10 / 5.3 * 0.6,
27010
+ padLength = bodyLength10 / 5.3 * 1,
27011
+ pitch = 0.5,
27012
+ thermalPadThickness = 0.2
27013
+ }) => {
27014
+ const pinPositions = [];
27015
+ const pinsPerSide = Math.floor(num_pins / 2);
27016
+ const pinSpan = pitch * (pinsPerSide - 1);
27017
+ for (let i = 0; i < num_pins; i++) {
27018
+ const side = i < pinsPerSide ? "left" : "right";
27019
+ const indexOnSide = i % pinsPerSide;
27020
+ const y = pinSpan / 2 - indexOnSide * pitch;
27021
+ const padSizeX = padLength;
27022
+ const padSizeY = padWidth;
27023
+ const x = side === "left" ? -bodyWidth / 2 + padSizeX / 2 : bodyWidth / 2 - padSizeX / 2;
27024
+ const pinNumber = i + 1;
27025
+ pinPositions.push({ pinNumber, x, y, padSizeX, padSizeY });
27026
+ }
27027
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27028
+ /* @__PURE__ */ jsx5(
27029
+ ChipBody,
27030
+ {
27031
+ center: { x: 0, y: 0, z: 0 },
27032
+ width: bodyWidth,
27033
+ length: bodyLength10,
27034
+ height: bodyThickness,
27035
+ heightAboveSurface: 0,
27036
+ color: "grey",
27037
+ chamferSize: 0.2,
27038
+ taperRatio: 0,
27039
+ notchPosition: {
27040
+ x: bodyWidth / 2 - padLength,
27041
+ y: bodyLength10 / 2 - padLength,
27042
+ z: bodyThickness
27043
+ }
27044
+ }
27045
+ ),
27046
+ pinPositions.map((p, i) => /* @__PURE__ */ jsx5(
27047
+ Cuboid,
27048
+ {
27049
+ center: [p.x, p.y, thermalPadThickness / 2],
27050
+ size: [p.padSizeX, p.padSizeY, thermalPadThickness]
27051
+ },
27052
+ i
27053
+ )),
27054
+ thermalPadSize?.length !== void 0 && thermalPadSize?.width !== void 0 && /* @__PURE__ */ jsx5(
27055
+ Cuboid,
27056
+ {
27057
+ center: [0, 0, thermalPadThickness / 2],
27058
+ size: [
27059
+ thermalPadSize.width,
27060
+ thermalPadSize.length,
27061
+ thermalPadThickness
27062
+ ]
27063
+ }
27064
+ )
27065
+ ] });
27066
+ };
27067
+ var HC49 = ({
27068
+ bodyLength: bodyLength10 = 10.2,
27069
+ bodyWidth = 4.65,
27070
+ bodyHeight = 13.46,
27071
+ leadSpacing = 5,
27072
+ leadDiameter = 0.8,
27073
+ leadLength = 12.7,
27074
+ color = "#ddd",
27075
+ leadColor = "#b87333"
27076
+ }) => {
27077
+ const halfLength = bodyLength10 / 2;
27078
+ const endRadius = bodyWidth / 2;
27079
+ const endCenterX = halfLength - endRadius;
27080
+ const leadCenterX = leadSpacing / 2;
27081
+ const baseHeight = 0.85;
27082
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27083
+ /* @__PURE__ */ jsxs(Colorize, { color, children: [
27084
+ /* @__PURE__ */ jsxs(Hull, { children: [
27085
+ /* @__PURE__ */ jsx5(
27086
+ RoundedCylinder,
27087
+ {
27088
+ height: bodyHeight,
27089
+ roundRadius: 0.5,
27090
+ radius: endRadius,
27091
+ center: [-endCenterX, 0, bodyHeight]
27092
+ }
27093
+ ),
27094
+ /* @__PURE__ */ jsx5(
27095
+ RoundedCylinder,
27096
+ {
27097
+ height: bodyHeight,
27098
+ roundRadius: 0.5,
27099
+ radius: endRadius,
27100
+ center: [endCenterX, 0, bodyHeight]
27101
+ }
27102
+ )
27103
+ ] }),
27104
+ /* @__PURE__ */ jsxs(Hull, { children: [
27105
+ /* @__PURE__ */ jsx5(
27106
+ RoundedCylinder,
27107
+ {
27108
+ height: baseHeight,
27109
+ roundRadius: 0.1,
27110
+ radius: endRadius + 0.85,
27111
+ center: [-endCenterX, 0, bodyHeight / 2 + baseHeight / 2]
27112
+ }
27113
+ ),
27114
+ /* @__PURE__ */ jsx5(
27115
+ RoundedCylinder,
27116
+ {
27117
+ height: baseHeight,
27118
+ roundRadius: 0.1,
27119
+ radius: endRadius + 0.85,
27120
+ center: [endCenterX, 0, bodyHeight / 2 + baseHeight / 2]
27121
+ }
27122
+ )
27123
+ ] })
27124
+ ] }),
27125
+ /* @__PURE__ */ jsxs(Colorize, { color: leadColor, children: [
27126
+ /* @__PURE__ */ jsx5(
27127
+ Cylinder,
27128
+ {
27129
+ height: leadLength + bodyHeight / 2,
27130
+ radius: leadDiameter / 2,
27131
+ center: [-leadCenterX + 0.06, 0, -(leadLength / 2) + bodyHeight / 2]
27132
+ }
27133
+ ),
27134
+ /* @__PURE__ */ jsx5(
27135
+ Cylinder,
27136
+ {
27137
+ height: leadLength + bodyHeight / 2,
27138
+ radius: leadDiameter / 2,
27139
+ center: [leadCenterX - 0.06, 0, -(leadLength / 2) + bodyHeight / 2]
27140
+ }
27141
+ )
27142
+ ] })
27143
+ ] });
27144
+ };
27145
+ var MicroMELF = ({
27146
+ bodyLength: bodyLength10 = 1.4,
27147
+ bodyDiameter = 1.1,
27148
+ color = "#3a3a3aff",
27149
+ contactColor = "#c6c6c6",
27150
+ cathodeIdentification = "#111"
27151
+ }) => {
27152
+ const padLength = 0.2;
27153
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27154
+ /* @__PURE__ */ jsx5(Colorize, { color, children: /* @__PURE__ */ jsxs(Rotate, { rotation: [0, "90deg", 0], children: [
27155
+ /* @__PURE__ */ jsx5(
27156
+ RoundedCuboid,
27157
+ {
27158
+ size: [bodyDiameter, bodyDiameter, bodyLength10 - padLength],
27159
+ roundRadius: padLength,
27160
+ center: [-bodyDiameter / 2, 0, 0.05]
27161
+ }
27162
+ ),
27163
+ /* @__PURE__ */ jsx5(
27164
+ Cylinder,
27165
+ {
27166
+ height: padLength / 2,
27167
+ radius: bodyDiameter / 2 - padLength,
27168
+ center: [-bodyDiameter / 2, 0, -bodyLength10 / 2 + padLength / 2]
27169
+ }
27170
+ )
27171
+ ] }) }),
27172
+ /* @__PURE__ */ jsx5(Colorize, { color: cathodeIdentification, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27173
+ RoundedCuboid,
27174
+ {
27175
+ size: [bodyDiameter * 1.01, bodyDiameter * 1.01, bodyLength10 / 3],
27176
+ roundRadius: padLength,
27177
+ center: [-bodyDiameter / 2, 0, -bodyLength10 / 4 + 0.1]
27178
+ }
27179
+ ) }) }),
27180
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27181
+ RoundedCylinder,
27182
+ {
27183
+ height: padLength,
27184
+ radius: bodyDiameter / 2,
27185
+ roundRadius: padLength / 3,
27186
+ center: [-bodyDiameter / 2, 0, -bodyLength10 / 2]
27187
+ }
27188
+ ) }) }),
27189
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27190
+ RoundedCylinder,
27191
+ {
27192
+ height: padLength,
27193
+ radius: bodyDiameter / 2,
27194
+ roundRadius: padLength / 3,
27195
+ center: [-bodyDiameter / 2, 0, bodyLength10 / 2]
27196
+ }
27197
+ ) }) })
27198
+ ] });
27199
+ };
27200
+ var MINIMELF = ({
27201
+ bodyLength: bodyLength10 = 3.5,
27202
+ bodyDiameter = 1.5,
27203
+ color = "#3a3a3aff",
27204
+ contactColor = "#c6c6c6"
27205
+ }) => {
27206
+ const padLength = 0.5;
27207
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27208
+ /* @__PURE__ */ jsx5(Colorize, { color, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27209
+ RoundedCylinder,
27210
+ {
27211
+ height: bodyLength10,
27212
+ radius: bodyDiameter / 2,
27213
+ roundRadius: 0.3,
27214
+ center: [-bodyDiameter / 2, 0, 0]
27215
+ }
27216
+ ) }) }),
27217
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27218
+ RoundedCylinder,
27219
+ {
27220
+ height: padLength,
27221
+ radius: bodyDiameter / 2,
27222
+ roundRadius: 0.2,
27223
+ center: [-bodyDiameter / 2, 0, -bodyLength10 / 2]
27224
+ }
27225
+ ) }) }),
27226
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27227
+ RoundedCylinder,
27228
+ {
27229
+ height: padLength,
27230
+ radius: bodyDiameter / 2,
27231
+ roundRadius: 0.2,
27232
+ center: [-bodyDiameter / 2, 0, bodyLength10 / 2]
27233
+ }
27234
+ ) }) })
27235
+ ] });
27236
+ };
27237
+ var MELF = ({
27238
+ bodyLength: bodyLength10 = 3.9,
27239
+ bodyDiameter = 2.5,
27240
+ color = "#3a3a3aff",
27241
+ contactColor = "#c6c6c6"
27242
+ }) => {
27243
+ const padLength = 0.55;
27244
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27245
+ /* @__PURE__ */ jsx5(Colorize, { color, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27246
+ RoundedCylinder,
27247
+ {
27248
+ height: bodyLength10,
27249
+ radius: bodyDiameter / 2,
27250
+ roundRadius: 0.3,
27251
+ center: [-bodyDiameter / 2, 0, 0]
27252
+ }
27253
+ ) }) }),
27254
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27255
+ RoundedCylinder,
27256
+ {
27257
+ height: padLength,
27258
+ radius: bodyDiameter / 2,
27259
+ roundRadius: 0.2,
27260
+ center: [-bodyDiameter / 2, 0, -bodyLength10 / 2]
27261
+ }
27262
+ ) }) }),
27263
+ /* @__PURE__ */ jsx5(Colorize, { color: contactColor, children: /* @__PURE__ */ jsx5(Rotate, { rotation: [0, "90deg", 0], children: /* @__PURE__ */ jsx5(
27264
+ RoundedCylinder,
27265
+ {
27266
+ height: padLength,
27267
+ radius: bodyDiameter / 2,
27268
+ roundRadius: 0.2,
27269
+ center: [-bodyDiameter / 2, 0, bodyLength10 / 2]
27270
+ }
27271
+ ) }) })
27272
+ ] });
27273
+ };
27274
+ var MS012 = ({
27275
+ pinCount,
27276
+ padContactLength = 0.6,
27277
+ leadWidth = 0.41,
27278
+ pitch = 1.27
27279
+ }) => {
27280
+ if (pinCount % 2 !== 0) {
27281
+ throw new Error("MS012 pinCount must be even");
27282
+ }
27283
+ const sidePinCount = pinCount / 2;
27284
+ const bodyWidth = 4.9;
27285
+ const bodyLength10 = 3.9;
27286
+ const pinOffsetToCenter = (sidePinCount - 1) * pitch / 2;
27287
+ const leadThickness = 0.2;
27288
+ return /* @__PURE__ */ jsxs(Fragment22, { children: [
27289
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
27290
+ SmdChipLead,
27291
+ {
27292
+ position: {
27293
+ x: -bodyLength10 / 2 - padContactLength - 0.3,
27294
+ y: i * pitch - pinOffsetToCenter,
27295
+ z: leadThickness / 2
27296
+ },
27297
+ width: leadWidth,
27298
+ thickness: leadThickness,
27299
+ padContactLength,
27300
+ bodyDistance: padContactLength + 0.4,
27301
+ height: 0.85
27302
+ },
27303
+ i
27304
+ )),
27305
+ Array.from({ length: sidePinCount }).map((_, i) => /* @__PURE__ */ jsx5(
27306
+ SmdChipLead,
27307
+ {
27308
+ rotation: Math.PI,
27309
+ position: {
27310
+ x: bodyLength10 / 2 + padContactLength + 0.3,
27311
+ y: i * pitch - pinOffsetToCenter,
27312
+ z: leadThickness / 2
27313
+ },
27314
+ width: leadWidth,
27315
+ thickness: leadThickness,
27316
+ padContactLength,
27317
+ bodyDistance: padContactLength + 0.4,
27318
+ height: 0.85
27319
+ },
27320
+ `right-${i}`
27321
+ )),
27322
+ /* @__PURE__ */ jsx5(
27323
+ ChipBody,
27324
+ {
27325
+ center: { x: 0, y: 0, z: leadThickness / 2 },
27326
+ width: bodyLength10,
27327
+ length: bodyWidth,
27328
+ height: 1.55,
27329
+ notchPosition: { x: bodyLength10 / 2 - 1, y: bodyWidth / 2 - 1, z: 1.55 },
27330
+ heightAboveSurface: 0.17,
27331
+ taperRatio: 0.09
27332
+ }
27333
+ )
27334
+ ] });
27335
+ };
27336
+ var Footprinter3d = ({ footprint }) => {
27337
+ const fpJson = fp.string(footprint).json();
27338
+ switch (fpJson.fn) {
27339
+ case "dip":
26036
27340
  return /* @__PURE__ */ jsx5(Dip, { numPins: fpJson.num_pins, pitch: fpJson.p, bodyWidth: fpJson.w });
26037
27341
  case "tssop":
26038
27342
  return /* @__PURE__ */ jsx5(
@@ -26045,6 +27349,17 @@ var Footprinter3d = ({ footprint }) => {
26045
27349
  bodyWidth: fpJson.w
26046
27350
  }
26047
27351
  );
27352
+ case "msop":
27353
+ return /* @__PURE__ */ jsx5(
27354
+ MSOP,
27355
+ {
27356
+ pinCount: fpJson.num_pins,
27357
+ padContactLength: fpJson.pl,
27358
+ leadWidth: fpJson.pw,
27359
+ pitch: fpJson.p,
27360
+ bodyWidth: fpJson.w
27361
+ }
27362
+ );
26048
27363
  case "vssop":
26049
27364
  return /* @__PURE__ */ jsx5(
26050
27365
  VSSOP,
@@ -26068,7 +27383,12 @@ var Footprinter3d = ({ footprint }) => {
26068
27383
  bodyWidth: fpJson.w
26069
27384
  }
26070
27385
  );
26071
- case "qfn":
27386
+ case "tqfp":
27387
+ return /* @__PURE__ */ jsx5(tqfp_default, {});
27388
+ case "lqfp":
27389
+ return /* @__PURE__ */ jsx5(LQFP, { pinCount: fpJson.num_pins });
27390
+ case "qfn": {
27391
+ const hasThermalPad = typeof fpJson.thermalpad?.x === "number" && typeof fpJson.thermalpad?.y === "number";
26072
27392
  return /* @__PURE__ */ jsx5(
26073
27393
  qfn_default,
26074
27394
  {
@@ -26078,12 +27398,31 @@ var Footprinter3d = ({ footprint }) => {
26078
27398
  pitch: fpJson.p,
26079
27399
  padLength: fpJson.pl,
26080
27400
  padWidth: fpJson.pw,
26081
- thermalPadSize: {
27401
+ thermalPadSize: hasThermalPad ? {
26082
27402
  width: fpJson.thermalpad.x,
26083
27403
  length: fpJson.thermalpad.y
26084
- }
27404
+ } : void 0
27405
+ }
27406
+ );
27407
+ }
27408
+ case "dfn": {
27409
+ const hasThermalPad = typeof fpJson.thermalpad?.x === "number" && typeof fpJson.thermalpad?.y === "number";
27410
+ return /* @__PURE__ */ jsx5(
27411
+ DFN,
27412
+ {
27413
+ num_pins: fpJson.num_pins,
27414
+ bodyWidth: fpJson.w,
27415
+ bodyLength: fpJson.h,
27416
+ pitch: fpJson.p,
27417
+ padLength: fpJson.pl,
27418
+ padWidth: fpJson.pw,
27419
+ thermalPadSize: hasThermalPad ? {
27420
+ width: fpJson.thermalpad.x,
27421
+ length: fpJson.thermalpad.y
27422
+ } : void 0
26085
27423
  }
26086
27424
  );
27425
+ }
26087
27426
  case "pinrow":
26088
27427
  if (fpJson.male)
26089
27428
  return /* @__PURE__ */ jsx5(PinRow, { numberOfPins: fpJson.num_pins, pitch: fpJson.p });
@@ -26113,6 +27452,10 @@ var Footprinter3d = ({ footprint }) => {
26113
27452
  }
26114
27453
  case "sot235":
26115
27454
  return /* @__PURE__ */ jsx5(SOT_235_default, {});
27455
+ case "sot223":
27456
+ return /* @__PURE__ */ jsx5(SOT223, {});
27457
+ case "sot323":
27458
+ return /* @__PURE__ */ jsx5(SOT323, {});
26116
27459
  case "pushbutton":
26117
27460
  return /* @__PURE__ */ jsx5(
26118
27461
  PushButton,
@@ -26135,6 +27478,42 @@ var Footprinter3d = ({ footprint }) => {
26135
27478
  );
26136
27479
  case "sod523":
26137
27480
  return /* @__PURE__ */ jsx5(SOD523, {});
27481
+ case "sod882":
27482
+ return /* @__PURE__ */ jsx5(SOD882, {});
27483
+ case "sma":
27484
+ return /* @__PURE__ */ jsx5(SMA, {});
27485
+ case "smb":
27486
+ return /* @__PURE__ */ jsx5(SMB, {});
27487
+ case "smc":
27488
+ return /* @__PURE__ */ jsx5(SMC, {});
27489
+ case "smf":
27490
+ return /* @__PURE__ */ jsx5(SMF, {});
27491
+ case "sod123f":
27492
+ return /* @__PURE__ */ jsx5(SOD123F, {});
27493
+ case "sod123fl":
27494
+ return /* @__PURE__ */ jsx5(SOD123FL, {});
27495
+ case "sod923":
27496
+ return /* @__PURE__ */ jsx5(SOD923, {});
27497
+ case "hc49":
27498
+ return /* @__PURE__ */ jsx5(HC49, {});
27499
+ case "micromelf":
27500
+ return /* @__PURE__ */ jsx5(MicroMELF, {});
27501
+ case "minimelf":
27502
+ return /* @__PURE__ */ jsx5(MINIMELF, {});
27503
+ case "melf":
27504
+ return /* @__PURE__ */ jsx5(MELF, {});
27505
+ case "ms012":
27506
+ return /* @__PURE__ */ jsx5(
27507
+ MS012,
27508
+ {
27509
+ pinCount: fpJson.num_pins,
27510
+ padContactLength: fpJson.pl,
27511
+ leadWidth: fpJson.pw,
27512
+ pitch: fpJson.p
27513
+ }
27514
+ );
27515
+ case "sot723":
27516
+ return /* @__PURE__ */ jsx5(SOT723, {});
26138
27517
  }
26139
27518
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
26140
27519
  const color = colorMatch ? colorMatch[1] : void 0;
@@ -26237,7 +27616,7 @@ function renderNode(node, colorCtx, renderCtx) {
26237
27616
  else if (type === Subtract)
26238
27617
  geom = booleans.subtract(geoms[0], geoms.slice(1));
26239
27618
  else geom = hulls.hull(geoms);
26240
- return [{ geom }];
27619
+ return [{ geom, color: colorCtx }];
26241
27620
  }
26242
27621
  if (type === Polygon) {
26243
27622
  const points = props?.points ?? [];
@@ -26258,7 +27637,7 @@ function renderNode(node, colorCtx, renderCtx) {
26258
27637
  }
26259
27638
  return [{ geom: g3, color: colorCtx ?? props?.color }];
26260
27639
  }
26261
- if (type === Cuboid || type === Cube || type === Cylinder || type === Sphere || type === RoundedCuboid) {
27640
+ if (type === Cuboid || type === Cube || type === Cylinder || type === Sphere || type === RoundedCuboid || type === RoundedCylinder) {
26262
27641
  let g;
26263
27642
  if (type === Cuboid) {
26264
27643
  const size5 = props?.size ?? [1, 1, 1];
@@ -26279,6 +27658,12 @@ function renderNode(node, colorCtx, renderCtx) {
26279
27658
  const radius = props?.radius ?? 1;
26280
27659
  const center = props?.center ?? [0, 0, 0];
26281
27660
  g = primitives.sphere({ radius, center });
27661
+ } else if (type === RoundedCylinder) {
27662
+ const height10 = props?.height ?? 1;
27663
+ const radius = props?.radius ?? 1;
27664
+ const roundRadius = props?.roundRadius ?? 0.1;
27665
+ const center = props?.center ?? [0, 0, 0];
27666
+ g = primitives.roundedCylinder({ height: height10, radius, roundRadius, center });
26282
27667
  } else {
26283
27668
  const size5 = props?.size ?? [1, 1, 1];
26284
27669
  const roundRadius = props?.roundRadius ?? 0.1;
@@ -26789,7 +28174,7 @@ import * as THREE14 from "three";
26789
28174
  // package.json
26790
28175
  var package_default = {
26791
28176
  name: "@tscircuit/3d-viewer",
26792
- version: "0.0.428",
28177
+ version: "0.0.430",
26793
28178
  main: "./dist/index.js",
26794
28179
  module: "./dist/index.js",
26795
28180
  type: "module",
@@ -26850,10 +28235,10 @@ var package_default = {
26850
28235
  "@vitejs/plugin-react": "^4.3.4",
26851
28236
  "bun-match-svg": "^0.0.9",
26852
28237
  "bun-types": "1.2.1",
26853
- "circuit-json": "0.0.300",
28238
+ "circuit-json": "0.0.303",
26854
28239
  "circuit-to-svg": "^0.0.179",
26855
28240
  debug: "^4.4.0",
26856
- "jscad-electronics": "^0.0.48",
28241
+ "jscad-electronics": "^0.0.89",
26857
28242
  "jscad-planner": "^0.0.13",
26858
28243
  jsdom: "^26.0.0",
26859
28244
  "manifold-3d": "^3.2.1",
@@ -27952,10 +29337,10 @@ var createBoardGeomFromCircuitJson = (circuitJson, opts = {}) => {
27952
29337
  };
27953
29338
 
27954
29339
  // src/BoardGeomBuilder.ts
27955
- var import_transforms6 = __toESM(require_transforms(), 1);
27956
- var import_primitives8 = __toESM(require_primitives(), 1);
27957
- var import_colors6 = __toESM(require_colors(), 1);
27958
- var import_booleans4 = __toESM(require_booleans(), 1);
29340
+ var import_transforms7 = __toESM(require_transforms(), 1);
29341
+ var import_primitives9 = __toESM(require_primitives(), 1);
29342
+ var import_colors7 = __toESM(require_colors(), 1);
29343
+ var import_booleans5 = __toESM(require_booleans(), 1);
27959
29344
  import { su as su3 } from "@tscircuit/circuit-json-util";
27960
29345
 
27961
29346
  // src/geoms/plated-hole.ts
@@ -28338,7 +29723,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
28338
29723
  };
28339
29724
 
28340
29725
  // src/BoardGeomBuilder.ts
28341
- var import_extrusions6 = __toESM(require_extrusions(), 1);
29726
+ var import_extrusions7 = __toESM(require_extrusions(), 1);
28342
29727
  var import_expansions4 = __toESM(require_expansions(), 1);
28343
29728
 
28344
29729
  // src/geoms/create-geoms-for-silkscreen-text.ts
@@ -28812,9 +30197,52 @@ function createSilkscreenRectGeom(rect, ctx) {
28812
30197
  return (0, import_colors5.colorize)([1, 1, 1], rectGeom);
28813
30198
  }
28814
30199
 
28815
- // src/geoms/brep-converter.ts
30200
+ // src/geoms/create-geoms-for-silkscreen-circle.ts
28816
30201
  var import_primitives7 = __toESM(require_primitives(), 1);
30202
+ var import_extrusions6 = __toESM(require_extrusions(), 1);
30203
+ var import_transforms6 = __toESM(require_transforms(), 1);
30204
+ var import_colors6 = __toESM(require_colors(), 1);
28817
30205
  var import_booleans3 = __toESM(require_booleans(), 1);
30206
+ var CIRCLE_SEGMENTS = 64;
30207
+ function createSilkscreenCircleGeom(circleEl, ctx) {
30208
+ const radius = coerceDimensionToMm(circleEl.radius, 0);
30209
+ if (radius <= 0) return void 0;
30210
+ const strokeWidth = coerceDimensionToMm(circleEl.stroke_width, 0.12);
30211
+ const hasStroke = strokeWidth > 0;
30212
+ const centerX = parseDimensionToMm(circleEl.center?.x) ?? 0;
30213
+ const centerY = parseDimensionToMm(circleEl.center?.y) ?? 0;
30214
+ const layerSign = circleEl.layer === "bottom" ? -1 : 1;
30215
+ const zPos = layerSign * ctx.pcbThickness / 2 + layerSign * M * 1.5;
30216
+ const baseHeight = 0.012;
30217
+ let circleGeom;
30218
+ if (hasStroke) {
30219
+ const outerRadius = radius + strokeWidth / 2;
30220
+ const innerRadius = radius - strokeWidth / 2;
30221
+ const outerCircle2d = (0, import_primitives7.circle)({
30222
+ radius: outerRadius,
30223
+ segments: CIRCLE_SEGMENTS
30224
+ });
30225
+ let ring3d = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, outerCircle2d);
30226
+ if (innerRadius > 0) {
30227
+ const innerCircle2d = (0, import_primitives7.circle)({
30228
+ radius: innerRadius,
30229
+ segments: CIRCLE_SEGMENTS
30230
+ });
30231
+ const inner3d = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, innerCircle2d);
30232
+ ring3d = (0, import_booleans3.subtract)(ring3d, inner3d);
30233
+ }
30234
+ circleGeom = ring3d;
30235
+ } else {
30236
+ const filledCircle2d = (0, import_primitives7.circle)({ radius, segments: CIRCLE_SEGMENTS });
30237
+ circleGeom = (0, import_extrusions6.extrudeLinear)({ height: baseHeight }, filledCircle2d);
30238
+ }
30239
+ const translatedGeom = (0, import_transforms6.translate)([centerX, centerY, zPos], circleGeom);
30240
+ return (0, import_colors6.colorize)([1, 1, 1], translatedGeom);
30241
+ }
30242
+
30243
+ // src/geoms/brep-converter.ts
30244
+ var import_primitives8 = __toESM(require_primitives(), 1);
30245
+ var import_booleans4 = __toESM(require_booleans(), 1);
28818
30246
  function segmentToPoints(p1, p2, bulge, arcSegments) {
28819
30247
  if (!bulge || Math.abs(bulge) < 1e-9) {
28820
30248
  return [];
@@ -28882,7 +30310,7 @@ function createGeom2FromBRep(brep, arcSegments = 16) {
28882
30310
  if (arePointsClockwise2(outerPoints)) {
28883
30311
  outerPoints.reverse();
28884
30312
  }
28885
- const outerGeom = (0, import_primitives7.polygon)({ points: outerPoints });
30313
+ const outerGeom = (0, import_primitives8.polygon)({ points: outerPoints });
28886
30314
  if (!brep.inner_rings || brep.inner_rings.length === 0) {
28887
30315
  return outerGeom;
28888
30316
  }
@@ -28891,10 +30319,10 @@ function createGeom2FromBRep(brep, arcSegments = 16) {
28891
30319
  if (arePointsClockwise2(innerPoints)) {
28892
30320
  innerPoints.reverse();
28893
30321
  }
28894
- return (0, import_primitives7.polygon)({ points: innerPoints });
30322
+ return (0, import_primitives8.polygon)({ points: innerPoints });
28895
30323
  });
28896
30324
  if (innerGeoms.length === 0) return outerGeom;
28897
- return (0, import_booleans3.subtract)(outerGeom, innerGeoms);
30325
+ return (0, import_booleans4.subtract)(outerGeom, innerGeoms);
28898
30326
  }
28899
30327
 
28900
30328
  // src/BoardGeomBuilder.ts
@@ -28904,15 +30332,15 @@ var BOARD_CLIP_XY_OUTSET = 0.05;
28904
30332
  var createCenteredRectPadGeom = (width10, height10, thickness, rectBorderRadius) => {
28905
30333
  const clampedRadius = clampRectBorderRadius(width10, height10, rectBorderRadius);
28906
30334
  if (clampedRadius <= 0) {
28907
- return (0, import_primitives8.cuboid)({ center: [0, 0, 0], size: [width10, height10, thickness] });
30335
+ return (0, import_primitives9.cuboid)({ center: [0, 0, 0], size: [width10, height10, thickness] });
28908
30336
  }
28909
- const rect2d = (0, import_primitives8.roundedRectangle)({
30337
+ const rect2d = (0, import_primitives9.roundedRectangle)({
28910
30338
  size: [width10, height10],
28911
30339
  roundRadius: clampedRadius,
28912
30340
  segments: PAD_ROUNDED_SEGMENTS
28913
30341
  });
28914
- const extruded = (0, import_extrusions6.extrudeLinear)({ height: thickness }, rect2d);
28915
- return (0, import_transforms6.translate)([0, 0, -thickness / 2], extruded);
30342
+ const extruded = (0, import_extrusions7.extrudeLinear)({ height: thickness }, rect2d);
30343
+ return (0, import_transforms7.translate)([0, 0, -thickness / 2], extruded);
28916
30344
  };
28917
30345
  var buildStateOrder = [
28918
30346
  "initializing",
@@ -28925,6 +30353,7 @@ var buildStateOrder = [
28925
30353
  "processing_vias",
28926
30354
  "processing_silkscreen_text",
28927
30355
  "processing_silkscreen_lines",
30356
+ "processing_silkscreen_circles",
28928
30357
  "processing_silkscreen_rects",
28929
30358
  "processing_silkscreen_paths",
28930
30359
  "finalizing",
@@ -28941,6 +30370,7 @@ var BoardGeomBuilder = class {
28941
30370
  silkscreenTexts;
28942
30371
  silkscreenPaths;
28943
30372
  silkscreenLines;
30373
+ silkscreenCircles;
28944
30374
  silkscreenRects;
28945
30375
  pcb_cutouts;
28946
30376
  pcb_copper_pours;
@@ -28955,6 +30385,7 @@ var BoardGeomBuilder = class {
28955
30385
  silkscreenTextGeoms = [];
28956
30386
  silkscreenPathGeoms = [];
28957
30387
  silkscreenLineGeoms = [];
30388
+ silkscreenCircleGeoms = [];
28958
30389
  silkscreenRectGeoms = [];
28959
30390
  copperPourGeoms = [];
28960
30391
  boardClipGeom = null;
@@ -28990,6 +30421,7 @@ var BoardGeomBuilder = class {
28990
30421
  this.silkscreenTexts = su3(circuitJson).pcb_silkscreen_text.list();
28991
30422
  this.silkscreenPaths = su3(circuitJson).pcb_silkscreen_path.list();
28992
30423
  this.silkscreenLines = su3(circuitJson).pcb_silkscreen_line.list();
30424
+ this.silkscreenCircles = su3(circuitJson).pcb_silkscreen_circle.list();
28993
30425
  this.silkscreenRects = su3(circuitJson).pcb_silkscreen_rect.list();
28994
30426
  this.pcb_cutouts = su3(circuitJson).pcb_cutout.list();
28995
30427
  this.pcb_copper_pours = circuitJson.filter(
@@ -29015,11 +30447,11 @@ var BoardGeomBuilder = class {
29015
30447
  { xyOutset: BOARD_CLIP_XY_OUTSET }
29016
30448
  );
29017
30449
  } else {
29018
- this.boardGeom = (0, import_primitives8.cuboid)({
30450
+ this.boardGeom = (0, import_primitives9.cuboid)({
29019
30451
  size: [this.board.width, this.board.height, this.ctx.pcbThickness],
29020
30452
  center: [this.board.center.x, this.board.center.y, 0]
29021
30453
  });
29022
- this.boardClipGeom = (0, import_primitives8.cuboid)({
30454
+ this.boardClipGeom = (0, import_primitives9.cuboid)({
29023
30455
  size: [
29024
30456
  this.board.width + 2 * BOARD_CLIP_XY_OUTSET,
29025
30457
  this.board.height + 2 * BOARD_CLIP_XY_OUTSET,
@@ -29099,6 +30531,16 @@ var BoardGeomBuilder = class {
29099
30531
  this.goToNextState();
29100
30532
  }
29101
30533
  break;
30534
+ case "processing_silkscreen_circles":
30535
+ if (this.currentIndex < this.silkscreenCircles.length) {
30536
+ this.processSilkscreenCircle(
30537
+ this.silkscreenCircles[this.currentIndex]
30538
+ );
30539
+ this.currentIndex++;
30540
+ } else {
30541
+ this.goToNextState();
30542
+ }
30543
+ break;
29102
30544
  case "processing_silkscreen_rects":
29103
30545
  if (this.currentIndex < this.silkscreenRects.length) {
29104
30546
  this.processSilkscreenRect(this.silkscreenRects[this.currentIndex]);
@@ -29145,17 +30587,17 @@ var BoardGeomBuilder = class {
29145
30587
  const cutoutHeight = this.ctx.pcbThickness * 1.5;
29146
30588
  switch (cutout.shape) {
29147
30589
  case "rect":
29148
- cutoutGeom = (0, import_primitives8.cuboid)({
30590
+ cutoutGeom = (0, import_primitives9.cuboid)({
29149
30591
  center: [cutout.center.x, cutout.center.y, 0],
29150
30592
  size: [cutout.width, cutout.height, cutoutHeight]
29151
30593
  });
29152
30594
  if (cutout.rotation) {
29153
30595
  const rotationRadians = cutout.rotation * Math.PI / 180;
29154
- cutoutGeom = (0, import_transforms6.rotateZ)(rotationRadians, cutoutGeom);
30596
+ cutoutGeom = (0, import_transforms7.rotateZ)(rotationRadians, cutoutGeom);
29155
30597
  }
29156
30598
  break;
29157
30599
  case "circle":
29158
- cutoutGeom = (0, import_primitives8.cylinder)({
30600
+ cutoutGeom = (0, import_primitives9.cylinder)({
29159
30601
  center: [cutout.center.x, cutout.center.y, 0],
29160
30602
  radius: cutout.radius,
29161
30603
  height: cutoutHeight
@@ -29172,13 +30614,13 @@ var BoardGeomBuilder = class {
29172
30614
  if (arePointsClockwise(pointsVec2)) {
29173
30615
  pointsVec2 = pointsVec2.reverse();
29174
30616
  }
29175
- const polygon2d = (0, import_primitives8.polygon)({ points: pointsVec2 });
29176
- cutoutGeom = (0, import_extrusions6.extrudeLinear)({ height: cutoutHeight }, polygon2d);
29177
- cutoutGeom = (0, import_transforms6.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
30617
+ const polygon2d = (0, import_primitives9.polygon)({ points: pointsVec2 });
30618
+ cutoutGeom = (0, import_extrusions7.extrudeLinear)({ height: cutoutHeight }, polygon2d);
30619
+ cutoutGeom = (0, import_transforms7.translate)([0, 0, -cutoutHeight / 2], cutoutGeom);
29178
30620
  break;
29179
30621
  }
29180
30622
  if (cutoutGeom) {
29181
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cutoutGeom);
30623
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cutoutGeom);
29182
30624
  }
29183
30625
  }
29184
30626
  processCopperPour(pour) {
@@ -29186,22 +30628,22 @@ var BoardGeomBuilder = class {
29186
30628
  const zPos = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.copper;
29187
30629
  let pourGeom = null;
29188
30630
  if (pour.shape === "rect") {
29189
- let baseGeom = (0, import_primitives8.cuboid)({
30631
+ let baseGeom = (0, import_primitives9.cuboid)({
29190
30632
  center: [0, 0, 0],
29191
30633
  // Create at origin for rotation
29192
30634
  size: [pour.width, pour.height, M]
29193
30635
  });
29194
30636
  if ("rotation" in pour && pour.rotation) {
29195
30637
  const rotationRadians = pour.rotation * Math.PI / 180;
29196
- baseGeom = (0, import_transforms6.rotateZ)(rotationRadians, baseGeom);
30638
+ baseGeom = (0, import_transforms7.rotateZ)(rotationRadians, baseGeom);
29197
30639
  }
29198
- pourGeom = (0, import_transforms6.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
30640
+ pourGeom = (0, import_transforms7.translate)([pour.center.x, pour.center.y, zPos], baseGeom);
29199
30641
  } else if (pour.shape === "brep") {
29200
30642
  const brepShape = pour.brep_shape;
29201
30643
  if (brepShape && brepShape.outer_ring) {
29202
30644
  const pourGeom2 = createGeom2FromBRep(brepShape);
29203
- pourGeom = (0, import_extrusions6.extrudeLinear)({ height: M }, pourGeom2);
29204
- pourGeom = (0, import_transforms6.translate)([0, 0, zPos], pourGeom);
30645
+ pourGeom = (0, import_extrusions7.extrudeLinear)({ height: M }, pourGeom2);
30646
+ pourGeom = (0, import_transforms7.translate)([0, 0, zPos], pourGeom);
29205
30647
  }
29206
30648
  } else if (pour.shape === "polygon") {
29207
30649
  let pointsVec2 = pour.points.map((p) => [p.x, p.y]);
@@ -29214,17 +30656,17 @@ var BoardGeomBuilder = class {
29214
30656
  if (arePointsClockwise(pointsVec2)) {
29215
30657
  pointsVec2 = pointsVec2.reverse();
29216
30658
  }
29217
- const polygon2d = (0, import_primitives8.polygon)({ points: pointsVec2 });
29218
- pourGeom = (0, import_extrusions6.extrudeLinear)({ height: M }, polygon2d);
29219
- pourGeom = (0, import_transforms6.translate)([0, 0, zPos], pourGeom);
30659
+ const polygon2d = (0, import_primitives9.polygon)({ points: pointsVec2 });
30660
+ pourGeom = (0, import_extrusions7.extrudeLinear)({ height: M }, polygon2d);
30661
+ pourGeom = (0, import_transforms7.translate)([0, 0, zPos], pourGeom);
29220
30662
  }
29221
30663
  if (pourGeom) {
29222
30664
  if (this.boardClipGeom) {
29223
- pourGeom = (0, import_booleans4.intersect)(this.boardClipGeom, pourGeom);
30665
+ pourGeom = (0, import_booleans5.intersect)(this.boardClipGeom, pourGeom);
29224
30666
  }
29225
30667
  const covered = pour.covered_with_solder_mask !== false;
29226
30668
  const pourMaterialColor = covered ? tracesMaterialColors[this.board.material] ?? colors.fr4GreenSolderWithMask : colors.copper;
29227
- const coloredPourGeom = (0, import_colors6.colorize)(pourMaterialColor, pourGeom);
30669
+ const coloredPourGeom = (0, import_colors7.colorize)(pourMaterialColor, pourGeom);
29228
30670
  this.copperPourGeoms.push(coloredPourGeom);
29229
30671
  }
29230
30672
  }
@@ -29233,7 +30675,7 @@ var BoardGeomBuilder = class {
29233
30675
  if (ph.shape === "circle" || ph.shape === "circular_hole_with_rect_pad") {
29234
30676
  let cyGeom = null;
29235
30677
  if (ph.shape === "circular_hole_with_rect_pad") {
29236
- cyGeom = (0, import_primitives8.cylinder)({
30678
+ cyGeom = (0, import_primitives9.cylinder)({
29237
30679
  center: [
29238
30680
  ph.x + (ph.hole_offset_x || 0),
29239
30681
  ph.y + (ph.hole_offset_y || 0),
@@ -29245,7 +30687,7 @@ var BoardGeomBuilder = class {
29245
30687
  // Ensure it cuts through
29246
30688
  });
29247
30689
  } else {
29248
- cyGeom = (0, import_primitives8.cylinder)({
30690
+ cyGeom = (0, import_primitives9.cylinder)({
29249
30691
  center: [ph.x, ph.y, 0],
29250
30692
  radius: ph.hole_diameter / 2 + M,
29251
30693
  // Add margin for subtraction
@@ -29254,10 +30696,10 @@ var BoardGeomBuilder = class {
29254
30696
  });
29255
30697
  }
29256
30698
  if (!opts.dontCutBoard) {
29257
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cyGeom);
30699
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cyGeom);
29258
30700
  }
29259
30701
  this.padGeoms = this.padGeoms.map(
29260
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, cyGeom))
30702
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, cyGeom))
29261
30703
  );
29262
30704
  const platedHoleGeom = platedHole(ph, this.ctx, {
29263
30705
  clipGeom: this.boardClipGeom
@@ -29271,8 +30713,8 @@ var BoardGeomBuilder = class {
29271
30713
  const rectLength = Math.abs(holeWidth - holeHeight);
29272
30714
  let pillHole;
29273
30715
  if (ph.shape === "pill_hole_with_rect_pad") {
29274
- pillHole = (0, import_booleans4.union)(
29275
- (0, import_primitives8.cuboid)({
30716
+ pillHole = (0, import_booleans5.union)(
30717
+ (0, import_primitives9.cuboid)({
29276
30718
  center: [
29277
30719
  ph.x + (ph.hole_offset_x || 0),
29278
30720
  ph.y + (ph.hole_offset_y || 0),
@@ -29280,7 +30722,7 @@ var BoardGeomBuilder = class {
29280
30722
  ],
29281
30723
  size: shouldRotate ? [holeHeight, rectLength, this.ctx.pcbThickness * 1.5] : [rectLength, holeHeight, this.ctx.pcbThickness * 1.5]
29282
30724
  }),
29283
- (0, import_primitives8.cylinder)({
30725
+ (0, import_primitives9.cylinder)({
29284
30726
  center: shouldRotate ? [
29285
30727
  ph.x + (ph.hole_offset_x || 0),
29286
30728
  ph.y + (ph.hole_offset_y || 0) - rectLength / 2,
@@ -29293,7 +30735,7 @@ var BoardGeomBuilder = class {
29293
30735
  radius: holeRadius,
29294
30736
  height: this.ctx.pcbThickness * 1.5
29295
30737
  }),
29296
- (0, import_primitives8.cylinder)({
30738
+ (0, import_primitives9.cylinder)({
29297
30739
  center: shouldRotate ? [
29298
30740
  ph.x + (ph.hole_offset_x || 0),
29299
30741
  ph.y + (ph.hole_offset_y || 0) + rectLength / 2,
@@ -29308,17 +30750,17 @@ var BoardGeomBuilder = class {
29308
30750
  })
29309
30751
  );
29310
30752
  } else {
29311
- pillHole = (0, import_booleans4.union)(
29312
- (0, import_primitives8.cuboid)({
30753
+ pillHole = (0, import_booleans5.union)(
30754
+ (0, import_primitives9.cuboid)({
29313
30755
  center: [ph.x, ph.y, 0],
29314
30756
  size: shouldRotate ? [holeHeight, rectLength, this.ctx.pcbThickness * 1.5] : [rectLength, holeHeight, this.ctx.pcbThickness * 1.5]
29315
30757
  }),
29316
- (0, import_primitives8.cylinder)({
30758
+ (0, import_primitives9.cylinder)({
29317
30759
  center: shouldRotate ? [ph.x, ph.y - rectLength / 2, 0] : [ph.x - rectLength / 2, ph.y, 0],
29318
30760
  radius: holeRadius,
29319
30761
  height: this.ctx.pcbThickness * 1.5
29320
30762
  }),
29321
- (0, import_primitives8.cylinder)({
30763
+ (0, import_primitives9.cylinder)({
29322
30764
  center: shouldRotate ? [ph.x, ph.y + rectLength / 2, 0] : [ph.x + rectLength / 2, ph.y, 0],
29323
30765
  radius: holeRadius,
29324
30766
  height: this.ctx.pcbThickness * 1.5
@@ -29326,10 +30768,10 @@ var BoardGeomBuilder = class {
29326
30768
  );
29327
30769
  }
29328
30770
  if (!opts.dontCutBoard) {
29329
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, pillHole);
30771
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, pillHole);
29330
30772
  }
29331
30773
  this.padGeoms = this.padGeoms.map(
29332
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, pillHole))
30774
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, pillHole))
29333
30775
  );
29334
30776
  const platedHoleGeom = platedHole(ph, this.ctx, {
29335
30777
  clipGeom: this.boardClipGeom
@@ -29342,22 +30784,22 @@ var BoardGeomBuilder = class {
29342
30784
  const holeDepth = this.ctx.pcbThickness * 1.5;
29343
30785
  const copperInset = 0.02;
29344
30786
  if (hole.hole_shape === "round" || hole.hole_shape === "circle") {
29345
- const cyGeom = (0, import_primitives8.cylinder)({
30787
+ const cyGeom = (0, import_primitives9.cylinder)({
29346
30788
  center: [hole.x, hole.y, 0],
29347
30789
  radius: hole.hole_diameter / 2 + M,
29348
30790
  height: holeDepth
29349
30791
  });
29350
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, cyGeom);
30792
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, cyGeom);
29351
30793
  this.padGeoms = this.padGeoms.map(
29352
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, cyGeom))
30794
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, cyGeom))
29353
30795
  );
29354
- const copperCut = (0, import_primitives8.cylinder)({
30796
+ const copperCut = (0, import_primitives9.cylinder)({
29355
30797
  center: [hole.x, hole.y, 0],
29356
30798
  radius: hole.hole_diameter / 2 + M / 2,
29357
30799
  height: holeDepth
29358
30800
  });
29359
30801
  this.platedHoleGeoms = this.platedHoleGeoms.map(
29360
- (phg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(phg, copperCut))
30802
+ (phg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperCut))
29361
30803
  );
29362
30804
  } else if (hole.hole_shape === "pill" || hole.hole_shape === "rotated_pill") {
29363
30805
  const holeWidth = hole.hole_width;
@@ -29367,34 +30809,34 @@ var BoardGeomBuilder = class {
29367
30809
  const isRotated = hole.hole_shape === "rotated_pill";
29368
30810
  let pillHole;
29369
30811
  if (holeWidth > holeHeight) {
29370
- pillHole = (0, import_booleans4.union)(
29371
- (0, import_primitives8.cuboid)({
30812
+ pillHole = (0, import_booleans5.union)(
30813
+ (0, import_primitives9.cuboid)({
29372
30814
  center: [hole.x, hole.y, 0],
29373
30815
  size: [rectLength, holeHeight, holeDepth]
29374
30816
  }),
29375
- (0, import_primitives8.cylinder)({
30817
+ (0, import_primitives9.cylinder)({
29376
30818
  center: [hole.x - rectLength / 2, hole.y, 0],
29377
30819
  radius: holeRadius,
29378
30820
  height: holeDepth
29379
30821
  }),
29380
- (0, import_primitives8.cylinder)({
30822
+ (0, import_primitives9.cylinder)({
29381
30823
  center: [hole.x + rectLength / 2, hole.y, 0],
29382
30824
  radius: holeRadius,
29383
30825
  height: holeDepth
29384
30826
  })
29385
30827
  );
29386
30828
  } else {
29387
- pillHole = (0, import_booleans4.union)(
29388
- (0, import_primitives8.cuboid)({
30829
+ pillHole = (0, import_booleans5.union)(
30830
+ (0, import_primitives9.cuboid)({
29389
30831
  center: [hole.x, hole.y, 0],
29390
30832
  size: [holeWidth, rectLength, holeDepth]
29391
30833
  }),
29392
- (0, import_primitives8.cylinder)({
30834
+ (0, import_primitives9.cylinder)({
29393
30835
  center: [hole.x, hole.y - rectLength / 2, 0],
29394
30836
  radius: holeRadius,
29395
30837
  height: holeDepth
29396
30838
  }),
29397
- (0, import_primitives8.cylinder)({
30839
+ (0, import_primitives9.cylinder)({
29398
30840
  center: [hole.x, hole.y + rectLength / 2, 0],
29399
30841
  radius: holeRadius,
29400
30842
  height: holeDepth
@@ -29403,15 +30845,15 @@ var BoardGeomBuilder = class {
29403
30845
  }
29404
30846
  if (isRotated) {
29405
30847
  const rotationRadians = hole.ccw_rotation * Math.PI / 180;
29406
- pillHole = (0, import_transforms6.rotateZ)(rotationRadians, pillHole);
30848
+ pillHole = (0, import_transforms7.rotateZ)(rotationRadians, pillHole);
29407
30849
  }
29408
- this.boardGeom = (0, import_booleans4.subtract)(this.boardGeom, pillHole);
30850
+ this.boardGeom = (0, import_booleans5.subtract)(this.boardGeom, pillHole);
29409
30851
  this.padGeoms = this.padGeoms.map(
29410
- (pg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(pg, pillHole))
30852
+ (pg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(pg, pillHole))
29411
30853
  );
29412
30854
  const copperPill = (0, import_expansions4.expand)({ delta: -copperInset }, pillHole);
29413
30855
  this.platedHoleGeoms = this.platedHoleGeoms.map(
29414
- (phg) => (0, import_colors6.colorize)(colors.copper, (0, import_booleans4.subtract)(phg, copperPill))
30856
+ (phg) => (0, import_colors7.colorize)(colors.copper, (0, import_booleans5.subtract)(phg, copperPill))
29415
30857
  );
29416
30858
  }
29417
30859
  }
@@ -29426,12 +30868,12 @@ var BoardGeomBuilder = class {
29426
30868
  M,
29427
30869
  rectBorderRadius
29428
30870
  );
29429
- const positionedPadGeom = (0, import_transforms6.translate)([pad2.x, pad2.y, zPos], basePadGeom);
30871
+ const positionedPadGeom = (0, import_transforms7.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29430
30872
  let finalPadGeom = positionedPadGeom;
29431
30873
  if (this.boardClipGeom) {
29432
- finalPadGeom = (0, import_booleans4.intersect)(this.boardClipGeom, finalPadGeom);
30874
+ finalPadGeom = (0, import_booleans5.intersect)(this.boardClipGeom, finalPadGeom);
29433
30875
  }
29434
- finalPadGeom = (0, import_colors6.colorize)(colors.copper, finalPadGeom);
30876
+ finalPadGeom = (0, import_colors7.colorize)(colors.copper, finalPadGeom);
29435
30877
  this.padGeoms.push(finalPadGeom);
29436
30878
  } else if (pad2.shape === "rotated_rect") {
29437
30879
  let basePadGeom = createCenteredRectPadGeom(
@@ -29441,24 +30883,24 @@ var BoardGeomBuilder = class {
29441
30883
  rectBorderRadius
29442
30884
  );
29443
30885
  const rotationRadians = pad2.ccw_rotation * Math.PI / 180;
29444
- basePadGeom = (0, import_transforms6.rotateZ)(rotationRadians, basePadGeom);
29445
- const positionedPadGeom = (0, import_transforms6.translate)([pad2.x, pad2.y, zPos], basePadGeom);
30886
+ basePadGeom = (0, import_transforms7.rotateZ)(rotationRadians, basePadGeom);
30887
+ const positionedPadGeom = (0, import_transforms7.translate)([pad2.x, pad2.y, zPos], basePadGeom);
29446
30888
  let finalPadGeom = positionedPadGeom;
29447
30889
  if (this.boardClipGeom) {
29448
- finalPadGeom = (0, import_booleans4.intersect)(this.boardClipGeom, finalPadGeom);
30890
+ finalPadGeom = (0, import_booleans5.intersect)(this.boardClipGeom, finalPadGeom);
29449
30891
  }
29450
- finalPadGeom = (0, import_colors6.colorize)(colors.copper, finalPadGeom);
30892
+ finalPadGeom = (0, import_colors7.colorize)(colors.copper, finalPadGeom);
29451
30893
  this.padGeoms.push(finalPadGeom);
29452
30894
  } else if (pad2.shape === "circle") {
29453
- let padGeom = (0, import_primitives8.cylinder)({
30895
+ let padGeom = (0, import_primitives9.cylinder)({
29454
30896
  center: [pad2.x, pad2.y, zPos],
29455
30897
  radius: pad2.radius,
29456
30898
  height: M
29457
30899
  });
29458
30900
  if (this.boardClipGeom) {
29459
- padGeom = (0, import_booleans4.intersect)(this.boardClipGeom, padGeom);
30901
+ padGeom = (0, import_booleans5.intersect)(this.boardClipGeom, padGeom);
29460
30902
  }
29461
- padGeom = (0, import_colors6.colorize)(colors.copper, padGeom);
30903
+ padGeom = (0, import_colors7.colorize)(colors.copper, padGeom);
29462
30904
  this.padGeoms.push(padGeom);
29463
30905
  }
29464
30906
  }
@@ -29472,14 +30914,14 @@ var BoardGeomBuilder = class {
29472
30914
  if (currentSegmentPoints.length >= 2 && currentLayer) {
29473
30915
  const layerSign = currentLayer === "bottom" ? -1 : 1;
29474
30916
  const zCenter = layerSign * this.ctx.pcbThickness / 2 + layerSign * BOARD_SURFACE_OFFSET.traces;
29475
- const linePath = (0, import_primitives8.line)(currentSegmentPoints);
30917
+ const linePath = (0, import_primitives9.line)(currentSegmentPoints);
29476
30918
  const expandedPath = (0, import_expansions4.expand)(
29477
30919
  { delta: currentWidth / 2, corners: "round" },
29478
30920
  linePath
29479
30921
  );
29480
- let traceGeom = (0, import_transforms6.translate)(
30922
+ let traceGeom = (0, import_transforms7.translate)(
29481
30923
  [0, 0, zCenter - M / 2],
29482
- (0, import_extrusions6.extrudeLinear)({ height: M }, expandedPath)
30924
+ (0, import_extrusions7.extrudeLinear)({ height: M }, expandedPath)
29483
30925
  );
29484
30926
  const startPointCoords = currentSegmentPoints[0];
29485
30927
  const endPointCoords = currentSegmentPoints[currentSegmentPoints.length - 1];
@@ -29488,27 +30930,27 @@ var BoardGeomBuilder = class {
29488
30930
  startPointCoords[1]
29489
30931
  );
29490
30932
  if (startHole) {
29491
- const cuttingCylinder = (0, import_primitives8.cylinder)({
30933
+ const cuttingCylinder = (0, import_primitives9.cylinder)({
29492
30934
  center: [startPointCoords[0], startPointCoords[1], zCenter],
29493
30935
  radius: startHole.diameter / 2 + M,
29494
30936
  height: M
29495
30937
  });
29496
- traceGeom = (0, import_booleans4.subtract)(traceGeom, cuttingCylinder);
30938
+ traceGeom = (0, import_booleans5.subtract)(traceGeom, cuttingCylinder);
29497
30939
  }
29498
30940
  const endHole = this.getHoleToCut(endPointCoords[0], endPointCoords[1]);
29499
30941
  if (endHole) {
29500
- const cuttingCylinder = (0, import_primitives8.cylinder)({
30942
+ const cuttingCylinder = (0, import_primitives9.cylinder)({
29501
30943
  center: [endPointCoords[0], endPointCoords[1], zCenter],
29502
30944
  radius: endHole.diameter / 2 + M,
29503
30945
  height: M
29504
30946
  });
29505
- traceGeom = (0, import_booleans4.subtract)(traceGeom, cuttingCylinder);
30947
+ traceGeom = (0, import_booleans5.subtract)(traceGeom, cuttingCylinder);
29506
30948
  }
29507
30949
  const tracesMaterialColor = tracesMaterialColors[this.board.material] ?? colors.fr4GreenSolderWithMask;
29508
30950
  if (this.boardClipGeom) {
29509
- traceGeom = (0, import_booleans4.intersect)(this.boardClipGeom, traceGeom);
30951
+ traceGeom = (0, import_booleans5.intersect)(this.boardClipGeom, traceGeom);
29510
30952
  }
29511
- traceGeom = (0, import_colors6.colorize)(tracesMaterialColor, traceGeom);
30953
+ traceGeom = (0, import_colors7.colorize)(tracesMaterialColor, traceGeom);
29512
30954
  this.traceGeoms.push(traceGeom);
29513
30955
  }
29514
30956
  currentSegmentPoints = [];
@@ -29575,7 +31017,7 @@ var BoardGeomBuilder = class {
29575
31017
  point2[0] + xOffset + st.anchor_position.x,
29576
31018
  point2[1] + yOffset + st.anchor_position.y
29577
31019
  ]);
29578
- const textPath = (0, import_primitives8.line)(alignedOutline);
31020
+ const textPath = (0, import_primitives9.line)(alignedOutline);
29579
31021
  const fontSize = st.font_size || 0.25;
29580
31022
  const expansionDelta = Math.min(
29581
31023
  Math.max(0.01, fontSize * 0.1),
@@ -29587,19 +31029,19 @@ var BoardGeomBuilder = class {
29587
31029
  );
29588
31030
  let textGeom;
29589
31031
  if (st.layer === "bottom") {
29590
- textGeom = (0, import_transforms6.translate)(
31032
+ textGeom = (0, import_transforms7.translate)(
29591
31033
  [0, 0, -this.ctx.pcbThickness / 2 - M],
29592
31034
  // Position above board
29593
- (0, import_extrusions6.extrudeLinear)({ height: 0.012 }, expandedPath)
31035
+ (0, import_extrusions7.extrudeLinear)({ height: 0.012 }, expandedPath)
29594
31036
  );
29595
31037
  } else {
29596
- textGeom = (0, import_transforms6.translate)(
31038
+ textGeom = (0, import_transforms7.translate)(
29597
31039
  [0, 0, this.ctx.pcbThickness / 2 + M],
29598
31040
  // Position above board
29599
- (0, import_extrusions6.extrudeLinear)({ height: 0.012 }, expandedPath)
31041
+ (0, import_extrusions7.extrudeLinear)({ height: 0.012 }, expandedPath)
29600
31042
  );
29601
31043
  }
29602
- textGeom = (0, import_colors6.colorize)([1, 1, 1], textGeom);
31044
+ textGeom = (0, import_colors7.colorize)([1, 1, 1], textGeom);
29603
31045
  this.silkscreenTextGeoms.push(textGeom);
29604
31046
  }
29605
31047
  }
@@ -29615,6 +31057,12 @@ var BoardGeomBuilder = class {
29615
31057
  this.silkscreenLineGeoms.push(lineGeom);
29616
31058
  }
29617
31059
  }
31060
+ processSilkscreenCircle(sc) {
31061
+ const circleGeom = createSilkscreenCircleGeom(sc, this.ctx);
31062
+ if (circleGeom) {
31063
+ this.silkscreenCircleGeoms.push(circleGeom);
31064
+ }
31065
+ }
29618
31066
  processSilkscreenRect(sr) {
29619
31067
  const rectGeom = createSilkscreenRectGeom(sr, this.ctx);
29620
31068
  if (rectGeom) {
@@ -29624,7 +31072,7 @@ var BoardGeomBuilder = class {
29624
31072
  finalize() {
29625
31073
  if (!this.boardGeom) return;
29626
31074
  const boardMaterialColor = boardMaterialColors[this.board.material] ?? colors.fr4Green;
29627
- this.boardGeom = (0, import_colors6.colorize)(boardMaterialColor, this.boardGeom);
31075
+ this.boardGeom = (0, import_colors7.colorize)(boardMaterialColor, this.boardGeom);
29628
31076
  this.finalGeoms = [
29629
31077
  this.boardGeom,
29630
31078
  ...this.platedHoleGeoms,
@@ -29634,6 +31082,7 @@ var BoardGeomBuilder = class {
29634
31082
  ...this.copperPourGeoms,
29635
31083
  ...this.silkscreenTextGeoms,
29636
31084
  ...this.silkscreenLineGeoms,
31085
+ ...this.silkscreenCircleGeoms,
29637
31086
  ...this.silkscreenRectGeoms,
29638
31087
  ...this.silkscreenPathGeoms
29639
31088
  ];
@@ -30160,11 +31609,13 @@ function createSilkscreenTextureForLayer({
30160
31609
  const pcbSilkscreenPaths = su6(circuitJson).pcb_silkscreen_path.list();
30161
31610
  const pcbSilkscreenLines = su6(circuitJson).pcb_silkscreen_line.list();
30162
31611
  const pcbSilkscreenRects = su6(circuitJson).pcb_silkscreen_rect.list();
31612
+ const pcbSilkscreenCircles = su6(circuitJson).pcb_silkscreen_circle.list();
30163
31613
  const textsOnLayer = pcbSilkscreenTexts.filter((t) => t.layer === layer);
30164
31614
  const pathsOnLayer = pcbSilkscreenPaths.filter((p) => p.layer === layer);
30165
31615
  const linesOnLayer = pcbSilkscreenLines.filter((l) => l.layer === layer);
30166
31616
  const rectsOnLayer = pcbSilkscreenRects.filter((r) => r.layer === layer);
30167
- if (textsOnLayer.length === 0 && pathsOnLayer.length === 0 && linesOnLayer.length === 0 && rectsOnLayer.length === 0) {
31617
+ const circlesOnLayer = pcbSilkscreenCircles.filter((c) => c.layer === layer);
31618
+ if (textsOnLayer.length === 0 && pathsOnLayer.length === 0 && linesOnLayer.length === 0 && rectsOnLayer.length === 0 && circlesOnLayer.length === 0) {
30168
31619
  return null;
30169
31620
  }
30170
31621
  const canvas = document.createElement("canvas");
@@ -30209,6 +31660,41 @@ function createSilkscreenTextureForLayer({
30209
31660
  });
30210
31661
  ctx.stroke();
30211
31662
  });
31663
+ circlesOnLayer.forEach((circleEl) => {
31664
+ const radius = coerceDimensionToMm(circleEl.radius, 0);
31665
+ if (radius <= 0) return;
31666
+ const strokeWidth = coerceDimensionToMm(circleEl.stroke_width, 0.12);
31667
+ const hasStroke = strokeWidth > 0;
31668
+ const centerXmm = parseDimensionToMm(circleEl.center?.x) ?? 0;
31669
+ const centerYmm = parseDimensionToMm(circleEl.center?.y) ?? 0;
31670
+ const canvasCenterX = canvasXFromPcb(centerXmm);
31671
+ const canvasCenterY = canvasYFromPcb(centerYmm);
31672
+ const radiusPx = radius * traceTextureResolution;
31673
+ ctx.save();
31674
+ ctx.translate(canvasCenterX, canvasCenterY);
31675
+ if (hasStroke) {
31676
+ const outerRadiusPx = radiusPx + strokeWidth / 2 * traceTextureResolution;
31677
+ const innerRadiusPx = Math.max(
31678
+ 0,
31679
+ radiusPx - strokeWidth / 2 * traceTextureResolution
31680
+ );
31681
+ if (innerRadiusPx > 0) {
31682
+ ctx.beginPath();
31683
+ ctx.arc(0, 0, outerRadiusPx, 0, 2 * Math.PI);
31684
+ ctx.arc(0, 0, innerRadiusPx, 0, 2 * Math.PI, true);
31685
+ ctx.fill("evenodd");
31686
+ } else {
31687
+ ctx.beginPath();
31688
+ ctx.arc(0, 0, outerRadiusPx, 0, 2 * Math.PI);
31689
+ ctx.fill();
31690
+ }
31691
+ } else {
31692
+ ctx.beginPath();
31693
+ ctx.arc(0, 0, radiusPx, 0, 2 * Math.PI);
31694
+ ctx.fill();
31695
+ }
31696
+ ctx.restore();
31697
+ });
30212
31698
  rectsOnLayer.forEach((rect) => {
30213
31699
  const width10 = coerceDimensionToMm(rect.width, 0);
30214
31700
  const height10 = coerceDimensionToMm(rect.height, 0);