@tscircuit/cli 0.1.653 → 0.1.654

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/main.js +1226 -291
  2. package/package.json +2 -2
package/dist/main.js CHANGED
@@ -74139,7 +74139,7 @@ var package_default = {
74139
74139
  chokidar: "4.0.1",
74140
74140
  "circuit-json": "0.0.325",
74141
74141
  "circuit-json-to-gltf": "^0.0.56",
74142
- "circuit-json-to-kicad": "^0.0.3",
74142
+ "circuit-json-to-kicad": "^0.0.29",
74143
74143
  "circuit-json-to-readable-netlist": "^0.0.13",
74144
74144
  "circuit-json-to-spice": "^0.0.10",
74145
74145
  "circuit-json-to-tscircuit": "^0.0.9",
@@ -81614,6 +81614,7 @@ import {
81614
81614
  Xy
81615
81615
  } from "kicadts";
81616
81616
  import { symbols } from "schematic-symbols";
81617
+ import { applyToPoint as applyToPoint3, scale as createScaleMatrix } from "transformation-matrix";
81617
81618
  import {
81618
81619
  SchematicSymbol as SchematicSymbol2,
81619
81620
  SymbolLibId,
@@ -81626,10 +81627,24 @@ import {
81626
81627
  TextEffectsFont as TextEffectsFont2,
81627
81628
  TextEffectsJustify
81628
81629
  } from "kicadts";
81629
- import { applyToPoint as applyToPoint3 } from "transformation-matrix";
81630
+ import { applyToPoint as applyToPoint23 } from "transformation-matrix";
81630
81631
  import { symbols as symbols2 } from "schematic-symbols";
81632
+ import {
81633
+ SchematicSymbol as SchematicSymbol3,
81634
+ SymbolLibId as SymbolLibId2,
81635
+ SymbolProperty as SymbolProperty3,
81636
+ SymbolPin as SymbolPin3,
81637
+ SymbolInstances as SymbolInstances2,
81638
+ SymbolInstancesProject as SymbolInstancesProject2,
81639
+ SymbolInstancePath as SymbolInstancePath2,
81640
+ TextEffects as TextEffects3,
81641
+ TextEffectsFont as TextEffectsFont3,
81642
+ TextEffectsJustify as TextEffectsJustify2,
81643
+ GlobalLabel
81644
+ } from "kicadts";
81645
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
81631
81646
  import { Wire, Pts as Pts2, Xy as Xy2, Stroke as Stroke2, Junction } from "kicadts";
81632
- import { applyToPoint as applyToPoint23 } from "transformation-matrix";
81647
+ import { applyToPoint as applyToPoint42 } from "transformation-matrix";
81633
81648
  import {
81634
81649
  SheetInstances,
81635
81650
  SheetInstancesRootPath,
@@ -81638,7 +81653,7 @@ import {
81638
81653
  } from "kicadts";
81639
81654
  import { KicadPcb } from "kicadts";
81640
81655
  import { cju as cju2 } from "@tscircuit/circuit-json-util";
81641
- import { compose as compose2, translate as translate2, scale as scale22 } from "transformation-matrix";
81656
+ import { compose as compose3, translate as translate3, scale as scale32 } from "transformation-matrix";
81642
81657
  import {
81643
81658
  Paper as Paper2,
81644
81659
  PcbLayers,
@@ -81647,14 +81662,45 @@ import {
81647
81662
  Setup
81648
81663
  } from "kicadts";
81649
81664
  import { PcbNet } from "kicadts";
81650
- import { Footprint, FpText, FootprintPad } from "kicadts";
81651
- import { applyToPoint as applyToPoint32 } from "transformation-matrix";
81665
+ import { Footprint, FootprintModel } from "kicadts";
81666
+ import { applyToPoint as applyToPoint92 } from "transformation-matrix";
81667
+ import {
81668
+ FootprintPad,
81669
+ PadPrimitives,
81670
+ PadPrimitiveGrPoly,
81671
+ Pts as Pts3,
81672
+ Xy as Xy3,
81673
+ PadOptions,
81674
+ PadNet
81675
+ } from "kicadts";
81676
+ import {
81677
+ applyToPoint as applyToPoint52,
81678
+ compose as compose2,
81679
+ translate as translate2,
81680
+ scale as scale22,
81681
+ rotate
81682
+ } from "transformation-matrix";
81683
+ import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
81684
+ import { applyToPoint as applyToPoint62, rotate as rotate2, identity } from "transformation-matrix";
81685
+ import { FootprintPad as FootprintPad3, PadDrill as PadDrill2 } from "kicadts";
81686
+ import { applyToPoint as applyToPoint72, rotate as rotate3, identity as identity2 } from "transformation-matrix";
81687
+ import { FpText, TextEffects as TextEffects4, TextEffectsFont as TextEffectsFont4 } from "kicadts";
81688
+ import { applyToPoint as applyToPoint8, rotate as rotate4, identity as identity3 } from "transformation-matrix";
81652
81689
  import { Segment, SegmentNet } from "kicadts";
81653
- import { applyToPoint as applyToPoint42 } from "transformation-matrix";
81690
+ import { applyToPoint as applyToPoint102 } from "transformation-matrix";
81654
81691
  import { Via, ViaNet } from "kicadts";
81655
- import { applyToPoint as applyToPoint52 } from "transformation-matrix";
81692
+ import { applyToPoint as applyToPoint11 } from "transformation-matrix";
81656
81693
  import { GrLine } from "kicadts";
81657
- import { applyToPoint as applyToPoint62 } from "transformation-matrix";
81694
+ import { applyToPoint as applyToPoint13 } from "transformation-matrix";
81695
+ import {
81696
+ GrText,
81697
+ TextEffects as TextEffects5,
81698
+ TextEffectsFont as TextEffectsFont5,
81699
+ TextEffectsJustify as TextEffectsJustify3,
81700
+ At
81701
+ } from "kicadts";
81702
+ import { applyToPoint as applyToPoint122 } from "transformation-matrix";
81703
+ import { cju as cju3 } from "@tscircuit/circuit-json-util";
81658
81704
  var ConverterStage = class {
81659
81705
  MAX_ITERATIONS = 1000;
81660
81706
  iteration = 0;
@@ -81686,13 +81732,13 @@ var ConverterStage = class {
81686
81732
  };
81687
81733
  var InitializeSchematicStage = class extends ConverterStage {
81688
81734
  _step() {
81689
- const { kicadSch } = this.ctx;
81735
+ const { kicadSch, schematicPaperSize } = this.ctx;
81690
81736
  if (!kicadSch) {
81691
81737
  throw new Error("KicadSch instance not initialized in context");
81692
81738
  }
81693
81739
  kicadSch.version = 20250114;
81694
81740
  const paper = new Paper;
81695
- paper.size = "A4";
81741
+ paper.size = schematicPaperSize?.name ?? "A4";
81696
81742
  kicadSch.paper = paper;
81697
81743
  kicadSch.uuid = new Uuid(crypto.randomUUID());
81698
81744
  this.finished = true;
@@ -81701,49 +81747,62 @@ var InitializeSchematicStage = class extends ConverterStage {
81701
81747
  return this.ctx.kicadSch;
81702
81748
  }
81703
81749
  };
81750
+ function getLibraryId(sourceComp, schematicComp) {
81751
+ if (sourceComp.type !== "source_component") {
81752
+ if (schematicComp.symbol_name) {
81753
+ return `Custom:${schematicComp.symbol_name}`;
81754
+ }
81755
+ return "Device:Component";
81756
+ }
81757
+ if (sourceComp.ftype === "simple_resistor") {
81758
+ return `Device:R_${sourceComp.source_component_id}`;
81759
+ }
81760
+ if (sourceComp.ftype === "simple_capacitor") {
81761
+ return `Device:C_${sourceComp.source_component_id}`;
81762
+ }
81763
+ if (sourceComp.ftype === "simple_inductor") {
81764
+ return `Device:L_${sourceComp.source_component_id}`;
81765
+ }
81766
+ if (sourceComp.ftype === "simple_diode") {
81767
+ return `Device:D_${sourceComp.source_component_id}`;
81768
+ }
81769
+ if (sourceComp.ftype === "simple_chip") {
81770
+ return `Device:U_${sourceComp.source_component_id}`;
81771
+ }
81772
+ if (schematicComp.symbol_name) {
81773
+ return `Custom:${schematicComp.symbol_name}`;
81774
+ }
81775
+ return `Device:Component_${sourceComp.source_component_id}`;
81776
+ }
81704
81777
  var AddLibrarySymbolsStage = class extends ConverterStage {
81705
81778
  _step() {
81706
81779
  const { kicadSch, db } = this.ctx;
81707
- const schematicComponents = db.schematic_component.list();
81708
- if (schematicComponents.length === 0) {
81709
- this.finished = true;
81710
- return;
81711
- }
81712
81780
  const libSymbols = new LibSymbols;
81713
- const symbolsToCreate = /* @__PURE__ */ new Set;
81714
- for (const comp of schematicComponents) {
81715
- if (comp.symbol_name) {
81716
- symbolsToCreate.add(comp.symbol_name);
81717
- } else {
81718
- const sourceComp = comp.source_component_id ? db.source_component.get(comp.source_component_id) : null;
81719
- if (sourceComp?.ftype === "simple_chip") {
81720
- symbolsToCreate.add(`generic_chip_${comp.source_component_id}`);
81721
- }
81722
- }
81723
- }
81724
81781
  const librarySymbols = [];
81725
- for (const symbolName of symbolsToCreate) {
81726
- let symbolData = symbols[symbolName];
81727
- let exampleComp;
81728
- let sourceComp;
81729
- if (symbolName.startsWith("generic_chip_")) {
81730
- const sourceCompId = symbolName.replace("generic_chip_", "");
81731
- sourceComp = db.source_component.get(sourceCompId);
81732
- exampleComp = schematicComponents.find((c) => c.source_component_id === sourceCompId);
81733
- if (exampleComp) {
81734
- symbolData = this.createGenericChipSymbolData(exampleComp, db);
81735
- }
81736
- } else {
81737
- symbolData = symbols[symbolName];
81738
- if (!symbolData) {
81739
- console.warn(`Symbol ${symbolName} not found in schematic-symbols`);
81740
- continue;
81782
+ const schematicComponents = db.schematic_component.list();
81783
+ for (const schematicComponent of schematicComponents) {
81784
+ const libSymbol = this.createLibrarySymbolForComponent(schematicComponent);
81785
+ if (libSymbol) {
81786
+ librarySymbols.push(libSymbol);
81787
+ }
81788
+ }
81789
+ const netLabels = db.schematic_net_label?.list?.() || [];
81790
+ for (const netLabel of netLabels) {
81791
+ if (netLabel.symbol_name) {
81792
+ const isPower = netLabel.source_net_id ? db.source_net.get(netLabel.source_net_id)?.is_power : false;
81793
+ const isGround = netLabel.source_net_id ? db.source_net.get(netLabel.source_net_id)?.is_ground : false;
81794
+ const isPowerOrGround = isPower || isGround;
81795
+ if (isPowerOrGround) {
81796
+ const libSymbol = this.createLibrarySymbolForNetLabel({
81797
+ netLabel,
81798
+ isPower: isPower ?? false,
81799
+ isGround: isGround ?? false
81800
+ });
81801
+ if (libSymbol) {
81802
+ librarySymbols.push(libSymbol);
81803
+ }
81741
81804
  }
81742
- exampleComp = schematicComponents.find((c) => c.symbol_name === symbolName);
81743
- sourceComp = exampleComp && exampleComp.source_component_id ? db.source_component.get(exampleComp.source_component_id) : null;
81744
81805
  }
81745
- const libSymbol = this.createLibrarySymbolFromSchematicSymbol(symbolName, symbolData, sourceComp);
81746
- librarySymbols.push(libSymbol);
81747
81806
  }
81748
81807
  libSymbols.symbols = librarySymbols;
81749
81808
  if (kicadSch) {
@@ -81751,6 +81810,59 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81751
81810
  }
81752
81811
  this.finished = true;
81753
81812
  }
81813
+ createLibrarySymbolForComponent(schematicComponent) {
81814
+ const { db } = this.ctx;
81815
+ const sourceComp = schematicComponent.source_component_id ? db.source_component.get(schematicComponent.source_component_id) : null;
81816
+ if (!sourceComp)
81817
+ return null;
81818
+ const symbolName = schematicComponent.symbol_name || (sourceComp.ftype === "simple_chip" ? `generic_chip_${schematicComponent.source_component_id}` : null);
81819
+ if (!symbolName)
81820
+ return null;
81821
+ const symbolData = this.getSymbolData(symbolName, schematicComponent);
81822
+ if (!symbolData)
81823
+ return null;
81824
+ const libId = getLibraryId(sourceComp, schematicComponent);
81825
+ const isChip = sourceComp.ftype === "simple_chip";
81826
+ const footprintName = sourceComp.ftype || "";
81827
+ return this.createLibrarySymbol({
81828
+ libId,
81829
+ symbolData,
81830
+ isChip,
81831
+ schematicComponent,
81832
+ description: this.getDescription(sourceComp),
81833
+ keywords: this.getKeywords(sourceComp),
81834
+ fpFilters: this.getFpFilters(sourceComp),
81835
+ footprintRef: footprintName ? `tscircuit:${footprintName}` : ""
81836
+ });
81837
+ }
81838
+ createLibrarySymbolForNetLabel({
81839
+ netLabel,
81840
+ isPower,
81841
+ isGround
81842
+ }) {
81843
+ const symbolName = netLabel.symbol_name;
81844
+ if (!symbolName)
81845
+ return null;
81846
+ const symbolData = symbols[symbolName];
81847
+ if (!symbolData)
81848
+ return null;
81849
+ const libId = `Custom:${symbolName}`;
81850
+ return this.createLibrarySymbol({
81851
+ libId,
81852
+ symbolData,
81853
+ isChip: false,
81854
+ schematicComponent: undefined,
81855
+ description: isPower ? "Power net label" : isGround ? "Ground net label" : "Net symbol",
81856
+ keywords: isPower ? "power net" : isGround ? "ground net" : "net",
81857
+ fpFilters: ""
81858
+ });
81859
+ }
81860
+ getSymbolData(symbolName, schematicComponent) {
81861
+ if (symbolName.startsWith("generic_chip_")) {
81862
+ return this.createGenericChipSymbolData(schematicComponent, this.ctx.db);
81863
+ }
81864
+ return symbols[symbolName] || null;
81865
+ }
81754
81866
  createGenericChipSymbolData(schematicComp, db) {
81755
81867
  const schematicPorts = db.schematic_port.list().filter((p) => p.schematic_component_id === schematicComp.schematic_component_id).sort((a, b) => (a.pin_number || 0) - (b.pin_number || 0));
81756
81868
  const width = schematicComp.size?.width || 1.5;
@@ -81782,8 +81894,16 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81782
81894
  size: { width, height }
81783
81895
  };
81784
81896
  }
81785
- createLibrarySymbolFromSchematicSymbol(symbolName, symbolData, sourceComp) {
81786
- const libId = this.getLibraryId(symbolName, sourceComp);
81897
+ createLibrarySymbol({
81898
+ libId,
81899
+ symbolData,
81900
+ isChip,
81901
+ schematicComponent,
81902
+ description,
81903
+ keywords,
81904
+ fpFilters,
81905
+ footprintRef = ""
81906
+ }) {
81787
81907
  const symbol = new SchematicSymbol({
81788
81908
  libraryId: libId,
81789
81909
  excludeFromSim: false,
@@ -81791,33 +81911,43 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81791
81911
  onBoard: true
81792
81912
  });
81793
81913
  const pinNumbers = new SymbolPinNumbers;
81794
- pinNumbers.hide = sourceComp?.ftype !== "simple_chip";
81914
+ pinNumbers.hide = !isChip;
81795
81915
  symbol._sxPinNumbers = pinNumbers;
81796
81916
  const pinNames = new SymbolPinNames;
81797
- pinNames.offset = sourceComp?.ftype === "simple_chip" ? 1.27 : 0;
81917
+ pinNames.offset = isChip ? 1.27 : 0;
81798
81918
  symbol._sxPinNames = pinNames;
81799
- this.addSymbolProperties(symbol, libId, sourceComp);
81800
- const isChip = sourceComp?.ftype === "simple_chip";
81801
- const drawingSymbol = this.createDrawingSubsymbol(libId, symbolData, isChip);
81919
+ this.addSymbolProperties({
81920
+ symbol,
81921
+ libId,
81922
+ description,
81923
+ keywords,
81924
+ fpFilters,
81925
+ footprintRef
81926
+ });
81927
+ const drawingSymbol = this.createDrawingSubsymbol({
81928
+ libId,
81929
+ symbolData,
81930
+ isChip
81931
+ });
81802
81932
  symbol.subSymbols.push(drawingSymbol);
81803
- const pinSymbol = this.createPinSubsymbol(libId, symbolData, isChip);
81933
+ const pinSymbol = this.createPinSubsymbol({
81934
+ libId,
81935
+ symbolData,
81936
+ isChip,
81937
+ schematicComponent
81938
+ });
81804
81939
  symbol.subSymbols.push(pinSymbol);
81805
81940
  symbol._sxEmbeddedFonts = new EmbeddedFonts(false);
81806
81941
  return symbol;
81807
81942
  }
81808
- getLibraryId(symbolName, sourceComp) {
81809
- if (sourceComp?.ftype === "simple_resistor") {
81810
- return "Device:R";
81811
- }
81812
- if (sourceComp?.ftype === "simple_capacitor") {
81813
- return "Device:C";
81814
- }
81815
- if (sourceComp?.ftype === "simple_chip") {
81816
- return "Device:U";
81817
- }
81818
- return `Custom:${symbolName}`;
81819
- }
81820
- addSymbolProperties(symbol, libId, sourceComp) {
81943
+ addSymbolProperties({
81944
+ symbol,
81945
+ libId,
81946
+ description,
81947
+ keywords,
81948
+ fpFilters,
81949
+ footprintRef = ""
81950
+ }) {
81821
81951
  const refPrefix = libId.split(":")[1]?.[0] || "U";
81822
81952
  const properties = [
81823
81953
  {
@@ -81830,7 +81960,7 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81830
81960
  { key: "Value", value: refPrefix, id: 1, at: [0, 0, 90], hide: false },
81831
81961
  {
81832
81962
  key: "Footprint",
81833
- value: "",
81963
+ value: footprintRef,
81834
81964
  id: 2,
81835
81965
  at: [-1.778, 0, 90],
81836
81966
  hide: true
@@ -81844,21 +81974,21 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81844
81974
  },
81845
81975
  {
81846
81976
  key: "Description",
81847
- value: this.getDescription(sourceComp),
81977
+ value: description,
81848
81978
  id: 4,
81849
81979
  at: [0, 0, 0],
81850
81980
  hide: true
81851
81981
  },
81852
81982
  {
81853
81983
  key: "ki_keywords",
81854
- value: this.getKeywords(sourceComp),
81984
+ value: keywords,
81855
81985
  id: 5,
81856
81986
  at: [0, 0, 0],
81857
81987
  hide: true
81858
81988
  },
81859
81989
  {
81860
81990
  key: "ki_fp_filters",
81861
- value: this.getFpFilters(sourceComp),
81991
+ value: fpFilters,
81862
81992
  id: 6,
81863
81993
  at: [0, 0, 0],
81864
81994
  hide: true
@@ -81901,7 +82031,11 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81901
82031
  return "*";
81902
82032
  return "*";
81903
82033
  }
81904
- createDrawingSubsymbol(libId, symbolData, isChip = false) {
82034
+ createDrawingSubsymbol({
82035
+ libId,
82036
+ symbolData,
82037
+ isChip
82038
+ }) {
81905
82039
  const drawingSymbol = new SchematicSymbol({
81906
82040
  libraryId: `${libId.split(":")[1]}_0_1`
81907
82041
  });
@@ -81909,15 +82043,31 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81909
82043
  for (const primitive of symbolData.primitives || []) {
81910
82044
  if (primitive.type === "path" && primitive.points) {
81911
82045
  const fillType = isChip ? "background" : "none";
81912
- const polyline = this.createPolylineFromPoints(primitive.points, symbolScale, fillType);
82046
+ const polyline = this.createPolylineFromPoints({
82047
+ points: primitive.points,
82048
+ scale: symbolScale,
82049
+ center: symbolData.center,
82050
+ fillType
82051
+ });
81913
82052
  drawingSymbol.polylines.push(polyline);
81914
82053
  }
81915
82054
  }
81916
82055
  return drawingSymbol;
81917
82056
  }
81918
- createPolylineFromPoints(points, scale32, fillType = "none") {
82057
+ createPolylineFromPoints({
82058
+ points,
82059
+ scale: scale42,
82060
+ center,
82061
+ fillType
82062
+ }) {
81919
82063
  const polyline = new SymbolPolyline;
81920
- const xyPoints = points.map((p) => new Xy(p.x * scale32, p.y * scale32));
82064
+ const cx = center?.x ?? 0;
82065
+ const cy = center?.y ?? 0;
82066
+ const scaleMatrix = createScaleMatrix(scale42, scale42);
82067
+ const xyPoints = points.map((p) => {
82068
+ const translated = applyToPoint3(scaleMatrix, { x: p.x - cx, y: p.y - cy });
82069
+ return new Xy(translated.x, translated.y);
82070
+ });
81921
82071
  const pts = new Pts(xyPoints);
81922
82072
  polyline.points = pts;
81923
82073
  const stroke = new Stroke;
@@ -81929,7 +82079,12 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81929
82079
  polyline.fill = fill;
81930
82080
  return polyline;
81931
82081
  }
81932
- createPinSubsymbol(libId, symbolData, isChip = false) {
82082
+ createPinSubsymbol({
82083
+ libId,
82084
+ symbolData,
82085
+ isChip,
82086
+ schematicComponent
82087
+ }) {
81933
82088
  const pinSymbol = new SchematicSymbol({
81934
82089
  libraryId: `${libId.split(":")[1]}_1_1`
81935
82090
  });
@@ -81938,9 +82093,9 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81938
82093
  const pin = new SymbolPin;
81939
82094
  pin.pinElectricalType = "passive";
81940
82095
  pin.pinGraphicStyle = "line";
81941
- const { x, y, angle } = this.calculatePinPosition(port, symbolData.center, symbolData.size, isChip);
82096
+ const { x, y, angle } = this.calculatePinPosition(port, symbolData.center, symbolData.size, isChip, i, schematicComponent);
81942
82097
  pin.at = [x, y, angle];
81943
- pin.length = isChip ? 2.54 : 1.27;
82098
+ pin.length = isChip ? 6 : 1.27;
81944
82099
  const nameFont = new TextEffectsFont;
81945
82100
  nameFont.size = { height: 1.27, width: 1.27 };
81946
82101
  const nameEffects = new TextEffects({ font: nameFont });
@@ -81958,17 +82113,50 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81958
82113
  }
81959
82114
  return pinSymbol;
81960
82115
  }
81961
- calculatePinPosition(port, center, size, isChip) {
82116
+ calculatePinPosition(port, center, size, isChip, portIndex, schematicComponent) {
81962
82117
  const symbolScale = this.ctx.c2kMatSch?.a || 15;
81963
- const dx = port.x - center.x;
81964
- const dy = port.y - center.y;
81965
- let x = port.x * symbolScale;
81966
- let y = port.y * symbolScale;
81967
- const chipPinLength = 2.54;
82118
+ let portX = port.x ?? 0;
82119
+ let portY = port.y ?? 0;
82120
+ let usingCircuitJsonPort = false;
82121
+ if (portIndex !== undefined && schematicComponent) {
82122
+ const schematicPorts = this.ctx.db.schematic_port.list().filter((p) => p.schematic_component_id === schematicComponent.schematic_component_id).sort((a, b) => (a.pin_number || 0) - (b.pin_number || 0));
82123
+ if (schematicPorts[portIndex]) {
82124
+ const schPort = schematicPorts[portIndex];
82125
+ portX = schPort.center.x - schematicComponent.center.x;
82126
+ portY = schPort.center.y - schematicComponent.center.y;
82127
+ usingCircuitJsonPort = true;
82128
+ }
82129
+ }
82130
+ let dx;
82131
+ let dy;
82132
+ if (usingCircuitJsonPort) {
82133
+ dx = portX;
82134
+ dy = portY;
82135
+ } else {
82136
+ const cx = center?.x ?? 0;
82137
+ const cy = center?.y ?? 0;
82138
+ dx = portX - cx;
82139
+ dy = portY - cy;
82140
+ }
82141
+ const scaleMatrix = createScaleMatrix(symbolScale, symbolScale);
82142
+ const scaled = applyToPoint3(scaleMatrix, { x: dx, y: dy });
82143
+ let isHorizontalPin;
82144
+ if (isChip && size) {
82145
+ const halfWidth = size.width / 2;
82146
+ const halfHeight = size.height / 2;
82147
+ const normalizedDx = Math.abs(dx) / halfWidth;
82148
+ const normalizedDy = Math.abs(dy) / halfHeight;
82149
+ isHorizontalPin = normalizedDx > normalizedDy;
82150
+ } else {
82151
+ isHorizontalPin = Math.abs(dx) > Math.abs(dy);
82152
+ }
82153
+ let x = scaled.x;
82154
+ let y = scaled.y;
82155
+ const chipPinLength = 6;
81968
82156
  if (isChip && size) {
81969
82157
  const halfWidth = size.width / 2 * symbolScale;
81970
82158
  const halfHeight = size.height / 2 * symbolScale;
81971
- if (Math.abs(dx) > Math.abs(dy)) {
82159
+ if (isHorizontalPin) {
81972
82160
  x = dx > 0 ? halfWidth : -halfWidth;
81973
82161
  y = dy * symbolScale;
81974
82162
  } else {
@@ -81977,7 +82165,7 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
81977
82165
  }
81978
82166
  }
81979
82167
  let angle = 0;
81980
- if (Math.abs(dx) > Math.abs(dy)) {
82168
+ if (isHorizontalPin) {
81981
82169
  if (dx > 0) {
81982
82170
  if (isChip) {
81983
82171
  angle = 180;
@@ -82042,7 +82230,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
82042
82230
  continue;
82043
82231
  if (!this.ctx.c2kMatSch)
82044
82232
  continue;
82045
- const { x, y } = applyToPoint3(this.ctx.c2kMatSch, {
82233
+ const { x, y } = applyToPoint23(this.ctx.c2kMatSch, {
82046
82234
  x: schematicComponent.center.x,
82047
82235
  y: schematicComponent.center.y
82048
82236
  });
@@ -82057,7 +82245,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
82057
82245
  uuid,
82058
82246
  fieldsAutoplaced: true
82059
82247
  });
82060
- const libId = this.getLibraryId(sourceComponent);
82248
+ const libId = getLibraryId(sourceComponent, schematicComponent);
82061
82249
  const symLibId = new SymbolLibId(libId);
82062
82250
  symbol._sxLibId = symLibId;
82063
82251
  const { reference, value, description } = this.getComponentMetadata(sourceComponent);
@@ -82125,7 +82313,7 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
82125
82313
  const schematicTexts = this.ctx.db.schematic_text?.list?.()?.filter((t2) => t2.schematic_component_id === schematicComponent.schematic_component_id) || [];
82126
82314
  const refText = schematicTexts.find((t2) => t2.text && t2.text.length > 0);
82127
82315
  if (refText && this.ctx.c2kMatSch) {
82128
- const refTextPos2 = applyToPoint3(this.ctx.c2kMatSch, {
82316
+ const refTextPos2 = applyToPoint23(this.ctx.c2kMatSch, {
82129
82317
  x: refText.position.x,
82130
82318
  y: refText.position.y
82131
82319
  });
@@ -82151,34 +82339,19 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
82151
82339
  }
82152
82340
  }
82153
82341
  }
82154
- const refTextPos = refTextPrimitive && this.ctx.c2kMatSch ? applyToPoint3(this.ctx.c2kMatSch, {
82155
- x: schematicComponent.center.x + refTextPrimitive.x,
82156
- y: schematicComponent.center.y + refTextPrimitive.y
82342
+ const symbolCenter = symbol.center || { x: 0, y: 0 };
82343
+ const isVertical = symbolName.includes("_down") || symbolName.includes("_up");
82344
+ const horizontalTextOffset = isVertical ? 0.15 : 0;
82345
+ const refTextPos = refTextPrimitive && this.ctx.c2kMatSch ? applyToPoint23(this.ctx.c2kMatSch, {
82346
+ x: schematicComponent.center.x + (refTextPrimitive.x - symbolCenter.x) + horizontalTextOffset,
82347
+ y: schematicComponent.center.y + (refTextPrimitive.y - symbolCenter.y)
82157
82348
  }) : { x: symbolKicadPos.x, y: symbolKicadPos.y - 6 };
82158
- const valTextPos = valTextPrimitive && this.ctx.c2kMatSch ? applyToPoint3(this.ctx.c2kMatSch, {
82159
- x: schematicComponent.center.x + valTextPrimitive.x,
82160
- y: schematicComponent.center.y + valTextPrimitive.y
82349
+ const valTextPos = valTextPrimitive && this.ctx.c2kMatSch ? applyToPoint23(this.ctx.c2kMatSch, {
82350
+ x: schematicComponent.center.x + (valTextPrimitive.x - symbolCenter.x) + horizontalTextOffset,
82351
+ y: schematicComponent.center.y + (valTextPrimitive.y - symbolCenter.y)
82161
82352
  }) : { x: symbolKicadPos.x, y: symbolKicadPos.y + 6 };
82162
82353
  return { refTextPos, valTextPos };
82163
82354
  }
82164
- getLibraryId(sourceComp) {
82165
- if (sourceComp.ftype === "simple_resistor") {
82166
- return "Device:R";
82167
- }
82168
- if (sourceComp.ftype === "simple_capacitor") {
82169
- return "Device:C";
82170
- }
82171
- if (sourceComp.ftype === "simple_inductor") {
82172
- return "Device:L";
82173
- }
82174
- if (sourceComp.ftype === "simple_diode") {
82175
- return "Device:D";
82176
- }
82177
- if (sourceComp.ftype === "simple_chip") {
82178
- return "Device:U";
82179
- }
82180
- return "Device:Component";
82181
- }
82182
82355
  getComponentMetadata(sourceComp) {
82183
82356
  const name = sourceComp.name || "?";
82184
82357
  if (sourceComp.ftype === "simple_resistor") {
@@ -82240,6 +82413,172 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
82240
82413
  return this.ctx.kicadSch;
82241
82414
  }
82242
82415
  };
82416
+ var AddSchematicNetLabelsStage = class extends ConverterStage {
82417
+ _step() {
82418
+ const { kicadSch, db } = this.ctx;
82419
+ const netLabels = db.schematic_net_label?.list?.() || [];
82420
+ if (netLabels.length === 0) {
82421
+ this.finished = true;
82422
+ return;
82423
+ }
82424
+ if (!this.ctx.c2kMatSch) {
82425
+ this.finished = true;
82426
+ return;
82427
+ }
82428
+ const symbols3 = [];
82429
+ const globalLabels = [];
82430
+ for (const netLabel of netLabels) {
82431
+ const labelText = netLabel.text || "";
82432
+ const symbolName = netLabel.symbol_name;
82433
+ if (symbolName) {
82434
+ const symbol = this.createSymbolFromNetLabel(netLabel, labelText, symbolName);
82435
+ if (symbol) {
82436
+ symbols3.push(symbol);
82437
+ }
82438
+ } else {
82439
+ const label = this.createGlobalLabel(netLabel, labelText);
82440
+ if (label) {
82441
+ globalLabels.push(label);
82442
+ }
82443
+ }
82444
+ }
82445
+ if (kicadSch && symbols3.length > 0) {
82446
+ const existingSymbols = kicadSch.symbols || [];
82447
+ kicadSch.symbols = [...existingSymbols, ...symbols3];
82448
+ }
82449
+ if (kicadSch && globalLabels.length > 0) {
82450
+ kicadSch.globalLabels = [
82451
+ ...kicadSch.globalLabels || [],
82452
+ ...globalLabels
82453
+ ];
82454
+ }
82455
+ this.finished = true;
82456
+ }
82457
+ createSymbolFromNetLabel(netLabel, labelText, symbolName) {
82458
+ if (!this.ctx.c2kMatSch)
82459
+ return null;
82460
+ const { x, y } = applyToPoint32(this.ctx.c2kMatSch, {
82461
+ x: netLabel.anchor_position?.x ?? netLabel.center?.x ?? 0,
82462
+ y: netLabel.anchor_position?.y ?? netLabel.center?.y ?? 0
82463
+ });
82464
+ const uuid = crypto.randomUUID();
82465
+ const symbol = new SchematicSymbol3({
82466
+ at: [x, y, 0],
82467
+ unit: 1,
82468
+ excludeFromSim: false,
82469
+ inBom: true,
82470
+ onBoard: true,
82471
+ dnp: false,
82472
+ uuid,
82473
+ fieldsAutoplaced: true
82474
+ });
82475
+ const libId = `Custom:${symbolName}`;
82476
+ const symLibId = new SymbolLibId2(libId);
82477
+ symbol._sxLibId = symLibId;
82478
+ const isUpSymbol = symbolName.includes("_up") || symbolName.toLowerCase().includes("vcc");
82479
+ const referenceOffset = isUpSymbol ? -4 : 4;
82480
+ const valueOffset = isUpSymbol ? -6 : 6;
82481
+ const referenceProperty = new SymbolProperty3({
82482
+ key: "Reference",
82483
+ value: labelText,
82484
+ id: 0,
82485
+ at: [x, y + referenceOffset, 0],
82486
+ effects: this.createTextEffects(1.27, false)
82487
+ });
82488
+ const valueProperty = new SymbolProperty3({
82489
+ key: "Value",
82490
+ value: labelText,
82491
+ id: 1,
82492
+ at: [x, y + valueOffset, 0],
82493
+ effects: this.createTextEffects(1.27, true)
82494
+ });
82495
+ const footprintProperty = new SymbolProperty3({
82496
+ key: "Footprint",
82497
+ value: "",
82498
+ id: 2,
82499
+ at: [x - 1.778, y, 90],
82500
+ effects: this.createTextEffects(1.27, true)
82501
+ });
82502
+ const datasheetProperty = new SymbolProperty3({
82503
+ key: "Datasheet",
82504
+ value: "~",
82505
+ id: 3,
82506
+ at: [x, y, 0],
82507
+ effects: this.createTextEffects(1.27, true)
82508
+ });
82509
+ const descriptionProperty = new SymbolProperty3({
82510
+ key: "Description",
82511
+ value: `Power/Net symbol: ${labelText}`,
82512
+ id: 4,
82513
+ at: [x, y, 0],
82514
+ effects: this.createTextEffects(1.27, true)
82515
+ });
82516
+ symbol.properties.push(referenceProperty, valueProperty, footprintProperty, datasheetProperty, descriptionProperty);
82517
+ const pin = new SymbolPin3;
82518
+ pin.numberString = "1";
82519
+ pin.uuid = crypto.randomUUID();
82520
+ symbol.pins.push(pin);
82521
+ const { kicadSch } = this.ctx;
82522
+ const instances = new SymbolInstances2;
82523
+ const project = new SymbolInstancesProject2("");
82524
+ const path27 = new SymbolInstancePath2(`/${kicadSch?.uuid?.value || ""}`);
82525
+ path27.reference = labelText;
82526
+ path27.unit = 1;
82527
+ project.paths.push(path27);
82528
+ instances.projects.push(project);
82529
+ symbol._sxInstances = instances;
82530
+ return symbol;
82531
+ }
82532
+ createGlobalLabel(netLabel, labelText) {
82533
+ if (!this.ctx.c2kMatSch || !this.ctx.kicadSch)
82534
+ return null;
82535
+ const { x, y } = applyToPoint32(this.ctx.c2kMatSch, {
82536
+ x: netLabel.anchor_position?.x ?? netLabel.center?.x ?? 0,
82537
+ y: netLabel.anchor_position?.y ?? netLabel.center?.y ?? 0
82538
+ });
82539
+ const anchorSide = netLabel.anchor_side || "left";
82540
+ const angleMap = {
82541
+ left: 0,
82542
+ right: 180,
82543
+ top: 270,
82544
+ bottom: 90
82545
+ };
82546
+ const angle = angleMap[anchorSide] || 0;
82547
+ const justifyMap = {
82548
+ left: { horizontal: "left" },
82549
+ right: { horizontal: "right" },
82550
+ top: { vertical: "top" },
82551
+ bottom: { vertical: "bottom" }
82552
+ };
82553
+ const justify = justifyMap[anchorSide] || {};
82554
+ const effects = this.createTextEffects(1.27, false);
82555
+ if (Object.keys(justify).length > 0) {
82556
+ effects.justify = new TextEffectsJustify2(justify);
82557
+ }
82558
+ const globalLabel = new GlobalLabel({
82559
+ value: labelText,
82560
+ at: [x, y, angle],
82561
+ effects,
82562
+ uuid: crypto.randomUUID(),
82563
+ fieldsAutoplaced: true
82564
+ });
82565
+ return globalLabel;
82566
+ }
82567
+ createTextEffects(size, hide = false) {
82568
+ const font = new TextEffectsFont3;
82569
+ font.size = { height: size, width: size };
82570
+ return new TextEffects3({
82571
+ font,
82572
+ hiddenText: hide
82573
+ });
82574
+ }
82575
+ getOutput() {
82576
+ if (!this.ctx.kicadSch) {
82577
+ throw new Error("kicadSch is not initialized");
82578
+ }
82579
+ return this.ctx.kicadSch;
82580
+ }
82581
+ };
82243
82582
  var AddSchematicTracesStage = class extends ConverterStage {
82244
82583
  _step() {
82245
82584
  const { kicadSch, db } = this.ctx;
@@ -82272,11 +82611,11 @@ var AddSchematicTracesStage = class extends ConverterStage {
82272
82611
  if (!this.ctx.c2kMatSch) {
82273
82612
  throw new Error("Schematic transformation matrix not initialized in context");
82274
82613
  }
82275
- const from = applyToPoint23(this.ctx.c2kMatSch, {
82614
+ const from = applyToPoint42(this.ctx.c2kMatSch, {
82276
82615
  x: edge.from.x,
82277
82616
  y: edge.from.y
82278
82617
  });
82279
- const to = applyToPoint23(this.ctx.c2kMatSch, {
82618
+ const to = applyToPoint42(this.ctx.c2kMatSch, {
82280
82619
  x: edge.to.x,
82281
82620
  y: edge.to.y
82282
82621
  });
@@ -82297,12 +82636,12 @@ var AddSchematicTracesStage = class extends ConverterStage {
82297
82636
  if (!this.ctx.c2kMatSch) {
82298
82637
  throw new Error("Schematic transformation matrix not initialized in context");
82299
82638
  }
82300
- const { x, y } = applyToPoint23(this.ctx.c2kMatSch, {
82639
+ const { x, y } = applyToPoint42(this.ctx.c2kMatSch, {
82301
82640
  x: junction.x,
82302
82641
  y: junction.y
82303
82642
  });
82304
82643
  const kicadJunction = new Junction({
82305
- at: [x, y, 0],
82644
+ at: [x, y],
82306
82645
  diameter: 0
82307
82646
  });
82308
82647
  kicadJunction.uuid = crypto.randomUUID();
@@ -82332,6 +82671,68 @@ var AddSheetInstancesStage = class extends ConverterStage {
82332
82671
  return this.ctx.kicadSch;
82333
82672
  }
82334
82673
  };
82674
+ function getSchematicBoundsAndCenter(db) {
82675
+ const schematicComponents = db.schematic_component.list();
82676
+ const schematicTraces = db.schematic_trace.list();
82677
+ let minX = Infinity;
82678
+ let minY = Infinity;
82679
+ let maxX = -Infinity;
82680
+ let maxY = -Infinity;
82681
+ for (const component of schematicComponents) {
82682
+ const width = component.size?.width ?? 0;
82683
+ const height = component.size?.height ?? 0;
82684
+ minX = Math.min(minX, component.center.x - width / 2);
82685
+ minY = Math.min(minY, component.center.y - height / 2);
82686
+ maxX = Math.max(maxX, component.center.x + width / 2);
82687
+ maxY = Math.max(maxY, component.center.y + height / 2);
82688
+ }
82689
+ for (const trace of schematicTraces) {
82690
+ for (const edge of trace.edges) {
82691
+ minX = Math.min(minX, edge.from.x, edge.to.x);
82692
+ minY = Math.min(minY, edge.from.y, edge.to.y);
82693
+ maxX = Math.max(maxX, edge.from.x, edge.to.x);
82694
+ maxY = Math.max(maxY, edge.from.y, edge.to.y);
82695
+ }
82696
+ }
82697
+ if (minX === Infinity) {
82698
+ minX = 0;
82699
+ minY = 0;
82700
+ maxX = 0;
82701
+ maxY = 0;
82702
+ }
82703
+ const centerX = (minX + maxX) / 2;
82704
+ const centerY = (minY + maxY) / 2;
82705
+ return {
82706
+ center: {
82707
+ x: centerX,
82708
+ y: centerY
82709
+ },
82710
+ bounds: {
82711
+ minX,
82712
+ minY,
82713
+ maxX,
82714
+ maxY
82715
+ }
82716
+ };
82717
+ }
82718
+ var PAPER_SIZES = [
82719
+ { name: "A4", width: 297, height: 210 },
82720
+ { name: "A3", width: 420, height: 297 },
82721
+ { name: "A2", width: 594, height: 420 },
82722
+ { name: "A1", width: 841, height: 594 },
82723
+ { name: "A0", width: 1189, height: 841 }
82724
+ ];
82725
+ function selectSchematicPaperSize(contentWidth, contentHeight, paddingMm = 20) {
82726
+ const requiredWidth = contentWidth + 2 * paddingMm;
82727
+ const requiredHeight = contentHeight + 2 * paddingMm;
82728
+ for (let i = 0;i < PAPER_SIZES.length; i++) {
82729
+ const paperSize = PAPER_SIZES[i];
82730
+ if (requiredWidth <= paperSize.width && requiredHeight <= paperSize.height) {
82731
+ return paperSize;
82732
+ }
82733
+ }
82734
+ return PAPER_SIZES[PAPER_SIZES.length - 1];
82735
+ }
82335
82736
  var CircuitJsonToKicadSchConverter = class {
82336
82737
  ctx;
82337
82738
  pipeline;
@@ -82342,21 +82743,28 @@ var CircuitJsonToKicadSchConverter = class {
82342
82743
  }
82343
82744
  constructor(circuitJson) {
82344
82745
  const CIRCUIT_JSON_SCALE_FACTOR = 15;
82345
- const KICAD_CENTER_X = 95.25;
82346
- const KICAD_CENTER_Y = 73.66;
82746
+ const db = cju(circuitJson);
82747
+ const { center, bounds } = getSchematicBoundsAndCenter(db);
82748
+ const schematicWidthMm = (bounds.maxX - bounds.minX) * CIRCUIT_JSON_SCALE_FACTOR;
82749
+ const schematicHeightMm = (bounds.maxY - bounds.minY) * CIRCUIT_JSON_SCALE_FACTOR;
82750
+ const paperSize = selectSchematicPaperSize(schematicWidthMm, schematicHeightMm);
82751
+ const KICAD_CENTER_X = paperSize.width / 2;
82752
+ const KICAD_CENTER_Y = paperSize.height / 2;
82347
82753
  this.ctx = {
82348
- db: cju(circuitJson),
82754
+ db,
82349
82755
  circuitJson,
82350
82756
  kicadSch: new KicadSch({
82351
82757
  generator: "circuit-json-to-kicad",
82352
82758
  generatorVersion: "0.0.1"
82353
82759
  }),
82354
- c2kMatSch: compose(translate(KICAD_CENTER_X, KICAD_CENTER_Y), scale6(CIRCUIT_JSON_SCALE_FACTOR, -CIRCUIT_JSON_SCALE_FACTOR))
82760
+ schematicPaperSize: paperSize,
82761
+ c2kMatSch: compose(translate(KICAD_CENTER_X, KICAD_CENTER_Y), scale6(CIRCUIT_JSON_SCALE_FACTOR, -CIRCUIT_JSON_SCALE_FACTOR), translate(-center.x, -center.y))
82355
82762
  };
82356
82763
  this.pipeline = [
82357
82764
  new InitializeSchematicStage(circuitJson, this.ctx),
82358
82765
  new AddLibrarySymbolsStage(circuitJson, this.ctx),
82359
82766
  new AddSchematicSymbolsStage(circuitJson, this.ctx),
82767
+ new AddSchematicNetLabelsStage(circuitJson, this.ctx),
82360
82768
  new AddSchematicTracesStage(circuitJson, this.ctx),
82361
82769
  new AddSheetInstancesStage(circuitJson, this.ctx)
82362
82770
  ];
@@ -82436,36 +82844,426 @@ var AddNetsStage = class extends ConverterStage {
82436
82844
  if (!kicadPcb) {
82437
82845
  throw new Error("KicadPcb instance not initialized in context");
82438
82846
  }
82439
- if (!this.ctx.pcbNetMap) {
82440
- this.ctx.pcbNetMap = /* @__PURE__ */ new Map;
82441
- }
82442
- const pcbTraces = this.ctx.db.pcb_trace.list();
82443
- const netNames = /* @__PURE__ */ new Set;
82444
- netNames.add("GND");
82445
- for (const trace of pcbTraces) {
82446
- if (trace.route && trace.route.length > 0) {
82447
- const netName = `Net-${trace.pcb_trace_id}`;
82448
- netNames.add(netName);
82449
- }
82450
- }
82451
- let netNumber = 0;
82452
- for (const netName of Array.from(netNames).sort()) {
82453
- const net2 = new PcbNet(netNumber, netName);
82454
- const nets = kicadPcb.nets;
82455
- nets.push(net2);
82456
- kicadPcb.nets = nets;
82457
- this.ctx.pcbNetMap.set(netName, netNumber);
82847
+ this.ctx.pcbNetMap = /* @__PURE__ */ new Map;
82848
+ const netNameByKey = /* @__PURE__ */ new Map;
82849
+ const sourceNets = this.ctx.db.source_net?.list() ?? [];
82850
+ for (const sourceNet of sourceNets) {
82851
+ const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
82852
+ if (!connectivityKey)
82853
+ continue;
82854
+ const candidateName = sourceNet.name || sourceNet.source_net_id || "";
82855
+ const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
82856
+ netNameByKey.set(connectivityKey, netName);
82857
+ }
82858
+ const sourceTraces = this.ctx.db.source_trace?.list() ?? [];
82859
+ for (const sourceTrace of sourceTraces) {
82860
+ let connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
82861
+ if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
82862
+ for (const sourceNetId of sourceTrace.connected_source_net_ids) {
82863
+ const connectedNet = this.ctx.db.source_net?.get(sourceNetId);
82864
+ if (connectedNet?.subcircuit_connectivity_map_key && connectedNet.subcircuit_connectivity_map_key.length > 0) {
82865
+ connectivityKey = connectedNet.subcircuit_connectivity_map_key;
82866
+ break;
82867
+ }
82868
+ }
82869
+ }
82870
+ if (!connectivityKey)
82871
+ continue;
82872
+ if (!netNameByKey.has(connectivityKey)) {
82873
+ const candidateName = sourceTrace.display_name || sourceTrace.source_trace_id || "";
82874
+ const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
82875
+ netNameByKey.set(connectivityKey, netName);
82876
+ }
82877
+ }
82878
+ const sortedEntries = Array.from(netNameByKey.entries()).sort((a, b) => a[0].localeCompare(b[0]));
82879
+ const nets = [];
82880
+ nets.push(new PcbNet(0, ""));
82881
+ let netNumber = 1;
82882
+ for (const [connectivityKey, netName] of sortedEntries) {
82883
+ const pcbNet = new PcbNet(netNumber, netName);
82884
+ nets.push(pcbNet);
82885
+ const netInfo = { id: netNumber, name: netName };
82886
+ this.ctx.pcbNetMap.set(connectivityKey, netInfo);
82458
82887
  netNumber++;
82459
82888
  }
82889
+ kicadPcb.nets = nets;
82460
82890
  this.finished = true;
82461
82891
  }
82462
82892
  getOutput() {
82463
82893
  return this.ctx.kicadPcb;
82464
82894
  }
82465
82895
  };
82896
+ function simpleHash(str) {
82897
+ let hash = 0;
82898
+ for (let i = 0;i < str.length; i++) {
82899
+ const char = str.charCodeAt(i);
82900
+ hash = (hash << 5) - hash + char;
82901
+ hash = hash & hash;
82902
+ }
82903
+ let result = "";
82904
+ for (let i = 0;i < 4; i++) {
82905
+ let h = hash;
82906
+ for (let j = 0;j < str.length; j++) {
82907
+ h = (h << 5) - h + str.charCodeAt(j) + i * 31;
82908
+ h = h & h;
82909
+ }
82910
+ result += Math.abs(h).toString(16).padStart(8, "0");
82911
+ }
82912
+ return result;
82913
+ }
82914
+ function generateDeterministicUuid(data) {
82915
+ const hash = simpleHash(data);
82916
+ return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
82917
+ }
82918
+ function createSmdPadFromCircuitJson({
82919
+ pcbPad,
82920
+ componentCenter,
82921
+ padNumber,
82922
+ componentRotation = 0,
82923
+ netInfo,
82924
+ componentId
82925
+ }) {
82926
+ let padX;
82927
+ let padY;
82928
+ if ("x" in pcbPad && "y" in pcbPad) {
82929
+ padX = pcbPad.x;
82930
+ padY = pcbPad.y;
82931
+ } else if ("points" in pcbPad && Array.isArray(pcbPad.points)) {
82932
+ const points = pcbPad.points;
82933
+ padX = points.reduce((sum, p) => sum + p.x, 0) / points.length;
82934
+ padY = points.reduce((sum, p) => sum + p.y, 0) / points.length;
82935
+ } else {
82936
+ throw new Error("Pad must have either x/y coordinates or points array");
82937
+ }
82938
+ const cj2kicadMatrix = compose2(componentRotation !== 0 ? rotate(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale22(1, -1), translate2(-componentCenter.x, -componentCenter.y));
82939
+ const rotatedPos = applyToPoint52(cj2kicadMatrix, {
82940
+ x: padX,
82941
+ y: padY
82942
+ });
82943
+ const layerMap = {
82944
+ top: "F.Cu",
82945
+ bottom: "B.Cu"
82946
+ };
82947
+ const padLayer = layerMap[pcbPad.layer] || "F.Cu";
82948
+ let padShape;
82949
+ let padSize;
82950
+ let padOptions;
82951
+ let padPrimitives;
82952
+ if (pcbPad.shape === "circle") {
82953
+ padShape = "circle";
82954
+ padSize = [
82955
+ "radius" in pcbPad ? pcbPad.radius * 2 : 0.5,
82956
+ "radius" in pcbPad ? pcbPad.radius * 2 : 0.5
82957
+ ];
82958
+ } else if (pcbPad.shape === "polygon" && "points" in pcbPad) {
82959
+ const points = pcbPad.points;
82960
+ const pointTransformMatrix = compose2(scale22(1, -1), translate2(-padX, -padY));
82961
+ const relativePoints = points.map((p) => {
82962
+ const transformed = applyToPoint52(pointTransformMatrix, { x: p.x, y: p.y });
82963
+ return new Xy3(transformed.x, transformed.y);
82964
+ });
82965
+ const grPoly = new PadPrimitiveGrPoly;
82966
+ grPoly.contours = [new Pts3(relativePoints)];
82967
+ grPoly.width = 0;
82968
+ grPoly.filled = true;
82969
+ padPrimitives = new PadPrimitives;
82970
+ padPrimitives.addGraphic(grPoly);
82971
+ padShape = "custom";
82972
+ padOptions = new PadOptions;
82973
+ padOptions.anchor = "circle";
82974
+ padSize = [0.2, 0.2];
82975
+ } else {
82976
+ padShape = "rect";
82977
+ padSize = [
82978
+ "width" in pcbPad ? pcbPad.width : 0.5,
82979
+ "height" in pcbPad ? pcbPad.height : 0.5
82980
+ ];
82981
+ }
82982
+ const padData = `pad:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
82983
+ const pad = new FootprintPad({
82984
+ number: String(padNumber),
82985
+ padType: "smd",
82986
+ shape: padShape,
82987
+ at: [rotatedPos.x, rotatedPos.y, 0],
82988
+ size: padSize,
82989
+ layers: [
82990
+ `${padLayer}`,
82991
+ `${padLayer === "F.Cu" ? "F" : "B"}.Paste`,
82992
+ `${padLayer === "F.Cu" ? "F" : "B"}.Mask`
82993
+ ],
82994
+ uuid: generateDeterministicUuid(padData)
82995
+ });
82996
+ if (padOptions) {
82997
+ pad.options = padOptions;
82998
+ }
82999
+ if (padPrimitives) {
83000
+ pad.primitives = padPrimitives;
83001
+ }
83002
+ if (netInfo) {
83003
+ pad.net = new PadNet(netInfo.id, netInfo.name);
83004
+ }
83005
+ return pad;
83006
+ }
83007
+ function createThruHolePadFromCircuitJson({
83008
+ platedHole,
83009
+ componentCenter,
83010
+ padNumber,
83011
+ componentRotation = 0,
83012
+ netInfo,
83013
+ componentId
83014
+ }) {
83015
+ if (!(("x" in platedHole) && ("y" in platedHole))) {
83016
+ return null;
83017
+ }
83018
+ const relativeX = platedHole.x - componentCenter.x;
83019
+ const relativeY = -(platedHole.y - componentCenter.y);
83020
+ const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) : identity();
83021
+ const rotatedPos = applyToPoint62(rotationMatrix, {
83022
+ x: relativeX,
83023
+ y: relativeY
83024
+ });
83025
+ let padShape = "circle";
83026
+ let padSize;
83027
+ let drill;
83028
+ let rotation = 0;
83029
+ const hasHoleOffset = "hole_offset_x" in platedHole || "hole_offset_y" in platedHole;
83030
+ let drillOffset;
83031
+ if (hasHoleOffset) {
83032
+ const rawOffset = {
83033
+ x: platedHole.hole_offset_x ?? 0,
83034
+ y: platedHole.hole_offset_y ?? 0
83035
+ };
83036
+ if (rawOffset.x !== 0 || rawOffset.y !== 0) {
83037
+ const rotatedOffset = applyToPoint62(rotationMatrix, {
83038
+ x: -rawOffset.x,
83039
+ y: rawOffset.y
83040
+ });
83041
+ drillOffset = rotatedOffset;
83042
+ }
83043
+ }
83044
+ if (platedHole.shape === "circle") {
83045
+ padShape = "circle";
83046
+ padSize = [platedHole.outer_diameter, platedHole.outer_diameter];
83047
+ drill = new PadDrill({
83048
+ diameter: platedHole.hole_diameter,
83049
+ offset: drillOffset
83050
+ });
83051
+ } else if (platedHole.shape === "pill" || platedHole.shape === "oval") {
83052
+ padShape = "oval";
83053
+ padSize = [
83054
+ platedHole.outer_width,
83055
+ platedHole.outer_height
83056
+ ];
83057
+ drill = new PadDrill({
83058
+ oval: true,
83059
+ diameter: platedHole.hole_width,
83060
+ width: platedHole.hole_height,
83061
+ offset: drillOffset
83062
+ });
83063
+ } else if (platedHole.shape === "pill_hole_with_rect_pad") {
83064
+ padShape = "rect";
83065
+ padSize = [
83066
+ platedHole.rect_pad_width,
83067
+ platedHole.rect_pad_height
83068
+ ];
83069
+ drill = new PadDrill({
83070
+ oval: true,
83071
+ diameter: platedHole.hole_width,
83072
+ width: platedHole.hole_height,
83073
+ offset: drillOffset
83074
+ });
83075
+ } else if (platedHole.shape === "circular_hole_with_rect_pad") {
83076
+ padShape = "rect";
83077
+ padSize = [
83078
+ platedHole.rect_pad_width,
83079
+ platedHole.rect_pad_height
83080
+ ];
83081
+ drill = new PadDrill({
83082
+ diameter: platedHole.hole_diameter,
83083
+ offset: drillOffset
83084
+ });
83085
+ } else if (platedHole.shape === "rotated_pill_hole_with_rect_pad") {
83086
+ padShape = "rect";
83087
+ padSize = [
83088
+ platedHole.rect_pad_width,
83089
+ platedHole.rect_pad_height
83090
+ ];
83091
+ drill = new PadDrill({
83092
+ oval: true,
83093
+ diameter: platedHole.hole_width,
83094
+ width: platedHole.hole_height,
83095
+ offset: drillOffset
83096
+ });
83097
+ rotation = platedHole.rect_ccw_rotation || 0;
83098
+ } else {
83099
+ padShape = "circle";
83100
+ padSize = [1.6, 1.6];
83101
+ drill = new PadDrill({ diameter: 0.8, offset: drillOffset });
83102
+ }
83103
+ const padData = `thruhole:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
83104
+ const pad = new FootprintPad2({
83105
+ number: String(padNumber),
83106
+ padType: "thru_hole",
83107
+ shape: padShape,
83108
+ at: [rotatedPos.x, rotatedPos.y, rotation],
83109
+ size: padSize,
83110
+ drill,
83111
+ layers: ["*.Cu", "*.Mask"],
83112
+ removeUnusedLayers: false,
83113
+ uuid: generateDeterministicUuid(padData)
83114
+ });
83115
+ if (netInfo) {
83116
+ pad.net = new PadNet2(netInfo.id, netInfo.name);
83117
+ }
83118
+ return pad;
83119
+ }
83120
+ function createNpthPadFromCircuitJson({
83121
+ pcbHole,
83122
+ componentCenter,
83123
+ componentRotation = 0
83124
+ }) {
83125
+ if (!(("x" in pcbHole) && ("y" in pcbHole))) {
83126
+ return null;
83127
+ }
83128
+ const relativeX = pcbHole.x - componentCenter.x;
83129
+ const relativeY = -(pcbHole.y - componentCenter.y);
83130
+ const rotationMatrix = componentRotation !== 0 ? rotate3(componentRotation * Math.PI / 180) : identity2();
83131
+ const rotatedPos = applyToPoint72(rotationMatrix, {
83132
+ x: relativeX,
83133
+ y: relativeY
83134
+ });
83135
+ let padShape = "circle";
83136
+ let padSize;
83137
+ let drill;
83138
+ if (pcbHole.hole_shape === "circle") {
83139
+ padShape = "circle";
83140
+ const diameter = pcbHole.hole_diameter;
83141
+ padSize = [diameter, diameter];
83142
+ drill = new PadDrill2({
83143
+ diameter
83144
+ });
83145
+ } else if (pcbHole.hole_shape === "oval") {
83146
+ padShape = "oval";
83147
+ const width = pcbHole.hole_width;
83148
+ const height = pcbHole.hole_height;
83149
+ padSize = [width, height];
83150
+ drill = new PadDrill2({
83151
+ oval: true,
83152
+ diameter: width,
83153
+ width: height
83154
+ });
83155
+ } else {
83156
+ padShape = "circle";
83157
+ const diameter = "hole_diameter" in pcbHole ? pcbHole.hole_diameter : 1;
83158
+ padSize = [diameter, diameter];
83159
+ drill = new PadDrill2({ diameter });
83160
+ }
83161
+ return new FootprintPad3({
83162
+ number: "",
83163
+ padType: "np_thru_hole",
83164
+ shape: padShape,
83165
+ at: [rotatedPos.x, rotatedPos.y, 0],
83166
+ size: padSize,
83167
+ drill,
83168
+ layers: ["*.Cu", "*.Mask"],
83169
+ removeUnusedLayers: false,
83170
+ uuid: crypto.randomUUID()
83171
+ });
83172
+ }
83173
+ function createFpTextFromCircuitJson({
83174
+ textElement,
83175
+ componentCenter,
83176
+ componentRotation = 0
83177
+ }) {
83178
+ if (!textElement.text || !textElement.anchor_position) {
83179
+ return null;
83180
+ }
83181
+ const relativeX = textElement.anchor_position.x - componentCenter.x;
83182
+ const relativeY = -(textElement.anchor_position.y - componentCenter.y);
83183
+ const rotationMatrix = componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) : identity3();
83184
+ const rotatedPos = applyToPoint8(rotationMatrix, {
83185
+ x: relativeX,
83186
+ y: relativeY
83187
+ });
83188
+ const relativePosition = {
83189
+ x: rotatedPos.x,
83190
+ y: rotatedPos.y
83191
+ };
83192
+ const layerMap = {
83193
+ top: "F.SilkS",
83194
+ bottom: "B.SilkS"
83195
+ };
83196
+ const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.SilkS";
83197
+ const fontSize = (textElement.font_size || 1) / 1.5;
83198
+ const font = new TextEffectsFont4;
83199
+ font.size = { width: fontSize, height: fontSize };
83200
+ const textEffects = new TextEffects4({
83201
+ font
83202
+ });
83203
+ const rotation = textElement.ccw_rotation || 0;
83204
+ return new FpText({
83205
+ type: "user",
83206
+ text: textElement.text,
83207
+ position: {
83208
+ x: relativePosition.x,
83209
+ y: relativePosition.y,
83210
+ angle: rotation
83211
+ },
83212
+ layer: kicadLayer,
83213
+ effects: textEffects
83214
+ });
83215
+ }
82466
83216
  var AddFootprintsStage = class extends ConverterStage {
82467
83217
  componentsProcessed = 0;
82468
83218
  pcbComponents = [];
83219
+ getNetInfoForPcbPort(pcbPortId) {
83220
+ if (!pcbPortId)
83221
+ return;
83222
+ const pcbPort = this.ctx.db.pcb_port?.get(pcbPortId);
83223
+ if (!pcbPort)
83224
+ return;
83225
+ const sourcePortId = pcbPort.source_port_id;
83226
+ if (!sourcePortId)
83227
+ return;
83228
+ const sourcePort = this.ctx.db.source_port?.get(sourcePortId);
83229
+ if (!sourcePort)
83230
+ return;
83231
+ const connectivityKey = sourcePort.subcircuit_connectivity_map_key;
83232
+ if (!connectivityKey)
83233
+ return;
83234
+ return this.ctx.pcbNetMap?.get(connectivityKey);
83235
+ }
83236
+ getCadComponentForPcbComponent(pcbComponentId) {
83237
+ const cadComponents = this.ctx.db.cad_component?.list() || [];
83238
+ return cadComponents.find((cad) => cad.pcb_component_id === pcbComponentId);
83239
+ }
83240
+ create3DModelsFromCadComponent(cadComponent, componentCenter) {
83241
+ const models = [];
83242
+ const modelUrl = cadComponent.model_step_url || cadComponent.model_wrl_url;
83243
+ if (!modelUrl)
83244
+ return models;
83245
+ const model = new FootprintModel(modelUrl);
83246
+ if (cadComponent.position) {
83247
+ model.offset = {
83248
+ x: (cadComponent.position.x || 0) - componentCenter.x,
83249
+ y: -((cadComponent.position.y || 0) - componentCenter.y),
83250
+ z: cadComponent.position.z || 0
83251
+ };
83252
+ }
83253
+ if (cadComponent.rotation) {
83254
+ model.rotate = {
83255
+ x: cadComponent.rotation.x || 0,
83256
+ y: cadComponent.rotation.y || 0,
83257
+ z: cadComponent.rotation.z || 0
83258
+ };
83259
+ }
83260
+ if (cadComponent.model_unit_to_mm_scale_factor) {
83261
+ const scale42 = cadComponent.model_unit_to_mm_scale_factor;
83262
+ model.scale = { x: scale42, y: scale42, z: scale42 };
83263
+ }
83264
+ models.push(model);
83265
+ return models;
83266
+ }
82469
83267
  constructor(input, ctx) {
82470
83268
  super(input, ctx);
82471
83269
  this.pcbComponents = this.ctx.db.pcb_component.list();
@@ -82485,74 +83283,81 @@ var AddFootprintsStage = class extends ConverterStage {
82485
83283
  const component = this.pcbComponents[this.componentsProcessed];
82486
83284
  const sourceComponent = component.source_component_id ? this.ctx.db.source_component.get(component.source_component_id) : null;
82487
83285
  const footprintName = sourceComponent?.ftype || "Unknown";
82488
- const componentName = sourceComponent?.name || `Component_${this.componentsProcessed}`;
82489
- const transformedPos = applyToPoint32(c2kMatPcb, {
83286
+ const transformedPos = applyToPoint92(c2kMatPcb, {
82490
83287
  x: component.center.x,
82491
83288
  y: component.center.y
82492
83289
  });
83290
+ const footprintData = `footprint:${component.pcb_component_id}:${transformedPos.x},${transformedPos.y}`;
82493
83291
  const footprint = new Footprint({
82494
83292
  libraryLink: `tscircuit:${footprintName}`,
82495
83293
  layer: "F.Cu",
82496
83294
  at: [transformedPos.x, transformedPos.y, component.rotation || 0],
82497
- uuid: crypto.randomUUID()
82498
- });
82499
- const refText = new FpText({
82500
- type: "reference",
82501
- text: componentName,
82502
- position: [0, -1.5, 0],
82503
- layer: "F.SilkS",
82504
- uuid: crypto.randomUUID()
82505
- });
82506
- const valueText = new FpText({
82507
- type: "value",
82508
- text: footprintName,
82509
- position: [0, 1.5, 0],
82510
- layer: "F.Fab",
82511
- uuid: crypto.randomUUID()
83295
+ uuid: generateDeterministicUuid(footprintData)
82512
83296
  });
82513
83297
  const fpTexts = footprint.fpTexts;
82514
- fpTexts.push(refText);
82515
- fpTexts.push(valueText);
83298
+ const pcbSilkscreenTexts = this.ctx.db.pcb_silkscreen_text?.list().filter((text) => text.pcb_component_id === component.pcb_component_id) || [];
83299
+ for (const textElement of pcbSilkscreenTexts) {
83300
+ const fpText = createFpTextFromCircuitJson({
83301
+ textElement,
83302
+ componentCenter: component.center,
83303
+ componentRotation: component.rotation || 0
83304
+ });
83305
+ if (fpText) {
83306
+ fpTexts.push(fpText);
83307
+ }
83308
+ }
82516
83309
  footprint.fpTexts = fpTexts;
82517
83310
  const pcbPads = this.ctx.db.pcb_smtpad?.list().filter((pad) => pad.pcb_component_id === component.pcb_component_id) || [];
82518
83311
  const fpPads = footprint.fpPads;
82519
83312
  let padNumber = 1;
82520
83313
  for (const pcbPad of pcbPads) {
82521
- if (!(("x" in pcbPad) && ("y" in pcbPad))) {
82522
- throw new Error("no support for polygon pads (or any pads w/o X/Y) yet");
82523
- }
82524
- const relativeX = pcbPad.x - component.center.x;
82525
- const relativeY = pcbPad.y - component.center.y;
82526
- const layerMap = {
82527
- top: "F.Cu",
82528
- bottom: "B.Cu"
82529
- };
82530
- const padLayer = layerMap[pcbPad.layer] || "F.Cu";
82531
- const padShape = pcbPad.shape === "circle" ? "circle" : "rect";
82532
- const padSize = pcbPad.shape === "circle" ? [
82533
- "radius" in pcbPad ? pcbPad.radius * 2 : 0.5,
82534
- "radius" in pcbPad ? pcbPad.radius * 2 : 0.5
82535
- ] : [
82536
- "width" in pcbPad ? pcbPad.width : 0.5,
82537
- "height" in pcbPad ? pcbPad.height : 0.5
82538
- ];
82539
- const pad = new FootprintPad({
82540
- number: String(padNumber),
82541
- padType: "smd",
82542
- shape: padShape,
82543
- at: [relativeX, relativeY, 0],
82544
- size: padSize,
82545
- layers: [
82546
- `${padLayer}`,
82547
- `${padLayer === "F.Cu" ? "F" : "B"}.Paste`,
82548
- `${padLayer === "F.Cu" ? "F" : "B"}.Mask`
82549
- ],
82550
- uuid: crypto.randomUUID()
83314
+ const netInfo = this.getNetInfoForPcbPort(pcbPad.pcb_port_id);
83315
+ const pad = createSmdPadFromCircuitJson({
83316
+ pcbPad,
83317
+ componentCenter: component.center,
83318
+ padNumber,
83319
+ componentRotation: component.rotation || 0,
83320
+ netInfo,
83321
+ componentId: component.pcb_component_id
82551
83322
  });
82552
83323
  fpPads.push(pad);
82553
83324
  padNumber++;
82554
83325
  }
83326
+ const pcbPlatedHoles = this.ctx.db.pcb_plated_hole?.list().filter((hole) => hole.pcb_component_id === component.pcb_component_id) || [];
83327
+ for (const platedHole of pcbPlatedHoles) {
83328
+ const netInfo = this.getNetInfoForPcbPort(platedHole.pcb_port_id);
83329
+ const pad = createThruHolePadFromCircuitJson({
83330
+ platedHole,
83331
+ componentCenter: component.center,
83332
+ padNumber,
83333
+ componentRotation: component.rotation || 0,
83334
+ netInfo,
83335
+ componentId: component.pcb_component_id
83336
+ });
83337
+ if (pad) {
83338
+ fpPads.push(pad);
83339
+ padNumber++;
83340
+ }
83341
+ }
83342
+ const pcbHoles = this.ctx.db.pcb_hole?.list().filter((hole) => hole.subcircuit_id === component.subcircuit_id) || [];
83343
+ for (const pcbHole of pcbHoles) {
83344
+ const pad = createNpthPadFromCircuitJson({
83345
+ pcbHole,
83346
+ componentCenter: component.center,
83347
+ componentRotation: component.rotation || 0
83348
+ });
83349
+ if (pad) {
83350
+ fpPads.push(pad);
83351
+ }
83352
+ }
82555
83353
  footprint.fpPads = fpPads;
83354
+ const cadComponent = this.getCadComponentForPcbComponent(component.pcb_component_id);
83355
+ if (cadComponent) {
83356
+ const models = this.create3DModelsFromCadComponent(cadComponent, component.center);
83357
+ if (models.length > 0) {
83358
+ footprint.models = models;
83359
+ }
83360
+ }
82556
83361
  const footprints = kicadPcb.footprints;
82557
83362
  footprints.push(footprint);
82558
83363
  kicadPcb.footprints = footprints;
@@ -82589,30 +83394,55 @@ var AddTracesStage = class extends ConverterStage {
82589
83394
  for (let i = 0;i < trace.route.length - 1; i++) {
82590
83395
  const startPoint = trace.route[i];
82591
83396
  const endPoint = trace.route[i + 1];
82592
- const transformedStart = applyToPoint42(c2kMatPcb, {
83397
+ const transformedStart = applyToPoint102(c2kMatPcb, {
82593
83398
  x: startPoint.x,
82594
83399
  y: startPoint.y
82595
83400
  });
82596
- const transformedEnd = applyToPoint42(c2kMatPcb, {
83401
+ const transformedEnd = applyToPoint102(c2kMatPcb, {
82597
83402
  x: endPoint.x,
82598
83403
  y: endPoint.y
82599
83404
  });
82600
- let netNumber = 0;
83405
+ let netInfo;
82601
83406
  if (pcbNetMap) {
82602
- const netName = `Net-${trace.pcb_trace_id}`;
82603
- netNumber = pcbNetMap.get(netName) ?? 0;
83407
+ let connectivityKey = trace.subcircuit_connectivity_map_key;
83408
+ if (!connectivityKey && trace.source_trace_id) {
83409
+ const sourceTrace = this.ctx.db.source_trace?.get(trace.source_trace_id);
83410
+ if (sourceTrace) {
83411
+ connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
83412
+ if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
83413
+ for (const sourceNetId of sourceTrace.connected_source_net_ids) {
83414
+ const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
83415
+ if (sourceNet?.subcircuit_connectivity_map_key) {
83416
+ connectivityKey = sourceNet.subcircuit_connectivity_map_key;
83417
+ break;
83418
+ }
83419
+ }
83420
+ }
83421
+ }
83422
+ }
83423
+ if (!connectivityKey && typeof trace.connection_name === "string") {
83424
+ const sourceNet = this.ctx.db.source_net?.get(trace.connection_name);
83425
+ if (sourceNet?.subcircuit_connectivity_map_key) {
83426
+ connectivityKey = sourceNet.subcircuit_connectivity_map_key;
83427
+ }
83428
+ }
83429
+ if (connectivityKey) {
83430
+ netInfo = pcbNetMap.get(connectivityKey);
83431
+ }
82604
83432
  }
82605
83433
  const layerMap = {
82606
83434
  top: "F.Cu",
82607
83435
  bottom: "B.Cu"
82608
83436
  };
82609
83437
  const kicadLayer = layerMap[startPoint.layer] || startPoint.layer || "F.Cu";
83438
+ const segmentData = `segment:${transformedStart.x},${transformedStart.y}:${transformedEnd.x},${transformedEnd.y}:${kicadLayer}:${netInfo?.id ?? 0}`;
82610
83439
  const segment = new Segment({
82611
83440
  start: { x: transformedStart.x, y: transformedStart.y },
82612
83441
  end: { x: transformedEnd.x, y: transformedEnd.y },
82613
83442
  layer: kicadLayer,
82614
83443
  width: trace.width || 0.25,
82615
- net: new SegmentNet(netNumber)
83444
+ net: new SegmentNet(netInfo?.id ?? 0),
83445
+ uuid: generateDeterministicUuid(segmentData)
82616
83446
  });
82617
83447
  const segments = kicadPcb.segments;
82618
83448
  segments.push(segment);
@@ -82644,20 +83474,56 @@ var AddViasStage = class extends ConverterStage {
82644
83474
  return;
82645
83475
  }
82646
83476
  const via = this.pcbVias[this.viasProcessed];
82647
- const transformedPos = applyToPoint52(c2kMatPcb, {
83477
+ const transformedPos = applyToPoint11(c2kMatPcb, {
82648
83478
  x: via.x,
82649
83479
  y: via.y
82650
83480
  });
82651
- let netNumber = 0;
82652
- if (pcbNetMap && via.net_name) {
82653
- netNumber = pcbNetMap.get(via.net_name) ?? 0;
83481
+ let netInfo;
83482
+ if (pcbNetMap) {
83483
+ let connectivityKey = via.subcircuit_connectivity_map_key;
83484
+ if (!connectivityKey && via.pcb_trace_id) {
83485
+ const pcbTrace = this.ctx.db.pcb_trace?.get(via.pcb_trace_id);
83486
+ if (pcbTrace) {
83487
+ if ("subcircuit_connectivity_map_key" in pcbTrace) {
83488
+ connectivityKey = pcbTrace.subcircuit_connectivity_map_key;
83489
+ }
83490
+ if (!connectivityKey && pcbTrace.source_trace_id) {
83491
+ const sourceTrace = this.ctx.db.source_trace?.get(pcbTrace.source_trace_id);
83492
+ if (sourceTrace) {
83493
+ if ("subcircuit_connectivity_map_key" in sourceTrace) {
83494
+ connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
83495
+ }
83496
+ if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
83497
+ for (const sourceNetId of sourceTrace.connected_source_net_ids) {
83498
+ const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
83499
+ if (sourceNet?.subcircuit_connectivity_map_key) {
83500
+ connectivityKey = sourceNet.subcircuit_connectivity_map_key;
83501
+ break;
83502
+ }
83503
+ }
83504
+ }
83505
+ }
83506
+ }
83507
+ }
83508
+ }
83509
+ if (!connectivityKey && via.connection_name) {
83510
+ const sourceNet = this.ctx.db.source_net?.get(via.connection_name);
83511
+ if (sourceNet?.subcircuit_connectivity_map_key) {
83512
+ connectivityKey = sourceNet.subcircuit_connectivity_map_key;
83513
+ }
83514
+ }
83515
+ if (connectivityKey) {
83516
+ netInfo = pcbNetMap.get(connectivityKey);
83517
+ }
82654
83518
  }
83519
+ const viaData = `via:${transformedPos.x},${transformedPos.y}:${via.outer_diameter || 0.8}:${via.hole_diameter || 0.4}:${netInfo?.id ?? 0}`;
82655
83520
  const kicadVia = new Via({
82656
83521
  at: [transformedPos.x, transformedPos.y],
82657
83522
  size: via.outer_diameter || 0.8,
82658
83523
  drill: via.hole_diameter || 0.4,
82659
83524
  layers: ["F.Cu", "B.Cu"],
82660
- net: new ViaNet(netNumber)
83525
+ net: new ViaNet(netInfo?.id ?? 0),
83526
+ uuid: generateDeterministicUuid(viaData)
82661
83527
  });
82662
83528
  const vias = kicadPcb.vias;
82663
83529
  vias.push(kicadVia);
@@ -82668,6 +83534,63 @@ var AddViasStage = class extends ConverterStage {
82668
83534
  return this.ctx.kicadPcb;
82669
83535
  }
82670
83536
  };
83537
+ function createGrTextFromCircuitJson({
83538
+ textElement,
83539
+ c2kMatPcb
83540
+ }) {
83541
+ if (!textElement.text || !textElement.anchor_position) {
83542
+ return null;
83543
+ }
83544
+ const transformedPos = applyToPoint122(c2kMatPcb, {
83545
+ x: textElement.anchor_position.x,
83546
+ y: textElement.anchor_position.y
83547
+ });
83548
+ const layerMap = {
83549
+ top: "F.SilkS",
83550
+ bottom: "B.SilkS"
83551
+ };
83552
+ const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.SilkS";
83553
+ const fontSize = (textElement.font_size || 1) / 1.5;
83554
+ const font = new TextEffectsFont5;
83555
+ font.size = { width: fontSize, height: fontSize };
83556
+ const justify = new TextEffectsJustify3;
83557
+ const anchorAlignment = textElement.anchor_alignment || "center";
83558
+ switch (anchorAlignment) {
83559
+ case "top_left":
83560
+ justify.horizontal = "left";
83561
+ justify.vertical = "top";
83562
+ break;
83563
+ case "top_right":
83564
+ justify.horizontal = "right";
83565
+ justify.vertical = "top";
83566
+ break;
83567
+ case "bottom_left":
83568
+ justify.horizontal = "left";
83569
+ justify.vertical = "bottom";
83570
+ break;
83571
+ case "bottom_right":
83572
+ justify.horizontal = "right";
83573
+ justify.vertical = "bottom";
83574
+ break;
83575
+ case "center":
83576
+ break;
83577
+ }
83578
+ const textEffects = new TextEffects5({
83579
+ font
83580
+ });
83581
+ if (anchorAlignment !== "center") {
83582
+ textEffects.justify = justify;
83583
+ }
83584
+ const rotation = textElement.ccw_rotation || 0;
83585
+ const position = new At([transformedPos.x, transformedPos.y, rotation]);
83586
+ const grText = new GrText({
83587
+ text: textElement.text,
83588
+ layer: kicadLayer,
83589
+ effects: textEffects
83590
+ });
83591
+ grText.position = position;
83592
+ return grText;
83593
+ }
82671
83594
  var AddGraphicsStage = class extends ConverterStage {
82672
83595
  _step() {
82673
83596
  const { kicadPcb, c2kMatPcb } = this.ctx;
@@ -82686,11 +83609,11 @@ var AddGraphicsStage = class extends ConverterStage {
82686
83609
  const endPoint = path27.route[i + 1];
82687
83610
  if (!startPoint || !endPoint)
82688
83611
  continue;
82689
- const transformedStart = applyToPoint62(c2kMatPcb, {
83612
+ const transformedStart = applyToPoint13(c2kMatPcb, {
82690
83613
  x: startPoint.x,
82691
83614
  y: startPoint.y
82692
83615
  });
82693
- const transformedEnd = applyToPoint62(c2kMatPcb, {
83616
+ const transformedEnd = applyToPoint13(c2kMatPcb, {
82694
83617
  x: endPoint.x,
82695
83618
  y: endPoint.y
82696
83619
  });
@@ -82710,6 +83633,18 @@ var AddGraphicsStage = class extends ConverterStage {
82710
83633
  kicadPcb.graphicLines = graphicLines;
82711
83634
  }
82712
83635
  }
83636
+ const standaloneSilkscreenTexts = this.ctx.db.pcb_silkscreen_text?.list().filter((text) => !text.pcb_component_id) || [];
83637
+ for (const textElement of standaloneSilkscreenTexts) {
83638
+ const grText = createGrTextFromCircuitJson({
83639
+ textElement,
83640
+ c2kMatPcb
83641
+ });
83642
+ if (grText) {
83643
+ const graphicTexts = kicadPcb.graphicTexts;
83644
+ graphicTexts.push(grText);
83645
+ kicadPcb.graphicTexts = graphicTexts;
83646
+ }
83647
+ }
82713
83648
  const pcbBoards = this.ctx.db.pcb_board?.list() || [];
82714
83649
  if (pcbBoards.length > 0) {
82715
83650
  const board = pcbBoards[0];
@@ -82721,8 +83656,8 @@ var AddGraphicsStage = class extends ConverterStage {
82721
83656
  if (board.outline && board.outline.length > 0) {
82722
83657
  corners = board.outline;
82723
83658
  } else {
82724
- const halfWidth = board.width / 2;
82725
- const halfHeight = board.height / 2;
83659
+ const halfWidth = board.width ? board.width / 2 : 0;
83660
+ const halfHeight = board.height ? board.height / 2 : 0;
82726
83661
  corners = [
82727
83662
  { x: board.center.x - halfWidth, y: board.center.y - halfHeight },
82728
83663
  { x: board.center.x + halfWidth, y: board.center.y - halfHeight },
@@ -82730,7 +83665,7 @@ var AddGraphicsStage = class extends ConverterStage {
82730
83665
  { x: board.center.x - halfWidth, y: board.center.y + halfHeight }
82731
83666
  ];
82732
83667
  }
82733
- const transformedCorners = corners.map((corner) => applyToPoint62(c2kMatPcb, corner));
83668
+ const transformedCorners = corners.map((corner) => applyToPoint13(c2kMatPcb, corner));
82734
83669
  for (let i = 0;i < transformedCorners.length; i++) {
82735
83670
  const start = transformedCorners[i];
82736
83671
  const end = transformedCorners[(i + 1) % transformedCorners.length];
@@ -82772,7 +83707,7 @@ var CircuitJsonToKicadPcbConverter = class {
82772
83707
  generator: "circuit-json-to-kicad",
82773
83708
  generatorVersion: "0.0.1"
82774
83709
  }),
82775
- c2kMatPcb: compose2(translate2(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale22(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE))
83710
+ c2kMatPcb: compose3(translate3(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale32(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE))
82776
83711
  };
82777
83712
  this.pipeline = [
82778
83713
  new InitializePcbStage(circuitJson, this.ctx),
@@ -82929,7 +83864,7 @@ async function generateCircuitJson({
82929
83864
  // cli/build/generate-kicad-footprint-library.ts
82930
83865
  import fs26 from "node:fs";
82931
83866
  import path28 from "node:path";
82932
- import { At, KicadPcb as KicadPcb2, parseKicadSexpr } from "kicadts";
83867
+ import { At as At2, KicadPcb as KicadPcb2, parseKicadSexpr } from "kicadts";
82933
83868
  var sanitizeLibraryAndFootprintName = (libraryLink) => {
82934
83869
  if (!libraryLink) {
82935
83870
  return {
@@ -82954,7 +83889,7 @@ var sanitizeLibraryAndFootprintName = (libraryLink) => {
82954
83889
  var sanitizeFootprint = (footprint) => {
82955
83890
  const { libraryName, footprintName } = sanitizeLibraryAndFootprintName(footprint.libraryLink);
82956
83891
  footprint.libraryLink = footprintName;
82957
- footprint.position = At.from([0, 0, 0]);
83892
+ footprint.position = At2.from([0, 0, 0]);
82958
83893
  footprint.locked = false;
82959
83894
  footprint.placed = false;
82960
83895
  footprint.uuid = undefined;
@@ -85839,7 +86774,7 @@ var require_svgson_umd = __commonJS2({
85839
86774
  });
85840
86775
  }
85841
86776
  });
85842
- function applyToPoint8(matrix, point2) {
86777
+ function applyToPoint14(matrix, point2) {
85843
86778
  return Array.isArray(point2) ? [
85844
86779
  matrix.a * point2[0] + matrix.c * point2[1] + matrix.e,
85845
86780
  matrix.b * point2[0] + matrix.d * point2[1] + matrix.f
@@ -85848,7 +86783,7 @@ function applyToPoint8(matrix, point2) {
85848
86783
  y: matrix.b * point2.x + matrix.d * point2.y + matrix.f
85849
86784
  };
85850
86785
  }
85851
- function translate3(tx2, ty2 = 0) {
86786
+ function translate4(tx2, ty2 = 0) {
85852
86787
  return {
85853
86788
  a: 1,
85854
86789
  c: 0,
@@ -85884,14 +86819,14 @@ function transform(...matrices) {
85884
86819
  }
85885
86820
  }
85886
86821
  }
85887
- function compose3(...matrices) {
86822
+ function compose4(...matrices) {
85888
86823
  return transform(...matrices);
85889
86824
  }
85890
86825
  function isUndefined2(val) {
85891
86826
  return typeof val === "undefined";
85892
86827
  }
85893
86828
  var { cos, sin, PI } = Math;
85894
- function rotate(angle, cx2, cy2) {
86829
+ function rotate5(angle, cx2, cy2) {
85895
86830
  const cosAngle = cos(angle);
85896
86831
  const sinAngle = sin(angle);
85897
86832
  const rotationMatrix = {
@@ -85906,9 +86841,9 @@ function rotate(angle, cx2, cy2) {
85906
86841
  return rotationMatrix;
85907
86842
  }
85908
86843
  return transform([
85909
- translate3(cx2, cy2),
86844
+ translate4(cx2, cy2),
85910
86845
  rotationMatrix,
85911
- translate3(-cx2, -cy2)
86846
+ translate4(-cx2, -cy2)
85912
86847
  ]);
85913
86848
  }
85914
86849
  function scale8(sx2, sy2 = undefined, cx2 = undefined, cy2 = undefined) {
@@ -85926,12 +86861,12 @@ function scale8(sx2, sy2 = undefined, cx2 = undefined, cy2 = undefined) {
85926
86861
  return scaleMatrix;
85927
86862
  }
85928
86863
  return transform([
85929
- translate3(cx2, cy2),
86864
+ translate4(cx2, cy2),
85930
86865
  scaleMatrix,
85931
- translate3(-cx2, -cy2)
86866
+ translate4(-cx2, -cy2)
85932
86867
  ]);
85933
86868
  }
85934
- function identity() {
86869
+ function identity4() {
85935
86870
  return {
85936
86871
  a: 1,
85937
86872
  c: 0,
@@ -86072,12 +87007,12 @@ peg$SyntaxError.buildMessage = function(expected, found) {
86072
87007
  function decomposeTSR2(matrix, flipX = false, flipY2 = false) {
86073
87008
  if (flipX) {
86074
87009
  if (flipY2) {
86075
- matrix = compose3(matrix, scale8(-1, -1));
87010
+ matrix = compose4(matrix, scale8(-1, -1));
86076
87011
  } else {
86077
- matrix = compose3(matrix, scale8(1, -1));
87012
+ matrix = compose4(matrix, scale8(1, -1));
86078
87013
  }
86079
87014
  } else if (flipY2) {
86080
- matrix = compose3(matrix, scale8(-1, 1));
87015
+ matrix = compose4(matrix, scale8(-1, 1));
86081
87016
  }
86082
87017
  const a = matrix.a;
86083
87018
  const b3 = matrix.b;
@@ -88155,7 +89090,7 @@ function buildSubtree(soup, opts) {
88155
89090
  }
88156
89091
  return soup.filter((e3) => included.has(e3));
88157
89092
  }
88158
- var cju3 = (circuitJsonInput, options = {}) => {
89093
+ var cju4 = (circuitJsonInput, options = {}) => {
88159
89094
  const circuitJson = circuitJsonInput;
88160
89095
  let internalStore = circuitJson._internal_store;
88161
89096
  if (!internalStore) {
@@ -88187,7 +89122,7 @@ var cju3 = (circuitJsonInput, options = {}) => {
88187
89122
  return internalStore.editCount;
88188
89123
  }
88189
89124
  if (prop === "subtree") {
88190
- return (opts) => cju3(buildSubtree(circuitJson, opts), options);
89125
+ return (opts) => cju4(buildSubtree(circuitJson, opts), options);
88191
89126
  }
88192
89127
  const component_type = prop;
88193
89128
  return {
@@ -88269,9 +89204,9 @@ var cju3 = (circuitJsonInput, options = {}) => {
88269
89204
  });
88270
89205
  return su22;
88271
89206
  };
88272
- cju3.unparsed = cju3;
88273
- var su6 = cju3;
88274
- var cju_default = cju3;
89207
+ cju4.unparsed = cju4;
89208
+ var su6 = cju4;
89209
+ var cju_default = cju4;
88275
89210
  function createIdKey(element) {
88276
89211
  const type = element.type;
88277
89212
  return `${type}:${element[`${type}_id`]}`;
@@ -88739,20 +89674,20 @@ var transformPCBElement = (elm, matrix) => {
88739
89674
  const tsr = decomposeTSR2(matrix);
88740
89675
  const flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
88741
89676
  if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
88742
- const { x, y } = applyToPoint8(matrix, {
89677
+ const { x, y } = applyToPoint14(matrix, {
88743
89678
  x: Number(elm.x),
88744
89679
  y: Number(elm.y)
88745
89680
  });
88746
89681
  elm.x = x;
88747
89682
  elm.y = y;
88748
89683
  } else if (elm.type === "pcb_keepout" || elm.type === "pcb_board") {
88749
- elm.center = applyToPoint8(matrix, elm.center);
89684
+ elm.center = applyToPoint14(matrix, elm.center);
88750
89685
  } else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text") {
88751
- elm.anchor_position = applyToPoint8(matrix, elm.anchor_position);
89686
+ elm.anchor_position = applyToPoint14(matrix, elm.anchor_position);
88752
89687
  } else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect") {
88753
- elm.center = applyToPoint8(matrix, elm.center);
89688
+ elm.center = applyToPoint14(matrix, elm.center);
88754
89689
  } else if (elm.type === "pcb_component") {
88755
- elm.center = applyToPoint8(matrix, elm.center);
89690
+ elm.center = applyToPoint14(matrix, elm.center);
88756
89691
  elm.rotation = elm.rotation + tsr.rotation.angle / Math.PI * 180;
88757
89692
  elm.rotation = elm.rotation % 360;
88758
89693
  if (flipPadWidthHeight) {
@@ -88760,7 +89695,7 @@ var transformPCBElement = (elm, matrix) => {
88760
89695
  }
88761
89696
  } else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path") {
88762
89697
  elm.route = elm.route.map((rp2) => {
88763
- const tp2 = applyToPoint8(matrix, rp2);
89698
+ const tp2 = applyToPoint14(matrix, rp2);
88764
89699
  rp2.x = tp2.x;
88765
89700
  rp2.y = tp2.y;
88766
89701
  return rp2;
@@ -88768,14 +89703,14 @@ var transformPCBElement = (elm, matrix) => {
88768
89703
  } else if (elm.type === "pcb_silkscreen_line") {
88769
89704
  const p12 = { x: elm.x1, y: elm.y1 };
88770
89705
  const p2 = { x: elm.x2, y: elm.y2 };
88771
- const p1t = applyToPoint8(matrix, p12);
88772
- const p2t = applyToPoint8(matrix, p2);
89706
+ const p1t = applyToPoint14(matrix, p12);
89707
+ const p2t = applyToPoint14(matrix, p2);
88773
89708
  elm.x1 = p1t.x;
88774
89709
  elm.y1 = p1t.y;
88775
89710
  elm.x2 = p2t.x;
88776
89711
  elm.y2 = p2t.y;
88777
89712
  } else if (elm.type === "cad_component") {
88778
- const newPos = applyToPoint8(matrix, {
89713
+ const newPos = applyToPoint14(matrix, {
88779
89714
  x: elm.position.x,
88780
89715
  y: elm.position.y
88781
89716
  });
@@ -88808,7 +89743,7 @@ var getElementById = (soup, id2) => {
88808
89743
  return soup.find((elm) => getElementId(elm) === id2) ?? null;
88809
89744
  };
88810
89745
  function getReadableNameForPcbTrace(soup, pcb_trace_id) {
88811
- const pcbTrace = cju3(soup).pcb_trace.get(pcb_trace_id);
89746
+ const pcbTrace = cju4(soup).pcb_trace.get(pcb_trace_id);
88812
89747
  if (!pcbTrace) {
88813
89748
  return `trace[${pcb_trace_id}]`;
88814
89749
  }
@@ -88817,16 +89752,16 @@ function getReadableNameForPcbTrace(soup, pcb_trace_id) {
88817
89752
  return `trace[${pcb_trace_id}]`;
88818
89753
  }
88819
89754
  function getComponentAndPortInfo(pcb_port_id) {
88820
- const pcbPort = cju3(soup).pcb_port.get(pcb_port_id);
89755
+ const pcbPort = cju4(soup).pcb_port.get(pcb_port_id);
88821
89756
  if (!pcbPort)
88822
89757
  return null;
88823
- const pcbComponent = cju3(soup).pcb_component.get(pcbPort.pcb_component_id);
89758
+ const pcbComponent = cju4(soup).pcb_component.get(pcbPort.pcb_component_id);
88824
89759
  if (!pcbComponent)
88825
89760
  return null;
88826
- const sourceComponent = cju3(soup).source_component.get(pcbComponent.source_component_id);
89761
+ const sourceComponent = cju4(soup).source_component.get(pcbComponent.source_component_id);
88827
89762
  if (!sourceComponent)
88828
89763
  return null;
88829
- const sourcePort = cju3(soup).source_port.get(pcbPort.source_port_id);
89764
+ const sourcePort = cju4(soup).source_port.get(pcbPort.source_port_id);
88830
89765
  const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : "";
88831
89766
  return {
88832
89767
  componentName: sourceComponent.name,
@@ -88843,19 +89778,19 @@ function getReadableNameForPcbTrace(soup, pcb_trace_id) {
88843
89778
  return `trace[${selectorParts.join(", ")}]`;
88844
89779
  }
88845
89780
  var getReadableNameForPcbPort = (soup, pcb_port_id) => {
88846
- const pcbPort = cju3(soup).pcb_port.get(pcb_port_id);
89781
+ const pcbPort = cju4(soup).pcb_port.get(pcb_port_id);
88847
89782
  if (!pcbPort) {
88848
89783
  return `pcb_port[#${pcb_port_id}]`;
88849
89784
  }
88850
- const pcbComponent = cju3(soup).pcb_component.get(pcbPort?.pcb_component_id);
89785
+ const pcbComponent = cju4(soup).pcb_component.get(pcbPort?.pcb_component_id);
88851
89786
  if (!pcbComponent) {
88852
89787
  return `pcb_port[#${pcb_port_id}]`;
88853
89788
  }
88854
- const sourceComponent = cju3(soup).source_component.get(pcbComponent.source_component_id);
89789
+ const sourceComponent = cju4(soup).source_component.get(pcbComponent.source_component_id);
88855
89790
  if (!sourceComponent) {
88856
89791
  return `pcb_port[#${pcb_port_id}]`;
88857
89792
  }
88858
- const sourcePort = cju3(soup).source_port.get(pcbPort.source_port_id);
89793
+ const sourcePort = cju4(soup).source_port.get(pcbPort.source_port_id);
88859
89794
  if (!sourcePort) {
88860
89795
  return `pcb_port[#${pcb_port_id}]`;
88861
89796
  }
@@ -88870,7 +89805,7 @@ var getReadableNameForPcbPort = (soup, pcb_port_id) => {
88870
89805
  return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`;
88871
89806
  };
88872
89807
  function getReadableNameForPcbSmtpad(soup, pcb_smtpad_id) {
88873
- const pcbSmtpad = cju3(soup).pcb_smtpad.get(pcb_smtpad_id);
89808
+ const pcbSmtpad = cju4(soup).pcb_smtpad.get(pcb_smtpad_id);
88874
89809
  if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {
88875
89810
  return `smtpad[${pcb_smtpad_id}]`;
88876
89811
  }
@@ -89172,7 +90107,7 @@ var repositionPcbComponentTo = (circuitJson, pcb_component_id, newCenter) => {
89172
90107
  return true;
89173
90108
  return false;
89174
90109
  });
89175
- const matrix = translate3(dx2, dy2);
90110
+ const matrix = translate4(dx2, dy2);
89176
90111
  transformPCBElements(elementsToMove, matrix);
89177
90112
  };
89178
90113
  var getCircuitJsonTree = (circuitJson, opts) => {
@@ -89858,8 +90793,8 @@ var Ty = E(Fe);
89858
90793
  var R = { paths: { path11: { type: "path", points: [{ x: -0.54, y: 0.04 }, { x: -0.22, y: 0.04 }], color: "primary", fill: false }, path12: { type: "path", points: [{ x: 0.14, y: 0.05 }, { x: 0.46, y: 0.05 }], color: "primary", fill: false }, "path12-6": { type: "path", points: [{ x: 0.14, y: -0.15 }, { x: 0.14, y: 0.25 }], color: "primary", fill: false }, "path11-0-9": { type: "path", points: [{ x: -0.22, y: 0.25 }, { x: -0.21, y: -0.15 }, { x: 0.14, y: 0.05 }, { x: -0.22, y: 0.25 }], color: "primary", fill: true } }, texts: { top1: { type: "text", text: "{REF}", x: -0.09, y: 0.38 }, bottom1: { type: "text", text: "{VAL}", x: -0.07, y: -0.38 }, right1: { type: "text", text: "", x: 0.59, y: -0.33 } }, refblocks: { left1: { x: -0.56, y: 0.04 }, right1: { x: 0.48, y: 0.05 } }, bounds: { minX: -0.59, maxX: 0.59, minY: -0.38, maxY: 0.38, width: 1.18, height: 0.76, centerX: 0, centerY: 0 }, circles: {} };
89859
90794
  var { paths: fc, texts: O7, bounds: Re, refblocks: Ey, circles: hc } = R;
89860
90795
  var Yy = e({ primitives: [...Object.values(fc), ...Object.values(hc), { type: "text", text: "{REF}", x: -0.15, y: 0.3294553499999995 }, { type: "text", text: "{VAL}", x: 0.15, y: 0.3294553499999995 }], ports: [{ ...Ey.left1, labels: ["1"] }, { ...Ey.right1, labels: ["2"] }], size: { width: Re.width, height: Re.height }, center: { x: Re.centerX, y: Re.centerY } }).rotateRightFacingSymbol("down").labelPort("left1", ["1"]).labelPort("right1", ["2"]).changeTextAnchor("{REF}", "middle_left").changeTextAnchor("{VAL}", "middle_left").build();
89861
- var { paths: cc, texts: C7, bounds: Te, refblocks: Xy3, circles: dc } = R;
89862
- var Ly = e({ primitives: [...Object.values(cc), ...Object.values(dc), { type: "text", text: "{REF}", x: -0, y: 0.4094553499999995 }, { type: "text", text: "{VAL}", x: 0, y: -0.4094553499999995 }], ports: [{ ...Xy3.left1, labels: ["1"] }, { ...Xy3.right1, labels: ["2"] }], size: { width: Te.width, height: Te.height }, center: { x: Te.centerX, y: Te.centerY } }).changeTextAnchor("{VAL}", "middle_top").rotateRightFacingSymbol("right").labelPort("left1", ["1"]).labelPort("right1", ["2"]).changeTextAnchor("{REF}", "middle_bottom").build();
90796
+ var { paths: cc, texts: C7, bounds: Te, refblocks: Xy4, circles: dc } = R;
90797
+ var Ly = e({ primitives: [...Object.values(cc), ...Object.values(dc), { type: "text", text: "{REF}", x: -0, y: 0.4094553499999995 }, { type: "text", text: "{VAL}", x: 0, y: -0.4094553499999995 }], ports: [{ ...Xy4.left1, labels: ["1"] }, { ...Xy4.right1, labels: ["2"] }], size: { width: Te.width, height: Te.height }, center: { x: Te.centerX, y: Te.centerY } }).changeTextAnchor("{VAL}", "middle_top").rotateRightFacingSymbol("right").labelPort("left1", ["1"]).labelPort("right1", ["2"]).changeTextAnchor("{REF}", "middle_bottom").build();
89863
90798
  var { paths: bc, texts: q7, bounds: Ee, refblocks: Vy, circles: _c } = R;
89864
90799
  var jy = e({ primitives: [...Object.values(bc), ...Object.values(_c), { type: "text", text: "{REF}", x: -0, y: -0.3094553499999995 }, { type: "text", text: "{VAL}", x: 0, y: 0.4094553499999995 }], ports: [{ ...Vy.left1, labels: ["1"] }, { ...Vy.right1, labels: ["2"] }], size: { width: Ee.width, height: Ee.height }, center: { x: Ee.centerX, y: Ee.centerY } }).changeTextAnchor("{VAL}", "middle_bottom").rotateRightFacingSymbol("left").labelPort("left1", ["1"]).labelPort("right1", ["2"]).changeTextAnchor("{REF}", "middle_bottom").build();
89865
90800
  var { paths: gc, texts: W7, bounds: Ye, refblocks: ky2, circles: uc } = R;
@@ -89870,12 +90805,12 @@ var { paths: Ac, texts: ov, bounds: Le, refblocks: $y, circles: Pc } = R;
89870
90805
  var My = e({ primitives: [...Object.values(Ac), ...Object.values(Pc), { type: "text", text: "{REF}", x: 0.15, y: -0.2894553499999995 }, { type: "text", text: "{VAL}", x: -0.15, y: -0.2894553499999995 }], ports: [{ ...$y.left1, labels: ["1"] }, { ...$y.right1, labels: ["2"] }], size: { width: Le.width, height: Le.height }, center: { x: Le.centerX, y: Le.centerY } }).rotateRightFacingSymbol("up").labelPort("left1", ["1"]).labelPort("right1", ["2"]).changeTextAnchor("{REF}", "middle_left").changeTextAnchor("{VAL}", "middle_left").build();
89871
90806
  var Cy = { paths: { path11: { type: "path", points: [{ x: -0.53, y: 0 }, { x: -0.3, y: 0 }], color: "primary", fill: false }, path12: { type: "path", points: [{ x: 0.29, y: 0 }, { x: 0.53, y: 0 }], color: "primary", fill: false } }, texts: { top1: { type: "text", text: "{REF}", x: -0.18, y: -0.36 }, bottom1: { type: "text", text: "{VAL}", x: -0.01, y: 0.43 }, left1: { type: "text", text: "Hz", x: 0, y: -0.04 } }, refblocks: { left1: { x: -0.54, y: 0 }, right1: { x: 0.54, y: 0 } }, bounds: { minX: -0.53, maxX: 0.53, minY: 0, maxY: 0, width: 1.06, height: 1, centerX: 0, centerY: 0 }, circles: { path1: { type: "circle", x: -0.01, y: -0.01, radius: 0.29, color: "primary", fill: false } } };
89872
90807
  var { paths: Fc, texts: Rc, bounds: Ve, refblocks: Ny, circles: Tc } = Cy;
89873
- var At2 = s({ primitives: [...Object.values(Fc), ...Object.values(Tc), { type: "text", text: "{REF}", x: 0, y: -0.3594553499999995, anchor: "middle_top" }, { type: "text", text: "{VAL}", x: 0, y: 0.35, anchor: "middle_bottom" }, { ...Rc.left1, x: 0, y: 0.01, anchor: "center", fontSize: 0.2 }], ports: [{ ...Ny.left1, labels: ["1"] }, { ...Ny.right1, labels: ["2"] }], size: { width: Ve.width, height: Ve.height }, center: { x: Ve.centerX, y: Ve.centerY } });
89874
- var { 5: Ec, ...Yc } = At2.primitives;
90808
+ var At3 = s({ primitives: [...Object.values(Fc), ...Object.values(Tc), { type: "text", text: "{REF}", x: 0, y: -0.3594553499999995, anchor: "middle_top" }, { type: "text", text: "{VAL}", x: 0, y: 0.35, anchor: "middle_bottom" }, { ...Rc.left1, x: 0, y: 0.01, anchor: "center", fontSize: 0.2 }], ports: [{ ...Ny.left1, labels: ["1"] }, { ...Ny.right1, labels: ["2"] }], size: { width: Ve.width, height: Ve.height }, center: { x: Ve.centerX, y: Ve.centerY } });
90809
+ var { 5: Ec, ...Yc } = At3.primitives;
89875
90810
  function Xc(t2) {
89876
90811
  return typeof t2 == "object";
89877
90812
  }
89878
- var Iy = r({ ...At2, primitives: Object.values(Yc).filter(Xc) });
90813
+ var Iy = r({ ...At3, primitives: Object.values(Yc).filter(Xc) });
89879
90814
  var By = { ...Iy, primitives: [...Iy.primitives, Ec] };
89880
90815
  var qy = { paths: { path10: { type: "path", points: [{ x: -0.53, y: 0.04 }, { x: 0.53, y: 0.04 }], color: "primary", fill: false }, path14: { type: "path", points: [{ x: 0, y: 0.17 }, { x: 0.27, y: 0.17 }, { x: 0.27, y: -0.1 }, { x: -0.26, y: -0.1 }, { x: -0.26, y: 0.17 }, { x: 0, y: 0.17 }], color: "primary", fill: false } }, texts: { top1: { type: "text", text: "{REF}", x: -0.01, y: 0.24 }, bottom1: { type: "text", text: "{VAL}", x: -0.17, y: -0.24 } }, refblocks: { left1: { x: -0.53, y: 0.04 }, right1: { x: 0.53, y: 0.04 } }, bounds: { minX: -0.56, maxX: 0.56, minY: -0.24, maxY: 0.24, width: 1.13, height: 0.47, centerX: 0, centerY: 0 }, circles: {} };
89881
90816
  var { paths: Vc, texts: jc, bounds: je, refblocks: Dy } = qy;
@@ -90655,7 +91590,7 @@ var mb = Cl.primitives.find((t3) => t3.type === "text" && t3.text === "{VAL}");
90655
91590
  sb.anchor = "middle_left";
90656
91591
  mb.anchor = "middle_right";
90657
91592
  var B1 = Cl;
90658
- var q1 = { ac_voltmeter_down: Ul, ac_voltmeter_horz: Wl, ac_voltmeter_left: Zl, ac_voltmeter_right: Kl, ac_voltmeter_up: ep, ac_voltmeter_vert: op, avalanche_diode_down: lp, avalanche_diode_horz: pp, avalanche_diode_left: yp, avalanche_diode_right: xp, avalanche_diode_up: mp, avalanche_diode_vert: fp, backward_diode_down: cp, backward_diode_left: Dt, backward_diode_right: _p, backward_diode_up: gp, battery_horz: Wt, battery_vert: Ap, boxresistor_down: Fp, boxresistor_left: Ep, boxresistor_right: Lp, boxresistor_small_down: jp, boxresistor_small_left: zp, boxresistor_small_right: Jp, boxresistor_small_up: Mp, boxresistor_up: Ip, bridged_ground_down: Dp, bridged_ground_left: Wp, bridged_ground_right: te, bridged_ground_up: Qp, capacitor_down: ta, capacitor_left: ea, capacitor_polarized_down: oa, capacitor_polarized_left: ia, capacitor_polarized_right: pa, capacitor_polarized_up: ya, capacitor_right: xa, capacitor_up: ma, constant_current_diode_down: fa, constant_current_diode_horz: ha, constant_current_diode_left: da, constant_current_diode_right: ba, constant_current_diode_up: ga, constant_current_diode_vert: va, crystal_4pin_down: wa, crystal_4pin_left: Aa, crystal_4pin_right: Pa, crystal_4pin_up: Sa, crystal_down: Ra, crystal_left: Ta, crystal_right: Ea, crystal_up: Xa, darlington_pair_transistor_down: La, darlington_pair_transistor_horz: Va, darlington_pair_transistor_left: ja, darlington_pair_transistor_right: ka, darlington_pair_transistor_up: za, darlington_pair_transistor_vert: Oa, dc_ammeter_horz: wt, dc_ammeter_vert: Ca, dc_voltmeter_down: Ia, dc_voltmeter_horz: qa, dc_voltmeter_left: Ua, dc_voltmeter_right: Wa, dc_voltmeter_up: Za, dc_voltmeter_vert: Ka, diac_down: ty, diac_horz: ey, diac_left: ry, diac_right: oy, diac_up: iy, diac_vert: ly, diode_down: ay, diode_left: yy, diode_right: $2, diode_up: xy, dpdt_normally_closed_switch_down: my, dpdt_normally_closed_switch_left: ny, dpdt_normally_closed_switch_right: M, dpdt_normally_closed_switch_up: fy, dpdt_switch_down: cy, dpdt_switch_left: dy, dpdt_switch_right: C, dpdt_switch_up: by, dpst_normally_closed_switch_down: gy, dpst_normally_closed_switch_left: uy, dpst_normally_closed_switch_right: N, dpst_normally_closed_switch_up: vy, dpst_switch_down: Ay, dpst_switch_left: Py, dpst_switch_right: I, dpst_switch_up: Sy, ferrite_bead_down: Ry, ferrite_bead_left: Ty, ferrite_bead_right: Fe, ferrite_bead_up: Se, filled_diode_down: Yy, filled_diode_horz: Ly, filled_diode_left: jy, filled_diode_right: zy, filled_diode_up: Jy, filled_diode_vert: My, frequency_meter_horz: At2, frequency_meter_vert: By, fuse_horz: ke, fuse_vert: Uy, ground_down: Gy, ground_horz: Wy, ground_left: Hy, ground_right: Zy, ground_up: Qy, ground_vert: Ky2, ground2_down: ex, ground2_left: ox, ground2_right: lx, ground2_up: ax, gunn_diode_horz: yx, gunn_diode_vert: xx, icled_down: mx, icled_left: nx, icled_right: q, icled_up: fx, igbt_transistor_horz: ze, igbt_transistor_vert: dx, illuminated_push_button_normally_open_horz: Oe, illuminated_push_button_normally_open_vert: ux, inductor_down: Px, inductor_left: Sx, inductor_right: _t, inductor_up: $e, laser_diode_down: Fx, laser_diode_left: Rx, laser_diode_right: D, laser_diode_up: Tx, led_down: Lx, led_left: Vx, led_right: gt, led_up: Ce, light_dependent_resistor_horz: Ie, light_dependent_resistor_vert: $x, mosfet_depletion_normally_on_horz: qe, mosfet_depletion_normally_on_vert: Ix, mushroom_head_normally_open_momentary_horz: Ue, mushroom_head_normally_open_momentary_vert: Ux, n_channel_d_mosfet_transistor_horz: He, n_channel_d_mosfet_transistor_vert: Qx, n_channel_e_mosfet_transistor_horz: Qe, n_channel_e_mosfet_transistor_vert: os5, njfet_transistor_horz: t0, njfet_transistor_vert: ys, not_connected_down: ms, not_connected_left: ns, not_connected_right: U, not_connected_up: fs30, npn_bipolar_transistor_down: hs, npn_bipolar_transistor_horz: cs, npn_bipolar_transistor_left: ds, npn_bipolar_transistor_right: bs, npn_bipolar_transistor_up: _s, npn_bipolar_transistor_vert: gs, opamp_no_power_down: vs, opamp_no_power_left: ws, opamp_no_power_right: G, opamp_no_power_up: As, opamp_with_power_down: Ss, opamp_with_power_left: Fs, opamp_with_power_right: W, opamp_with_power_up: Rs, p_channel_d_mosfet_transistor_horz: a0, p_channel_d_mosfet_transistor_vert: Ls, p_channel_e_mosfet_transistor_horz: x0, p_channel_e_mosfet_transistor_vert: Os, photodiode_horz: s0, photodiode_vert: Cs, pjfet_transistor_horz: n0, pjfet_transistor_vert: Ds, pnp_bipolar_transistor_down: Us, pnp_bipolar_transistor_horz: Gs, pnp_bipolar_transistor_left: Ws, pnp_bipolar_transistor_right: Hs, pnp_bipolar_transistor_up: Zs, pnp_bipolar_transistor_vert: Qs, potentiometer_horz: g0, potentiometer_vert: rm, potentiometer2_down: pm, potentiometer2_left: am, potentiometer2_right: H, potentiometer2_up: ym, potentiometer3_down: xm, potentiometer3_left: sm, potentiometer3_right: mm, potentiometer3_up: nm, power_factor_meter_horz: S0, power_factor_meter_vert: dm, push_button_normally_closed_momentary_horz: R0, push_button_normally_closed_momentary_vert: um, push_button_normally_open_momentary_horz: E0, push_button_normally_open_momentary_vert: Pm, rectifier_diode_horz: L0, rectifier_diode_vert: Rm, resistor_down: Em, resistor_left: Xm, resistor_right: Vm, resistor_up: km, resonator_down: Om, resonator_horz: M0, resonator_left: Jm, resonator_right: K, resonator_up: $m, resonator_vert: Mm, schottky_diode_down: Nm, schottky_diode_left: Im, schottky_diode_right: tt, schottky_diode_up: Bm, silicon_controlled_rectifier_horz: C0, silicon_controlled_rectifier_vert: Um, solderjumper2_bridged12_down: Gm, solderjumper2_bridged12_left: Wm, solderjumper2_bridged12_right: Hm, solderjumper2_bridged12_up: Zm, solderjumper2_down: Qm, solderjumper2_left: Km, solderjumper2_right: tn, solderjumper2_up: en, solderjumper3_bridged12_down: rn, solderjumper3_bridged12_left: on2, solderjumper3_bridged12_right: ln, solderjumper3_bridged12_up: pn, solderjumper3_bridged123_down: an, solderjumper3_bridged123_left: yn, solderjumper3_bridged123_right: xn, solderjumper3_bridged123_up: sn, solderjumper3_bridged23_down: mn, solderjumper3_bridged23_left: nn, solderjumper3_bridged23_right: fn, solderjumper3_bridged23_up: hn, solderjumper3_down: cn, solderjumper3_left: dn, solderjumper3_right: bn, solderjumper3_up: _n, spdt_normally_closed_switch_down: un, spdt_normally_closed_switch_left: vn, spdt_normally_closed_switch_right: at, spdt_normally_closed_switch_up: wn, spdt_switch_down: Pn, spdt_switch_left: Sn, spdt_switch_right: yt, spdt_switch_up: Fn, spst_normally_closed_switch_down: Rn, spst_normally_closed_switch_left: Tn, spst_normally_closed_switch_right: xt, spst_normally_closed_switch_up: En, spst_switch_down: Yn, spst_switch_left: Xn, spst_switch_right: st, spst_switch_up: Ln, square_wave_down: Vn, square_wave_left: jn, square_wave_right: kn, square_wave_up: zn, step_recovery_diode_horz: N0, step_recovery_diode_vert: On, tachometer_horz: Tt, tachometer_vert: Cn, testpoint_down: Bn, testpoint_left: qn, testpoint_right: nt, testpoint_up: Gn, tilted_ground_down: Hn, tilted_ground_left: Zn, tilted_ground_right: ut, tilted_ground_up: B0, triac_horz: q0, triac_vert: t1, tunnel_diode_horz: U0, tunnel_diode_vert: i1, unijunction_transistor_horz: W0, unijunction_transistor_vert: s1, usbc: n1, var_meter_horz: Z0, var_meter_vert: c1, varactor_diode_horz: K0, varactor_diode_vert: g1, varistor_horz: er, varistor_vert: A1, varmeter_horz: Et, varmeter_vert: R1, vcc_down: T1, vcc_left: E1, vcc_right: Y1, vcc_up: X1, volt_meter_horz: or, volt_meter_vert: L1, watt_hour_meter_horz: Yt, watt_hour_meter_vert: z1, wattmeter_horz: Xt, wattmeter_vert: M1, zener_diode_horz: ar, zener_diode_vert: B1 };
91593
+ var q1 = { ac_voltmeter_down: Ul, ac_voltmeter_horz: Wl, ac_voltmeter_left: Zl, ac_voltmeter_right: Kl, ac_voltmeter_up: ep, ac_voltmeter_vert: op, avalanche_diode_down: lp, avalanche_diode_horz: pp, avalanche_diode_left: yp, avalanche_diode_right: xp, avalanche_diode_up: mp, avalanche_diode_vert: fp, backward_diode_down: cp, backward_diode_left: Dt, backward_diode_right: _p, backward_diode_up: gp, battery_horz: Wt, battery_vert: Ap, boxresistor_down: Fp, boxresistor_left: Ep, boxresistor_right: Lp, boxresistor_small_down: jp, boxresistor_small_left: zp, boxresistor_small_right: Jp, boxresistor_small_up: Mp, boxresistor_up: Ip, bridged_ground_down: Dp, bridged_ground_left: Wp, bridged_ground_right: te, bridged_ground_up: Qp, capacitor_down: ta, capacitor_left: ea, capacitor_polarized_down: oa, capacitor_polarized_left: ia, capacitor_polarized_right: pa, capacitor_polarized_up: ya, capacitor_right: xa, capacitor_up: ma, constant_current_diode_down: fa, constant_current_diode_horz: ha, constant_current_diode_left: da, constant_current_diode_right: ba, constant_current_diode_up: ga, constant_current_diode_vert: va, crystal_4pin_down: wa, crystal_4pin_left: Aa, crystal_4pin_right: Pa, crystal_4pin_up: Sa, crystal_down: Ra, crystal_left: Ta, crystal_right: Ea, crystal_up: Xa, darlington_pair_transistor_down: La, darlington_pair_transistor_horz: Va, darlington_pair_transistor_left: ja, darlington_pair_transistor_right: ka, darlington_pair_transistor_up: za, darlington_pair_transistor_vert: Oa, dc_ammeter_horz: wt, dc_ammeter_vert: Ca, dc_voltmeter_down: Ia, dc_voltmeter_horz: qa, dc_voltmeter_left: Ua, dc_voltmeter_right: Wa, dc_voltmeter_up: Za, dc_voltmeter_vert: Ka, diac_down: ty, diac_horz: ey, diac_left: ry, diac_right: oy, diac_up: iy, diac_vert: ly, diode_down: ay, diode_left: yy, diode_right: $2, diode_up: xy, dpdt_normally_closed_switch_down: my, dpdt_normally_closed_switch_left: ny, dpdt_normally_closed_switch_right: M, dpdt_normally_closed_switch_up: fy, dpdt_switch_down: cy, dpdt_switch_left: dy, dpdt_switch_right: C, dpdt_switch_up: by, dpst_normally_closed_switch_down: gy, dpst_normally_closed_switch_left: uy, dpst_normally_closed_switch_right: N, dpst_normally_closed_switch_up: vy, dpst_switch_down: Ay, dpst_switch_left: Py, dpst_switch_right: I, dpst_switch_up: Sy, ferrite_bead_down: Ry, ferrite_bead_left: Ty, ferrite_bead_right: Fe, ferrite_bead_up: Se, filled_diode_down: Yy, filled_diode_horz: Ly, filled_diode_left: jy, filled_diode_right: zy, filled_diode_up: Jy, filled_diode_vert: My, frequency_meter_horz: At3, frequency_meter_vert: By, fuse_horz: ke, fuse_vert: Uy, ground_down: Gy, ground_horz: Wy, ground_left: Hy, ground_right: Zy, ground_up: Qy, ground_vert: Ky2, ground2_down: ex, ground2_left: ox, ground2_right: lx, ground2_up: ax, gunn_diode_horz: yx, gunn_diode_vert: xx, icled_down: mx, icled_left: nx, icled_right: q, icled_up: fx, igbt_transistor_horz: ze, igbt_transistor_vert: dx, illuminated_push_button_normally_open_horz: Oe, illuminated_push_button_normally_open_vert: ux, inductor_down: Px, inductor_left: Sx, inductor_right: _t, inductor_up: $e, laser_diode_down: Fx, laser_diode_left: Rx, laser_diode_right: D, laser_diode_up: Tx, led_down: Lx, led_left: Vx, led_right: gt, led_up: Ce, light_dependent_resistor_horz: Ie, light_dependent_resistor_vert: $x, mosfet_depletion_normally_on_horz: qe, mosfet_depletion_normally_on_vert: Ix, mushroom_head_normally_open_momentary_horz: Ue, mushroom_head_normally_open_momentary_vert: Ux, n_channel_d_mosfet_transistor_horz: He, n_channel_d_mosfet_transistor_vert: Qx, n_channel_e_mosfet_transistor_horz: Qe, n_channel_e_mosfet_transistor_vert: os5, njfet_transistor_horz: t0, njfet_transistor_vert: ys, not_connected_down: ms, not_connected_left: ns, not_connected_right: U, not_connected_up: fs30, npn_bipolar_transistor_down: hs, npn_bipolar_transistor_horz: cs, npn_bipolar_transistor_left: ds, npn_bipolar_transistor_right: bs, npn_bipolar_transistor_up: _s, npn_bipolar_transistor_vert: gs, opamp_no_power_down: vs, opamp_no_power_left: ws, opamp_no_power_right: G, opamp_no_power_up: As, opamp_with_power_down: Ss, opamp_with_power_left: Fs, opamp_with_power_right: W, opamp_with_power_up: Rs, p_channel_d_mosfet_transistor_horz: a0, p_channel_d_mosfet_transistor_vert: Ls, p_channel_e_mosfet_transistor_horz: x0, p_channel_e_mosfet_transistor_vert: Os, photodiode_horz: s0, photodiode_vert: Cs, pjfet_transistor_horz: n0, pjfet_transistor_vert: Ds, pnp_bipolar_transistor_down: Us, pnp_bipolar_transistor_horz: Gs, pnp_bipolar_transistor_left: Ws, pnp_bipolar_transistor_right: Hs, pnp_bipolar_transistor_up: Zs, pnp_bipolar_transistor_vert: Qs, potentiometer_horz: g0, potentiometer_vert: rm, potentiometer2_down: pm, potentiometer2_left: am, potentiometer2_right: H, potentiometer2_up: ym, potentiometer3_down: xm, potentiometer3_left: sm, potentiometer3_right: mm, potentiometer3_up: nm, power_factor_meter_horz: S0, power_factor_meter_vert: dm, push_button_normally_closed_momentary_horz: R0, push_button_normally_closed_momentary_vert: um, push_button_normally_open_momentary_horz: E0, push_button_normally_open_momentary_vert: Pm, rectifier_diode_horz: L0, rectifier_diode_vert: Rm, resistor_down: Em, resistor_left: Xm, resistor_right: Vm, resistor_up: km, resonator_down: Om, resonator_horz: M0, resonator_left: Jm, resonator_right: K, resonator_up: $m, resonator_vert: Mm, schottky_diode_down: Nm, schottky_diode_left: Im, schottky_diode_right: tt, schottky_diode_up: Bm, silicon_controlled_rectifier_horz: C0, silicon_controlled_rectifier_vert: Um, solderjumper2_bridged12_down: Gm, solderjumper2_bridged12_left: Wm, solderjumper2_bridged12_right: Hm, solderjumper2_bridged12_up: Zm, solderjumper2_down: Qm, solderjumper2_left: Km, solderjumper2_right: tn, solderjumper2_up: en, solderjumper3_bridged12_down: rn, solderjumper3_bridged12_left: on2, solderjumper3_bridged12_right: ln, solderjumper3_bridged12_up: pn, solderjumper3_bridged123_down: an, solderjumper3_bridged123_left: yn, solderjumper3_bridged123_right: xn, solderjumper3_bridged123_up: sn, solderjumper3_bridged23_down: mn, solderjumper3_bridged23_left: nn, solderjumper3_bridged23_right: fn, solderjumper3_bridged23_up: hn, solderjumper3_down: cn, solderjumper3_left: dn, solderjumper3_right: bn, solderjumper3_up: _n, spdt_normally_closed_switch_down: un, spdt_normally_closed_switch_left: vn, spdt_normally_closed_switch_right: at, spdt_normally_closed_switch_up: wn, spdt_switch_down: Pn, spdt_switch_left: Sn, spdt_switch_right: yt, spdt_switch_up: Fn, spst_normally_closed_switch_down: Rn, spst_normally_closed_switch_left: Tn, spst_normally_closed_switch_right: xt, spst_normally_closed_switch_up: En, spst_switch_down: Yn, spst_switch_left: Xn, spst_switch_right: st, spst_switch_up: Ln, square_wave_down: Vn, square_wave_left: jn, square_wave_right: kn, square_wave_up: zn, step_recovery_diode_horz: N0, step_recovery_diode_vert: On, tachometer_horz: Tt, tachometer_vert: Cn, testpoint_down: Bn, testpoint_left: qn, testpoint_right: nt, testpoint_up: Gn, tilted_ground_down: Hn, tilted_ground_left: Zn, tilted_ground_right: ut, tilted_ground_up: B0, triac_horz: q0, triac_vert: t1, tunnel_diode_horz: U0, tunnel_diode_vert: i1, unijunction_transistor_horz: W0, unijunction_transistor_vert: s1, usbc: n1, var_meter_horz: Z0, var_meter_vert: c1, varactor_diode_horz: K0, varactor_diode_vert: g1, varistor_horz: er, varistor_vert: A1, varmeter_horz: Et, varmeter_vert: R1, vcc_down: T1, vcc_left: E1, vcc_right: Y1, vcc_up: X1, volt_meter_horz: or, volt_meter_vert: L1, watt_hour_meter_horz: Yt, watt_hour_meter_vert: z1, wattmeter_horz: Xt, wattmeter_vert: M1, zener_diode_horz: ar, zener_diode_vert: B1 };
90659
91594
  var Y$ = Object.fromEntries(Object.keys(q1).map((t3) => [t3, t3]));
90660
91595
  function doesLineIntersectLine([a12, a22], [b12, b22], {
90661
91596
  lineThickness = 0
@@ -129801,7 +130736,7 @@ var m2host = (raw_params) => {
129801
130736
  }
129802
130737
  const centerX = (minX + maxX) / 2;
129803
130738
  const centerY = (minY + maxY) / 2;
129804
- const translate4 = (el2) => {
130739
+ const translate42 = (el2) => {
129805
130740
  if (typeof el2.x === "number")
129806
130741
  el2.x -= centerX;
129807
130742
  if (typeof el2.y === "number")
@@ -129818,9 +130753,9 @@ var m2host = (raw_params) => {
129818
130753
  }
129819
130754
  };
129820
130755
  for (const pad2 of pads)
129821
- translate4(pad2);
129822
- translate4(cutout);
129823
- translate4(pin1Marker);
130756
+ translate42(pad2);
130757
+ translate42(cutout);
130758
+ translate42(pin1Marker);
129824
130759
  return {
129825
130760
  circuitJson: [
129826
130761
  ...pads,
@@ -166713,11 +167648,11 @@ var SchematicPartitionProcessor = class {
166713
167648
  continue;
166714
167649
  const stroke = getColorByIndex(partitionIdx, this.wipPartitions.length, 1);
166715
167650
  const { x, y } = getPinPosition(this.lastGraph, boxId, pinId);
166716
- const scale32 = 1 + 0.1 * partitionIdx;
167651
+ const scale33 = 1 + 0.1 * partitionIdx;
166717
167652
  graphics.rects.push({
166718
167653
  center: { x, y },
166719
- width: unexploredRectBaseSize * scale32,
166720
- height: unexploredRectBaseSize * scale32,
167654
+ width: unexploredRectBaseSize * scale33,
167655
+ height: unexploredRectBaseSize * scale33,
166721
167656
  fill: "none",
166722
167657
  stroke
166723
167658
  });
@@ -174463,14 +175398,14 @@ var PrimitiveComponent2 = class extends Renderable {
174463
175398
  }
174464
175399
  computePcbPropsTransform() {
174465
175400
  const { _parsedProps: props } = this;
174466
- const matrix2 = compose3(translate3(props.pcbX ?? 0, props.pcbY ?? 0), rotate((props.pcbRotation ?? 0) * Math.PI / 180));
175401
+ const matrix2 = compose4(translate4(props.pcbX ?? 0, props.pcbY ?? 0), rotate5((props.pcbRotation ?? 0) * Math.PI / 180));
174467
175402
  return matrix2;
174468
175403
  }
174469
175404
  _computePcbGlobalTransformBeforeLayout() {
174470
175405
  const { _parsedProps: props } = this;
174471
175406
  const manualPlacement = this.getSubcircuit()._getPcbManualPlacementForComponent(this);
174472
175407
  if (manualPlacement && this.props.pcbX === undefined && this.props.pcbY === undefined) {
174473
- return compose3(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(), compose3(translate3(manualPlacement.x, manualPlacement.y), rotate((props.pcbRotation ?? 0) * Math.PI / 180)));
175408
+ return compose4(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity4(), compose4(translate4(manualPlacement.x, manualPlacement.y), rotate5((props.pcbRotation ?? 0) * Math.PI / 180)));
174474
175409
  }
174475
175410
  if (this.isPcbPrimitive) {
174476
175411
  const primitiveContainer = this.getPrimitiveContainer();
@@ -174478,12 +175413,12 @@ var PrimitiveComponent2 = class extends Renderable {
174478
175413
  const isFlipped = primitiveContainer._parsedProps.layer === "bottom";
174479
175414
  const containerCenter = primitiveContainer._getGlobalPcbPositionBeforeLayout();
174480
175415
  if (isFlipped) {
174481
- const flipOperation = compose3(translate3(containerCenter.x, containerCenter.y), flipY(), translate3(-containerCenter.x, -containerCenter.y));
174482
- return compose3(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(), flipY(), this.computePcbPropsTransform());
175416
+ const flipOperation = compose4(translate4(containerCenter.x, containerCenter.y), flipY(), translate4(-containerCenter.x, -containerCenter.y));
175417
+ return compose4(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity4(), flipY(), this.computePcbPropsTransform());
174483
175418
  }
174484
175419
  }
174485
175420
  }
174486
- return compose3(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(), this.computePcbPropsTransform());
175421
+ return compose4(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity4(), this.computePcbPropsTransform());
174487
175422
  }
174488
175423
  getPrimitiveContainer() {
174489
175424
  if (this.isPrimitiveContainer)
@@ -174514,13 +175449,13 @@ var PrimitiveComponent2 = class extends Renderable {
174514
175449
  }
174515
175450
  computeSchematicPropsTransform() {
174516
175451
  const { _parsedProps: props } = this;
174517
- return compose3(translate3(props.schX ?? 0, props.schY ?? 0));
175452
+ return compose4(translate4(props.schX ?? 0, props.schY ?? 0));
174518
175453
  }
174519
175454
  computeSchematicGlobalTransform() {
174520
175455
  const manualPlacementTransform = this._getSchematicGlobalManualPlacementTransform(this);
174521
175456
  if (manualPlacementTransform)
174522
175457
  return manualPlacementTransform;
174523
- return compose3(this.parent?.computeSchematicGlobalTransform?.() ?? identity(), this.computeSchematicPropsTransform());
175458
+ return compose4(this.parent?.computeSchematicGlobalTransform?.() ?? identity4(), this.computeSchematicPropsTransform());
174524
175459
  }
174525
175460
  _getSchematicSymbolName() {
174526
175461
  const { _parsedProps: props } = this;
@@ -174606,7 +175541,7 @@ var PrimitiveComponent2 = class extends Renderable {
174606
175541
  return null;
174607
175542
  for (const position2 of placementConfigPositions) {
174608
175543
  if (isMatchingSelector(component, position2.selector) || component.props.name === position2.selector) {
174609
- const center2 = applyToPoint8(this._computePcbGlobalTransformBeforeLayout(), position2.center);
175544
+ const center2 = applyToPoint14(this._computePcbGlobalTransformBeforeLayout(), position2.center);
174610
175545
  return center2;
174611
175546
  }
174612
175547
  }
@@ -174623,7 +175558,7 @@ var PrimitiveComponent2 = class extends Renderable {
174623
175558
  return null;
174624
175559
  for (const position2 of placementConfigPositions) {
174625
175560
  if (isMatchingSelector(component, position2.selector) || component.props.name === position2.selector) {
174626
- const center2 = applyToPoint8(this.computeSchematicGlobalTransform(), position2.center);
175561
+ const center2 = applyToPoint14(this.computeSchematicGlobalTransform(), position2.center);
174627
175562
  return center2;
174628
175563
  }
174629
175564
  }
@@ -174636,20 +175571,20 @@ var PrimitiveComponent2 = class extends Renderable {
174636
175571
  for (const position2 of manualEdits.schematic_placements ?? []) {
174637
175572
  if (isMatchingSelector(component, position2.selector) || component.props.name === position2.selector) {
174638
175573
  if (position2.relative_to === "group_center") {
174639
- return compose3(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(), translate3(position2.center.x, position2.center.y));
175574
+ return compose4(this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity4(), translate4(position2.center.x, position2.center.y));
174640
175575
  }
174641
175576
  }
174642
175577
  }
174643
175578
  return null;
174644
175579
  }
174645
175580
  _getGlobalPcbPositionBeforeLayout() {
174646
- return applyToPoint8(this._computePcbGlobalTransformBeforeLayout(), {
175581
+ return applyToPoint14(this._computePcbGlobalTransformBeforeLayout(), {
174647
175582
  x: 0,
174648
175583
  y: 0
174649
175584
  });
174650
175585
  }
174651
175586
  _getGlobalSchematicPositionBeforeLayout() {
174652
- return applyToPoint8(this.computeSchematicGlobalTransform(), { x: 0, y: 0 });
175587
+ return applyToPoint14(this.computeSchematicGlobalTransform(), { x: 0, y: 0 });
174653
175588
  }
174654
175589
  get root() {
174655
175590
  return this.parent?.root ?? null;
@@ -175080,7 +176015,7 @@ var createInstanceFromReactElement = (reactElm) => {
175080
176015
  this.children.push(instance);
175081
176016
  },
175082
176017
  computePcbGlobalTransform() {
175083
- return identity();
176018
+ return identity4();
175084
176019
  }
175085
176020
  };
175086
176021
  const containerErrors = [];
@@ -175615,7 +176550,7 @@ var SilkscreenPath = class extends PrimitiveComponent2 {
175615
176550
  pcb_component_id,
175616
176551
  layer,
175617
176552
  route: props.route.map((p) => {
175618
- const transformedPosition = applyToPoint8(transform2, {
176553
+ const transformedPosition = applyToPoint14(transform2, {
175619
176554
  x: p.x,
175620
176555
  y: p.y
175621
176556
  });
@@ -175698,7 +176633,7 @@ var PcbTrace = class extends PrimitiveComponent2 {
175698
176633
  const parentTransform = this._computePcbGlobalTransformBeforeLayout();
175699
176634
  const transformedRoute = props.route.map((point5) => {
175700
176635
  const { x, y, ...restOfPoint } = point5;
175701
- const transformedPoint = applyToPoint8(parentTransform, { x, y });
176636
+ const transformedPoint = applyToPoint14(parentTransform, { x, y });
175702
176637
  if (point5.route_type === "wire" && point5.layer) {
175703
176638
  return {
175704
176639
  ...transformedPoint,
@@ -176145,7 +177080,7 @@ var Cutout = class extends PrimitiveComponent2 {
176145
177080
  inserted_pcb_cutout = db.pcb_cutout.insert(circleData);
176146
177081
  } else if (props.shape === "polygon") {
176147
177082
  const transform2 = this._computePcbGlobalTransformBeforeLayout();
176148
- const transformedPoints = props.points.map((p) => applyToPoint8(transform2, p));
177083
+ const transformedPoints = props.points.map((p) => applyToPoint14(transform2, p));
176149
177084
  const polygonData = {
176150
177085
  shape: "polygon",
176151
177086
  points: transformedPoints,
@@ -176616,8 +177551,8 @@ var Port = class extends PrimitiveComponent2 {
176616
177551
  throw new Error(`Couldn't find schematicSymbolPortDef for port ${this.getString()}, searched internally connected ports and none had a schematicSymbolPortDef. Why are we trying to get the schematic position of this port?`);
176617
177552
  }
176618
177553
  }
176619
- const transform2 = compose3(this.parent.computeSchematicGlobalTransform(), translate3(-symbol.center.x, -symbol.center.y));
176620
- return applyToPoint8(transform2, schematicSymbolPortDef);
177554
+ const transform2 = compose4(this.parent.computeSchematicGlobalTransform(), translate4(-symbol.center.x, -symbol.center.y));
177555
+ return applyToPoint14(transform2, schematicSymbolPortDef);
176621
177556
  }
176622
177557
  const parentBoxDim = this?.parent?._getSchematicBoxDimensions();
176623
177558
  if (parentBoxDim && this.props.pinNumber !== undefined) {
@@ -176625,7 +177560,7 @@ var Port = class extends PrimitiveComponent2 {
176625
177560
  if (!localPortPosition) {
176626
177561
  throw new Error(`Couldn't find position for schematic_port for port ${this.getString()} inside of the schematic box`);
176627
177562
  }
176628
- return applyToPoint8(this.parent.computeSchematicGlobalTransform(), localPortPosition);
177563
+ return applyToPoint14(this.parent.computeSchematicGlobalTransform(), localPortPosition);
176629
177564
  }
176630
177565
  throw new Error(`Couldn't find position for schematic_port for port ${this.getString()}`);
176631
177566
  }
@@ -180192,7 +181127,7 @@ var TraceHint = class extends PrimitiveComponent2 {
180192
181127
  return [];
180193
181128
  const globalTransform = this._computePcbGlobalTransformBeforeLayout();
180194
181129
  return offsets.map((offset) => ({
180195
- ...applyToPoint8(globalTransform, offset),
181130
+ ...applyToPoint14(globalTransform, offset),
180196
181131
  via: offset.via,
180197
181132
  to_layer: offset.to_layer,
180198
181133
  trace_width: offset.trace_width
@@ -180913,7 +181848,7 @@ function Group_doInitialPcbLayoutGrid(group) {
180913
181848
  const newCenter = { x: targetCellCenterX, y: targetCellCenterY };
180914
181849
  const deltaX = newCenter.x - oldCenter.x;
180915
181850
  const deltaY = newCenter.y - oldCenter.y;
180916
- const mat = translate3(deltaX, deltaY);
181851
+ const mat = translate4(deltaX, deltaY);
180917
181852
  const related = db.toArray().filter((e3) => e3.pcb_component_id === child.pcb_component_id);
180918
181853
  const moved = transformPCBElements(related, mat);
180919
181854
  for (const elm of moved) {
@@ -181008,7 +181943,7 @@ var Group_doInitialPcbLayoutPack = (group) => {
181008
181943
  const pcbComponent = db.pcb_component.get(componentId);
181009
181944
  if (pcbComponent) {
181010
181945
  const originalCenter2 = pcbComponent.center;
181011
- const transformMatrix2 = compose3(group._computePcbGlobalTransformBeforeLayout(), translate3(center2.x, center2.y), rotate(ccwRotationOffset || 0), translate3(-originalCenter2.x, -originalCenter2.y));
181946
+ const transformMatrix2 = compose4(group._computePcbGlobalTransformBeforeLayout(), translate4(center2.x, center2.y), rotate5(ccwRotationOffset || 0), translate4(-originalCenter2.x, -originalCenter2.y));
181012
181947
  const related = db.toArray().filter((elm) => ("pcb_component_id" in elm) && elm.pcb_component_id === componentId);
181013
181948
  transformPCBElements(related, transformMatrix2);
181014
181949
  continue;
@@ -181017,7 +181952,7 @@ var Group_doInitialPcbLayoutPack = (group) => {
181017
181952
  if (!pcbGroup)
181018
181953
  continue;
181019
181954
  const originalCenter = pcbGroup.center;
181020
- const transformMatrix = compose3(group._computePcbGlobalTransformBeforeLayout(), translate3(center2.x, center2.y), rotate(ccwRotationOffset || 0), translate3(-originalCenter.x, -originalCenter.y));
181955
+ const transformMatrix = compose4(group._computePcbGlobalTransformBeforeLayout(), translate4(center2.x, center2.y), rotate5(ccwRotationOffset || 0), translate4(-originalCenter.x, -originalCenter.y));
181021
181956
  const subtree = buildSubtree(db.toArray(), { source_group_id: componentId });
181022
181957
  transformPCBElements(subtree, transformMatrix);
181023
181958
  db.pcb_group.update(pcbGroup.pcb_group_id, { center: center2 });
@@ -181918,7 +182853,7 @@ var Board = class extends Group {
181918
182853
  this.pcb_board_id = null;
181919
182854
  }
181920
182855
  _computePcbGlobalTransformBeforeLayout() {
181921
- return identity();
182856
+ return identity4();
181922
182857
  }
181923
182858
  doInitialPcbDesignRuleChecks() {
181924
182859
  if (this.root?.pcbDisabled)
@@ -182599,7 +183534,7 @@ var FabricationNotePath = class extends PrimitiveComponent2 {
182599
183534
  layer,
182600
183535
  color: props.color,
182601
183536
  route: props.route.map((p) => {
182602
- const transformedPosition = applyToPoint8(transform2, {
183537
+ const transformedPosition = applyToPoint14(transform2, {
182603
183538
  x: p.x,
182604
183539
  y: p.y
182605
183540
  });
@@ -182817,8 +183752,8 @@ var NetLabel = class extends PrimitiveComponent2 {
182817
183752
  const connectedPorts = this._getConnectedPorts();
182818
183753
  if (connectedPorts.length > 0) {
182819
183754
  const portPos = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
182820
- const parentCenter = applyToPoint8(this.parent?.computeSchematicGlobalTransform?.() ?? identity(), { x: 0, y: 0 });
182821
- return translate3(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
183755
+ const parentCenter = applyToPoint14(this.parent?.computeSchematicGlobalTransform?.() ?? identity4(), { x: 0, y: 0 });
183756
+ return translate4(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
182822
183757
  }
182823
183758
  }
182824
183759
  return super.computeSchematicPropsTransform();
@@ -184348,25 +185283,25 @@ var convertEasyEdaJsonToCircuitJson = (easyEdaJson, { useModelCdn, shouldRecente
184348
185283
  const elementsForBounds = circuitElements.filter((e3) => e3.type !== "pcb_component" && e3.type !== "cad_component");
184349
185284
  const bounds = findBoundsAndCenter(elementsForBounds);
184350
185285
  if (Number.isFinite(bounds.center.x) && Number.isFinite(bounds.center.y)) {
184351
- const matrix2 = compose3(translate3(-bounds.center.x, bounds.center.y), scale8(1, -1));
185286
+ const matrix2 = compose4(translate4(-bounds.center.x, bounds.center.y), scale8(1, -1));
184352
185287
  const elementsForTransform = circuitElements.filter((e3) => !(e3.type === "pcb_smtpad" && e3.shape === "polygon") && e3.type !== "cad_component");
184353
185288
  transformPCBElements(elementsForTransform, matrix2);
184354
185289
  for (const e3 of circuitElements) {
184355
185290
  if (e3.type === "pcb_cutout") {
184356
185291
  if (e3.shape === "polygon") {
184357
- e3.points = e3.points.map((p) => applyToPoint8(matrix2, p));
185292
+ e3.points = e3.points.map((p) => applyToPoint14(matrix2, p));
184358
185293
  } else {
184359
- e3.center = applyToPoint8(matrix2, e3.center);
185294
+ e3.center = applyToPoint14(matrix2, e3.center);
184360
185295
  }
184361
185296
  } else if (e3.type === "pcb_smtpad" && e3.shape === "polygon") {
184362
- e3.points = e3.points.map((p) => applyToPoint8(matrix2, p));
185297
+ e3.points = e3.points.map((p) => applyToPoint14(matrix2, p));
184363
185298
  }
184364
185299
  }
184365
185300
  const cad = circuitElements.find((e3) => e3.type === "cad_component");
184366
185301
  if (cad) {
184367
185302
  if (!cad.rotation)
184368
185303
  cad.rotation = { x: 0, y: 0, z: 0 };
184369
- const p = applyToPoint8(matrix2, { x: cad.position.x, y: cad.position.y });
185304
+ const p = applyToPoint14(matrix2, { x: cad.position.x, y: cad.position.y });
184370
185305
  cad.position.x = p.x;
184371
185306
  cad.position.y = p.y;
184372
185307
  const side = pcb_component2.layer ?? "top";