@tscircuit/footprinter 0.0.156 → 0.0.158

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/index.d.ts CHANGED
@@ -1028,6 +1028,7 @@ type Footprinter = {
1028
1028
  sma: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
1029
1029
  smf: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
1030
1030
  smb: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
1031
+ potentiometer: () => FootprinterParamsBuilder<"w" | "h" | "p" | "id" | "od" | "pw" | "ca">;
1031
1032
  sod923: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
1032
1033
  sod323: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
1033
1034
  sod80: () => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw">;
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ __export(fn_exports, {
27
27
  msop: () => msop,
28
28
  pad: () => pad,
29
29
  pinrow: () => pinrow,
30
+ potentiometer: () => potentiometer,
30
31
  pushbutton: () => pushbutton,
31
32
  qfn: () => qfn,
32
33
  qfp: () => qfp,
@@ -1580,43 +1581,103 @@ var pinrow_def = z11.object({
1580
1581
  });
1581
1582
  var pinrow = (raw_params) => {
1582
1583
  const parameters = pinrow_def.parse(raw_params);
1583
- const { p, id, od, rows } = parameters;
1584
- const numPins = parameters.num_pins;
1584
+ const { p, id, od, rows, num_pins } = parameters;
1585
1585
  const holes = [];
1586
+ const numPinsPerRow = Math.ceil(num_pins / rows);
1587
+ const ySpacing = -p;
1586
1588
  const addPin = (pinNumber, xoff, yoff) => {
1587
1589
  holes.push(platedhole(pinNumber, xoff, yoff, id, od));
1588
1590
  holes.push(
1589
1591
  silkscreenPin({ x: xoff, y: yoff + p / 2, fs: od / 5, pn: pinNumber })
1590
1592
  );
1591
1593
  };
1592
- if (rows > 1) {
1593
- const numPinsPerRow = Math.ceil(numPins / rows);
1594
- const ySpacing = p;
1595
- for (let row = 0; row < rows; row++) {
1596
- const yoff = row * ySpacing;
1597
- const startPin = row * numPinsPerRow;
1598
- const xStart = -((numPinsPerRow - 1) / 2) * p;
1599
- for (let i = 0; i < numPinsPerRow; i++) {
1600
- const pinNumber = startPin + i + 1;
1601
- if (pinNumber > numPins)
1602
- break;
1603
- const xoff = xStart + i * p;
1604
- addPin(pinNumber, xoff, yoff);
1605
- }
1606
- }
1607
- } else {
1608
- const xStart = -((numPins - 1) / 2) * p;
1609
- for (let i = 0; i < numPins; i++) {
1594
+ const usedPositions = /* @__PURE__ */ new Set();
1595
+ const useBGAStyle = rows > 2 && numPinsPerRow > 2;
1596
+ if (rows === 1) {
1597
+ const xStart = -((num_pins - 1) / 2) * p;
1598
+ for (let i = 0; i < num_pins; i++) {
1610
1599
  const pinNumber = i + 1;
1611
1600
  const xoff = xStart + i * p;
1601
+ const posKey = `${xoff},${0}`;
1602
+ if (usedPositions.has(posKey))
1603
+ throw new Error(`Overlap at ${posKey}`);
1604
+ usedPositions.add(posKey);
1612
1605
  addPin(pinNumber, xoff, 0);
1613
1606
  }
1607
+ } else if (useBGAStyle) {
1608
+ const xStart = -((numPinsPerRow - 1) / 2) * p;
1609
+ let currentPin = 1;
1610
+ for (let row = 0; row < rows && currentPin <= num_pins; row++) {
1611
+ for (let col = 0; col < numPinsPerRow && currentPin <= num_pins; col++) {
1612
+ const xoff = xStart + col * p;
1613
+ const yoff = row * ySpacing;
1614
+ const posKey = `${xoff},${yoff}`;
1615
+ if (usedPositions.has(posKey))
1616
+ throw new Error(`Overlap at ${posKey}`);
1617
+ usedPositions.add(posKey);
1618
+ addPin(currentPin++, xoff, yoff);
1619
+ }
1620
+ }
1621
+ } else {
1622
+ const xStart = -((numPinsPerRow - 1) / 2) * p;
1623
+ let currentPin = 1;
1624
+ let top = 0;
1625
+ let bottom = rows - 1;
1626
+ let left = 0;
1627
+ let right = numPinsPerRow - 1;
1628
+ while (currentPin <= num_pins && top <= bottom && left <= right) {
1629
+ for (let row = top; row <= bottom && currentPin <= num_pins; row++) {
1630
+ const xoff = xStart + left * p;
1631
+ const yoff = row * ySpacing;
1632
+ const posKey = `${xoff},${yoff}`;
1633
+ if (usedPositions.has(posKey))
1634
+ throw new Error(`Overlap at ${posKey}`);
1635
+ usedPositions.add(posKey);
1636
+ addPin(currentPin++, xoff, yoff);
1637
+ }
1638
+ left++;
1639
+ for (let col = left; col <= right && currentPin <= num_pins; col++) {
1640
+ const xoff = xStart + col * p;
1641
+ const yoff = bottom * ySpacing;
1642
+ const posKey = `${xoff},${yoff}`;
1643
+ if (usedPositions.has(posKey))
1644
+ throw new Error(`Overlap at ${posKey}`);
1645
+ usedPositions.add(posKey);
1646
+ addPin(currentPin++, xoff, yoff);
1647
+ }
1648
+ bottom--;
1649
+ if (left <= right) {
1650
+ for (let row = bottom; row >= top && currentPin <= num_pins; row--) {
1651
+ const xoff = xStart + right * p;
1652
+ const yoff = row * ySpacing;
1653
+ const posKey = `${xoff},${yoff}`;
1654
+ if (usedPositions.has(posKey))
1655
+ throw new Error(`Overlap at ${posKey}`);
1656
+ usedPositions.add(posKey);
1657
+ addPin(currentPin++, xoff, yoff);
1658
+ }
1659
+ right--;
1660
+ }
1661
+ if (top <= bottom) {
1662
+ for (let col = right; col >= left && currentPin <= num_pins; col--) {
1663
+ const xoff = xStart + col * p;
1664
+ const yoff = top * ySpacing;
1665
+ const posKey = `${xoff},${yoff}`;
1666
+ if (usedPositions.has(posKey))
1667
+ throw new Error(`Overlap at ${posKey}`);
1668
+ usedPositions.add(posKey);
1669
+ addPin(currentPin++, xoff, yoff);
1670
+ }
1671
+ top++;
1672
+ }
1673
+ }
1674
+ if (currentPin - 1 < num_pins) {
1675
+ throw new Error(
1676
+ `Missing pins: assigned ${currentPin - 1}, expected ${num_pins}`
1677
+ );
1678
+ }
1614
1679
  }
1615
- const perRow = rows > 1 ? Math.ceil(numPins / rows) : numPins;
1616
- const xStartGroup = -((perRow - 1) / 2) * p;
1617
- const groupTextX = xStartGroup + (perRow - 1) / 2 * p;
1618
- const groupTextY = rows * p;
1619
- const refText = silkscreenRef(groupTextX, groupTextY, 0.5);
1680
+ const refText = silkscreenRef(0, p, 0.5);
1620
1681
  return {
1621
1682
  circuitJson: [...holes, refText],
1622
1683
  parameters
@@ -3938,8 +3999,8 @@ var to220_def = z34.object({
3938
3999
  });
3939
4000
  var to220 = (raw_params) => {
3940
4001
  const parameters = to220_def.parse(raw_params);
3941
- const { fn, id, od, w, h, string: string2 } = parameters;
3942
- const numPins = Number.parseInt(string2?.split("_")[1] ?? "3");
4002
+ const { fn, id, od, w, h, string: string3 } = parameters;
4003
+ const numPins = Number.parseInt(string3?.split("_")[1] ?? "3");
3943
4004
  const holeY = -1;
3944
4005
  const halfWidth = w / 2;
3945
4006
  const halfHeight = h / 2;
@@ -5703,13 +5764,91 @@ var solderjumper = (params) => {
5703
5764
  };
5704
5765
  };
5705
5766
 
5767
+ // src/fn/potentiometer.ts
5768
+ import { z as z52 } from "zod";
5769
+ var potentiometer_def = z52.object({
5770
+ fn: z52.string(),
5771
+ num_pins: z52.union([z52.literal(3), z52.literal(2)]).default(3),
5772
+ p: z52.string().default("3.8mm"),
5773
+ id: z52.string().default("1.25mm"),
5774
+ od: z52.string().default("2.35mm"),
5775
+ ca: z52.string().default("14mm").describe(
5776
+ "Caliper axis (width or diameter of the potentiometer body or adjustment knob)"
5777
+ ),
5778
+ w: z52.string().default("5.35mm"),
5779
+ h: z52.string().default("4mm"),
5780
+ string: z52.string().optional()
5781
+ });
5782
+ var potentiometer_acp = (parameters) => {
5783
+ const { p, id, od, h, ca } = parameters;
5784
+ const y = Number.parseFloat(h);
5785
+ const caliper = Number.parseFloat(ca);
5786
+ return [
5787
+ platedhole(1, 0, caliper / 4 + 0.3, id, od),
5788
+ platedhole(2, y, 0, id, od),
5789
+ platedhole(3, 0, -caliper / 4 - 0.3, id, od)
5790
+ ];
5791
+ };
5792
+ var potentiometer = (raw_params) => {
5793
+ const match = raw_params.string?.match(/^potentiometer_(\d+)/);
5794
+ const numPins = match ? Number.parseInt(match[1], 10) : 3;
5795
+ const parameters = potentiometer_def.parse({
5796
+ ...raw_params,
5797
+ num_pins: numPins
5798
+ });
5799
+ let platedHoles = [];
5800
+ if (parameters.num_pins === 3) {
5801
+ platedHoles = potentiometer_acp(parameters);
5802
+ }
5803
+ const y = Number.parseFloat(parameters.ca) / 2 + 0.15;
5804
+ const x = Number.parseFloat(parameters.w);
5805
+ const od = Number.parseFloat(parameters.od) / 2 + 0.35;
5806
+ const silkscreenBody = {
5807
+ type: "pcb_silkscreen_path",
5808
+ layer: "top",
5809
+ pcb_component_id: "",
5810
+ route: [
5811
+ { x: 0, y: y - 1.75 },
5812
+ { x: 0, y },
5813
+ { x, y },
5814
+ { x, y: od }
5815
+ ],
5816
+ stroke_width: 0.1,
5817
+ pcb_silkscreen_path_id: ""
5818
+ };
5819
+ const silkscreenBody2 = {
5820
+ type: "pcb_silkscreen_path",
5821
+ layer: "top",
5822
+ pcb_component_id: "",
5823
+ route: [
5824
+ { x, y: -od },
5825
+ { x, y: -y },
5826
+ { x: 0, y: -y },
5827
+ { x: 0, y: -y + 1.75 }
5828
+ ],
5829
+ stroke_width: 0.1,
5830
+ pcb_silkscreen_path_id: ""
5831
+ };
5832
+ const W = Number.parseFloat(parameters.w) / 2;
5833
+ const silkscreenRefText = silkscreenRef(W, y + 1, 0.5);
5834
+ return {
5835
+ circuitJson: [
5836
+ ...platedHoles,
5837
+ silkscreenBody,
5838
+ silkscreenBody2,
5839
+ silkscreenRefText
5840
+ ],
5841
+ parameters
5842
+ };
5843
+ };
5844
+
5706
5845
  // src/helpers/is-not-null.ts
5707
5846
  function isNotNull(value) {
5708
5847
  return value !== null;
5709
5848
  }
5710
5849
 
5711
5850
  // src/footprinter.ts
5712
- var string = (def) => {
5851
+ var string2 = (def) => {
5713
5852
  let fp2 = footprinter();
5714
5853
  const modifiedDef = (def.length === 4 || def.length === 5) && /^\d+$/.test(def) ? `res${def}` : def;
5715
5854
  const def_parts = modifiedDef.split("_").map((s) => {
@@ -5813,7 +5952,7 @@ var footprinter = () => {
5813
5952
  );
5814
5953
  return proxy;
5815
5954
  };
5816
- footprinter.string = string;
5955
+ footprinter.string = string2;
5817
5956
  footprinter.getFootprintNames = getFootprintNames;
5818
5957
  var fp = footprinter;
5819
5958
  export {
@@ -5822,6 +5961,6 @@ export {
5822
5961
  getFootprintNames,
5823
5962
  getFootprintNamesByType,
5824
5963
  getFootprintSizes,
5825
- string
5964
+ string2 as string
5826
5965
  };
5827
5966
  //# sourceMappingURL=index.js.map