@tscircuit/cli 0.1.1150 → 0.1.1151

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/cli/main.js CHANGED
@@ -98175,7 +98175,7 @@ var import_perfect_cli = __toESM2(require_dist2(), 1);
98175
98175
  // lib/getVersion.ts
98176
98176
  import { createRequire as createRequire2 } from "node:module";
98177
98177
  // package.json
98178
- var version = "0.1.1149";
98178
+ var version = "0.1.1150";
98179
98179
  var package_default = {
98180
98180
  name: "@tscircuit/cli",
98181
98181
  version,
@@ -98217,7 +98217,7 @@ var package_default = {
98217
98217
  cosmiconfig: "^9.0.0",
98218
98218
  debug: "^4.4.0",
98219
98219
  delay: "^6.0.0",
98220
- "dsn-converter": "^0.0.63",
98220
+ "dsn-converter": "0.0.86",
98221
98221
  easyeda: "^0.0.252",
98222
98222
  "fuse.js": "^7.1.0",
98223
98223
  "get-port": "^7.1.0",
@@ -242126,33 +242126,31 @@ import {
242126
242126
  } from "circuit-to-svg";
242127
242127
 
242128
242128
  // node_modules/dsn-converter/dist/index.js
242129
- import { applyToPoint as applyToPoint21, scale as scale6 } from "transformation-matrix";
242130
242129
  import { su as su7 } from "@tscircuit/soup-util";
242130
+ import { applyToPoint as applyToPoint21, scale as scale6 } from "transformation-matrix";
242131
242131
  import { su as su23 } from "@tscircuit/soup-util";
242132
242132
  import Debug4 from "debug";
242133
242133
  import { su as su33 } from "@tscircuit/soup-util";
242134
242134
  import { applyToPoint as applyToPoint22, scale as scale22 } from "transformation-matrix";
242135
242135
  import { su as su42 } from "@tscircuit/soup-util";
242136
242136
  import Debug22 from "debug";
242137
- import { su as su5 } from "@tscircuit/soup-util";
242138
- import { scale as scale32 } from "transformation-matrix";
242139
- import { scale as scale42, applyToPoint as applyToPoint102 } from "transformation-matrix";
242140
- import { applyToPoint as applyToPoint42 } from "transformation-matrix";
242137
+ import { scale as scale32, applyToPoint as applyToPoint92 } from "transformation-matrix";
242138
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
242141
242139
  import Debug32 from "debug";
242142
242140
  import"transformation-matrix";
242141
+ import { applyToPoint as applyToPoint42 } from "transformation-matrix";
242143
242142
  import { applyToPoint as applyToPoint52 } from "transformation-matrix";
242144
- import { applyToPoint as applyToPoint62 } from "transformation-matrix";
242145
242143
  import Debug42 from "debug";
242146
242144
  import Debug6 from "debug";
242147
- import { applyToPoint as applyToPoint72 } from "transformation-matrix";
242145
+ import { applyToPoint as applyToPoint62 } from "transformation-matrix";
242148
242146
  import Debug5 from "debug";
242149
- import { applyToPoint as applyToPoint92 } from "transformation-matrix";
242150
- import { su as su62 } from "@tscircuit/soup-util";
242147
+ import { applyToPoint as applyToPoint82 } from "transformation-matrix";
242148
+ import { su as su5 } from "@tscircuit/soup-util";
242151
242149
  import"transformation-matrix";
242150
+ import { su as su62 } from "@tscircuit/soup-util";
242152
242151
  import Debug7 from "debug";
242153
- import { applyToPoint as applyToPoint122, scale as scale5 } from "transformation-matrix";
242152
+ import { applyToPoint as applyToPoint112, scale as scale42 } from "transformation-matrix";
242154
242153
  import"transformation-matrix";
242155
- import { su as su72 } from "@tscircuit/soup-util";
242156
242154
  import Debug10 from "debug";
242157
242155
  import Debug8 from "debug";
242158
242156
  import Debug9 from "debug";
@@ -242282,6 +242280,81 @@ function createRectangularPadstack(name, width, height, layer) {
242282
242280
  attach: "off"
242283
242281
  };
242284
242282
  }
242283
+ function createCircularHoleRectangularPadstack(name, outerWidth, outerHeight, holeDiameter) {
242284
+ const halfWidth = outerWidth / 2;
242285
+ const halfHeight = outerHeight / 2;
242286
+ const rectPolygon = [
242287
+ -halfWidth,
242288
+ halfHeight,
242289
+ halfWidth,
242290
+ halfHeight,
242291
+ halfWidth,
242292
+ -halfHeight,
242293
+ -halfWidth,
242294
+ -halfHeight,
242295
+ -halfWidth,
242296
+ halfHeight
242297
+ ];
242298
+ return {
242299
+ name,
242300
+ shapes: [
242301
+ {
242302
+ shapeType: "polygon",
242303
+ layer: "F.Cu",
242304
+ width: 0,
242305
+ coordinates: rectPolygon
242306
+ },
242307
+ {
242308
+ shapeType: "polygon",
242309
+ layer: "B.Cu",
242310
+ width: 0,
242311
+ coordinates: rectPolygon
242312
+ }
242313
+ ],
242314
+ hole: {
242315
+ shape: "circle",
242316
+ diameter: holeDiameter
242317
+ },
242318
+ attach: "off"
242319
+ };
242320
+ }
242321
+ function createAndAddPadstackFromPcbSmtPad(pcb, pad2, processedPadstacks) {
242322
+ const isCircle = pad2.shape === "circle";
242323
+ const padstackParams = {
242324
+ shape: isCircle ? "circle" : "rect",
242325
+ outerDiameter: isCircle ? pad2.radius * 1000 * 2 : undefined,
242326
+ holeDiameter: isCircle ? pad2.radius * 1000 * 2 : undefined,
242327
+ width: isCircle ? undefined : pad2.width * 1000,
242328
+ height: isCircle ? undefined : pad2.height * 1000,
242329
+ layer: pad2.layer
242330
+ };
242331
+ const padstackName = getPadstackName(padstackParams);
242332
+ if (!processedPadstacks.has(padstackName)) {
242333
+ const padstack = isCircle ? createCircularPadstack(padstackName, padstackParams.outerDiameter, padstackParams.holeDiameter) : createRectangularPadstack(padstackName, padstackParams.width, padstackParams.height, pad2.layer);
242334
+ pcb.library.padstacks.push(padstack);
242335
+ processedPadstacks.add(padstackName);
242336
+ }
242337
+ return padstackName;
242338
+ }
242339
+ function createPinForImage(pad2, pcbComponent, sourcePort) {
242340
+ if (!sourcePort)
242341
+ return;
242342
+ const isCircle = pad2.shape === "circle";
242343
+ const padstackParams = {
242344
+ shape: isCircle ? "circle" : "rect",
242345
+ outerDiameter: isCircle ? pad2.radius * 1000 * 2 : undefined,
242346
+ holeDiameter: isCircle ? pad2.radius * 1000 * 2 : undefined,
242347
+ width: isCircle ? undefined : pad2.width * 1000,
242348
+ height: isCircle ? undefined : pad2.height * 1000,
242349
+ layer: pad2.layer
242350
+ };
242351
+ return {
242352
+ padstack_name: getPadstackName(padstackParams),
242353
+ pin_number: sourcePort.port_hints?.find((hint) => !Number.isNaN(Number(hint))) || 1,
242354
+ x: (pad2.x - pcbComponent.center.x) * 1000,
242355
+ y: (pad2.y - pcbComponent.center.y) * 1000
242356
+ };
242357
+ }
242285
242358
  var transformMmToUm = scale6(1000);
242286
242359
  function processComponentsAndPads(componentGroups, circuitElements, pcb) {
242287
242360
  const processedPadstacks = /* @__PURE__ */ new Set;
@@ -242315,42 +242388,16 @@ function processComponentsAndPads(componentGroups, circuitElements, pcb) {
242315
242388
  if (!componentGroup)
242316
242389
  continue;
242317
242390
  for (const pad2 of componentGroup.pcb_smtpads) {
242318
- if (pad2.shape === "rect") {
242319
- const padstackName = getPadstackName({
242320
- shape: "rect",
242321
- width: pad2.width * 1000,
242322
- height: pad2.height * 1000,
242323
- layer: pad2.layer
242324
- });
242325
- if (!processedPadstacks.has(padstackName)) {
242326
- const padWidthInUm = Math.round(pad2.width * 1000);
242327
- const padHeightInUm = Math.round(pad2.height * 1000);
242328
- const padstack = createRectangularPadstack(padstackName, padWidthInUm, padHeightInUm, pad2.layer);
242329
- pcb.library.padstacks.push(padstack);
242330
- processedPadstacks.add(padstackName);
242331
- }
242332
- }
242391
+ createAndAddPadstackFromPcbSmtPad(pcb, pad2, processedPadstacks);
242333
242392
  }
242334
242393
  const image = {
242335
242394
  name: footprintName,
242336
242395
  outlines: [],
242337
242396
  pins: componentGroup.pcb_smtpads.map((pad2) => {
242338
242397
  const pcbComponent = circuitElements.find((e4) => e4.type === "pcb_component" && e4.source_component_id === firstComponent.sourceComponent?.source_component_id);
242339
- if (pad2.shape === "rect") {
242340
- const pcbPort = su7(circuitElements).pcb_port.list().find((e4) => e4.pcb_port_id === pad2.pcb_port_id);
242341
- const sourcePort = su7(circuitElements).source_port.list().find((e4) => e4.source_port_id === pcbPort?.source_port_id);
242342
- return {
242343
- padstack_name: getPadstackName({
242344
- shape: "rect",
242345
- width: pad2.width * 1000,
242346
- height: pad2.height * 1000,
242347
- layer: pad2.layer
242348
- }),
242349
- pin_number: sourcePort?.port_hints?.find((hint) => !Number.isNaN(Number(hint))) || 1,
242350
- x: (pad2.x - pcbComponent.center.x) * 1000,
242351
- y: (pad2.y - pcbComponent.center.y) * 1000
242352
- };
242353
- }
242398
+ const pcbPort = su7(circuitElements).pcb_port.list().find((e4) => e4.pcb_port_id === pad2.pcb_port_id);
242399
+ const sourcePort = su7(circuitElements).source_port.list().find((e4) => e4.source_port_id === pcbPort?.source_port_id);
242400
+ return createPinForImage(pad2, pcbComponent, sourcePort);
242354
242401
  }).filter((pin) => pin !== undefined)
242355
242402
  };
242356
242403
  pcb.library.images.push(image);
@@ -242394,6 +242441,7 @@ function processNets(circuitElements, pcb) {
242394
242441
  }
242395
242442
  }
242396
242443
  const netMap = /* @__PURE__ */ new Map;
242444
+ const netTraceWidthMap = /* @__PURE__ */ new Map;
242397
242445
  for (const element of circuitElements) {
242398
242446
  if (element.type === "source_trace" && element.connected_source_port_ids) {
242399
242447
  const connectedPorts = element.connected_source_port_ids;
@@ -242410,6 +242458,10 @@ function processNets(circuitElements, pcb) {
242410
242458
  netMap.get(netName)?.add(`${padInfo.componentName}-${padInfo.pinNumber}`);
242411
242459
  }
242412
242460
  }
242461
+ if ("min_trace_thickness" in element && element.min_trace_thickness) {
242462
+ const traceWidthMicrons = element.min_trace_thickness * 1000;
242463
+ netTraceWidthMap.set(netName, traceWidthMicrons);
242464
+ }
242413
242465
  }
242414
242466
  }
242415
242467
  }
@@ -242429,6 +242481,13 @@ function processNets(circuitElements, pcb) {
242429
242481
  const connectedTraces = circuitElements.filter((e4) => e4.type === "source_trace" && e4.connected_source_net_ids?.includes(element.source_net_id) && e4.connected_source_port_ids?.includes(sourcePortId));
242430
242482
  if (connectedTraces.length > 0) {
242431
242483
  isInSourceNet = true;
242484
+ for (const trace of connectedTraces) {
242485
+ if ("min_trace_thickness" in trace && trace.min_trace_thickness) {
242486
+ const traceWidthMicrons = trace.min_trace_thickness * 1000;
242487
+ netTraceWidthMap.set(`${element.name}_${element.source_net_id}`, traceWidthMicrons);
242488
+ break;
242489
+ }
242490
+ }
242432
242491
  break;
242433
242492
  }
242434
242493
  }
@@ -242452,6 +242511,10 @@ function processNets(circuitElements, pcb) {
242452
242511
  netMap.get(netName)?.add(`${padInfo.componentName}-${padInfo.pinNumber}`);
242453
242512
  }
242454
242513
  }
242514
+ if ("min_trace_thickness" in trace && trace.min_trace_thickness && !netTraceWidthMap.has(netName)) {
242515
+ const traceWidthMicrons = trace.min_trace_thickness * 1000;
242516
+ netTraceWidthMap.set(netName, traceWidthMicrons);
242517
+ }
242455
242518
  }
242456
242519
  }
242457
242520
  }
@@ -242470,13 +242533,56 @@ function processNets(circuitElements, pcb) {
242470
242533
  return 1;
242471
242534
  return a2.localeCompare(b);
242472
242535
  });
242536
+ const traceWidthClassMap = /* @__PURE__ */ new Map;
242537
+ const defaultTraceWidth = 200;
242538
+ traceWidthClassMap.set(defaultTraceWidth, "kicad_default");
242539
+ for (const [netName, traceWidth] of netTraceWidthMap.entries()) {
242540
+ if (traceWidth !== defaultTraceWidth && !traceWidthClassMap.has(traceWidth)) {
242541
+ const className = `trace_width_${traceWidth}um`;
242542
+ traceWidthClassMap.set(traceWidth, className);
242543
+ pcb.network.classes.push({
242544
+ name: className,
242545
+ description: `Trace width ${traceWidth}μm`,
242546
+ net_names: [],
242547
+ circuit: {
242548
+ use_via: "Via[0-1]_600:300_um"
242549
+ },
242550
+ rule: {
242551
+ clearances: [
242552
+ {
242553
+ value: 200,
242554
+ type: ""
242555
+ }
242556
+ ],
242557
+ width: traceWidth
242558
+ }
242559
+ });
242560
+ }
242561
+ }
242562
+ const netsByClass = /* @__PURE__ */ new Map;
242473
242563
  for (const netName of allNets) {
242564
+ const traceWidth = netTraceWidthMap.get(netName) || defaultTraceWidth;
242565
+ const className = traceWidthClassMap.get(traceWidth) || "kicad_default";
242566
+ if (!netsByClass.has(className)) {
242567
+ netsByClass.set(className, []);
242568
+ }
242569
+ netsByClass.get(className)?.push(netName);
242474
242570
  pcb.network.nets.push({
242475
242571
  name: netName,
242476
242572
  pins: Array.from(netMap.get(netName) || []).map((pin) => pin.replace("pin", ""))
242477
242573
  });
242478
242574
  }
242479
- pcb.network.classes[0].net_names = allNets;
242575
+ for (const [className, nets] of netsByClass.entries()) {
242576
+ const classIndex = pcb.network.classes.findIndex((c3) => c3.name === className);
242577
+ if (classIndex !== -1) {
242578
+ pcb.network.classes[classIndex].net_names = nets;
242579
+ }
242580
+ }
242581
+ for (const classObj of pcb.network.classes) {
242582
+ if (classObj.net_names.length === 0) {
242583
+ classObj.net_names = allNets;
242584
+ }
242585
+ }
242480
242586
  }
242481
242587
  function findOrCreateViaPadstack(pcb, outerDiameter, holeDiameter) {
242482
242588
  const viaName = `Via[0-1]_${outerDiameter}:${holeDiameter}_um`;
@@ -242563,7 +242669,7 @@ function createWire(opts) {
242563
242669
  return {
242564
242670
  path: {
242565
242671
  layer: opts.layer === "top" ? "F.Cu" : "B.Cu",
242566
- width: opts.widthMm * 1000,
242672
+ width: opts.widthMm,
242567
242673
  coordinates: []
242568
242674
  },
242569
242675
  net: opts.netName,
@@ -242598,7 +242704,7 @@ function processPcbTraces(circuitElements, pcb) {
242598
242704
  if (isFirstPoint) {
242599
242705
  currentWire = createWire({
242600
242706
  layer: point5.layer,
242601
- widthMm: point5.width,
242707
+ widthMm: point5.width * CJ_TO_DSN_SCALE,
242602
242708
  netName
242603
242709
  });
242604
242710
  dsnWrapper.addWire(currentWire);
@@ -242667,123 +242773,164 @@ function processPcbTraces(circuitElements, pcb) {
242667
242773
  var transformMmToUm2 = scale22(1000);
242668
242774
  function processPlatedHoles(componentGroups, circuitElements, pcb) {
242669
242775
  const processedPadstacks = /* @__PURE__ */ new Set;
242670
- const componentsByFootprint = /* @__PURE__ */ new Map;
242671
- for (const group of componentGroups) {
242672
- const { pcb_component_id, pcb_plated_holes, pcb_smtpads } = group;
242673
- if (pcb_plated_holes.length === 0)
242674
- continue;
242675
- const pcbComponent = su42(circuitElements).pcb_component.list().find((e4) => e4.pcb_component_id === pcb_component_id);
242676
- const sourceComponent = pcbComponent && su42(circuitElements).source_component.list().find((e4) => e4.source_component_id === pcbComponent.source_component_id);
242677
- if (!pcbComponent)
242678
- continue;
242679
- const footprintName = getFootprintName(sourceComponent, pcbComponent);
242680
- const componentName = sourceComponent.name || "Unknown";
242681
- const circuitSpaceCoordinates = applyToPoint22(transformMmToUm2, pcbComponent.center);
242682
- if (pcb_smtpads.length === 0) {
242683
- if (!componentsByFootprint.has(footprintName)) {
242684
- componentsByFootprint.set(footprintName, []);
242685
- }
242686
- componentsByFootprint.get(footprintName)?.push({
242687
- componentName,
242688
- coordinates: circuitSpaceCoordinates,
242689
- rotation: pcbComponent?.rotation || 0,
242690
- value: getComponentValue(sourceComponent),
242691
- sourceComponent
242692
- });
242693
- }
242694
- for (const hole of pcb_plated_holes) {
242695
- if (hole.shape === "circle") {
242696
- const padstackName = getPadstackName({
242776
+ function ensurePadstack(hole) {
242777
+ switch (hole.shape) {
242778
+ case "circle": {
242779
+ const name = getPadstackName({
242697
242780
  shape: "circle",
242698
242781
  holeDiameter: hole.hole_diameter * 1000,
242699
242782
  outerDiameter: hole.outer_diameter * 1000,
242700
242783
  layer: "all"
242701
242784
  });
242702
- if (!processedPadstacks.has(padstackName)) {
242703
- const padDiameterInUm = Math.round(hole.outer_diameter * 1000);
242704
- pcb.library.padstacks.push(createCircularPadstack(padstackName, padDiameterInUm, padDiameterInUm));
242705
- processedPadstacks.add(padstackName);
242785
+ if (!processedPadstacks.has(name)) {
242786
+ const d3 = Math.round(hole.outer_diameter * 1000);
242787
+ pcb.library.padstacks.push(createCircularPadstack(name, d3, d3));
242788
+ processedPadstacks.add(name);
242706
242789
  }
242707
- } else if (hole.shape === "oval" || hole.shape === "pill") {
242708
- const padstackName = getPadstackName({
242790
+ return name;
242791
+ }
242792
+ case "oval":
242793
+ case "pill": {
242794
+ const name = getPadstackName({
242709
242795
  shape: hole.shape,
242710
242796
  width: hole.hole_width * 1000,
242711
242797
  height: hole.hole_height * 1000,
242712
242798
  layer: "all"
242713
242799
  });
242714
- if (!processedPadstacks.has(padstackName)) {
242715
- const padInnerWidthInUm = Math.round(hole.hole_width * 1000);
242716
- const padInnerHeightInUm = Math.round(hole.hole_height * 1000);
242717
- const padOuterWidthInUm = Math.round(hole.outer_width * 1000);
242718
- const padOuterHeightInUm = Math.round(hole.outer_height * 1000);
242719
- pcb.library.padstacks.push(createOvalPadstack(padstackName, padOuterWidthInUm, padOuterHeightInUm, padInnerWidthInUm, padInnerHeightInUm));
242720
- processedPadstacks.add(padstackName);
242800
+ if (!processedPadstacks.has(name)) {
242801
+ const iW = Math.round(hole.hole_width * 1000);
242802
+ const iH = Math.round(hole.hole_height * 1000);
242803
+ const oW = Math.round(hole.outer_width * 1000);
242804
+ const oH = Math.round(hole.outer_height * 1000);
242805
+ pcb.library.padstacks.push(createOvalPadstack(name, oW, oH, iW, iH));
242806
+ processedPadstacks.add(name);
242721
242807
  }
242808
+ return name;
242722
242809
  }
242810
+ case "circular_hole_with_rect_pad": {
242811
+ const name = getPadstackName({
242812
+ shape: "rect",
242813
+ width: hole.rect_pad_width * 1000,
242814
+ height: hole.rect_pad_height * 1000,
242815
+ layer: "all"
242816
+ });
242817
+ if (!processedPadstacks.has(name)) {
242818
+ const oW = Math.round(hole.rect_pad_width * 1000);
242819
+ const oH = Math.round(hole.rect_pad_height * 1000);
242820
+ const hD = Math.round(hole.hole_diameter * 1000);
242821
+ pcb.library.padstacks.push(createCircularHoleRectangularPadstack(name, oW, oH, hD));
242822
+ processedPadstacks.add(name);
242823
+ }
242824
+ return name;
242825
+ }
242826
+ default:
242827
+ throw new Error(`Unsupported plated-hole shape: ${hole.shape}`);
242828
+ }
242829
+ }
242830
+ function ensureImage(name) {
242831
+ let image = pcb.library.images.find((img) => img.name === name);
242832
+ if (!image) {
242833
+ image = { name, outlines: [], pins: [] };
242834
+ pcb.library.images.push(image);
242723
242835
  }
242724
- let existingImage = pcb.library.images.find((img) => img.name === footprintName);
242725
- if (!existingImage) {
242726
- existingImage = {
242727
- name: footprintName,
242728
- outlines: [],
242729
- pins: []
242836
+ return image;
242837
+ }
242838
+ function createNextPinNumberGenerator(image) {
242839
+ let current2 = image.pins.reduce((max, p3) => {
242840
+ const n3 = Number(typeof p3.pin_number === "string" ? p3.pin_number.replace(/pin/i, "") : p3.pin_number);
242841
+ return Number.isNaN(n3) ? max : Math.max(max, n3);
242842
+ }, 0) + 1;
242843
+ return () => current2++;
242844
+ }
242845
+ function findNumericHint(port) {
242846
+ const hint = port?.port_hints?.find((h4) => !Number.isNaN(Number(h4)));
242847
+ return hint !== undefined ? Number(hint) : undefined;
242848
+ }
242849
+ const componentsByFootprint = /* @__PURE__ */ new Map;
242850
+ for (const group of componentGroups) {
242851
+ const { pcb_component_id, pcb_plated_holes, pcb_smtpads } = group;
242852
+ if (pcb_plated_holes.length === 0)
242853
+ continue;
242854
+ const pcbComponent = su42(circuitElements).pcb_component.list().find((e4) => e4.pcb_component_id === pcb_component_id);
242855
+ if (!pcbComponent)
242856
+ continue;
242857
+ const sourceComponent = su42(circuitElements).source_component.list().find((e4) => e4.source_component_id === pcbComponent.source_component_id);
242858
+ const footprintName = getFootprintName(sourceComponent, pcbComponent);
242859
+ const image = ensureImage(footprintName);
242860
+ const nextPinNumber = createNextPinNumberGenerator(image);
242861
+ for (const hole of pcb_plated_holes) {
242862
+ const padstackName = ensurePadstack(hole);
242863
+ const pcbPort = hole.pcb_port_id ? su42(circuitElements).pcb_port.list().find((e4) => e4.pcb_port_id === hole.pcb_port_id) : undefined;
242864
+ const sourcePort = pcbPort ? su42(circuitElements).source_port.list().find((e4) => e4.source_port_id === pcbPort.source_port_id) : undefined;
242865
+ const pinNumber = findNumericHint(sourcePort) ?? nextPinNumber();
242866
+ const pin = {
242867
+ padstack_name: padstackName,
242868
+ pin_number: pinNumber,
242869
+ x: (Number(hole.x.toFixed(3)) - pcbComponent.center.x) * 1000,
242870
+ y: (Number(hole.y.toFixed(3)) - pcbComponent.center.y) * 1000
242730
242871
  };
242731
- pcb.library.images.push(existingImage);
242872
+ const duplicate = image.pins.some((p3) => p3.x === pin.x && p3.y === pin.y && p3.padstack_name === pin.padstack_name);
242873
+ if (!duplicate)
242874
+ image.pins.push(pin);
242875
+ }
242876
+ if (pcb_smtpads.length === 0) {
242877
+ const key = footprintName;
242878
+ if (!componentsByFootprint.has(key))
242879
+ componentsByFootprint.set(key, []);
242880
+ componentsByFootprint.get(key).push({
242881
+ componentName: sourceComponent?.name || "Unknown",
242882
+ coordinates: applyToPoint22(transformMmToUm2, pcbComponent.center),
242883
+ rotation: pcbComponent.rotation || 0,
242884
+ value: getComponentValue(sourceComponent),
242885
+ sourceComponent
242886
+ });
242732
242887
  }
242733
- const platedHolePins = pcb_plated_holes.map((hole) => {
242734
- const pcbPort = su42(circuitElements).pcb_port.list().find((e4) => e4.pcb_port_id === hole.pcb_port_id);
242735
- const sourcePort = pcbPort && su42(circuitElements).source_port.list().find((e4) => e4.source_port_id === pcbPort.source_port_id);
242736
- if (hole.shape === "circle") {
242737
- const pin = {
242738
- padstack_name: getPadstackName({
242739
- shape: "circle",
242740
- holeDiameter: hole.hole_diameter * 1000,
242741
- outerDiameter: hole.outer_diameter * 1000,
242742
- layer: "all"
242743
- }),
242744
- pin_number: sourcePort?.port_hints?.find((hint) => !Number.isNaN(Number(hint))) || 1,
242745
- x: (Number(hole.x.toFixed(3)) - pcbComponent.center.x) * 1000,
242746
- y: (Number(hole.y.toFixed(3)) - pcbComponent.center.y) * 1000
242747
- };
242748
- return !existingImage.pins.some((existingPin) => {
242749
- const samePinNumber = existingPin.pin_number === pin.pin_number;
242750
- const samePositionAndPadstack = existingPin.x === pin.x && existingPin.y === pin.y && existingPin.padstack_name === pin.padstack_name;
242751
- return samePinNumber || samePositionAndPadstack;
242752
- }) ? pin : undefined;
242753
- } else if (hole.shape === "oval" || hole.shape === "pill") {
242754
- const pin = {
242755
- padstack_name: getPadstackName({
242756
- shape: hole.shape,
242757
- width: hole.hole_width * 1000,
242758
- height: hole.hole_height * 1000,
242759
- layer: "all"
242760
- }),
242761
- pin_number: sourcePort?.port_hints?.find((hint) => !Number.isNaN(Number(hint))) || 1,
242762
- x: (Number(hole.x.toFixed(3)) - pcbComponent.center.x) * 1000,
242763
- y: (Number(hole.y.toFixed(3)) - pcbComponent.center.y) * 1000
242764
- };
242765
- return !existingImage.pins.some((existingPin) => existingPin.x === pin.x && existingPin.y === pin.y && existingPin.padstack_name === pin.padstack_name) ? pin : undefined;
242766
- }
242767
- }).filter((pin) => pin !== undefined);
242768
- existingImage.pins.push(...platedHolePins);
242769
242888
  }
242770
- for (const [footprintName, components] of componentsByFootprint) {
242771
- const componentEntry = {
242772
- name: footprintName,
242773
- places: components.map((component) => ({
242774
- refdes: `${component.componentName}_${component.sourceComponent?.source_component_id}`,
242775
- x: component.coordinates.x,
242776
- y: component.coordinates.y,
242889
+ for (const [footprint, comps] of componentsByFootprint) {
242890
+ pcb.placement.components.push({
242891
+ name: footprint,
242892
+ places: comps.map((c3) => ({
242893
+ refdes: `${c3.componentName}_${c3.sourceComponent?.source_component_id}`,
242894
+ x: c3.coordinates.x,
242895
+ y: c3.coordinates.y,
242777
242896
  side: "front",
242778
- rotation: component.rotation % 90,
242779
- PN: component.value
242897
+ rotation: c3.rotation % 90,
242898
+ PN: c3.value
242780
242899
  }))
242781
- };
242782
- pcb.placement.components.push(componentEntry);
242900
+ });
242901
+ }
242902
+ }
242903
+ function generateLayers(numLayers) {
242904
+ const layers = [];
242905
+ layers.push({
242906
+ name: "F.Cu",
242907
+ type: "signal",
242908
+ property: {
242909
+ index: 0
242910
+ }
242911
+ });
242912
+ for (let i2 = 1;i2 < numLayers - 1; i2++) {
242913
+ layers.push({
242914
+ name: `In${i2}.Cu`,
242915
+ type: "signal",
242916
+ property: {
242917
+ index: i2
242918
+ }
242919
+ });
242783
242920
  }
242921
+ layers.push({
242922
+ name: "B.Cu",
242923
+ type: "signal",
242924
+ property: {
242925
+ index: numLayers - 1
242926
+ }
242927
+ });
242928
+ return layers;
242784
242929
  }
242785
- function convertCircuitJsonToDsnJson(circuitElements) {
242930
+ function convertCircuitJsonToDsnJson(circuitElements, options = {}) {
242786
242931
  const pcbBoard = circuitElements.find((element) => element.type === "pcb_board");
242932
+ const numLayers = pcbBoard?.num_layers ?? 2;
242933
+ const layers = generateLayers(numLayers);
242787
242934
  const pcb = {
242788
242935
  is_dsn_pcb: true,
242789
242936
  filename: "",
@@ -242799,22 +242946,7 @@ function convertCircuitJsonToDsnJson(circuitElements) {
242799
242946
  },
242800
242947
  unit: "um",
242801
242948
  structure: {
242802
- layers: [
242803
- {
242804
- name: "F.Cu",
242805
- type: "signal",
242806
- property: {
242807
- index: 0
242808
- }
242809
- },
242810
- {
242811
- name: "B.Cu",
242812
- type: "signal",
242813
- property: {
242814
- index: 1
242815
- }
242816
- }
242817
- ],
242949
+ layers,
242818
242950
  boundary: {
242819
242951
  path: {
242820
242952
  layer: "pcb",
@@ -242826,11 +242958,7 @@ function convertCircuitJsonToDsnJson(circuitElements) {
242826
242958
  rule: {
242827
242959
  clearances: [
242828
242960
  {
242829
- value: 200
242830
- },
242831
- {
242832
- value: 200,
242833
- type: "default_smd"
242961
+ value: options.traceClearance ?? 150
242834
242962
  },
242835
242963
  {
242836
242964
  value: 50,
@@ -242877,11 +243005,10 @@ function convertCircuitJsonToDsnJson(circuitElements) {
242877
243005
  rule: {
242878
243006
  clearances: [
242879
243007
  {
242880
- value: 200,
242881
- type: ""
243008
+ value: options.traceClearance ?? 150
242882
243009
  }
242883
243010
  ],
242884
- width: 100
243011
+ width: 150
242885
243012
  }
242886
243013
  }
242887
243014
  ]
@@ -243125,8 +243252,8 @@ var stringifyDsnJson = (dsnJson) => {
243125
243252
  `;
243126
243253
  return result;
243127
243254
  };
243128
- var convertCircuitJsonToDsnString = (circuitJson) => {
243129
- const dsnJson = convertCircuitJsonToDsnJson(circuitJson);
243255
+ var convertCircuitJsonToDsnString = (circuitJson, options = {}) => {
243256
+ const dsnJson = convertCircuitJsonToDsnJson(circuitJson, options);
243130
243257
  return stringifyDsnJson(dsnJson);
243131
243258
  };
243132
243259
  var debug33 = Debug32("dsn-converter:convertPadstacksToSmtpads");
package/dist/lib/index.js CHANGED
@@ -60445,7 +60445,7 @@ var getNodeHandler = (winterSpec, { port, middleware = [] }) => {
60445
60445
  }));
60446
60446
  };
60447
60447
  // package.json
60448
- var version = "0.1.1149";
60448
+ var version = "0.1.1150";
60449
60449
  var package_default = {
60450
60450
  name: "@tscircuit/cli",
60451
60451
  version,
@@ -60487,7 +60487,7 @@ var package_default = {
60487
60487
  cosmiconfig: "^9.0.0",
60488
60488
  debug: "^4.4.0",
60489
60489
  delay: "^6.0.0",
60490
- "dsn-converter": "^0.0.63",
60490
+ "dsn-converter": "0.0.86",
60491
60491
  easyeda: "^0.0.252",
60492
60492
  "fuse.js": "^7.1.0",
60493
60493
  "get-port": "^7.1.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.1150",
3
+ "version": "0.1.1151",
4
4
  "main": "dist/cli/main.js",
5
5
  "exports": {
6
6
  ".": "./dist/cli/main.js",
@@ -39,7 +39,7 @@
39
39
  "cosmiconfig": "^9.0.0",
40
40
  "debug": "^4.4.0",
41
41
  "delay": "^6.0.0",
42
- "dsn-converter": "^0.0.63",
42
+ "dsn-converter": "0.0.86",
43
43
  "easyeda": "^0.0.252",
44
44
  "fuse.js": "^7.1.0",
45
45
  "get-port": "^7.1.0",