@tscircuit/cli 0.1.2126 → 0.1.2127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/main.js CHANGED
@@ -154317,7 +154317,7 @@ var package_default = {
154317
154317
  "@tscircuit/check-shorts": "https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.24.tgz",
154318
154318
  "@tscircuit/circuit-json-placement-analysis": "^0.0.15",
154319
154319
  "@tscircuit/circuit-json-routing-analysis": "^0.0.8",
154320
- "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#41260fc05b736c0f3fdc33892b6da0ece40107b9",
154320
+ "@tscircuit/circuit-json-schematic-placement-analysis": "https://jscdn.tscircuit.com/@tscircuit/circuit-json-schematic-placement-analysis/0.0.11.tgz",
154321
154321
  "@tscircuit/circuit-json-util": "^0.0.113",
154322
154322
  "@tscircuit/eval": "0.0.1402",
154323
154323
  "@tscircuit/fake-snippets": "^0.0.182",
@@ -331022,8 +331022,129 @@ function segmentCrossesBox(a, b, box) {
331022
331022
  return Math.max(a.x, b.x) > bounds.left && Math.min(a.x, b.x) < bounds.right && Math.max(a.y, b.y) > bounds.bottom && Math.min(a.y, b.y) < bounds.top;
331023
331023
  }
331024
331024
 
331025
- // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/CapacitorOrientationSolver/CapacitorOrientationSolver.ts
331025
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/LowSideTransistorPlacementSolver/LowSideTransistorPlacementSolver.ts
331026
331026
  import { BaseSolver as BaseSolver6 } from "@tscircuit/solver-utils";
331027
+ class LowSideTransistorPlacementSolver extends BaseSolver6 {
331028
+ index;
331029
+ positiveNets = new Set;
331030
+ transistorIds;
331031
+ issues;
331032
+ currentIndex = 0;
331033
+ constructor({
331034
+ ctx,
331035
+ issues
331036
+ }) {
331037
+ super();
331038
+ this.issues = issues;
331039
+ this.index = new PlacementNetworkIndex(ctx);
331040
+ for (const element of ctx.circuitJson) {
331041
+ if (element.type === "source_net" && element.is_positive_voltage_source)
331042
+ this.positiveNets.add(this.index.connected(element.source_net_id));
331043
+ }
331044
+ this.transistorIds = [...this.index.components.values()].filter((component) => component.ftype === "simple_transistor" && component.transistor_type === "npn").map((component) => component.source_component_id);
331045
+ this.solved = this.transistorIds.length === 0;
331046
+ }
331047
+ _step() {
331048
+ const id = this.transistorIds[this.currentIndex++];
331049
+ this.solved = this.currentIndex >= this.transistorIds.length;
331050
+ if (!id)
331051
+ return;
331052
+ const index = this.index;
331053
+ const transistor = index.placement(id);
331054
+ if (!transistor || index.portsByComponent.get(id)?.length !== 3)
331055
+ return;
331056
+ const base = index.namedPort(id, "base");
331057
+ const collector = index.namedPort(id, "collector");
331058
+ const emitter = index.namedPort(id, "emitter");
331059
+ if (!base || !collector || !emitter)
331060
+ return;
331061
+ const baseNet = index.connected(base.source_port_id);
331062
+ const collectorNet = index.connected(collector.source_port_id);
331063
+ const emitterNet = index.connected(emitter.source_port_id);
331064
+ if (new Set([baseNet, collectorNet, emitterNet]).size !== 3 || !index.groundNets.has(emitterNet) || index.powerNets.has(emitterNet) || index.isRail(baseNet) || index.isRail(collectorNet))
331065
+ return;
331066
+ const basePeers = (index.portsByNet.get(baseNet) ?? []).filter((port) => port.source_component_id !== id);
331067
+ if (basePeers.length !== 1)
331068
+ return;
331069
+ const resistorId = basePeers[0].source_component_id;
331070
+ const resistor = index.components.get(resistorId);
331071
+ const baseResistor = index.placement(resistorId);
331072
+ const resistorNets = index.twoTerminalNets(resistorId);
331073
+ const inputNet = resistorNets?.find((net) => net !== baseNet);
331074
+ if (resistor?.ftype !== "simple_resistor" || resistor.resistance <= 0 || !baseResistor || !index.sameLocalScope(transistor, baseResistor) || !inputNet || index.isRail(inputNet) || inputNet === collectorNet)
331075
+ return;
331076
+ const collectorPeers = (index.portsByNet.get(collectorNet) ?? []).filter((port) => port.source_component_id !== id);
331077
+ const loadPeers = collectorPeers.filter((port) => {
331078
+ const type = index.components.get(port.source_component_id)?.ftype;
331079
+ return type === "simple_chip";
331080
+ });
331081
+ if (loadPeers.length !== 1)
331082
+ return;
331083
+ const loadId = loadPeers[0].source_component_id;
331084
+ const load2 = index.placement(loadId);
331085
+ const loadNets = index.twoTerminalNets(loadId);
331086
+ const supplyNet = loadNets?.find((net) => net !== collectorNet);
331087
+ if (!load2 || !index.sameLocalScope(transistor, load2) || !supplyNet || !this.positiveNets.has(supplyNet) || index.groundNets.has(supplyNet))
331088
+ return;
331089
+ const clampPeers = collectorPeers.filter((port) => port.source_component_id !== loadId);
331090
+ if (clampPeers.length !== 1)
331091
+ return;
331092
+ const clampId = clampPeers[0].source_component_id;
331093
+ const clamp = index.placement(clampId);
331094
+ const anode = index.namedPort(clampId, "anode");
331095
+ const cathode = index.namedPort(clampId, "cathode");
331096
+ if (index.components.get(clampId)?.ftype !== "simple_diode" || !index.twoTerminalNets(clampId) || !anode || !cathode || index.connected(anode.source_port_id) !== collectorNet || index.connected(cathode.source_port_id) !== supplyNet || !clamp || !index.sameLocalScope(transistor, clamp))
331097
+ return;
331098
+ const collectorPin = index.port(collector);
331099
+ const emitterPin = index.port(emitter);
331100
+ const basePin = index.port(base);
331101
+ if (!collectorPin || !emitterPin || !basePin)
331102
+ return;
331103
+ const collectorFacingDirection = collectorPin.facing_direction;
331104
+ const emitterFacingDirection = emitterPin.facing_direction;
331105
+ if (!collectorFacingDirection || !emitterFacingDirection)
331106
+ return;
331107
+ const placementProblems = [];
331108
+ if (transistor.schY >= load2.schY)
331109
+ placementProblems.push("transistor_not_below_load");
331110
+ if (collectorFacingDirection !== "up")
331111
+ placementProblems.push("collector_not_up");
331112
+ if (emitterFacingDirection !== "down")
331113
+ placementProblems.push("emitter_not_down");
331114
+ if (placementProblems.length === 0)
331115
+ return;
331116
+ const name = transistor.sourceComponentName ?? id;
331117
+ const loadName = load2.sourceComponentName ?? loadId;
331118
+ this.issues.push({
331119
+ lineItemType: "LowSideTransistorNotAlignedWithLoad",
331120
+ transistorSchematicBox: transistor,
331121
+ loadSchematicBox: load2,
331122
+ baseResistorSchematicBox: baseResistor,
331123
+ clampDiodeSchematicBox: clamp,
331124
+ collectorSourcePortId: collector.source_port_id,
331125
+ emitterSourcePortId: emitter.source_port_id,
331126
+ collectorFacingDirection,
331127
+ emitterFacingDirection,
331128
+ placementProblems,
331129
+ message: `Arrange ${name} below ${loadName}, with its collector facing up toward the load and emitter facing down toward ground; place ${baseResistor.sourceComponentName ?? resistorId} beside the base. Preserve all pin connections and reroute affected traces.`
331130
+ });
331131
+ }
331132
+ static issueToString(issue) {
331133
+ const attrs = [];
331134
+ addAttr(attrs, "transistorName", issue.transistorSchematicBox.sourceComponentName);
331135
+ addAttr(attrs, "loadName", issue.loadSchematicBox.sourceComponentName);
331136
+ addAttr(attrs, "baseResistorName", issue.baseResistorSchematicBox.sourceComponentName);
331137
+ addAttr(attrs, "clampDiodeName", issue.clampDiodeSchematicBox.sourceComponentName);
331138
+ addAttr(attrs, "placementProblems", issue.placementProblems.join(","));
331139
+ addAttr(attrs, "collectorFacingDirection", issue.collectorFacingDirection);
331140
+ addAttr(attrs, "emitterFacingDirection", issue.emitterFacingDirection);
331141
+ addAttr(attrs, "message", issue.message);
331142
+ return `<LowSideTransistorNotAlignedWithLoad ${attrs.join(" ")} />`;
331143
+ }
331144
+ }
331145
+
331146
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/CapacitorOrientationSolver/CapacitorOrientationSolver.ts
331147
+ import { BaseSolver as BaseSolver7 } from "@tscircuit/solver-utils";
331027
331148
 
331028
331149
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/graphics.ts
331029
331150
  import { mergeGraphics as mergeGraphics2 } from "graphics-debug";
@@ -331058,7 +331179,8 @@ function visualizeCircuitJson(circuitJson) {
331058
331179
  }
331059
331180
 
331060
331181
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/CapacitorOrientationSolver/CapacitorOrientationSolver.ts
331061
- class CapacitorOrientationSolver extends BaseSolver6 {
331182
+ class CapacitorOrientationSolver extends BaseSolver7 {
331183
+ static EPSILON = 0.01;
331062
331184
  static ORIENTATION_MESSAGE = 'Use schOrientation="vertical" on this capacitor to fix the symbol orientation';
331063
331185
  ctx;
331064
331186
  out;
@@ -331163,12 +331285,32 @@ class CapacitorOrientationSolver extends BaseSolver6 {
331163
331285
  return;
331164
331286
  if (this.feedbackCapacitorIds.has(placement.sourceComponentId))
331165
331287
  return;
331288
+ if (this.isInlineWithHorizontalTraces(placement.schematicComponentId))
331289
+ return;
331166
331290
  return {
331167
331291
  lineItemType: "CapacitorSymbolHorizontal",
331168
331292
  schematicBox: this.createIssuePlacement(placement),
331169
331293
  message: CapacitorOrientationSolver.ORIENTATION_MESSAGE
331170
331294
  };
331171
331295
  }
331296
+ isInlineWithHorizontalTraces(schematicComponentId) {
331297
+ const ports = this.ctx.circuitJson.filter((element) => element.type === "schematic_port" && element.schematic_component_id === schematicComponentId);
331298
+ if (ports.length !== 2)
331299
+ return false;
331300
+ const traces = ports.map((port) => this.getOutwardHorizontalTrace(port));
331301
+ return traces.every((trace) => trace !== undefined) && traces.some((trace) => trace !== undefined && trace.edges.every((edge) => Math.abs(edge.from.y - edge.to.y) <= CapacitorOrientationSolver.EPSILON));
331302
+ }
331303
+ getOutwardHorizontalTrace(port) {
331304
+ if (port.facing_direction !== "left" && port.facing_direction !== "right")
331305
+ return;
331306
+ return this.ctx.circuitJson.find((element) => element.type === "schematic_trace" && element.schematic_sheet_id === port.schematic_sheet_id && element.edges.some((edge) => {
331307
+ const other = this.pointsEqual(edge.from, port.center) ? edge.to : this.pointsEqual(edge.to, port.center) ? edge.from : undefined;
331308
+ return other !== undefined && Math.abs(other.y - port.center.y) <= CapacitorOrientationSolver.EPSILON && (port.facing_direction === "left" ? other.x < port.center.x - CapacitorOrientationSolver.EPSILON : other.x > port.center.x + CapacitorOrientationSolver.EPSILON);
331309
+ }));
331310
+ }
331311
+ pointsEqual(first, second) {
331312
+ return Math.abs(first.x - second.x) <= CapacitorOrientationSolver.EPSILON && Math.abs(first.y - second.y) <= CapacitorOrientationSolver.EPSILON;
331313
+ }
331172
331314
  static issueToString(issue) {
331173
331315
  const attrs = [];
331174
331316
  addAttr(attrs, "componentName", issue.schematicBox.sourceComponentName);
@@ -331182,8 +331324,8 @@ class CapacitorOrientationSolver extends BaseSolver6 {
331182
331324
  }
331183
331325
 
331184
331326
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/DecouplingCapacitorGroupingSolver/DecouplingCapacitorGroupingSolver.ts
331185
- import { BaseSolver as BaseSolver7 } from "@tscircuit/solver-utils";
331186
- class DecouplingCapacitorGroupingSolver extends BaseSolver7 {
331327
+ import { BaseSolver as BaseSolver8 } from "@tscircuit/solver-utils";
331328
+ class DecouplingCapacitorGroupingSolver extends BaseSolver8 {
331187
331329
  params;
331188
331330
  static MIN_BODY_GAP = 4;
331189
331331
  banks = [];
@@ -331279,13 +331421,45 @@ class DecouplingCapacitorGroupingSolver extends BaseSolver7 {
331279
331421
  }
331280
331422
  }
331281
331423
 
331424
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/net-label-bounds.ts
331425
+ function getNetLabelBounds(label) {
331426
+ const anchorSide = label.anchor_side;
331427
+ const isVertical = anchorSide === "top" || anchorSide === "bottom";
331428
+ if (isVertical) {
331429
+ const anchorY = label.anchor_position?.y ?? label.center.y;
331430
+ const textHalfExtent = (label.text?.length ?? 8) * 0.13 / 2 + 0.1;
331431
+ const left = label.center.x - 0.1;
331432
+ const right = label.center.x + 0.1;
331433
+ if (anchorSide === "top") {
331434
+ return {
331435
+ left,
331436
+ right,
331437
+ top: anchorY,
331438
+ bottom: anchorY - textHalfExtent * 2
331439
+ };
331440
+ }
331441
+ return { left, right, top: anchorY + textHalfExtent * 2, bottom: anchorY };
331442
+ }
331443
+ const anchorX = label.anchor_position?.x ?? label.center.x;
331444
+ const halfWidth = Math.abs(label.center.x - anchorX);
331445
+ const farHalfWidth = halfWidth + 0.1;
331446
+ const top = label.center.y + 0.1;
331447
+ const bottom = label.center.y - 0.1;
331448
+ if (label.center.x >= anchorX) {
331449
+ return {
331450
+ left: anchorX,
331451
+ right: label.center.x + farHalfWidth,
331452
+ top,
331453
+ bottom
331454
+ };
331455
+ }
331456
+ return { left: label.center.x - farHalfWidth, right: anchorX, top, bottom };
331457
+ }
331458
+
331282
331459
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ComponentNetLabelCollisionSolver/ComponentNetLabelCollisionSolver.ts
331283
- import { BaseSolver as BaseSolver8 } from "@tscircuit/solver-utils";
331284
- class ComponentNetLabelCollisionSolver extends BaseSolver8 {
331460
+ import { BaseSolver as BaseSolver9 } from "@tscircuit/solver-utils";
331461
+ class ComponentNetLabelCollisionSolver extends BaseSolver9 {
331285
331462
  params;
331286
- LABEL_HALF_HEIGHT = 0.1;
331287
- LABEL_BOUNDS_SLACK = 0.1;
331288
- SCH_CHAR_WIDTH = 0.13;
331289
331463
  placements;
331290
331464
  netLabelsByComponentId;
331291
331465
  rawCollisions = [];
@@ -331338,8 +331512,8 @@ class ComponentNetLabelCollisionSolver extends BaseSolver8 {
331338
331512
  const hits = [];
331339
331513
  for (const leftLabel of leftLabels) {
331340
331514
  for (const rightLabel of rightLabels) {
331341
- const leftBounds = this.getNetLabelBounds(leftLabel);
331342
- const rightBounds = this.getNetLabelBounds(rightLabel);
331515
+ const leftBounds = getNetLabelBounds(leftLabel);
331516
+ const rightBounds = getNetLabelBounds(rightLabel);
331343
331517
  if (rectOverlap(leftBounds, rightBounds)) {
331344
331518
  hits.push({
331345
331519
  type: "label-label",
@@ -331372,7 +331546,7 @@ class ComponentNetLabelCollisionSolver extends BaseSolver8 {
331372
331546
  const boxIsLeft = boxComp.schX <= labelComp.schX;
331373
331547
  const hits = [];
331374
331548
  for (const label of labels) {
331375
- const labelBounds = this.getNetLabelBounds(label);
331549
+ const labelBounds = getNetLabelBounds(label);
331376
331550
  if (!rectOverlap(boxBounds, labelBounds))
331377
331551
  continue;
331378
331552
  let xSeparation;
@@ -331593,39 +331767,6 @@ class ComponentNetLabelCollisionSolver extends BaseSolver8 {
331593
331767
  }
331594
331768
  return result;
331595
331769
  }
331596
- getNetLabelBounds(label) {
331597
- const anchorSide = label.anchor_side;
331598
- const isVertical = anchorSide === "top" || anchorSide === "bottom";
331599
- if (isVertical) {
331600
- const anchorY = label.anchor_position?.y ?? label.center.y;
331601
- const textHalfExtent = (label.text?.length ?? 8) * this.SCH_CHAR_WIDTH / 2 + this.LABEL_BOUNDS_SLACK;
331602
- const left = label.center.x - this.LABEL_HALF_HEIGHT;
331603
- const right = label.center.x + this.LABEL_HALF_HEIGHT;
331604
- if (anchorSide === "top") {
331605
- return {
331606
- left,
331607
- right,
331608
- top: anchorY,
331609
- bottom: anchorY - textHalfExtent * 2
331610
- };
331611
- }
331612
- return { left, right, top: anchorY + textHalfExtent * 2, bottom: anchorY };
331613
- }
331614
- const anchorX = label.anchor_position?.x ?? label.center.x;
331615
- const halfWidth = Math.abs(label.center.x - anchorX);
331616
- const farHalfWidth = halfWidth + this.LABEL_BOUNDS_SLACK;
331617
- const top = label.center.y + this.LABEL_HALF_HEIGHT;
331618
- const bottom = label.center.y - this.LABEL_HALF_HEIGHT;
331619
- if (label.center.x >= anchorX) {
331620
- return {
331621
- left: anchorX,
331622
- right: label.center.x + farHalfWidth,
331623
- top,
331624
- bottom
331625
- };
331626
- }
331627
- return { left: label.center.x - farHalfWidth, right: anchorX, top, bottom };
331628
- }
331629
331770
  static netLabelCollisionToString(issue) {
331630
331771
  const pairAttrs = issue.pairs.map((pair, i) => `pair${i + 1}="${pair.comp1Name}/${pair.comp2Name}"`).join(" ");
331631
331772
  const moves = issue.moves.map((move) => ` <Move componentName="${move.componentName}" newSchX="${move.newSchX}" newSchY="${move.newSchY}" />`);
@@ -331641,8 +331782,8 @@ class ComponentNetLabelCollisionSolver extends BaseSolver8 {
331641
331782
  }
331642
331783
 
331643
331784
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ComponentPinAlignmentSolver/ComponentPinAlignmentSolver.ts
331644
- import { BaseSolver as BaseSolver9 } from "@tscircuit/solver-utils";
331645
- class ComponentPinAlignmentSolver extends BaseSolver9 {
331785
+ import { BaseSolver as BaseSolver10 } from "@tscircuit/solver-utils";
331786
+ class ComponentPinAlignmentSolver extends BaseSolver10 {
331646
331787
  static ALIGNMENT_EPSILON = 0.01;
331647
331788
  ctx;
331648
331789
  out;
@@ -331776,8 +331917,8 @@ class ComponentPinAlignmentSolver extends BaseSolver9 {
331776
331917
  }
331777
331918
 
331778
331919
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/CrystalLoadCapacitorPlacementSolver/CrystalLoadCapacitorPlacementSolver.ts
331779
- import { BaseSolver as BaseSolver10 } from "@tscircuit/solver-utils";
331780
- class CrystalLoadCapacitorPlacementSolver extends BaseSolver10 {
331920
+ import { BaseSolver as BaseSolver11 } from "@tscircuit/solver-utils";
331921
+ class CrystalLoadCapacitorPlacementSolver extends BaseSolver11 {
331781
331922
  static ALIGNMENT_TOLERANCE = 0.1;
331782
331923
  issues;
331783
331924
  networks;
@@ -331937,13 +332078,15 @@ var distance50 = (first, second) => Math.hypot(first.schX - second.schX, first.s
331937
332078
  var round2 = (value) => Math.round(value * 100) / 100;
331938
332079
 
331939
332080
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/DiodeResistorAlignmentSolver/DiodeResistorAlignmentSolver.ts
331940
- import { BaseSolver as BaseSolver11 } from "@tscircuit/solver-utils";
331941
- class DiodeResistorAlignmentSolver extends BaseSolver11 {
332081
+ import { BaseSolver as BaseSolver12 } from "@tscircuit/solver-utils";
332082
+ import { getSourcePortConnectivityMapFromCircuitJson as getSourcePortConnectivityMapFromCircuitJson2 } from "circuit-json-to-connectivity-map";
332083
+ class DiodeResistorAlignmentSolver extends BaseSolver12 {
331942
332084
  static DIODE_FTYPES = new Set(["simple_led", "simple_diode"]);
331943
332085
  ctx;
331944
332086
  out;
331945
332087
  schematicTraces;
331946
332088
  currentIndex = 0;
332089
+ sourceConnectivity;
331947
332090
  sourceComponentFtypeById;
331948
332091
  sourceComponentIdBySourcePortId;
331949
332092
  schematicPorts;
@@ -331956,6 +332099,7 @@ class DiodeResistorAlignmentSolver extends BaseSolver11 {
331956
332099
  this.ctx = ctx;
331957
332100
  this.out = issues;
331958
332101
  const { circuitJson } = ctx;
332102
+ this.sourceConnectivity = getSourcePortConnectivityMapFromCircuitJson2(circuitJson);
331959
332103
  this.sourceComponentFtypeById = this.buildSourceComponentFtypeById(circuitJson);
331960
332104
  this.sourceComponentIdBySourcePortId = this.buildSourceComponentIdBySourcePortId(circuitJson);
331961
332105
  this.schematicPorts = circuitJson.filter((el) => el.type === "schematic_port");
@@ -332000,6 +332144,8 @@ class DiodeResistorAlignmentSolver extends BaseSolver11 {
332000
332144
  const resistorPort = this.findNearestPort(startFtype === "simple_resistor" ? start : end, schematicSheetId);
332001
332145
  if (!diodePort?.center || !resistorPort?.center)
332002
332146
  return;
332147
+ if (!this.sourceConnectivity.areIdsConnected(diodePort.source_port_id, resistorPort.source_port_id))
332148
+ return;
332003
332149
  const diodeName = diodeBox.sourceComponentName ?? diodeCompId;
332004
332150
  const resistorName = resistorBox.sourceComponentName ?? resistorCompId;
332005
332151
  const diodePin = diodePort?.display_pin_label ?? diodePort?.pin_number?.toString();
@@ -332100,8 +332246,8 @@ class DiodeResistorAlignmentSolver extends BaseSolver11 {
332100
332246
  }
332101
332247
 
332102
332248
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/FeedbackNetworkPlacementSolver/FeedbackNetworkPlacementSolver.ts
332103
- import { BaseSolver as BaseSolver12 } from "@tscircuit/solver-utils";
332104
- class FeedbackNetworkPlacementSolver extends BaseSolver12 {
332249
+ import { BaseSolver as BaseSolver13 } from "@tscircuit/solver-utils";
332250
+ class FeedbackNetworkPlacementSolver extends BaseSolver13 {
332105
332251
  static MIN_BODY_GAP = 4;
332106
332252
  index;
332107
332253
  amplifierIds;
@@ -332186,8 +332332,8 @@ function distanceBetweenBoxes(a, b) {
332186
332332
  }
332187
332333
 
332188
332334
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/PullResistorPlacementSolver/PullResistorPlacementSolver.ts
332189
- import { BaseSolver as BaseSolver13 } from "@tscircuit/solver-utils";
332190
- class PullResistorPlacementSolver extends BaseSolver13 {
332335
+ import { BaseSolver as BaseSolver14 } from "@tscircuit/solver-utils";
332336
+ class PullResistorPlacementSolver extends BaseSolver14 {
332191
332337
  static MIN_WRONG_SIDE_GAP = 1.5;
332192
332338
  index;
332193
332339
  resistorIds;
@@ -332283,12 +332429,13 @@ class PullResistorPlacementSolver extends BaseSolver13 {
332283
332429
  }
332284
332430
 
332285
332431
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentRailOrientationSolver/TwoPinComponentRailOrientationSolver.ts
332286
- import { BaseSolver as BaseSolver14 } from "@tscircuit/solver-utils";
332287
- class TwoPinComponentRailOrientationSolver extends BaseSolver14 {
332432
+ import { BaseSolver as BaseSolver15 } from "@tscircuit/solver-utils";
332433
+ class TwoPinComponentRailOrientationSolver extends BaseSolver15 {
332288
332434
  static EPSILON = 0.01;
332289
332435
  index;
332290
332436
  powerNets;
332291
332437
  groundNets;
332438
+ positiveVoltageNets = new Set;
332292
332439
  componentIds;
332293
332440
  issues;
332294
332441
  currentIndex = 0;
@@ -332302,6 +332449,8 @@ class TwoPinComponentRailOrientationSolver extends BaseSolver14 {
332302
332449
  this.powerNets = new Set(this.index.powerNets);
332303
332450
  this.groundNets = new Set(this.index.groundNets);
332304
332451
  for (const element of ctx.circuitJson) {
332452
+ if (element.type === "source_net" && element.is_positive_voltage_source)
332453
+ this.positiveVoltageNets.add(this.index.connected(element.source_net_id));
332305
332454
  if (element.type !== "source_port")
332306
332455
  continue;
332307
332456
  const net = this.index.connected(element.source_port_id);
@@ -332323,6 +332472,8 @@ class TwoPinComponentRailOrientationSolver extends BaseSolver14 {
332323
332472
  const nets = index.twoTerminalNets(id);
332324
332473
  if (!component || !nets)
332325
332474
  return;
332475
+ if (index.components.get(id)?.ftype === "simple_inductor" && !nets.some((net) => this.groundNets.has(net)))
332476
+ return;
332326
332477
  if (nets.some((net) => this.powerNets.has(net) && this.groundNets.has(net)))
332327
332478
  return;
332328
332479
  const railTypes = nets.map((net) => this.powerNets.has(net) ? "power" : this.groundNets.has(net) ? "ground" : undefined);
@@ -332339,6 +332490,20 @@ class TwoPinComponentRailOrientationSolver extends BaseSolver14 {
332339
332490
  const otherPort = index.port(otherSourcePort);
332340
332491
  if (!railPort || !otherPort)
332341
332492
  return;
332493
+ const invertedRails = this.positiveVoltageNets.has(rail) && this.groundNets.has(index.connected(otherSourcePort.source_port_id)) && Math.abs(railPort.center.x - otherPort.center.x) <= TwoPinComponentRailOrientationSolver.EPSILON && railPort.center.y < otherPort.center.y - TwoPinComponentRailOrientationSolver.EPSILON && railPort.facing_direction === "down" && otherPort.facing_direction === "up";
332494
+ if (invertedRails) {
332495
+ this.issues.push({
332496
+ lineItemType: "TwoPinComponentHasInvertedRails",
332497
+ schematicBox: component,
332498
+ railSourcePortId: railSourcePort.source_port_id,
332499
+ railPinName: railSourcePort.name,
332500
+ railType: "power",
332501
+ deltaSchRotation: 180,
332502
+ suggestedRailFacingDirection: "up",
332503
+ message: `rotate ${component.sourceComponentName ?? id} by 180° so its positive-supply pin faces up and its ground pin faces down; preserve pin connections and reroute attached traces`
332504
+ });
332505
+ return;
332506
+ }
332342
332507
  const horizontal = Math.abs(railPort.center.y - otherPort.center.y) <= TwoPinComponentRailOrientationSolver.EPSILON && Math.abs(railPort.center.x - otherPort.center.x) > TwoPinComponentRailOrientationSolver.EPSILON && (railPort.facing_direction === "left" && otherPort.facing_direction === "right" || railPort.facing_direction === "right" && otherPort.facing_direction === "left");
332343
332508
  if (!horizontal)
332344
332509
  return;
@@ -332363,13 +332528,18 @@ class TwoPinComponentRailOrientationSolver extends BaseSolver14 {
332363
332528
  addAttr(attrs, "deltaSchRotation", issue.deltaSchRotation);
332364
332529
  addAttr(attrs, "suggestedRailFacingDirection", issue.suggestedRailFacingDirection);
332365
332530
  addAttr(attrs, "message", issue.message);
332366
- return `<TwoPinComponentShouldBeVertical ${attrs.join(" ")} />`;
332531
+ return `<${issue.lineItemType} ${attrs.join(" ")} />`;
332367
332532
  }
332368
332533
  }
332369
332534
 
332535
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/schematic-box-components.ts
332536
+ function getSchematicBoxComponentIds(circuitJson) {
332537
+ return new Set(circuitJson.flatMap((element) => element.type === "schematic_component" && element.is_box_with_pins !== false && !element.symbol_name && !element.schematic_symbol_id ? [element.schematic_component_id] : []));
332538
+ }
332539
+
332370
332540
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxInnerLabelCollisionSolver/SchematicBoxInnerLabelCollisionSolver.ts
332371
- import { BaseSolver as BaseSolver15 } from "@tscircuit/solver-utils";
332372
- class SchematicBoxInnerLabelCollisionSolver extends BaseSolver15 {
332541
+ import { BaseSolver as BaseSolver16 } from "@tscircuit/solver-utils";
332542
+ class SchematicBoxInnerLabelCollisionSolver extends BaseSolver16 {
332373
332543
  params;
332374
332544
  MESSAGE = "Inner labels are colliding. Increase the schWidth or schHeight.";
332375
332545
  PIN_LABEL_EDGE_PADDING = 0.1;
@@ -332388,9 +332558,8 @@ class SchematicBoxInnerLabelCollisionSolver extends BaseSolver15 {
332388
332558
  const { circuitJson, componentPlacements } = params2.ctx;
332389
332559
  this.placementById = this.getPlacementBySchematicComponentId(componentPlacements);
332390
332560
  this.sourcePortById = this.getSourcePortById(circuitJson);
332391
- this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson));
332392
- const passiveComponentIds = new Set(circuitJson.filter((el) => el.type === "schematic_component").filter((el) => el.symbol_name).map((el) => el.schematic_component_id));
332393
- this.entries = this.entries.filter(([id]) => !passiveComponentIds.has(id));
332561
+ const boxIds = getSchematicBoxComponentIds(circuitJson);
332562
+ this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson)).filter(([id]) => boxIds.has(id));
332394
332563
  this.solved = this.entries.length === 0;
332395
332564
  }
332396
332565
  _step() {
@@ -332567,8 +332736,8 @@ class SchematicBoxInnerLabelCollisionSolver extends BaseSolver15 {
332567
332736
  }
332568
332737
 
332569
332738
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxOverlapSolver/SchematicBoxOverlapSolver.ts
332570
- import { BaseSolver as BaseSolver16 } from "@tscircuit/solver-utils";
332571
- class SchematicBoxOverlapSolver extends BaseSolver16 {
332739
+ import { BaseSolver as BaseSolver17 } from "@tscircuit/solver-utils";
332740
+ class SchematicBoxOverlapSolver extends BaseSolver17 {
332572
332741
  params;
332573
332742
  placements;
332574
332743
  firstIndex = 0;
@@ -332687,8 +332856,8 @@ class SchematicBoxOverlapSolver extends BaseSolver16 {
332687
332856
  }
332688
332857
 
332689
332858
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicBoxTooWideSolver/SchematicBoxTooWideSolver.ts
332690
- import { BaseSolver as BaseSolver17 } from "@tscircuit/solver-utils";
332691
- class SchematicBoxTooWideSolver extends BaseSolver17 {
332859
+ import { BaseSolver as BaseSolver18 } from "@tscircuit/solver-utils";
332860
+ class SchematicBoxTooWideSolver extends BaseSolver18 {
332692
332861
  params;
332693
332862
  SCHEMATIC_BOX_TOO_WIDE_MESSAGE = "Shrink schematic box width";
332694
332863
  PIN_HEADER_MAX_ALLOWED_GAP = 0.1;
@@ -332709,7 +332878,8 @@ class SchematicBoxTooWideSolver extends BaseSolver17 {
332709
332878
  this.placementById = this.getPlacementBySchematicComponentId(componentPlacements);
332710
332879
  this.sourcePortById = this.getSourcePortById(circuitJson);
332711
332880
  this.sourceComponentById = this.getSourceComponentById(circuitJson);
332712
- this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson));
332881
+ const boxIds = getSchematicBoxComponentIds(circuitJson);
332882
+ this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson)).filter(([id]) => boxIds.has(id));
332713
332883
  this.solved = this.entries.length === 0;
332714
332884
  }
332715
332885
  _step() {
@@ -332723,6 +332893,9 @@ class SchematicBoxTooWideSolver extends BaseSolver17 {
332723
332893
  const schematicBox = this.placementById.get(schematicComponentId);
332724
332894
  if (!schematicBox)
332725
332895
  return;
332896
+ const sourceComponent = schematicBox.sourceComponentId ? this.sourceComponentById.get(schematicBox.sourceComponentId) : undefined;
332897
+ if (sourceComponent?.ftype === "simple_connector" && sourceComponent.standard === "usb_c")
332898
+ return;
332726
332899
  const bounds = this.getCenteredRectBounds(schematicBox);
332727
332900
  const leftCol = this.getLabelColumn("left", ports, this.sourcePortById);
332728
332901
  const rightCol = this.getLabelColumn("right", ports, this.sourcePortById);
@@ -332790,6 +332963,7 @@ class SchematicBoxTooWideSolver extends BaseSolver17 {
332790
332963
  return {
332791
332964
  type: "source_component",
332792
332965
  source_component_id: el.source_component_id,
332966
+ standard: "standard" in el && typeof el.standard === "string" ? el.standard : undefined,
332793
332967
  ftype: "ftype" in el && typeof el.ftype === "string" ? el.ftype : undefined
332794
332968
  };
332795
332969
  }
@@ -332863,8 +333037,8 @@ class SchematicBoxTooWideSolver extends BaseSolver17 {
332863
333037
  }
332864
333038
 
332865
333039
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicPinPaddingToEdgeSolver/SchematicPinPaddingToEdgeSolver.ts
332866
- import { BaseSolver as BaseSolver18 } from "@tscircuit/solver-utils";
332867
- class SchematicPinPaddingToEdgeSolver extends BaseSolver18 {
333040
+ import { BaseSolver as BaseSolver19 } from "@tscircuit/solver-utils";
333041
+ class SchematicPinPaddingToEdgeSolver extends BaseSolver19 {
332868
333042
  params;
332869
333043
  MESSAGE = "Move schematic pins closer to the box edge or change the schematic box";
332870
333044
  PIN_NAME_CHARACTER_WIDTH = 0.095;
@@ -332882,7 +333056,8 @@ class SchematicPinPaddingToEdgeSolver extends BaseSolver18 {
332882
333056
  this.placementById = this.getPlacementBySchematicComponentId(componentPlacements);
332883
333057
  this.schematicComponentById = this.getSchematicComponentById(circuitJson);
332884
333058
  this.sourcePortById = this.getSourcePortById(circuitJson);
332885
- this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson));
333059
+ const boxIds = getSchematicBoxComponentIds(circuitJson);
333060
+ this.entries = Array.from(this.getPortsBySchematicComponentId(circuitJson)).filter(([id]) => boxIds.has(id));
332886
333061
  this.solved = this.entries.length === 0;
332887
333062
  }
332888
333063
  _step() {
@@ -332909,7 +333084,10 @@ class SchematicPinPaddingToEdgeSolver extends BaseSolver18 {
332909
333084
  portsBySide.set(port.side_of_component, sidePorts);
332910
333085
  }
332911
333086
  const useLabelAwareMaxPadding = this.hasPinsOnAllSides(portsBySide);
333087
+ const candidates = [];
332912
333088
  for (const [pinSide, sidePorts] of portsBySide) {
333089
+ if (sidePorts.length === 1)
333090
+ continue;
332913
333091
  for (const edgeSide of this.getBoxEdgeSidesForPinSide(pinSide)) {
332914
333092
  const outerPin = this.getOuterPinBySide(edgeSide, sidePorts);
332915
333093
  if (!outerPin)
@@ -332918,27 +333096,65 @@ class SchematicPinPaddingToEdgeSolver extends BaseSolver18 {
332918
333096
  const maxAllowedPadding = useLabelAwareMaxPadding ? this.getMaxAllowedPinPadding(pinSpacing, edgeSide, maxLabelLengthBySide) : pinSpacing;
332919
333097
  if (!this.exceedsMaxAllowedGap(measuredPadding, maxAllowedPadding))
332920
333098
  continue;
332921
- this.params.issues.push(this.createIssue({
333099
+ candidates.push({
332922
333100
  schematicBox,
332923
333101
  pinSide,
332924
333102
  edgeSide,
332925
333103
  pinName: this.getPinName(outerPin, this.sourcePortById),
332926
333104
  measuredPadding,
332927
333105
  maxAllowedPadding
332928
- }));
333106
+ });
332929
333107
  }
332930
333108
  }
333109
+ if (!candidates.length)
333110
+ return;
333111
+ const details = candidates.map((candidate) => this.createIssue(candidate));
333112
+ const representative = details.reduce((a, b) => b.excessPadding > a.excessPadding ? b : a);
333113
+ const widths = details.flatMap((detail) => detail.suggestedSchWidth === undefined ? [] : [detail.suggestedSchWidth]);
333114
+ const heights = details.flatMap((detail) => detail.suggestedSchHeight === undefined ? [] : [detail.suggestedSchHeight]);
333115
+ const dimensions = [
333116
+ widths.length ? "width" : "",
333117
+ heights.length ? "height" : ""
333118
+ ].filter(Boolean).join(" and ");
333119
+ this.params.issues.push({
333120
+ ...representative,
333121
+ paddingDetails: details.map(({
333122
+ pinSide,
333123
+ edgeSide,
333124
+ pinName,
333125
+ measuredPadding,
333126
+ maxAllowedPadding,
333127
+ excessPadding
333128
+ }) => ({
333129
+ pinSide,
333130
+ edgeSide,
333131
+ pinName,
333132
+ measuredPadding,
333133
+ maxAllowedPadding,
333134
+ excessPadding
333135
+ })),
333136
+ suggestedSchWidth: widths.length ? Math.max(...widths) : undefined,
333137
+ suggestedSchHeight: heights.length ? Math.max(...heights) : undefined,
333138
+ message: `${this.MESSAGE} ${dimensions}`
333139
+ });
332931
333140
  }
332932
333141
  static issueToString(issue) {
332933
333142
  const attrs = [];
332934
333143
  addAttr(attrs, "message", issue.message);
332935
333144
  addAttr(attrs, "componentName", issue.schematicBox.sourceComponentName);
332936
- addAttr(attrs, "pinSide", issue.pinSide);
332937
- addAttr(attrs, "edgeSide", issue.edgeSide);
332938
- addAttr(attrs, "pinName", issue.pinName);
332939
- addAttr(attrs, "measuredPadding", issue.measuredPadding);
332940
- addAttr(attrs, "maxAllowedPadding", issue.maxAllowedPadding);
332941
- addAttr(attrs, "excessPadding", issue.excessPadding);
333145
+ if (issue.paddingDetails) {
333146
+ addAttr(attrs, "pinSides", [...new Set(issue.paddingDetails.map((detail) => detail.pinSide))].join(","));
333147
+ addAttr(attrs, "edgeSides", [
333148
+ ...new Set(issue.paddingDetails.map((detail) => detail.edgeSide))
333149
+ ].join(","));
333150
+ } else {
333151
+ addAttr(attrs, "pinSide", issue.pinSide);
333152
+ addAttr(attrs, "edgeSide", issue.edgeSide);
333153
+ addAttr(attrs, "pinName", issue.pinName);
333154
+ addAttr(attrs, "measuredPadding", issue.measuredPadding);
333155
+ addAttr(attrs, "maxAllowedPadding", issue.maxAllowedPadding);
333156
+ addAttr(attrs, "excessPadding", issue.excessPadding);
333157
+ }
332942
333158
  addAttr(attrs, "suggestedSchWidth", issue.suggestedSchWidth);
332943
333159
  addAttr(attrs, "suggestedSchHeight", issue.suggestedSchHeight);
332944
333160
  return `<SchematicPinPaddingToEdgeTooLarge ${attrs.join(" ")} />`;
@@ -333201,9 +333417,160 @@ var buildSolverContext = (circuitJson) => {
333201
333417
  return { circuitJson, componentPlacements };
333202
333418
  };
333203
333419
 
333420
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/trace-name.ts
333421
+ function getTraceName(circuitJson, trace) {
333422
+ const sourceTrace = circuitJson.find((e) => e.type === "source_trace" && e.source_trace_id === trace.source_trace_id);
333423
+ if (sourceTrace?.type === "source_trace" && sourceTrace.name)
333424
+ return sourceTrace.name;
333425
+ const first = trace.edges[0];
333426
+ const last = trace.edges.at(-1);
333427
+ const endpointName = (point, id) => {
333428
+ const ports = circuitJson.filter((e) => e.type === "schematic_port" && e.schematic_sheet_id === trace.schematic_sheet_id && (id ? e.schematic_port_id === id : Math.hypot(e.center.x - point.x, e.center.y - point.y) <= 0.01));
333429
+ if (ports.length !== 1 || ports[0]?.type !== "schematic_port")
333430
+ return;
333431
+ const port = ports[0];
333432
+ const sourcePort = circuitJson.find((e) => e.type === "source_port" && e.source_port_id === port.source_port_id);
333433
+ const component = circuitJson.find((e) => e.type === "schematic_component" && e.schematic_component_id === port.schematic_component_id);
333434
+ const sourceComponentId = sourcePort?.type === "source_port" ? sourcePort.source_component_id : component?.type === "schematic_component" ? component.source_component_id : undefined;
333435
+ const sourceComponent = circuitJson.find((e) => e.type === "source_component" && e.source_component_id === sourceComponentId);
333436
+ if (sourceComponent?.type !== "source_component" || !sourceComponent.name)
333437
+ return;
333438
+ const pin = sourcePort?.type === "source_port" && sourcePort.name ? sourcePort.name : port.pin_number !== undefined ? `pin${port.pin_number}` : port.display_pin_label;
333439
+ return pin ? `${sourceComponent.name}.${pin}` : sourceComponent.name;
333440
+ };
333441
+ const from = first && endpointName(first.from, first.from_schematic_port_id);
333442
+ const to = last && endpointName(last.to, last.to_schematic_port_id);
333443
+ if (from && to)
333444
+ return `${from} to ${to}`;
333445
+ return sourceTrace?.type === "source_trace" && sourceTrace.display_name || from || to || "trace";
333446
+ }
333447
+
333204
333448
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TraceSimplificationSolver/TraceSimplificationSolver.ts
333205
- import { BaseSolver as BaseSolver19 } from "@tscircuit/solver-utils";
333206
- class TraceSimplificationSolver extends BaseSolver19 {
333449
+ import { calculateElbow as calculateElbow3 } from "calculate-elbow/lib";
333450
+
333451
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/schematic-text-geometry.ts
333452
+ var rectPolygon = (bounds) => [
333453
+ { x: bounds.left, y: bounds.bottom },
333454
+ { x: bounds.right, y: bounds.bottom },
333455
+ { x: bounds.right, y: bounds.top },
333456
+ { x: bounds.left, y: bounds.top }
333457
+ ];
333458
+ var advance = (character) => {
333459
+ if (/\s/.test(character))
333460
+ return 0.28;
333461
+ if (/[ilI.,:;!'|]/.test(character))
333462
+ return 0.25;
333463
+ if (/[MW@%]/.test(character))
333464
+ return 0.9;
333465
+ if (/[mw]/.test(character))
333466
+ return 0.8;
333467
+ if (/[A-Z]/.test(character))
333468
+ return 0.67;
333469
+ return 0.56;
333470
+ };
333471
+ var widthInEm = (text) => Array.from(text).reduce((width, character) => width + advance(character), 0);
333472
+ function getSchematicTextPolygons(text) {
333473
+ const size = text.font_size;
333474
+ if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(text.rotation) || !Number.isFinite(text.position.x) || !Number.isFinite(text.position.y))
333475
+ return [];
333476
+ const anchor = text.anchor;
333477
+ const horizontal = anchor.includes("left") ? 0 : anchor.includes("right") ? 1 : 0.5;
333478
+ const top = anchor.includes("top") ? 0 : anchor.includes("bottom") ? size : size / 2;
333479
+ const radians = -text.rotation * Math.PI / 180;
333480
+ const cos = Math.cos(radians);
333481
+ const sin = Math.sin(radians);
333482
+ return text.text.split(`
333483
+ `).flatMap((line, index) => {
333484
+ const visible = line.trim();
333485
+ if (!visible)
333486
+ return [];
333487
+ const leading = line.length - line.trimStart().length;
333488
+ const left = (widthInEm(line.slice(0, leading)) - widthInEm(line) * horizontal) * size;
333489
+ const polygon = rectPolygon({
333490
+ left,
333491
+ right: left + widthInEm(visible) * size,
333492
+ top: top - index * size - size * 0.05,
333493
+ bottom: top - (index + 1) * size + size * 0.05
333494
+ });
333495
+ return [
333496
+ polygon.map(({ x, y }) => ({
333497
+ x: text.position.x + x * cos - y * sin,
333498
+ y: text.position.y + x * sin + y * cos
333499
+ }))
333500
+ ];
333501
+ });
333502
+ }
333503
+ function polygonsOverlap(a, b) {
333504
+ for (const polygon of [a, b]) {
333505
+ for (let i = 0;i < polygon.length; i++) {
333506
+ const p = polygon[i];
333507
+ const q = polygon[(i + 1) % polygon.length];
333508
+ const length = Math.hypot(q.x - p.x, q.y - p.y);
333509
+ if (length < 0.000000001)
333510
+ continue;
333511
+ const nx = -(q.y - p.y) / length;
333512
+ const ny = (q.x - p.x) / length;
333513
+ const project = (points) => points.map(({ x, y }) => x * nx + y * ny);
333514
+ const pa = project(a);
333515
+ const pb = project(b);
333516
+ if (Math.min(Math.max(...pa), Math.max(...pb)) - Math.max(Math.min(...pa), Math.min(...pb)) <= 0.000001)
333517
+ return false;
333518
+ }
333519
+ }
333520
+ return true;
333521
+ }
333522
+ function traceSegmentPolygon(from, to) {
333523
+ const length = Math.hypot(to.x - from.x, to.y - from.y);
333524
+ if (length < 0.000000001)
333525
+ return;
333526
+ const dx = -(to.y - from.y) / length * 0.01;
333527
+ const dy = (to.x - from.x) / length * 0.01;
333528
+ return [
333529
+ { x: from.x + dx, y: from.y + dy },
333530
+ { x: to.x + dx, y: to.y + dy },
333531
+ { x: to.x - dx, y: to.y - dy },
333532
+ { x: from.x - dx, y: from.y - dy }
333533
+ ];
333534
+ }
333535
+ function segmentCrossesPolygon(from, to, polygon) {
333536
+ if (Math.hypot(to.x - from.x, to.y - from.y) < 0.000000001)
333537
+ return false;
333538
+ let low = 0;
333539
+ let high = 1;
333540
+ for (let i = 0;i < polygon.length; i++) {
333541
+ const p = polygon[i];
333542
+ const q = polygon[(i + 1) % polygon.length];
333543
+ const length = Math.hypot(q.x - p.x, q.y - p.y);
333544
+ if (length < 0.000000001)
333545
+ continue;
333546
+ const nx = -(q.y - p.y) / length;
333547
+ const ny = (q.x - p.x) / length;
333548
+ const start = (from.x - p.x) * nx + (from.y - p.y) * ny - 0.000001;
333549
+ const end = (to.x - p.x) * nx + (to.y - p.y) * ny - 0.000001;
333550
+ if (start <= 0 && end <= 0)
333551
+ return false;
333552
+ if (start <= 0)
333553
+ low = Math.max(low, -start / (end - start));
333554
+ if (end <= 0)
333555
+ high = Math.min(high, -start / (end - start));
333556
+ if (high <= low)
333557
+ return false;
333558
+ }
333559
+ return high > low;
333560
+ }
333561
+ var polygonBounds = (polygons) => {
333562
+ const points = polygons.flat();
333563
+ return {
333564
+ left: Math.min(...points.map((p) => p.x)),
333565
+ right: Math.max(...points.map((p) => p.x)),
333566
+ top: Math.max(...points.map((p) => p.y)),
333567
+ bottom: Math.min(...points.map((p) => p.y))
333568
+ };
333569
+ };
333570
+
333571
+ // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TraceSimplificationSolver/TraceSimplificationSolver.ts
333572
+ import { BaseSolver as BaseSolver20 } from "@tscircuit/solver-utils";
333573
+ class TraceSimplificationSolver extends BaseSolver20 {
333207
333574
  static EPSILON = 0.01;
333208
333575
  ctx;
333209
333576
  out;
@@ -333245,18 +333612,40 @@ class TraceSimplificationSolver extends BaseSolver19 {
333245
333612
  placementsByComponentId
333246
333613
  })
333247
333614
  ].filter((candidate) => Boolean(candidate));
333615
+ for (const candidate of [...candidates]) {
333616
+ if (!candidate.target.sourceComponentName?.startsWith("U"))
333617
+ continue;
333618
+ for (const point of [points[0], points.at(-1)]) {
333619
+ const port = this.findPortAtPoint(ports, point, trace.schematic_sheet_id);
333620
+ const target = port?.schematic_component_id ? placementsByComponentId.get(port.schematic_component_id) : undefined;
333621
+ if (!target || !/^[CR]/.test(target.sourceComponentName ?? ""))
333622
+ continue;
333623
+ candidates.push({
333624
+ target,
333625
+ deltaSchX: -candidate.deltaSchX,
333626
+ deltaSchY: -candidate.deltaSchY,
333627
+ currentTurnCount,
333628
+ suggestedTurnCount: candidate.suggestedTurnCount
333629
+ });
333630
+ }
333631
+ }
333632
+ const priority = (candidate) => /^[CR]/.test(candidate.target.sourceComponentName ?? "") ? 0 : candidate.target.sourceComponentName?.startsWith("U") ? 2 : 1;
333633
+ candidates.sort((a, b) => priority(a) - priority(b));
333248
333634
  for (const candidate of candidates) {
333249
333635
  if (this.wouldOverlapAnotherComponent(candidate))
333250
333636
  continue;
333637
+ if (!this.validateMove(trace, candidate, ports))
333638
+ continue;
333251
333639
  const moveKey = [
333252
333640
  candidate.target.schematicComponentId,
333253
333641
  candidate.deltaSchX.toFixed(3),
333254
333642
  candidate.deltaSchY.toFixed(3)
333255
333643
  ].join("\x00");
333256
333644
  if (emittedMoves.has(moveKey))
333257
- continue;
333645
+ break;
333258
333646
  emittedMoves.add(moveKey);
333259
333647
  this.out.push(this.makeIssue(trace, candidate));
333648
+ break;
333260
333649
  }
333261
333650
  }
333262
333651
  this.solved = true;
@@ -333324,6 +333713,110 @@ class TraceSimplificationSolver extends BaseSolver19 {
333324
333713
  suggestedTurnCount
333325
333714
  };
333326
333715
  }
333716
+ validateMove(targetTrace, candidate, ports) {
333717
+ const componentId = candidate.target.schematicComponentId;
333718
+ const sheetId = candidate.target.schematicSheetId;
333719
+ const sheetPorts = ports.filter((p) => p.schematic_sheet_id === sheetId);
333720
+ const movingPorts = sheetPorts.filter((p) => p.schematic_component_id === componentId);
333721
+ const traces = this.ctx.circuitJson.filter((e) => e.type === "schematic_trace" && e.schematic_sheet_id === sheetId);
333722
+ const touchesPort = (trace, port) => trace.edges.some((edge) => edge.from_schematic_port_id === port.schematic_port_id || edge.to_schematic_port_id === port.schematic_port_id || this.pointsEqual(edge.from, port.center) || this.pointsEqual(edge.to, port.center));
333723
+ const affected = traces.filter((trace) => movingPorts.some((port) => touchesPort(trace, port)));
333724
+ if (!affected.includes(targetTrace))
333725
+ return false;
333726
+ if (this.ctx.circuitJson.some((e) => e.type === "schematic_net_label" && e.schematic_sheet_id === sheetId && movingPorts.some((p) => this.pointsEqual(e.anchor_position ?? e.center, p.center))))
333727
+ return false;
333728
+ const shift = (point) => ({
333729
+ x: point.x + candidate.deltaSchX,
333730
+ y: point.y + candidate.deltaSchY
333731
+ });
333732
+ const directions = {
333733
+ left: "x-",
333734
+ right: "x+",
333735
+ up: "y+",
333736
+ down: "y-"
333737
+ };
333738
+ const endpoint = (port, moved) => ({
333739
+ ...moved && port.schematic_component_id === componentId ? shift(port.center) : port.center,
333740
+ facingDirection: directions[port.facing_direction]
333741
+ });
333742
+ const length = (points) => points.slice(1).reduce((sum, p, i) => sum + Math.abs(p.x - points[i].x) + Math.abs(p.y - points[i].y), 0);
333743
+ const segments = (points) => points.slice(1).map((to, i) => ({ from: points[i], to }));
333744
+ const movedBounds = centeredRect(candidate.target.schX + candidate.deltaSchX, candidate.target.schY + candidate.deltaSchY, candidate.target.width, candidate.target.height);
333745
+ const unaffected = traces.filter((trace) => !affected.includes(trace));
333746
+ if (unaffected.some((trace) => trace.edges.some((edge) => segmentCrossesPolygon(edge.from, edge.to, rectPolygon(movedBounds)))))
333747
+ return false;
333748
+ const textPolygons = this.ctx.circuitJson.flatMap((e) => {
333749
+ if (e.type === "schematic_net_label" && e.schematic_sheet_id === sheetId)
333750
+ return [rectPolygon(getNetLabelBounds(e))];
333751
+ if (e.type !== "schematic_text" || e.schematic_sheet_id !== sheetId)
333752
+ return [];
333753
+ return getSchematicTextPolygons(e.schematic_component_id === componentId ? { ...e, position: shift(e.position) } : e);
333754
+ });
333755
+ if (textPolygons.some((polygon) => polygonsOverlap(polygon, rectPolygon(movedBounds))))
333756
+ return false;
333757
+ const proposed = [];
333758
+ for (const trace of affected) {
333759
+ const oldPoints = this.getTracePoints(trace);
333760
+ if (oldPoints.length < 2 || trace.junctions?.length)
333761
+ return false;
333762
+ const resolve = (point, id) => {
333763
+ const matches = sheetPorts.filter((p) => id ? p.schematic_port_id === id : this.pointsEqual(p.center, point));
333764
+ return matches.length === 1 && this.pointsEqual(matches[0].center, point) ? matches[0] : undefined;
333765
+ };
333766
+ const start = resolve(oldPoints[0], trace.edges[0].from_schematic_port_id);
333767
+ const end = resolve(oldPoints.at(-1), trace.edges.at(-1).to_schematic_port_id);
333768
+ if (!start?.facing_direction || !end?.facing_direction)
333769
+ return false;
333770
+ if (movingPorts.some((p) => touchesPort(trace, p) && p !== start && p !== end))
333771
+ return false;
333772
+ const isInteriorConnection = (point) => !this.pointsEqual(point, start.center) && !this.pointsEqual(point, end.center) && segments(oldPoints).some(({ from, to }) => Math.abs(Math.hypot(point.x - from.x, point.y - from.y) + Math.hypot(point.x - to.x, point.y - to.y) - Math.hypot(to.x - from.x, to.y - from.y)) < 0.000001);
333773
+ if (traces.some((other) => other !== trace && other.edges.some((edge) => isInteriorConnection(edge.from) || isInteriorConnection(edge.to))))
333774
+ return false;
333775
+ if (this.ctx.circuitJson.some((e) => e.type === "schematic_net_label" && e.schematic_sheet_id === sheetId && isInteriorConnection(e.anchor_position ?? e.center)))
333776
+ return false;
333777
+ const points = calculateElbow3(endpoint(start, true), endpoint(end, true)).filter((point, i, all) => i === 0 || !this.pointsEqual(point, all[i - 1]));
333778
+ const turns = this.countTurns(points);
333779
+ const oldTurns = this.countTurns(oldPoints);
333780
+ if (points.length < 2 || turns === undefined || oldTurns === undefined || turns > oldTurns || length(points) > length(oldPoints) + 0.000001)
333781
+ return false;
333782
+ if (!this.isPointInFacingDirection(points[0], points[1], start.facing_direction) || !this.isPointInFacingDirection(points.at(-1), points.at(-2), end.facing_direction))
333783
+ return false;
333784
+ if (trace === targetTrace) {
333785
+ const baselineTurns = this.countTurns(calculateElbow3(endpoint(start, false), endpoint(end, false)));
333786
+ if (turns >= oldTurns || baselineTurns === undefined || turns >= baselineTurns)
333787
+ return false;
333788
+ candidate.suggestedTurnCount = turns;
333789
+ }
333790
+ for (const segment of segments(points)) {
333791
+ if (textPolygons.some((polygon) => segmentCrossesPolygon(segment.from, segment.to, polygon)))
333792
+ return false;
333793
+ if (this.ctx.componentPlacements.some((p) => {
333794
+ if (p.schematicSheetId !== sheetId)
333795
+ return false;
333796
+ const bounds = p.schematicComponentId === componentId ? movedBounds : centeredRect(p.schX, p.schY, p.width, p.height);
333797
+ return segmentCrossesPolygon(segment.from, segment.to, rectPolygon(bounds));
333798
+ }))
333799
+ return false;
333800
+ const polygon = traceSegmentPolygon(segment.from, segment.to);
333801
+ if (!polygon)
333802
+ continue;
333803
+ const otherSegments = [
333804
+ ...unaffected.flatMap((t) => t.edges),
333805
+ ...proposed.flatMap((t) => segments(t.points))
333806
+ ];
333807
+ if (otherSegments.some((edge) => {
333808
+ if ([start, end].some((port) => port.schematic_component_id !== componentId && [segment.from, segment.to].some((p) => this.pointsEqual(p, port.center)) && [edge.from, edge.to].some((p) => this.pointsEqual(p, port.center))) && this.getAxis(segment.from, segment.to) !== this.getAxis(edge.from, edge.to))
333809
+ return false;
333810
+ const other = traceSegmentPolygon(edge.from, edge.to);
333811
+ return other && polygonsOverlap(polygon, other);
333812
+ }))
333813
+ return false;
333814
+ }
333815
+ proposed.push({ schematicTraceId: trace.schematic_trace_id, points });
333816
+ }
333817
+ candidate.suggestedTraces = proposed;
333818
+ return true;
333819
+ }
333327
333820
  getTracePoints(trace) {
333328
333821
  const firstEdge = trace.edges[0];
333329
333822
  if (!firstEdge)
@@ -333401,6 +333894,7 @@ class TraceSimplificationSolver extends BaseSolver19 {
333401
333894
  return {
333402
333895
  lineItemType: "TraceCanBeSimplifiedByMovingComponent",
333403
333896
  schematicTraceId: trace.schematic_trace_id,
333897
+ traceName: getTraceName(this.ctx.circuitJson, trace),
333404
333898
  targetComponent: candidate.target,
333405
333899
  deltaSchX: candidate.deltaSchX,
333406
333900
  deltaSchY: candidate.deltaSchY,
@@ -333408,6 +333902,7 @@ class TraceSimplificationSolver extends BaseSolver19 {
333408
333902
  newSchY,
333409
333903
  currentTurnCount: candidate.currentTurnCount,
333410
333904
  suggestedTurnCount: candidate.suggestedTurnCount,
333905
+ suggestedTraces: candidate.suggestedTraces,
333411
333906
  message: `move ${targetName} ${direction} by ${fmtNumber4(distance)} (to schX=${fmtNumber4(newSchX)}, schY=${fmtNumber4(newSchY)}) to reduce this trace from ${candidate.currentTurnCount} turns to ${candidate.suggestedTurnCount}`
333412
333907
  };
333413
333908
  }
@@ -333419,7 +333914,7 @@ class TraceSimplificationSolver extends BaseSolver19 {
333419
333914
  }
333420
333915
  static issueToString(issue) {
333421
333916
  const attrs = [];
333422
- addAttr(attrs, "schematicTraceId", issue.schematicTraceId);
333917
+ addAttr(attrs, "traceName", issue.traceName);
333423
333918
  addAttr(attrs, "targetComponentName", issue.targetComponent.sourceComponentName);
333424
333919
  addAttr(attrs, "deltaSchX", issue.deltaSchX, { formatDelta: true });
333425
333920
  addAttr(attrs, "deltaSchY", issue.deltaSchY, { formatDelta: true });
@@ -333433,12 +333928,12 @@ class TraceSimplificationSolver extends BaseSolver19 {
333433
333928
  }
333434
333929
 
333435
333930
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/TwoPinComponentOrientationSolver.ts
333436
- import { BaseSolver as BaseSolver20 } from "@tscircuit/solver-utils";
333931
+ import { BaseSolver as BaseSolver21 } from "@tscircuit/solver-utils";
333437
333932
 
333438
333933
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/getPowerOrGroundConnectionIds.ts
333439
333934
  import {
333440
333935
  findConnectedNetworks as findConnectedNetworks3,
333441
- getSourcePortConnectivityMapFromCircuitJson as getSourcePortConnectivityMapFromCircuitJson2
333936
+ getSourcePortConnectivityMapFromCircuitJson as getSourcePortConnectivityMapFromCircuitJson3
333442
333937
  } from "circuit-json-to-connectivity-map";
333443
333938
  function getPowerOrGroundConnectionIds(circuitJson) {
333444
333939
  const powerOrGroundIds = new Set;
@@ -333457,7 +333952,7 @@ function getPowerOrGroundConnectionIds(circuitJson) {
333457
333952
  idsByConnectivityKey.set(key, ids);
333458
333953
  }
333459
333954
  }
333460
- const sourceConnectivity = getSourcePortConnectivityMapFromCircuitJson2(circuitJson);
333955
+ const sourceConnectivity = getSourcePortConnectivityMapFromCircuitJson3(circuitJson);
333461
333956
  const networks = findConnectedNetworks3([
333462
333957
  ...Object.values(sourceConnectivity.netMap),
333463
333958
  ...idsByConnectivityKey.values()
@@ -333472,7 +333967,7 @@ function getPowerOrGroundConnectionIds(circuitJson) {
333472
333967
  }
333473
333968
 
333474
333969
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/TwoPinComponentOrientationSolver/TwoPinComponentOrientationSolver.ts
333475
- class TwoPinComponentOrientationSolver extends BaseSolver20 {
333970
+ class TwoPinComponentOrientationSolver extends BaseSolver21 {
333476
333971
  static EPSILON = 0.01;
333477
333972
  ctx;
333478
333973
  out;
@@ -333689,6 +334184,7 @@ class TwoPinComponentOrientationSolver extends BaseSolver20 {
333689
334184
  return {
333690
334185
  lineItemType: "TwoPinComponentCouldBeFlipped",
333691
334186
  schematicTraceId: candidate.trace.schematic_trace_id,
334187
+ traceName: getTraceName(this.ctx.circuitJson, candidate.trace),
333692
334188
  targetComponent: candidate.targetPlacement,
333693
334189
  connectedComponent: candidate.connectedPlacement,
333694
334190
  targetPin,
@@ -333702,7 +334198,7 @@ class TwoPinComponentOrientationSolver extends BaseSolver20 {
333702
334198
  }
333703
334199
  static issueToString(issue) {
333704
334200
  const attrs = [];
333705
- addAttr(attrs, "schematicTraceId", issue.schematicTraceId);
334201
+ addAttr(attrs, "traceName", issue.traceName);
333706
334202
  addAttr(attrs, "targetComponentName", issue.targetComponent.sourceComponentName);
333707
334203
  addAttr(attrs, "connectedComponentName", issue.connectedComponent.sourceComponentName);
333708
334204
  addAttr(attrs, "targetPin", issue.targetPin);
@@ -333717,8 +334213,8 @@ class TwoPinComponentOrientationSolver extends BaseSolver20 {
333717
334213
  }
333718
334214
 
333719
334215
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/VerboseNetLabelSolver/VerboseNetLabelSolver.ts
333720
- import { BaseSolver as BaseSolver21 } from "@tscircuit/solver-utils";
333721
- class VerboseNetLabelSolver extends BaseSolver21 {
334216
+ import { BaseSolver as BaseSolver22 } from "@tscircuit/solver-utils";
334217
+ class VerboseNetLabelSolver extends BaseSolver22 {
333722
334218
  params;
333723
334219
  VERBOSE_NET_LABEL_MESSAGE = "Create trace with schDisplayLabel";
333724
334220
  netLabels;
@@ -333827,130 +334323,8 @@ class VerboseNetLabelSolver extends BaseSolver21 {
333827
334323
  }
333828
334324
 
333829
334325
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicTextClearanceSolver/SchematicTextClearanceSolver.ts
333830
- import { BaseSolver as BaseSolver22 } from "@tscircuit/solver-utils";
333831
-
333832
- // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/utils/schematic-text-geometry.ts
333833
- var rectPolygon = (bounds) => [
333834
- { x: bounds.left, y: bounds.bottom },
333835
- { x: bounds.right, y: bounds.bottom },
333836
- { x: bounds.right, y: bounds.top },
333837
- { x: bounds.left, y: bounds.top }
333838
- ];
333839
- var advance = (character) => {
333840
- if (/\s/.test(character))
333841
- return 0.28;
333842
- if (/[ilI.,:;!'|]/.test(character))
333843
- return 0.25;
333844
- if (/[MW@%]/.test(character))
333845
- return 0.9;
333846
- if (/[mw]/.test(character))
333847
- return 0.8;
333848
- if (/[A-Z]/.test(character))
333849
- return 0.67;
333850
- return 0.56;
333851
- };
333852
- var widthInEm = (text) => Array.from(text).reduce((width, character) => width + advance(character), 0);
333853
- function getSchematicTextPolygons(text) {
333854
- const size = text.font_size;
333855
- if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(text.rotation) || !Number.isFinite(text.position.x) || !Number.isFinite(text.position.y))
333856
- return [];
333857
- const anchor = text.anchor;
333858
- const horizontal = anchor.includes("left") ? 0 : anchor.includes("right") ? 1 : 0.5;
333859
- const top = anchor.includes("top") ? 0 : anchor.includes("bottom") ? size : size / 2;
333860
- const radians = -text.rotation * Math.PI / 180;
333861
- const cos = Math.cos(radians);
333862
- const sin = Math.sin(radians);
333863
- return text.text.split(`
333864
- `).flatMap((line, index) => {
333865
- const visible = line.trim();
333866
- if (!visible)
333867
- return [];
333868
- const leading = line.length - line.trimStart().length;
333869
- const left = (widthInEm(line.slice(0, leading)) - widthInEm(line) * horizontal) * size;
333870
- const polygon = rectPolygon({
333871
- left,
333872
- right: left + widthInEm(visible) * size,
333873
- top: top - index * size - size * 0.05,
333874
- bottom: top - (index + 1) * size + size * 0.05
333875
- });
333876
- return [
333877
- polygon.map(({ x, y }) => ({
333878
- x: text.position.x + x * cos - y * sin,
333879
- y: text.position.y + x * sin + y * cos
333880
- }))
333881
- ];
333882
- });
333883
- }
333884
- function polygonsOverlap(a, b) {
333885
- for (const polygon of [a, b]) {
333886
- for (let i = 0;i < polygon.length; i++) {
333887
- const p = polygon[i];
333888
- const q = polygon[(i + 1) % polygon.length];
333889
- const length = Math.hypot(q.x - p.x, q.y - p.y);
333890
- if (length < 0.000000001)
333891
- continue;
333892
- const nx = -(q.y - p.y) / length;
333893
- const ny = (q.x - p.x) / length;
333894
- const project = (points) => points.map(({ x, y }) => x * nx + y * ny);
333895
- const pa = project(a);
333896
- const pb = project(b);
333897
- if (Math.min(Math.max(...pa), Math.max(...pb)) - Math.max(Math.min(...pa), Math.min(...pb)) <= 0.000001)
333898
- return false;
333899
- }
333900
- }
333901
- return true;
333902
- }
333903
- function traceSegmentPolygon(from, to) {
333904
- const length = Math.hypot(to.x - from.x, to.y - from.y);
333905
- if (length < 0.000000001)
333906
- return;
333907
- const dx = -(to.y - from.y) / length * 0.01;
333908
- const dy = (to.x - from.x) / length * 0.01;
333909
- return [
333910
- { x: from.x + dx, y: from.y + dy },
333911
- { x: to.x + dx, y: to.y + dy },
333912
- { x: to.x - dx, y: to.y - dy },
333913
- { x: from.x - dx, y: from.y - dy }
333914
- ];
333915
- }
333916
- function segmentCrossesPolygon(from, to, polygon) {
333917
- if (Math.hypot(to.x - from.x, to.y - from.y) < 0.000000001)
333918
- return false;
333919
- let low = 0;
333920
- let high = 1;
333921
- for (let i = 0;i < polygon.length; i++) {
333922
- const p = polygon[i];
333923
- const q = polygon[(i + 1) % polygon.length];
333924
- const length = Math.hypot(q.x - p.x, q.y - p.y);
333925
- if (length < 0.000000001)
333926
- continue;
333927
- const nx = -(q.y - p.y) / length;
333928
- const ny = (q.x - p.x) / length;
333929
- const start = (from.x - p.x) * nx + (from.y - p.y) * ny - 0.000001;
333930
- const end = (to.x - p.x) * nx + (to.y - p.y) * ny - 0.000001;
333931
- if (start <= 0 && end <= 0)
333932
- return false;
333933
- if (start <= 0)
333934
- low = Math.max(low, -start / (end - start));
333935
- if (end <= 0)
333936
- high = Math.min(high, -start / (end - start));
333937
- if (high <= low)
333938
- return false;
333939
- }
333940
- return high > low;
333941
- }
333942
- var polygonBounds = (polygons) => {
333943
- const points = polygons.flat();
333944
- return {
333945
- left: Math.min(...points.map((p) => p.x)),
333946
- right: Math.max(...points.map((p) => p.x)),
333947
- top: Math.max(...points.map((p) => p.y)),
333948
- bottom: Math.min(...points.map((p) => p.y))
333949
- };
333950
- };
333951
-
333952
- // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/SchematicTextClearanceSolver/SchematicTextClearanceSolver.ts
333953
- class SchematicTextClearanceSolver extends BaseSolver22 {
334326
+ import { BaseSolver as BaseSolver23 } from "@tscircuit/solver-utils";
334327
+ class SchematicTextClearanceSolver extends BaseSolver23 {
333954
334328
  params;
333955
334329
  texts;
333956
334330
  obstacles;
@@ -334101,8 +334475,8 @@ class SchematicTextClearanceSolver extends BaseSolver22 {
334101
334475
  }
334102
334476
 
334103
334477
  // node_modules/@tscircuit/circuit-json-schematic-placement-analysis/lib/solvers/ResetNetworkGroupingSolver/ResetNetworkGroupingSolver.ts
334104
- import { BaseSolver as BaseSolver23 } from "@tscircuit/solver-utils";
334105
- class ResetNetworkGroupingSolver extends BaseSolver23 {
334478
+ import { BaseSolver as BaseSolver24 } from "@tscircuit/solver-utils";
334479
+ class ResetNetworkGroupingSolver extends BaseSolver24 {
334106
334480
  params;
334107
334481
  static MIN_DISTANCE = 6;
334108
334482
  networks;
@@ -334316,6 +334690,9 @@ class SchematicPlacementPipeline extends BasePipelineSolver2 {
334316
334690
  ]),
334317
334691
  definePipelineStep3("ConnectorPlacementSolver", ConnectorPlacementSolver, (p) => [
334318
334692
  { ctx: p.ctx, issues: p.issues }
334693
+ ]),
334694
+ definePipelineStep3("LowSideTransistorPlacementSolver", LowSideTransistorPlacementSolver, (p) => [
334695
+ { ctx: p.ctx, issues: p.issues }
334319
334696
  ])
334320
334697
  ];
334321
334698
  _setup() {
@@ -334367,6 +334744,12 @@ var getRelevantPlacementsForIssues = ({
334367
334744
  };
334368
334745
  for (const issue of issues) {
334369
334746
  switch (issue.lineItemType) {
334747
+ case "LowSideTransistorNotAlignedWithLoad":
334748
+ addPlacement(issue.transistorSchematicBox);
334749
+ addPlacement(issue.loadSchematicBox);
334750
+ addPlacement(issue.baseResistorSchematicBox);
334751
+ addPlacement(issue.clampDiodeSchematicBox);
334752
+ break;
334370
334753
  case "DecouplingCapacitorsNotCloseTogether":
334371
334754
  for (const placement of issue.capacitorSchematicBoxes)
334372
334755
  addPlacement(placement);
@@ -334444,6 +334827,7 @@ var getRelevantPlacementsForIssues = ({
334444
334827
  addPlacement(component);
334445
334828
  break;
334446
334829
  case "TwoPinComponentShouldBeVertical":
334830
+ case "TwoPinComponentHasInvertedRails":
334447
334831
  addPlacement(issue.schematicBox);
334448
334832
  break;
334449
334833
  case "PullResistorOnWrongSide":
@@ -334554,8 +334938,10 @@ class SchematicPlacementAnalysis {
334554
334938
  ResetNetworkNotGrouped: 0,
334555
334939
  TwoPinComponentCouldBeFlipped: 0,
334556
334940
  TwoPinComponentShouldBeVertical: 0,
334941
+ TwoPinComponentHasInvertedRails: 0,
334557
334942
  DecouplingCapacitorsNotCloseTogether: 0,
334558
- ConnectorPositionCausesTraceDetours: 0
334943
+ ConnectorPositionCausesTraceDetours: 0,
334944
+ LowSideTransistorNotAlignedWithLoad: 0
334559
334945
  };
334560
334946
  for (const issue of this.getIssues(filter))
334561
334947
  counts[issue.lineItemType]++;
@@ -334604,6 +334990,7 @@ class SchematicPlacementAnalysis {
334604
334990
  case "FeedbackNetworkNotCompact":
334605
334991
  return FeedbackNetworkPlacementSolver.issueToString(issue);
334606
334992
  case "TwoPinComponentShouldBeVertical":
334993
+ case "TwoPinComponentHasInvertedRails":
334607
334994
  return TwoPinComponentRailOrientationSolver.issueToString(issue);
334608
334995
  case "PullResistorOnWrongSide":
334609
334996
  return PullResistorPlacementSolver.issueToString(issue);
@@ -334615,6 +335002,8 @@ class SchematicPlacementAnalysis {
334615
335002
  return ResetNetworkGroupingSolver.issueToString(issue);
334616
335003
  case "ConnectorPositionCausesTraceDetours":
334617
335004
  return ConnectorPlacementSolver.issueToString(issue);
335005
+ case "LowSideTransistorNotAlignedWithLoad":
335006
+ return LowSideTransistorPlacementSolver.issueToString(issue);
334618
335007
  default:
334619
335008
  return "";
334620
335009
  }
package/dist/lib/index.js CHANGED
@@ -69128,7 +69128,7 @@ var package_default = {
69128
69128
  "@tscircuit/check-shorts": "https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.24.tgz",
69129
69129
  "@tscircuit/circuit-json-placement-analysis": "^0.0.15",
69130
69130
  "@tscircuit/circuit-json-routing-analysis": "^0.0.8",
69131
- "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#41260fc05b736c0f3fdc33892b6da0ece40107b9",
69131
+ "@tscircuit/circuit-json-schematic-placement-analysis": "https://jscdn.tscircuit.com/@tscircuit/circuit-json-schematic-placement-analysis/0.0.11.tgz",
69132
69132
  "@tscircuit/circuit-json-util": "^0.0.113",
69133
69133
  "@tscircuit/eval": "0.0.1402",
69134
69134
  "@tscircuit/fake-snippets": "^0.0.182",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.2126",
3
+ "version": "0.1.2127",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/tscircuit/cli"
@@ -16,7 +16,7 @@
16
16
  "@tscircuit/check-shorts": "https://jscdn.tscircuit.com/@tscircuit/check-shorts/0.0.24.tgz",
17
17
  "@tscircuit/circuit-json-placement-analysis": "^0.0.15",
18
18
  "@tscircuit/circuit-json-routing-analysis": "^0.0.8",
19
- "@tscircuit/circuit-json-schematic-placement-analysis": "github:tscircuit/circuit-json-schematic-placement-analysis#41260fc05b736c0f3fdc33892b6da0ece40107b9",
19
+ "@tscircuit/circuit-json-schematic-placement-analysis": "https://jscdn.tscircuit.com/@tscircuit/circuit-json-schematic-placement-analysis/0.0.11.tgz",
20
20
  "@tscircuit/circuit-json-util": "^0.0.113",
21
21
  "@tscircuit/eval": "0.0.1402",
22
22
  "@tscircuit/fake-snippets": "^0.0.182",