jscad-electronics 0.0.159 → 0.0.161

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.
package/dist/vanilla.js CHANGED
@@ -49,8 +49,18 @@ var FootprintPad = ({
49
49
  isPin1
50
50
  }) => {
51
51
  const color = isPin1 ? [0, 255, 0] : [255, 0, 0];
52
- if (pad.shape === "rect") {
53
- return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Translate, { offset: [pad.x, pad.y, -5e-3], children: /* @__PURE__ */ jsx(Cuboid, { size: [pad.width, pad.height, PAD_THICKNESS] }) }) });
52
+ if (pad.shape === "rect" || pad.shape === "rotated_rect") {
53
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Translate, { offset: [pad.x, pad.y, -5e-3], children: /* @__PURE__ */ jsx(
54
+ Rotate,
55
+ {
56
+ angles: [
57
+ 0,
58
+ 0,
59
+ pad.shape === "rotated_rect" ? pad.ccw_rotation * Math.PI / 180 : 0
60
+ ],
61
+ children: /* @__PURE__ */ jsx(Cuboid, { size: [pad.width, pad.height, PAD_THICKNESS] })
62
+ }
63
+ ) }) });
54
64
  }
55
65
  if (pad.shape === "circle") {
56
66
  const radius = pad.radius ?? pad.r ?? 0.25;
@@ -183,8 +193,67 @@ var ExtrudedPads = ({
183
193
  ] });
184
194
  };
185
195
 
196
+ // lib/TantalumCapacitor.tsx
197
+ import { fp as fp2 } from "@tscircuit/footprinter";
198
+ var tantalumCases = {
199
+ A: [3.2, 1.6, 1.6, 1.2, 0.8],
200
+ B: [3.5, 2.8, 1.9, 2.2, 0.8],
201
+ C: [6, 3.2, 2.6, 2.2, 1.3],
202
+ D: [7.3, 4.3, 2.9, 2.4, 1.3]
203
+ };
204
+ var TantalumCapacitor = ({
205
+ caseSize = "A",
206
+ footprint = "smdpads2_p3.1mm_pw1.4mm_ph1.6mm"
207
+ }) => {
208
+ const dims = tantalumCases[caseSize];
209
+ if (!dims) throw new Error("Unsupported tantalum case");
210
+ const [length, width10, height10, leadWidth, leadLength] = dims;
211
+ const pads = fp2.string(footprint).circuitJson().filter(
212
+ (e) => e.type === "pcb_smtpad" && (e.shape === "rect" || e.shape === "rotated_rect")
213
+ );
214
+ if (pads.length !== 2) throw new Error("TantalumCapacitor requires two pads");
215
+ const [a, b] = pads;
216
+ const angle = Math.atan2(b.y - a.y, b.x - a.x);
217
+ return /* @__PURE__ */ jsx(Translate, { offset: [(a.x + b.x) / 2, (a.y + b.y) / 2, 0], children: /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 0, angle], children: [
218
+ /* @__PURE__ */ jsx(Colorize, { color: "#d5a64e", children: /* @__PURE__ */ jsxs(Hull, { children: [
219
+ /* @__PURE__ */ jsx(Cuboid, { size: [length - 0.1, width10, 0.02], center: [0, 0, 0.21] }),
220
+ /* @__PURE__ */ jsx(
221
+ Cuboid,
222
+ {
223
+ size: [length - 0.25, width10 - 0.15, 0.02],
224
+ center: [0, 0, height10 - 0.01]
225
+ }
226
+ )
227
+ ] }) }),
228
+ /* @__PURE__ */ jsx(Colorize, { color: "#c5c8cb", children: [-1, 1].map((side) => /* @__PURE__ */ jsxs(Union, { children: [
229
+ /* @__PURE__ */ jsx(
230
+ Cuboid,
231
+ {
232
+ size: [leadLength, leadWidth, 0.25],
233
+ center: [side * (length - leadLength) / 2, 0, 0.125]
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx(
237
+ Cuboid,
238
+ {
239
+ size: [0.15, leadWidth, height10 * 0.45],
240
+ center: [side * (length - 0.15) / 2, 0, height10 * 0.225]
241
+ }
242
+ )
243
+ ] }, side)) }),
244
+ /* @__PURE__ */ jsx(
245
+ Cuboid,
246
+ {
247
+ size: [0.25, width10 - 0.25, 0.01],
248
+ center: [-length / 2 + 0.5, 0, height10],
249
+ color: "#423426"
250
+ }
251
+ )
252
+ ] }) });
253
+ };
254
+
186
255
  // lib/Footprinter3d.tsx
187
- import { fp as fp6 } from "@tscircuit/footprinter";
256
+ import { fp as fp9 } from "@tscircuit/footprinter";
188
257
  import { mp } from "@tscircuit/modelprinter";
189
258
 
190
259
  // lib/ChipBody.tsx
@@ -5170,7 +5239,7 @@ var JSTPH2_0mm = ({
5170
5239
  };
5171
5240
 
5172
5241
  // lib/JSTXH2_5mm.tsx
5173
- import { fp as fp2 } from "@tscircuit/footprinter";
5242
+ import { fp as fp3 } from "@tscircuit/footprinter";
5174
5243
  var JSTXH2_5mm = ({
5175
5244
  numPins = 4,
5176
5245
  showPins = true,
@@ -5279,7 +5348,7 @@ var JSTXH2_5mm = ({
5279
5348
  showPins && Array.from({ length: numPins }).map((_, i) => /* @__PURE__ */ jsx(Colorize, { color: pinColor, children: /* @__PURE__ */ jsx(Translate, { offset: [startX + i * pitch, 0, pinLength / 2 - 3.4], children: /* @__PURE__ */ jsx(Cuboid, { size: [0.64, 0.64, pinLength] }) }) }, i)),
5280
5349
  showFootprint && (() => {
5281
5350
  try {
5282
- const circuitJson = fp2.string(`jst${numPins}_xh`).circuitJson();
5351
+ const circuitJson = fp3.string(`jst${numPins}_xh`).circuitJson();
5283
5352
  const platedHoles = circuitJson.filter(
5284
5353
  (e) => e.type === "pcb_plated_hole"
5285
5354
  );
@@ -5775,9 +5844,9 @@ var SmdPinHeader = ({
5775
5844
  import { mm } from "@tscircuit/mm";
5776
5845
 
5777
5846
  // lib/utils/getPlatedHoleCenters.ts
5778
- import { fp as fp3 } from "@tscircuit/footprinter";
5847
+ import { fp as fp4 } from "@tscircuit/footprinter";
5779
5848
  var getPlatedHoleCenters = (footprint) => {
5780
- const elements = fp3.string(footprint).circuitJson();
5849
+ const elements = fp4.string(footprint).circuitJson();
5781
5850
  return elements.filter(
5782
5851
  (element) => element.type === "pcb_plated_hole" && Number.isFinite(element.x) && Number.isFinite(element.y)
5783
5852
  ).map((element) => ({
@@ -5788,9 +5857,9 @@ var getPlatedHoleCenters = (footprint) => {
5788
5857
  };
5789
5858
 
5790
5859
  // lib/utils/getSmtPadRects.ts
5791
- import { fp as fp4 } from "@tscircuit/footprinter";
5860
+ import { fp as fp5 } from "@tscircuit/footprinter";
5792
5861
  var getSmtPadRects = (footprint) => {
5793
- const elements = fp4.string(footprint).circuitJson();
5862
+ const elements = fp5.string(footprint).circuitJson();
5794
5863
  return elements.filter(
5795
5864
  (element) => element.type === "pcb_smtpad" && element.shape === "rect" && Number.isFinite(element.x) && Number.isFinite(element.y)
5796
5865
  ).map((element) => ({
@@ -6546,7 +6615,7 @@ var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
6546
6615
  };
6547
6616
 
6548
6617
  // lib/BGA.tsx
6549
- import { fp as fp5 } from "@tscircuit/footprinter";
6618
+ import { fp as fp6 } from "@tscircuit/footprinter";
6550
6619
  var BGA = ({
6551
6620
  packageWidth = 10,
6552
6621
  packageLength = 10,
@@ -6562,7 +6631,7 @@ var BGA = ({
6562
6631
  const bodyHeight = packageHeight - standoffHeight;
6563
6632
  const bodyOffset = standoffHeight + bodyHeight / 2;
6564
6633
  const ballOffset = Math.max(standoffHeight / 2, ballDiameter / 2);
6565
- const ballsSoup = footprintString ? fp5.string(footprintString).circuitJson() : null;
6634
+ const ballsSoup = footprintString ? fp6.string(footprintString).circuitJson() : null;
6566
6635
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
6567
6636
  /* @__PURE__ */ jsx(Translate, { z: bodyOffset, children: /* @__PURE__ */ jsx(Colorize, { color: "#555", children: /* @__PURE__ */ jsx(Cuboid, { size: [packageWidth, packageLength, bodyHeight] }) }) }),
6568
6637
  !footprintString && Array.from({ length: ballRows * ballColumns }).map((_, index) => {
@@ -6591,6 +6660,160 @@ var BGA = ({
6591
6660
  ] });
6592
6661
  };
6593
6662
 
6663
+ // lib/UsbCMidmount.tsx
6664
+ import { fp as fp7 } from "@tscircuit/footprinter";
6665
+ var Capsule = ({
6666
+ width: width10,
6667
+ height: height10,
6668
+ depth
6669
+ }) => /* @__PURE__ */ jsx(Hull, { children: [-1, 1].map((side) => /* @__PURE__ */ jsx(Translate, { offset: [side * (width10 - height10) / 2, 0, 0], children: /* @__PURE__ */ jsx(Rotate, { rotation: [Math.PI / 2, 0, 0], children: /* @__PURE__ */ jsx(Cylinder, { radius: height10 / 2, height: depth }) }) }, side)) });
6670
+ var UsbCMidmount = ({
6671
+ footprint = "usbcmidmount16"
6672
+ }) => {
6673
+ const canonical = footprint.replace(/_pin1location\([^)]*\)/g, "");
6674
+ const params = fp7.string(canonical).json();
6675
+ const elements = fp7.string(canonical).circuitJson();
6676
+ const pads = elements.filter(
6677
+ (e) => e.type === "pcb_smtpad" && e.shape === "rect"
6678
+ );
6679
+ const slots = elements.filter((e) => e.type === "pcb_plated_hole");
6680
+ const holes = elements.filter((e) => e.type === "pcb_hole");
6681
+ const target = fp7.string(footprint).circuitJson().find((e) => e.type === "pcb_plated_hole");
6682
+ const first = slots[0];
6683
+ const angle = first && target && "x" in target ? Math.atan2(target.y, target.x) - Math.atan2(first.y, first.x) : 0;
6684
+ const width10 = 8.94, height10 = 3.2, wall = 0.22;
6685
+ const back = params.rowy + 0.23, front = -params.bodybottom;
6686
+ const depth = back - front, centerY = (back + front) / 2, centerZ = 1.65;
6687
+ if (!Number.isFinite(depth) || depth < 3 || slots.length !== 4)
6688
+ throw new Error(
6689
+ "UsbCMidmount requires four mounting slots and a positive body depth"
6690
+ );
6691
+ const tabBottom = -0.9, tabTop = centerZ + 0.1;
6692
+ return /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 0, angle], children: [
6693
+ /* @__PURE__ */ jsx(Colorize, { color: "#b8bdc4", children: /* @__PURE__ */ jsx(Translate, { offset: [0, centerY, centerZ], children: /* @__PURE__ */ jsxs(Subtract, { children: [
6694
+ /* @__PURE__ */ jsx(Capsule, { width: width10, height: height10, depth }),
6695
+ /* @__PURE__ */ jsx(
6696
+ Capsule,
6697
+ {
6698
+ width: width10 - wall * 2,
6699
+ height: height10 - wall * 2,
6700
+ depth: depth + 0.2
6701
+ }
6702
+ )
6703
+ ] }) }) }),
6704
+ /* @__PURE__ */ jsxs(Colorize, { color: "#242529", children: [
6705
+ /* @__PURE__ */ jsx(
6706
+ Cuboid,
6707
+ {
6708
+ size: [6.65, depth - 1.1, 0.7],
6709
+ center: [0, centerY + 0.3, centerZ]
6710
+ }
6711
+ ),
6712
+ /* @__PURE__ */ jsx(Cuboid, { size: [7.6, 1, 2.45], center: [0, back - 0.65, centerZ] }),
6713
+ holes.map(
6714
+ (hole, i) => "x" in hole && "hole_diameter" in hole ? /* @__PURE__ */ jsx(
6715
+ Cylinder,
6716
+ {
6717
+ radius: hole.hole_diameter * 0.42,
6718
+ height: 0.8,
6719
+ center: [hole.x, hole.y, -0.3]
6720
+ },
6721
+ i
6722
+ ) : null
6723
+ )
6724
+ ] }),
6725
+ /* @__PURE__ */ jsxs(Colorize, { color: "#d3ad57", children: [
6726
+ [-1, 1].flatMap(
6727
+ (side) => [-2.75, -2.25, -1.25, -0.25, 0.25, 1.25, 2.25, 2.75].map((x) => /* @__PURE__ */ jsx(
6728
+ Cuboid,
6729
+ {
6730
+ size: [0.24, depth - 2, 0.04],
6731
+ center: [x, centerY + 0.1, centerZ + side * 0.365]
6732
+ },
6733
+ `${side}-${x}`
6734
+ ))
6735
+ ),
6736
+ pads.map((pad, i) => /* @__PURE__ */ jsx(
6737
+ Cuboid,
6738
+ {
6739
+ size: [
6740
+ Math.min(pad.width * 0.7, 0.35),
6741
+ pad.height * 0.8 + 0.35,
6742
+ 0.15
6743
+ ],
6744
+ center: [pad.x, pad.y - 0.175, 0.075]
6745
+ },
6746
+ i
6747
+ ))
6748
+ ] }),
6749
+ /* @__PURE__ */ jsx(Colorize, { color: "#b8bdc4", children: slots.map((slot, i) => /* @__PURE__ */ jsx(
6750
+ Cuboid,
6751
+ {
6752
+ size: [
6753
+ 0.4,
6754
+ "hole_height" in slot ? Math.max(0.3, slot.hole_height - 0.2) : 1,
6755
+ tabTop - tabBottom
6756
+ ],
6757
+ center: [slot.x, slot.y, (tabTop + tabBottom) / 2]
6758
+ },
6759
+ i
6760
+ )) })
6761
+ ] });
6762
+ };
6763
+
6764
+ // lib/SOT143.tsx
6765
+ import { fp as fp8 } from "@tscircuit/footprinter";
6766
+ var getPads = (footprint) => fp8.string(footprint).circuitJson().filter(
6767
+ (element) => element.type === "pcb_smtpad" && (element.shape === "rect" || element.shape === "rotated_rect")
6768
+ ).map((pad) => ({ x: pad.x, y: pad.y, pin: pad.port_hints?.[0] }));
6769
+ var SOT143 = ({ footprint = "sot143" }) => {
6770
+ const pads = getPads(footprint);
6771
+ if (pads.length !== 4) throw new Error("SOT143 requires four signal pads");
6772
+ const canonical = getPads("sot143");
6773
+ const options = fp8.string(footprint).json();
6774
+ const origin = canonical[1];
6775
+ const target = pads.find((pad) => pad.pin === "2");
6776
+ const angle = options.pin1location ? Math.round(
6777
+ (Math.atan2(target.y, target.x) - Math.atan2(origin.y, origin.x)) / (Math.PI / 2)
6778
+ ) * (Math.PI / 2) : 0;
6779
+ const local = pads.map((pad) => ({
6780
+ ...pad,
6781
+ x: pad.x * Math.cos(angle) + pad.y * Math.sin(angle),
6782
+ y: -pad.x * Math.sin(angle) + pad.y * Math.cos(angle)
6783
+ }));
6784
+ return /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 0, angle], children: [
6785
+ /* @__PURE__ */ jsx(
6786
+ ChipBody,
6787
+ {
6788
+ width: 2.9,
6789
+ length: 1.3,
6790
+ height: 0.95,
6791
+ heightAboveSurface: 0.05,
6792
+ center: { x: 0, y: 0, z: 0 },
6793
+ includeNotch: false,
6794
+ taperRatio: 0.06
6795
+ }
6796
+ ),
6797
+ local.map((pad) => {
6798
+ const side = pad.y < 0 ? -1 : 1;
6799
+ const leadWidth = pad.pin === "1" ? 0.83 : 0.43;
6800
+ return /* @__PURE__ */ jsx(
6801
+ SmdChipLead,
6802
+ {
6803
+ width: leadWidth,
6804
+ thickness: 0.12,
6805
+ height: 0.45,
6806
+ padContactLength: 0.3,
6807
+ bodyDistance: 0.6,
6808
+ rotation: side < 0 ? Math.PI / 2 : -Math.PI / 2,
6809
+ position: { x: pad.x, y: side * 1.15, z: 0.06 }
6810
+ },
6811
+ pad.pin
6812
+ );
6813
+ })
6814
+ ] });
6815
+ };
6816
+
6594
6817
  // lib/FlexScreen.tsx
6595
6818
  var DEFAULT_ASPECT_RATIO = 16 / 9;
6596
6819
  var DEFAULT_DIAGONAL = 40;
@@ -7134,6 +7357,15 @@ var FlexScreen = (props) => {
7134
7357
 
7135
7358
  // lib/Footprinter3d.tsx
7136
7359
  var Footprinter3d = ({ footprint }) => {
7360
+ const tantalum = footprint.match(/(?:^|_)tantalum([ABCD])(?:_|$)/);
7361
+ if (tantalum)
7362
+ return /* @__PURE__ */ jsx(
7363
+ TantalumCapacitor,
7364
+ {
7365
+ footprint,
7366
+ caseSize: tantalum[1]
7367
+ }
7368
+ );
7137
7369
  const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
7138
7370
  if (mp.getModelNames().includes(modelFn)) {
7139
7371
  const model = mp.string(footprint).json();
@@ -7158,7 +7390,7 @@ var Footprinter3d = ({ footprint }) => {
7158
7390
  const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "2";
7159
7391
  normalizedFootprint = `jst${numPins}_xh`;
7160
7392
  }
7161
- const fpJson = fp6.string(normalizedFootprint).json();
7393
+ const fpJson = fp9.string(normalizedFootprint).json();
7162
7394
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
7163
7395
  const color = colorMatch ? colorMatch[1] : void 0;
7164
7396
  const dim = (value, fallback) => {
@@ -7368,6 +7600,10 @@ var Footprinter3d = ({ footprint }) => {
7368
7600
  }
7369
7601
  case "sot457":
7370
7602
  return /* @__PURE__ */ jsx(SOT457, {});
7603
+ case "usbcmidmount":
7604
+ return /* @__PURE__ */ jsx(UsbCMidmount, { footprint: normalizedFootprint });
7605
+ case "sot143":
7606
+ return /* @__PURE__ */ jsx(SOT143, { footprint: normalizedFootprint });
7371
7607
  case "sot223":
7372
7608
  return /* @__PURE__ */ jsx(SOT223, {});
7373
7609
  case "sot23w":