jscad-electronics 0.0.142 → 0.0.144

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
@@ -4777,6 +4777,142 @@ var JSTZH1_5mm = ({
4777
4777
  ] });
4778
4778
  };
4779
4779
 
4780
+ // lib/Crystal.tsx
4781
+ var getTerminalPoints = ([centerX, centerY], width10, length, chamfer, isPinOne) => {
4782
+ const xDirection = Math.sign(centerX);
4783
+ const yDirection = Math.sign(centerY);
4784
+ const halfWidth = width10 / 2;
4785
+ const halfLength = length / 2;
4786
+ const innerChamfer = isPinOne ? Math.min(0.32, length * 0.36) : 0;
4787
+ const outerChamfer = Math.min(chamfer, halfWidth, halfLength);
4788
+ const points = [
4789
+ [-halfWidth, -halfLength],
4790
+ [halfWidth, -halfLength],
4791
+ [halfWidth, halfLength - outerChamfer],
4792
+ [halfWidth - outerChamfer, halfLength],
4793
+ [-halfWidth, halfLength]
4794
+ ];
4795
+ if (innerChamfer) {
4796
+ points[0] = [-halfWidth + innerChamfer, -halfLength];
4797
+ points.push([-halfWidth, -halfLength + innerChamfer]);
4798
+ }
4799
+ const oriented = points.map(
4800
+ ([x, y]) => [centerX + x * xDirection, centerY + y * yDirection]
4801
+ );
4802
+ return xDirection * yDirection < 0 ? oriented.reverse() : oriented;
4803
+ };
4804
+ var getRoundedRectProfile = ({
4805
+ width: width10,
4806
+ length,
4807
+ radius,
4808
+ height: height10,
4809
+ z
4810
+ }) => {
4811
+ const x = width10 / 2 - radius;
4812
+ const y = length / 2 - radius;
4813
+ return [
4814
+ [-x, -y],
4815
+ [x, -y],
4816
+ [x, y],
4817
+ [-x, y]
4818
+ ].map(([cornerX, cornerY], index) => /* @__PURE__ */ jsx(
4819
+ Cylinder,
4820
+ {
4821
+ center: [cornerX, cornerY, z + height10 / 2],
4822
+ height: height10,
4823
+ radius
4824
+ },
4825
+ `${z}-${index}`
4826
+ ));
4827
+ };
4828
+ var Crystal = ({
4829
+ horizontalPadPitch = 2.2,
4830
+ verticalPadPitch = 1.7,
4831
+ padWidth = 1.4,
4832
+ padHeight = 1.2,
4833
+ bodyHeight = 0.7
4834
+ }) => {
4835
+ const bodyWidth = horizontalPadPitch + padWidth * (5 / 7);
4836
+ const bodyLength10 = verticalPadPitch + padHeight * (2 / 3);
4837
+ const terminalThickness = Math.min(0.01, bodyHeight * 0.02);
4838
+ const terminalWidth = padWidth * (5 / 7);
4839
+ const terminalLength = padHeight * 0.75;
4840
+ const ceramicTopZ = bodyHeight * (5 / 7);
4841
+ const baseHeight = ceramicTopZ - terminalThickness;
4842
+ const sealHeight = bodyHeight * (2 / 35);
4843
+ const sealWidth = bodyWidth * 0.95;
4844
+ const sealLength = bodyLength10 * 0.94;
4845
+ const lidShoulderWidth = bodyWidth * 0.905;
4846
+ const lidShoulderLength = bodyLength10 * 0.9;
4847
+ const lidTopWidth = bodyWidth * 0.83;
4848
+ const lidTopLength = bodyLength10 * 0.82;
4849
+ const lidBaseZ = ceramicTopZ + sealHeight;
4850
+ const lidProfileHeight = Math.min(0.01, bodyHeight * 0.015);
4851
+ const bodyChamfer = Math.min(0.12, bodyLength10 * 0.05);
4852
+ const terminalX = (bodyWidth - terminalWidth) / 2;
4853
+ const terminalY = (bodyLength10 - terminalLength) / 2;
4854
+ const terminalPositions = [
4855
+ [-terminalX, -terminalY],
4856
+ [terminalX, -terminalY],
4857
+ [terminalX, terminalY],
4858
+ [-terminalX, terminalY]
4859
+ ];
4860
+ const sealProfile = getRoundedRectProfile({
4861
+ width: sealWidth,
4862
+ length: sealLength,
4863
+ radius: Math.min(0.13, sealLength * 0.08),
4864
+ height: sealHeight,
4865
+ z: ceramicTopZ
4866
+ });
4867
+ const lidProfiles = [
4868
+ ...getRoundedRectProfile({
4869
+ width: lidShoulderWidth,
4870
+ length: lidShoulderLength,
4871
+ radius: Math.min(0.14, lidShoulderLength * 0.08),
4872
+ height: lidProfileHeight,
4873
+ z: lidBaseZ
4874
+ }),
4875
+ ...getRoundedRectProfile({
4876
+ width: lidTopWidth,
4877
+ length: lidTopLength,
4878
+ radius: Math.min(0.15, lidTopLength * 0.09),
4879
+ height: lidProfileHeight,
4880
+ z: bodyHeight - lidProfileHeight
4881
+ })
4882
+ ];
4883
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
4884
+ terminalPositions.map((center, index) => /* @__PURE__ */ jsx(Colorize, { color: "#d6a258", children: /* @__PURE__ */ jsx(ExtrudeLinear, { height: terminalThickness, children: /* @__PURE__ */ jsx(
4885
+ Polygon,
4886
+ {
4887
+ points: getTerminalPoints(
4888
+ center,
4889
+ terminalWidth,
4890
+ terminalLength,
4891
+ bodyChamfer,
4892
+ index === 0
4893
+ )
4894
+ }
4895
+ ) }) }, index)),
4896
+ /* @__PURE__ */ jsx(
4897
+ ChipBody,
4898
+ {
4899
+ center: { x: 0, y: 0, z: terminalThickness },
4900
+ width: bodyWidth,
4901
+ length: bodyLength10,
4902
+ height: baseHeight - 5e-3,
4903
+ heightAboveSurface: 0,
4904
+ color: "#34343d",
4905
+ taperRatio: 0,
4906
+ straightHeightRatio: 1,
4907
+ includeNotch: false,
4908
+ chamferSize: bodyChamfer
4909
+ }
4910
+ ),
4911
+ /* @__PURE__ */ jsx(Colorize, { color: "#d2a057", children: /* @__PURE__ */ jsx(Hull, { children: sealProfile }) }),
4912
+ /* @__PURE__ */ jsx(Colorize, { color: "#b9bec2", children: /* @__PURE__ */ jsx(Hull, { children: lidProfiles }) })
4913
+ ] });
4914
+ };
4915
+
4780
4916
  // lib/FPC.tsx
4781
4917
  var HOUSING_COLOR = "#303339";
4782
4918
  var HOUSING_SHADOW = "#1f2227";
@@ -5114,6 +5250,128 @@ var SmdPinHeader = ({
5114
5250
  }) });
5115
5251
  };
5116
5252
 
5253
+ // lib/Footprinter3d.tsx
5254
+ import { mm } from "@tscircuit/mm";
5255
+
5256
+ // lib/ParametricChip.tsx
5257
+ var ParametricChip = ({
5258
+ padPitch,
5259
+ padHeight,
5260
+ color = "#333"
5261
+ }) => {
5262
+ const fullLength10 = padPitch;
5263
+ const width10 = padHeight * 0.85;
5264
+ const height10 = width10;
5265
+ const terminatorWidth9 = fullLength10 * 0.2;
5266
+ const bodyLength10 = fullLength10 - terminatorWidth9 * 2;
5267
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5268
+ /* @__PURE__ */ jsx(
5269
+ Cuboid,
5270
+ {
5271
+ size: [bodyLength10, width10, height10],
5272
+ offset: [0, 0, height10 / 2],
5273
+ color
5274
+ }
5275
+ ),
5276
+ /* @__PURE__ */ jsx(
5277
+ Cuboid,
5278
+ {
5279
+ size: [terminatorWidth9, height10, width10],
5280
+ offset: [fullLength10 / 2 - terminatorWidth9 / 2, 0, height10 / 2],
5281
+ color: "#ccc"
5282
+ }
5283
+ ),
5284
+ /* @__PURE__ */ jsx(
5285
+ Cuboid,
5286
+ {
5287
+ size: [terminatorWidth9, height10, width10],
5288
+ offset: [-fullLength10 / 2 + terminatorWidth9 / 2, 0, height10 / 2],
5289
+ color: "#ccc"
5290
+ }
5291
+ )
5292
+ ] });
5293
+ };
5294
+
5295
+ // lib/Led5050.tsx
5296
+ var Led5050 = ({
5297
+ color = "#ffff00",
5298
+ bodyColor = "#ffffff",
5299
+ leadColor = "#dedede"
5300
+ }) => {
5301
+ const bodySize = 5;
5302
+ const leadSpan = 5.4;
5303
+ const bodyBottom = 0.2;
5304
+ const bodyHeight = 1.3;
5305
+ const bodyTop = bodyBottom + bodyHeight;
5306
+ const leadLength = 1.4;
5307
+ const leadWidth = 1;
5308
+ const leadThickness = 0.2;
5309
+ const leadCenterX = leadSpan / 2 - leadLength / 2;
5310
+ const lensRadius = 2;
5311
+ const lensHeight = 0.25;
5312
+ const lensTop = 1.55;
5313
+ const cornerCutDepth = 0.3;
5314
+ const leadYPositions = [-1.7, 0, 1.7];
5315
+ const leadSides = [-1, 1];
5316
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
5317
+ leadYPositions.flatMap(
5318
+ (y) => leadSides.map((side) => /* @__PURE__ */ jsx(
5319
+ Cuboid,
5320
+ {
5321
+ color: leadColor,
5322
+ size: [leadLength, leadWidth, leadThickness],
5323
+ center: [side * leadCenterX, y, leadThickness / 2]
5324
+ },
5325
+ `${side}-${y}`
5326
+ ))
5327
+ ),
5328
+ /* @__PURE__ */ jsx(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
5329
+ /* @__PURE__ */ jsx(
5330
+ ChipBody,
5331
+ {
5332
+ width: bodySize,
5333
+ length: bodySize,
5334
+ height: bodyHeight,
5335
+ heightAboveSurface: bodyBottom,
5336
+ center: { x: 0, y: 0, z: 0 },
5337
+ color: bodyColor,
5338
+ taperRatio: 0.036,
5339
+ straightHeightRatio: 0.01,
5340
+ includeNotch: false
5341
+ }
5342
+ ),
5343
+ /* @__PURE__ */ jsx(
5344
+ Cylinder,
5345
+ {
5346
+ radius: lensRadius,
5347
+ height: lensHeight,
5348
+ center: [0, 0, bodyTop - lensHeight / 2]
5349
+ }
5350
+ ),
5351
+ /* @__PURE__ */ jsx(
5352
+ Translate,
5353
+ {
5354
+ offset: [
5355
+ -bodySize / 2,
5356
+ bodySize / 2,
5357
+ bodyTop - cornerCutDepth / 2 + 5e-3
5358
+ ],
5359
+ children: /* @__PURE__ */ jsx(Rotate, { rotation: [0, 0, Math.PI / 4], children: /* @__PURE__ */ jsx(Cuboid, { size: [0.9, 0.9, cornerCutDepth + 0.01] }) })
5360
+ }
5361
+ )
5362
+ ] }) }),
5363
+ /* @__PURE__ */ jsx(
5364
+ Cylinder,
5365
+ {
5366
+ color,
5367
+ radius: lensRadius,
5368
+ height: lensHeight,
5369
+ center: [0, 0, lensTop - lensHeight / 2]
5370
+ }
5371
+ )
5372
+ ] });
5373
+ };
5374
+
5117
5375
  // lib/RJ45.tsx
5118
5376
  var range2 = (length) => Array.from({ length }, (_, index) => index);
5119
5377
  var RJ45 = ({
@@ -5359,7 +5617,19 @@ var Footprinter3d = ({ footprint }) => {
5359
5617
  normalizedFootprint = `zh${numPins}`;
5360
5618
  }
5361
5619
  const fpJson = fp2.string(normalizedFootprint).json();
5620
+ const colorMatch = footprint.match(/_color\(([^)]+)\)/);
5621
+ const color = colorMatch ? colorMatch[1] : void 0;
5362
5622
  switch (fpJson.fn) {
5623
+ case "crystal":
5624
+ return /* @__PURE__ */ jsx(
5625
+ Crystal,
5626
+ {
5627
+ horizontalPadPitch: fpJson.px,
5628
+ verticalPadPitch: fpJson.py,
5629
+ padWidth: fpJson.pw,
5630
+ padHeight: fpJson.ph
5631
+ }
5632
+ );
5363
5633
  case "dip":
5364
5634
  return /* @__PURE__ */ jsx(Dip, { numPins: fpJson.num_pins, pitch: fpJson.p, bodyWidth: fpJson.w });
5365
5635
  case "axial":
@@ -5484,6 +5754,8 @@ var Footprinter3d = ({ footprint }) => {
5484
5754
  bodyWidth: fpJson.bh
5485
5755
  }
5486
5756
  );
5757
+ case "led5050":
5758
+ return /* @__PURE__ */ jsx(Led5050, { color });
5487
5759
  case "cap": {
5488
5760
  switch (fpJson.imperial) {
5489
5761
  case "0402":
@@ -5505,6 +5777,7 @@ var Footprinter3d = ({ footprint }) => {
5505
5777
  case "2512":
5506
5778
  return /* @__PURE__ */ jsx(A2512, { color: "#856c4d" });
5507
5779
  }
5780
+ break;
5508
5781
  }
5509
5782
  case "sot235":
5510
5783
  return /* @__PURE__ */ jsx(SOT_235_default, {});
@@ -5706,8 +5979,6 @@ var Footprinter3d = ({ footprint }) => {
5706
5979
  );
5707
5980
  }
5708
5981
  }
5709
- const colorMatch = footprint.match(/_color\(([^)]+)\)/);
5710
- const color = colorMatch ? colorMatch[1] : void 0;
5711
5982
  switch (fpJson.imperial) {
5712
5983
  case "0402":
5713
5984
  return /* @__PURE__ */ jsx(A0402, { color });
@@ -5728,6 +5999,20 @@ var Footprinter3d = ({ footprint }) => {
5728
5999
  case "2512":
5729
6000
  return /* @__PURE__ */ jsx(A2512, { color });
5730
6001
  }
6002
+ if ((fpJson.fn === "res" || fpJson.fn === "cap") && fpJson.p !== void 0 && fpJson.ph !== void 0) {
6003
+ const padPitch = mm(fpJson.p);
6004
+ const padHeight = mm(fpJson.ph);
6005
+ if (Number.isFinite(padPitch) && Number.isFinite(padHeight)) {
6006
+ return /* @__PURE__ */ jsx(
6007
+ ParametricChip,
6008
+ {
6009
+ padPitch,
6010
+ padHeight,
6011
+ color: color ?? (fpJson.fn === "cap" ? "#856c4d" : void 0)
6012
+ }
6013
+ );
6014
+ }
6015
+ }
5731
6016
  return null;
5732
6017
  };
5733
6018