@tscircuit/schematic-trace-solver 0.0.66 → 0.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4550,6 +4550,7 @@ var visualizeCollision = (collisionInfo) => {
4550
4550
  // lib/solvers/TraceCleanupSolver/sub-solver/UntangleTraceSubsolver.ts
4551
4551
  var UntangleTraceSubsolver = class extends BaseSolver {
4552
4552
  input;
4553
+ chipObstacleSpatialIndex;
4553
4554
  lShapesToProcess = [];
4554
4555
  visualizationMode = "l_shapes";
4555
4556
  currentLShape = null;
@@ -4570,6 +4571,10 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4570
4571
  super();
4571
4572
  this.input = solverInput;
4572
4573
  this.visualizationMode = "l_shapes";
4574
+ this.chipObstacleSpatialIndex = this.input.inputProblem._chipObstacleSpatialIndex ?? new ChipObstacleSpatialIndex(this.input.inputProblem.chips);
4575
+ if (!this.input.inputProblem._chipObstacleSpatialIndex) {
4576
+ this.input.inputProblem._chipObstacleSpatialIndex = this.chipObstacleSpatialIndex;
4577
+ }
4573
4578
  for (const trace of this.input.allTraces) {
4574
4579
  const lShapes = findAllLShapedTurns(trace.tracePath);
4575
4580
  this.lShapesToProcess.push(
@@ -4696,6 +4701,12 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4696
4701
  this.input.allTraces,
4697
4702
  this.currentLShape.traceId
4698
4703
  );
4704
+ if (!collisionResult?.isColliding && this._doesCandidateCrossChip(currentCandidate)) {
4705
+ this.lastCollision = null;
4706
+ this.collidingCandidate = currentCandidate;
4707
+ this.currentCandidateIndex++;
4708
+ return;
4709
+ }
4699
4710
  if (!collisionResult?.isColliding) {
4700
4711
  this.bestRouteFound = currentCandidate;
4701
4712
  this.lastCollision = null;
@@ -4706,6 +4717,21 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4706
4717
  this.currentCandidateIndex++;
4707
4718
  }
4708
4719
  }
4720
+ /**
4721
+ * Returns true if any segment of the candidate reroute passes through a
4722
+ * schematic component (chip) body.
4723
+ */
4724
+ _doesCandidateCrossChip(candidate) {
4725
+ for (let i = 0; i < candidate.length - 1; i++) {
4726
+ if (this.chipObstacleSpatialIndex.doesOrthogonalLineIntersectChip([
4727
+ candidate[i],
4728
+ candidate[i + 1]
4729
+ ])) {
4730
+ return true;
4731
+ }
4732
+ }
4733
+ return false;
4734
+ }
4709
4735
  _applyBestRoute(bestRoute) {
4710
4736
  this.bestRoute = bestRoute;
4711
4737
  this.collidingCandidate = null;
@@ -6285,28 +6311,29 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6285
6311
  getSideOffsetAnchor(params) {
6286
6312
  const { anchorPoint, labelAnchorPoint, orientation, width, height } = params;
6287
6313
  const chipSide = this.getChipSideForPoint(labelAnchorPoint);
6314
+ const sideClearance = this.getContainingChipSide(labelAnchorPoint) ? WICK_CLEARANCE : LABEL_SEARCH_STEP;
6288
6315
  if (isYOrientation(orientation) && chipSide === "left") {
6289
6316
  return {
6290
- x: anchorPoint.x - width / 2 - WICK_CLEARANCE,
6317
+ x: anchorPoint.x - width / 2 - sideClearance,
6291
6318
  y: anchorPoint.y
6292
6319
  };
6293
6320
  }
6294
6321
  if (isYOrientation(orientation) && chipSide === "right") {
6295
6322
  return {
6296
- x: anchorPoint.x + width / 2 + WICK_CLEARANCE,
6323
+ x: anchorPoint.x + width / 2 + sideClearance,
6297
6324
  y: anchorPoint.y
6298
6325
  };
6299
6326
  }
6300
6327
  if (isXOrientation(orientation) && chipSide === "bottom") {
6301
6328
  return {
6302
6329
  x: anchorPoint.x,
6303
- y: anchorPoint.y - height / 2 - WICK_CLEARANCE
6330
+ y: anchorPoint.y - height / 2 - sideClearance
6304
6331
  };
6305
6332
  }
6306
6333
  if (isXOrientation(orientation) && chipSide === "top") {
6307
6334
  return {
6308
6335
  x: anchorPoint.x,
6309
- y: anchorPoint.y + height / 2 + WICK_CLEARANCE
6336
+ y: anchorPoint.y + height / 2 + sideClearance
6310
6337
  };
6311
6338
  }
6312
6339
  return anchorPoint;
@@ -474,28 +474,31 @@ export class AvailableNetOrientationSolver extends BaseSolver {
474
474
  }) {
475
475
  const { anchorPoint, labelAnchorPoint, orientation, width, height } = params
476
476
  const chipSide = this.getChipSideForPoint(labelAnchorPoint)
477
+ const sideClearance = this.getContainingChipSide(labelAnchorPoint)
478
+ ? WICK_CLEARANCE
479
+ : LABEL_SEARCH_STEP
477
480
  if (isYOrientation(orientation) && chipSide === "left") {
478
481
  return {
479
- x: anchorPoint.x - width / 2 - WICK_CLEARANCE,
482
+ x: anchorPoint.x - width / 2 - sideClearance,
480
483
  y: anchorPoint.y,
481
484
  }
482
485
  }
483
486
  if (isYOrientation(orientation) && chipSide === "right") {
484
487
  return {
485
- x: anchorPoint.x + width / 2 + WICK_CLEARANCE,
488
+ x: anchorPoint.x + width / 2 + sideClearance,
486
489
  y: anchorPoint.y,
487
490
  }
488
491
  }
489
492
  if (isXOrientation(orientation) && chipSide === "bottom") {
490
493
  return {
491
494
  x: anchorPoint.x,
492
- y: anchorPoint.y - height / 2 - WICK_CLEARANCE,
495
+ y: anchorPoint.y - height / 2 - sideClearance,
493
496
  }
494
497
  }
495
498
  if (isXOrientation(orientation) && chipSide === "top") {
496
499
  return {
497
500
  x: anchorPoint.x,
498
- y: anchorPoint.y + height / 2 + WICK_CLEARANCE,
501
+ y: anchorPoint.y + height / 2 + sideClearance,
499
502
  }
500
503
  }
501
504
  return anchorPoint
@@ -2,6 +2,7 @@ import { BaseSolver } from "../../BaseSolver/BaseSolver"
2
2
  import type { InputProblem } from "../../../types/InputProblem"
3
3
  import type { SolvedTracePath } from "../../SchematicTraceLinesSolver/SchematicTraceLinesSolver"
4
4
  import type { NetLabelPlacement } from "../../NetLabelPlacementSolver/NetLabelPlacementSolver"
5
+ import { ChipObstacleSpatialIndex } from "lib/data-structures/ChipObstacleSpatialIndex"
5
6
 
6
7
  import { findAllLShapedTurns, type LShape } from "./findAllLShapedTurns"
7
8
  import { getTraceObstacles } from "./getTraceObstacles"
@@ -57,6 +58,7 @@ type VisualizationMode =
57
58
  */
58
59
  export class UntangleTraceSubsolver extends BaseSolver {
59
60
  private input: UntangleTraceSubsolverInput
61
+ private chipObstacleSpatialIndex: ChipObstacleSpatialIndex
60
62
  private lShapesToProcess: LShape[] = []
61
63
  private visualizationMode: VisualizationMode = "l_shapes"
62
64
 
@@ -86,6 +88,14 @@ export class UntangleTraceSubsolver extends BaseSolver {
86
88
  this.input = solverInput
87
89
  this.visualizationMode = "l_shapes"
88
90
 
91
+ this.chipObstacleSpatialIndex =
92
+ this.input.inputProblem._chipObstacleSpatialIndex ??
93
+ new ChipObstacleSpatialIndex(this.input.inputProblem.chips)
94
+ if (!this.input.inputProblem._chipObstacleSpatialIndex) {
95
+ this.input.inputProblem._chipObstacleSpatialIndex =
96
+ this.chipObstacleSpatialIndex
97
+ }
98
+
89
99
  for (const trace of this.input.allTraces) {
90
100
  const lShapes = findAllLShapedTurns(trace.tracePath)
91
101
  this.lShapesToProcess.push(
@@ -232,6 +242,20 @@ export class UntangleTraceSubsolver extends BaseSolver {
232
242
  this.currentLShape!.traceId,
233
243
  )
234
244
 
245
+ // Untangling must never move a trace through a component body. The candidate
246
+ // only covers the rerouted corner (not the pin-terminal segments), so reject
247
+ // any candidate that crosses a chip; the original (component-clear) path is
248
+ // kept instead, so this stage only ever improves or leaves the trace valid.
249
+ if (
250
+ !collisionResult?.isColliding &&
251
+ this._doesCandidateCrossChip(currentCandidate)
252
+ ) {
253
+ this.lastCollision = null
254
+ this.collidingCandidate = currentCandidate
255
+ this.currentCandidateIndex++
256
+ return
257
+ }
258
+
235
259
  if (!collisionResult?.isColliding) {
236
260
  this.bestRouteFound = currentCandidate
237
261
  this.lastCollision = null
@@ -243,6 +267,24 @@ export class UntangleTraceSubsolver extends BaseSolver {
243
267
  }
244
268
  }
245
269
 
270
+ /**
271
+ * Returns true if any segment of the candidate reroute passes through a
272
+ * schematic component (chip) body.
273
+ */
274
+ private _doesCandidateCrossChip(candidate: Point[]): boolean {
275
+ for (let i = 0; i < candidate.length - 1; i++) {
276
+ if (
277
+ this.chipObstacleSpatialIndex.doesOrthogonalLineIntersectChip([
278
+ candidate[i]!,
279
+ candidate[i + 1]!,
280
+ ])
281
+ ) {
282
+ return true
283
+ }
284
+ }
285
+ return false
286
+ }
287
+
246
288
  private _applyBestRoute(bestRoute: Point[]) {
247
289
  this.bestRoute = bestRoute
248
290
  this.collidingCandidate = null
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-trace-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.66",
4
+ "version": "0.0.68",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -0,0 +1,468 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="100%" height="100%" fill="white" />
3
+ <g>
4
+ <circle data-type="point" data-label="U1.1
5
+ x-" data-x="-1.5" data-y="0.10000000000000009" cx="397.19404110880635" cy="306.00792004525744" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
6
+ </g>
7
+ <g>
8
+ <circle data-type="point" data-label="U1.8
9
+ x+" data-x="1.5" data-y="1.3" cx="555.5949462568358" cy="242.64755798604565" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
10
+ </g>
11
+ <g>
12
+ <circle data-type="point" data-label="U1.11
13
+ x-" data-x="-1.5" data-y="1.3" cx="397.19404110880635" cy="242.64755798604565" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
14
+ </g>
15
+ <g>
16
+ <circle data-type="point" data-label="U1.12
17
+ x-" data-x="-1.5" data-y="1.1" cx="397.19404110880635" cy="253.20761832924762" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
18
+ </g>
19
+ <g>
20
+ <circle data-type="point" data-label="U1.17
21
+ x+" data-x="1.5" data-y="1.0999999999999999" cx="555.5949462568358" cy="253.20761832924762" r="3" fill="hsl(224, 100%, 50%, 0.8)" />
22
+ </g>
23
+ <g>
24
+ <circle data-type="point" data-label="U1.25
25
+ x-" data-x="-1.5" data-y="0.9" cx="397.19404110880635" cy="263.76767867244956" r="3" fill="hsl(253, 100%, 50%, 0.8)" />
26
+ </g>
27
+ <g>
28
+ <circle data-type="point" data-label="U1.26
29
+ x-" data-x="-1.5" data-y="-0.4999999999999998" cx="397.19404110880635" cy="337.6881010748633" r="3" fill="hsl(254, 100%, 50%, 0.8)" />
30
+ </g>
31
+ <g>
32
+ <circle data-type="point" data-label="U1.27
33
+ x-" data-x="-1.5" data-y="-0.6999999999999997" cx="397.19404110880635" cy="348.24816141806525" r="3" fill="hsl(255, 100%, 50%, 0.8)" />
34
+ </g>
35
+ <g>
36
+ <circle data-type="point" data-label="U1.28
37
+ x-" data-x="-1.5" data-y="-1.0999999999999999" cx="397.19404110880635" cy="369.3682821044692" r="3" fill="hsl(256, 100%, 50%, 0.8)" />
38
+ </g>
39
+ <g>
40
+ <circle data-type="point" data-label="U1.30
41
+ x-" data-x="-1.5" data-y="0.5" cx="397.19404110880635" cy="284.8877993588535" r="3" fill="hsl(279, 100%, 50%, 0.8)" />
42
+ </g>
43
+ <g>
44
+ <circle data-type="point" data-label="U1.31
45
+ x+" data-x="1.5" data-y="0.8999999999999997" cx="555.5949462568358" cy="263.7676786724496" r="3" fill="hsl(280, 100%, 50%, 0.8)" />
46
+ </g>
47
+ <g>
48
+ <circle data-type="point" data-label="U1.34
49
+ x-" data-x="-1.5" data-y="-0.09999999999999987" cx="397.19404110880635" cy="316.5679803884594" r="3" fill="hsl(283, 100%, 50%, 0.8)" />
50
+ </g>
51
+ <g>
52
+ <circle data-type="point" data-label="U1.35
53
+ x+" data-x="1.5" data-y="-1.1" cx="555.5949462568358" cy="369.3682821044692" r="3" fill="hsl(284, 100%, 50%, 0.8)" />
54
+ </g>
55
+ <g>
56
+ <circle data-type="point" data-label="U1.36
57
+ x+" data-x="1.5" data-y="-1.3" cx="555.5949462568358" cy="379.9283424476712" r="3" fill="hsl(285, 100%, 50%, 0.8)" />
58
+ </g>
59
+ <g>
60
+ <circle data-type="point" data-label="U1.37
61
+ x-" data-x="-1.5" data-y="-0.8999999999999997" cx="397.19404110880635" cy="358.8082217612672" r="3" fill="hsl(286, 100%, 50%, 0.8)" />
62
+ </g>
63
+ <g>
64
+ <circle data-type="point" data-label="U1.38
65
+ x+" data-x="1.5" data-y="0.6999999999999997" cx="555.5949462568358" cy="274.32773901565156" r="3" fill="hsl(287, 100%, 50%, 0.8)" />
66
+ </g>
67
+ <g>
68
+ <circle data-type="point" data-label="U1.39
69
+ x+" data-x="1.5" data-y="-2.220446049250313e-16" cx="555.5949462568358" cy="311.2879502168584" r="3" fill="hsl(288, 100%, 50%, 0.8)" />
70
+ </g>
71
+ <g>
72
+ <circle data-type="point" data-label="U1.40
73
+ x+" data-x="1.5" data-y="-0.40000000000000013" cx="555.5949462568358" cy="332.40807090326234" r="3" fill="hsl(310, 100%, 50%, 0.8)" />
74
+ </g>
75
+ <g>
76
+ <circle data-type="point" data-label="U1.41
77
+ x-" data-x="-1.5" data-y="-1.3" cx="397.19404110880635" cy="379.9283424476712" r="3" fill="hsl(311, 100%, 50%, 0.8)" />
78
+ </g>
79
+ <g>
80
+ <circle data-type="point" data-label="L1.1
81
+ x-" data-x="-6.08" data-y="0.58" cx="155.36865924948142" cy="280.66377522157273" r="3" fill="hsl(40, 100%, 50%, 0.8)" />
82
+ </g>
83
+ <g>
84
+ <circle data-type="point" data-label="L1.2
85
+ x+" data-x="-4.92" data-y="0.57" cx="216.61700924005282" cy="281.1917782387328" r="3" fill="hsl(41, 100%, 50%, 0.8)" />
86
+ </g>
87
+ <g>
88
+ <circle data-type="point" data-label="C105.1
89
+ y+" data-x="-8" data-y="-0.44999999999999996" cx="53.99207995474262" cy="335.0480859890628" r="3" fill="hsl(102, 100%, 50%, 0.8)" />
90
+ </g>
91
+ <g>
92
+ <circle data-type="point" data-label="C105.2
93
+ y-" data-x="-8" data-y="-1.55" cx="53.99207995474262" cy="393.1284178766736" r="3" fill="hsl(103, 100%, 50%, 0.8)" />
94
+ </g>
95
+ <g>
96
+ <circle data-type="point" data-label="C106.1
97
+ y+" data-x="-4.3" data-y="-0.44999999999999996" cx="249.3531963039789" cy="335.0480859890628" r="3" fill="hsl(343, 100%, 50%, 0.8)" />
98
+ </g>
99
+ <g>
100
+ <circle data-type="point" data-label="C106.2
101
+ y-" data-x="-4.3" data-y="-1.55" cx="249.3531963039789" cy="393.1284178766736" r="3" fill="hsl(344, 100%, 50%, 0.8)" />
102
+ </g>
103
+ <g>
104
+ <circle data-type="point" data-label="C107.1
105
+ y+" data-x="-5.8" data-y="-0.44999999999999996" cx="170.1527437299642" cy="335.0480859890628" r="3" fill="hsl(224, 100%, 50%, 0.8)" />
106
+ </g>
107
+ <g>
108
+ <circle data-type="point" data-label="C107.2
109
+ y-" data-x="-5.8" data-y="-1.55" cx="170.1527437299642" cy="393.1284178766736" r="3" fill="hsl(225, 100%, 50%, 0.8)" />
110
+ </g>
111
+ <g>
112
+ <circle data-type="point" data-label="anchorPoint
113
+ orientation: y+" data-x="-1.85" data-y="-0.09899999999999987" cx="378.7139355082029" cy="316.5151800867434" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
114
+ </g>
115
+ <g>
116
+ <circle data-type="point" data-label="anchorPoint
117
+ orientation: y+" data-x="-6.28" data-y="0.58" cx="144.80859890627949" cy="280.66377522157273" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
118
+ </g>
119
+ <g>
120
+ <circle data-type="point" data-label="anchorPoint
121
+ orientation: y+" data-x="1.7" data-y="1.3" cx="566.1550066000377" cy="242.64755798604565" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
122
+ </g>
123
+ <g>
124
+ <circle data-type="point" data-label="anchorPoint
125
+ orientation: x-" data-x="-1.5" data-y="1.3" cx="397.19404110880635" cy="242.64755798604565" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
126
+ </g>
127
+ <g>
128
+ <circle data-type="point" data-label="anchorPoint
129
+ orientation: x-" data-x="-1.5" data-y="1.1" cx="397.19404110880635" cy="253.20761832924762" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
130
+ </g>
131
+ <g>
132
+ <circle data-type="point" data-label="anchorPoint
133
+ orientation: y+" data-x="-2.355" data-y="0.5" cx="352.049783141618" cy="284.8877993588535" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
134
+ </g>
135
+ <g>
136
+ <circle data-type="point" data-label="anchorPoint
137
+ orientation: x+" data-x="1.5" data-y="-2.220446049250313e-16" cx="555.5949462568358" cy="311.2879502168584" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
138
+ </g>
139
+ <g>
140
+ <circle data-type="point" data-label="anchorPoint
141
+ orientation: y-" data-x="1.7000000000000002" data-y="-1.7" cx="566.1550066000377" cy="401.04846313407506" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
142
+ </g>
143
+ <g>
144
+ <circle data-type="point" data-label="anchorPoint
145
+ orientation: y-" data-x="-5.8" data-y="-1.7500000000000002" cx="170.1527437299642" cy="403.6884782198756" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
146
+ </g>
147
+ <g>
148
+ <polyline data-points="-1.5,0.5 -4.92,0.57" data-type="line" data-label="" points="397.19404110880635,284.8877993588535 216.61700924005282,281.1917782387328" fill="none" stroke="hsl(240, 100%, 50%, 0.8)" stroke-width="1" />
149
+ </g>
150
+ <g>
151
+ <polyline data-points="-1.5,0.10000000000000009 -1.5,-0.09999999999999987" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 397.19404110880635,316.5679803884594" fill="none" stroke="hsl(64, 100%, 50%, 0.8)" stroke-width="1" />
152
+ </g>
153
+ <g>
154
+ <polyline data-points="-4.3,-0.44999999999999996 -6.08,0.58" data-type="line" data-label="" points="249.3531963039789,335.0480859890628 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(216, 100%, 50%, 0.8)" stroke-width="1" />
155
+ </g>
156
+ <g>
157
+ <polyline data-points="-5.8,-0.44999999999999996 -4.3,-0.44999999999999996" data-type="line" data-label="" points="170.1527437299642,335.0480859890628 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(184, 100%, 50%, 0.8)" stroke-width="1" />
158
+ </g>
159
+ <g>
160
+ <polyline data-points="-1.5,0.10000000000000009 1.5,1.3" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 555.5949462568358,242.64755798604565" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
161
+ </g>
162
+ <g>
163
+ <polyline data-points="-1.5,0.10000000000000009 1.5,1.0999999999999999" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 555.5949462568358,253.20761832924762" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
164
+ </g>
165
+ <g>
166
+ <polyline data-points="-1.5,0.10000000000000009 1.5,0.8999999999999997" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 555.5949462568358,263.7676786724496" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
167
+ </g>
168
+ <g>
169
+ <polyline data-points="-1.5,0.10000000000000009 -1.5,-0.09999999999999987" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 397.19404110880635,316.5679803884594" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
170
+ </g>
171
+ <g>
172
+ <polyline data-points="-1.5,0.10000000000000009 1.5,0.6999999999999997" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 555.5949462568358,274.32773901565156" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
173
+ </g>
174
+ <g>
175
+ <polyline data-points="-1.5,0.10000000000000009 -6.08,0.58" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
176
+ </g>
177
+ <g>
178
+ <polyline data-points="-1.5,0.10000000000000009 -8,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
179
+ </g>
180
+ <g>
181
+ <polyline data-points="-1.5,0.10000000000000009 -4.3,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
182
+ </g>
183
+ <g>
184
+ <polyline data-points="-1.5,0.10000000000000009 -5.8,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,306.00792004525744 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
185
+ </g>
186
+ <g>
187
+ <polyline data-points="1.5,1.3 1.5,1.0999999999999999" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 555.5949462568358,253.20761832924762" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
188
+ </g>
189
+ <g>
190
+ <polyline data-points="1.5,1.3 1.5,0.8999999999999997" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 555.5949462568358,263.7676786724496" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
191
+ </g>
192
+ <g>
193
+ <polyline data-points="1.5,1.3 -1.5,-0.09999999999999987" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 397.19404110880635,316.5679803884594" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
194
+ </g>
195
+ <g>
196
+ <polyline data-points="1.5,1.3 1.5,0.6999999999999997" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 555.5949462568358,274.32773901565156" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
197
+ </g>
198
+ <g>
199
+ <polyline data-points="1.5,1.3 -6.08,0.58" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
200
+ </g>
201
+ <g>
202
+ <polyline data-points="1.5,1.3 -8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
203
+ </g>
204
+ <g>
205
+ <polyline data-points="1.5,1.3 -4.3,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
206
+ </g>
207
+ <g>
208
+ <polyline data-points="1.5,1.3 -5.8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
209
+ </g>
210
+ <g>
211
+ <polyline data-points="1.5,1.0999999999999999 1.5,0.8999999999999997" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 555.5949462568358,263.7676786724496" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
212
+ </g>
213
+ <g>
214
+ <polyline data-points="1.5,1.0999999999999999 -1.5,-0.09999999999999987" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 397.19404110880635,316.5679803884594" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
215
+ </g>
216
+ <g>
217
+ <polyline data-points="1.5,1.0999999999999999 1.5,0.6999999999999997" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 555.5949462568358,274.32773901565156" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
218
+ </g>
219
+ <g>
220
+ <polyline data-points="1.5,1.0999999999999999 -6.08,0.58" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
221
+ </g>
222
+ <g>
223
+ <polyline data-points="1.5,1.0999999999999999 -8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
224
+ </g>
225
+ <g>
226
+ <polyline data-points="1.5,1.0999999999999999 -4.3,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
227
+ </g>
228
+ <g>
229
+ <polyline data-points="1.5,1.0999999999999999 -5.8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,253.20761832924762 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
230
+ </g>
231
+ <g>
232
+ <polyline data-points="1.5,0.8999999999999997 -1.5,-0.09999999999999987" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 397.19404110880635,316.5679803884594" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
233
+ </g>
234
+ <g>
235
+ <polyline data-points="1.5,0.8999999999999997 1.5,0.6999999999999997" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 555.5949462568358,274.32773901565156" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
236
+ </g>
237
+ <g>
238
+ <polyline data-points="1.5,0.8999999999999997 -6.08,0.58" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
239
+ </g>
240
+ <g>
241
+ <polyline data-points="1.5,0.8999999999999997 -8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
242
+ </g>
243
+ <g>
244
+ <polyline data-points="1.5,0.8999999999999997 -4.3,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
245
+ </g>
246
+ <g>
247
+ <polyline data-points="1.5,0.8999999999999997 -5.8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
248
+ </g>
249
+ <g>
250
+ <polyline data-points="-1.5,-0.09999999999999987 1.5,0.6999999999999997" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 555.5949462568358,274.32773901565156" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
251
+ </g>
252
+ <g>
253
+ <polyline data-points="-1.5,-0.09999999999999987 -6.08,0.58" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
254
+ </g>
255
+ <g>
256
+ <polyline data-points="-1.5,-0.09999999999999987 -8,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
257
+ </g>
258
+ <g>
259
+ <polyline data-points="-1.5,-0.09999999999999987 -4.3,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
260
+ </g>
261
+ <g>
262
+ <polyline data-points="-1.5,-0.09999999999999987 -5.8,-0.44999999999999996" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
263
+ </g>
264
+ <g>
265
+ <polyline data-points="1.5,0.6999999999999997 -6.08,0.58" data-type="line" data-label="" points="555.5949462568358,274.32773901565156 155.36865924948142,280.66377522157273" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
266
+ </g>
267
+ <g>
268
+ <polyline data-points="1.5,0.6999999999999997 -8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,274.32773901565156 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
269
+ </g>
270
+ <g>
271
+ <polyline data-points="1.5,0.6999999999999997 -4.3,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,274.32773901565156 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
272
+ </g>
273
+ <g>
274
+ <polyline data-points="1.5,0.6999999999999997 -5.8,-0.44999999999999996" data-type="line" data-label="" points="555.5949462568358,274.32773901565156 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
275
+ </g>
276
+ <g>
277
+ <polyline data-points="-6.08,0.58 -8,-0.44999999999999996" data-type="line" data-label="" points="155.36865924948142,280.66377522157273 53.99207995474262,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
278
+ </g>
279
+ <g>
280
+ <polyline data-points="-6.08,0.58 -4.3,-0.44999999999999996" data-type="line" data-label="" points="155.36865924948142,280.66377522157273 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
281
+ </g>
282
+ <g>
283
+ <polyline data-points="-6.08,0.58 -5.8,-0.44999999999999996" data-type="line" data-label="" points="155.36865924948142,280.66377522157273 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
284
+ </g>
285
+ <g>
286
+ <polyline data-points="-8,-0.44999999999999996 -4.3,-0.44999999999999996" data-type="line" data-label="" points="53.99207995474262,335.0480859890628 249.3531963039789,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
287
+ </g>
288
+ <g>
289
+ <polyline data-points="-8,-0.44999999999999996 -5.8,-0.44999999999999996" data-type="line" data-label="" points="53.99207995474262,335.0480859890628 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
290
+ </g>
291
+ <g>
292
+ <polyline data-points="-4.3,-0.44999999999999996 -5.8,-0.44999999999999996" data-type="line" data-label="" points="249.3531963039789,335.0480859890628 170.1527437299642,335.0480859890628" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
293
+ </g>
294
+ <g>
295
+ <polyline data-points="1.5,-0.40000000000000013 -1.5,-1.3" data-type="line" data-label="" points="555.5949462568358,332.40807090326234 397.19404110880635,379.9283424476712" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
296
+ </g>
297
+ <g>
298
+ <polyline data-points="1.5,-0.40000000000000013 -8,-1.55" data-type="line" data-label="" points="555.5949462568358,332.40807090326234 53.99207995474262,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
299
+ </g>
300
+ <g>
301
+ <polyline data-points="1.5,-0.40000000000000013 -4.3,-1.55" data-type="line" data-label="" points="555.5949462568358,332.40807090326234 249.3531963039789,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
302
+ </g>
303
+ <g>
304
+ <polyline data-points="1.5,-0.40000000000000013 -5.8,-1.55" data-type="line" data-label="" points="555.5949462568358,332.40807090326234 170.1527437299642,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
305
+ </g>
306
+ <g>
307
+ <polyline data-points="-1.5,-1.3 -8,-1.55" data-type="line" data-label="" points="397.19404110880635,379.9283424476712 53.99207995474262,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
308
+ </g>
309
+ <g>
310
+ <polyline data-points="-1.5,-1.3 -4.3,-1.55" data-type="line" data-label="" points="397.19404110880635,379.9283424476712 249.3531963039789,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
311
+ </g>
312
+ <g>
313
+ <polyline data-points="-1.5,-1.3 -5.8,-1.55" data-type="line" data-label="" points="397.19404110880635,379.9283424476712 170.1527437299642,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
314
+ </g>
315
+ <g>
316
+ <polyline data-points="-8,-1.55 -4.3,-1.55" data-type="line" data-label="" points="53.99207995474262,393.1284178766736 249.3531963039789,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
317
+ </g>
318
+ <g>
319
+ <polyline data-points="-8,-1.55 -5.8,-1.55" data-type="line" data-label="" points="53.99207995474262,393.1284178766736 170.1527437299642,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
320
+ </g>
321
+ <g>
322
+ <polyline data-points="-4.3,-1.55 -5.8,-1.55" data-type="line" data-label="" points="249.3531963039789,393.1284178766736 170.1527437299642,393.1284178766736" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
323
+ </g>
324
+ <g>
325
+ <polyline data-points="-5.8,-0.44999999999999996 -5.8,-0.24999999999999978 -8,-0.24999999999999978 -8,-0.44999999999999996" data-type="line" data-label="" points="170.1527437299642,335.0480859890628 170.1527437299642,324.48802564586083 53.99207995474262,324.48802564586083 53.99207995474262,335.0480859890628" fill="none" stroke="purple" stroke-width="1" />
326
+ </g>
327
+ <g>
328
+ <polyline data-points="-6.08,0.58 -6.28,0.58 -6.28,0.065 -5.8,0.065 -5.8,-0.44999999999999996" data-type="line" data-label="" points="155.36865924948142,280.66377522157273 144.80859890627949,280.66377522157273 144.80859890627949,307.8559306053178 170.1527437299642,307.8559306053178 170.1527437299642,335.0480859890628" fill="none" stroke="purple" stroke-width="1" />
329
+ </g>
330
+ <g>
331
+ <polyline data-points="-4.3,-0.44999999999999996 -4.3,-0.24999999999999978 -5.8,-0.24999999999999978 -5.8,-0.44999999999999996" data-type="line" data-label="" points="249.3531963039789,335.0480859890628 249.3531963039789,324.48802564586083 170.1527437299642,324.48802564586083 170.1527437299642,335.0480859890628" fill="none" stroke="purple" stroke-width="1" />
332
+ </g>
333
+ <g>
334
+ <polyline data-points="-1.5,-0.09999999999999987 -1.7,-0.09999999999999987 -1.7,0.10000000000000009 -1.5,0.10000000000000009" data-type="line" data-label="" points="397.19404110880635,316.5679803884594 386.6339807656044,316.5679803884594 386.6339807656044,306.00792004525744 397.19404110880635,306.00792004525744" fill="none" stroke="purple" stroke-width="1" />
335
+ </g>
336
+ <g>
337
+ <polyline data-points="1.5,0.8999999999999997 1.7,0.8999999999999997 1.7,1.0999999999999999 1.5,1.0999999999999999" data-type="line" data-label="" points="555.5949462568358,263.7676786724496 566.1550066000377,263.7676786724496 566.1550066000377,253.20761832924762 555.5949462568358,253.20761832924762" fill="none" stroke="purple" stroke-width="1" />
338
+ </g>
339
+ <g>
340
+ <polyline data-points="1.5,0.6999999999999997 1.7,0.6999999999999997 1.7,0.8999999999999997 1.5,0.8999999999999997" data-type="line" data-label="" points="555.5949462568358,274.32773901565156 566.1550066000377,274.32773901565156 566.1550066000377,263.7676786724496 555.5949462568358,263.7676786724496" fill="none" stroke="purple" stroke-width="1" />
341
+ </g>
342
+ <g>
343
+ <polyline data-points="1.5,1.3 1.7,1.3 1.7,1.0999999999999999 1.5,1.0999999999999999" data-type="line" data-label="" points="555.5949462568358,242.64755798604565 566.1550066000377,242.64755798604565 566.1550066000377,253.20761832924762 555.5949462568358,253.20761832924762" fill="none" stroke="purple" stroke-width="1" />
344
+ </g>
345
+ <g>
346
+ <polyline data-points="-5.8,-1.55 -5.8,-1.7500000000000002 -8,-1.7500000000000002 -8,-1.55" data-type="line" data-label="" points="170.1527437299642,393.1284178766736 170.1527437299642,403.6884782198756 53.99207995474262,403.6884782198756 53.99207995474262,393.1284178766736" fill="none" stroke="purple" stroke-width="1" />
347
+ </g>
348
+ <g>
349
+ <polyline data-points="-4.3,-1.55 -4.3,-1.7500000000000002 -5.8,-1.7500000000000002 -5.8,-1.55" data-type="line" data-label="" points="249.3531963039789,393.1284178766736 249.3531963039789,403.6884782198756 170.1527437299642,403.6884782198756 170.1527437299642,393.1284178766736" fill="none" stroke="purple" stroke-width="1" />
350
+ </g>
351
+ <g>
352
+ <polyline data-points="-1.5,0.5 -1.65,0.5 -1.65,0.6010000000000001 -2.0500000000000003,0.6010000000000001 -2.0500000000000003,0.5 -3.21,0.5 -3.21,0.57 -4.92,0.57" data-type="line" data-label="" points="397.19404110880635,284.8877993588535 389.2739958514049,284.8877993588535 389.2739958514049,279.5549688855365 368.15387516500095,279.5549688855365 368.15387516500095,284.8877993588535 306.9055251744296,284.8877993588535 306.9055251744296,281.1917782387328 216.61700924005282,281.1917782387328" fill="none" stroke="purple" stroke-width="1" />
353
+ </g>
354
+ <g>
355
+ <polyline data-points="1.5,-0.40000000000000013 1.7000000000000002,-0.40000000000000013 1.7000000000000002,-1.7 -1.7,-1.7 -1.7,-1.3 -1.5,-1.3" data-type="line" data-label="" points="555.5949462568358,332.40807090326234 566.1550066000377,332.40807090326234 566.1550066000377,401.04846313407506 386.6339807656044,401.04846313407506 386.6339807656044,379.9283424476712 397.19404110880635,379.9283424476712" fill="none" stroke="purple" stroke-width="1" />
356
+ </g>
357
+ <g>
358
+ <polyline data-points="-1.7,-0.09999999999999987 -1.85,-0.09999999999999987 -1.85,-0.09899999999999987" data-type="line" data-label="" points="386.6339807656044,316.5679803884594 378.7139355082029,316.5679803884594 378.7139355082029,316.5151800867434" fill="none" stroke="purple" stroke-width="1" />
359
+ </g>
360
+ <g>
361
+ <rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="397.19404110880635" y="232.0874976428437" width="158.40090514802944" height="158.40090514802944" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018939285714285714" />
362
+ </g>
363
+ <g>
364
+ <rect data-type="rect" data-label="schematic_component_1" data-x="-5.5" data-y="0.6" x="155.36865924948142" y="267.46369979257025" width="61.2483499905714" height="24.288138789364496" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018939285714285714" />
365
+ </g>
366
+ <g>
367
+ <rect data-type="rect" data-label="schematic_component_2" data-x="-8" data-y="-1" x="40" y="335.0480859890628" width="27.984159909485186" height="58.08033188761078" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018939285714285714" />
368
+ </g>
369
+ <g>
370
+ <rect data-type="rect" data-label="schematic_component_3" data-x="-4.3" data-y="-1" x="235.36111634923634" y="335.0480859890628" width="27.98415990948513" height="58.08033188761078" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018939285714285714" />
371
+ </g>
372
+ <g>
373
+ <rect data-type="rect" data-label="schematic_component_4" data-x="-5.8" data-y="-1" x="156.16066377522162" y="335.0480859890628" width="27.984159909485186" height="58.08033188761078" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018939285714285714" />
374
+ </g>
375
+ <g>
376
+ <rect data-type="rect" data-label="netId: VDDS
377
+ globalConnNetId: connectivity_net1" data-x="-1.85" data-y="0.20100000000000012" x="373.4339053366019" y="284.8349990571375" width="10.560060343201997" height="31.680181029605876" fill="#ef444466" stroke="#ef4444" stroke-width="0.018939285714285714" />
378
+ </g>
379
+ <g>
380
+ <rect data-type="rect" data-label="netId: VDDS
381
+ globalConnNetId: connectivity_net1" data-x="-6.28" data-y="0.8799999999999999" x="139.52856873467852" y="248.98359419196683" width="10.56006034320194" height="31.680181029605905" fill="#ef444466" stroke="#ef4444" stroke-width="0.018939285714285714" />
382
+ </g>
383
+ <g>
384
+ <rect data-type="rect" data-label="netId: VDDS
385
+ globalConnNetId: connectivity_net1" data-x="1.7" data-y="1.6" x="560.8749764284368" y="210.96737695643975" width="10.56006034320194" height="31.680181029605905" fill="#ef444466" stroke="#ef4444" stroke-width="0.018939285714285714" />
386
+ </g>
387
+ <g>
388
+ <rect data-type="rect" data-label="netId: WMCU_SWDIO
389
+ globalConnNetId: connectivity_net3" data-x="-2.161" data-y="1.3" x="327.4448425419574" y="237.36752781444466" width="69.69639826513293" height="10.560060343201997" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018939285714285714" />
390
+ </g>
391
+ <g>
392
+ <rect data-type="rect" data-label="netId: WMCU_SWDCK
393
+ globalConnNetId: connectivity_net4" data-x="-2.161" data-y="1.1" x="327.4448425419574" y="247.92758815764662" width="69.69639826513293" height="10.560060343201968" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018939285714285714" />
394
+ </g>
395
+ <g>
396
+ <rect data-type="rect" data-label="netId: .U1 &gt; .DCDC to L1.pin2
397
+ globalConnNetId: connectivity_net0" data-x="-2.355" data-y="0.725" x="346.76975297001695" y="261.1276635866491" width="10.560060343201997" height="23.76013577220442" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018939285714285714" />
398
+ </g>
399
+ <g>
400
+ <rect data-type="rect" data-label="netId: ANT_RF
401
+ globalConnNetId: connectivity_net5" data-x="1.9209999999999998" data-y="-2.220446049250313e-16" x="555.6477465585517" y="306.00792004525744" width="44.35225344144828" height="10.56006034320194" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018939285714285714" />
402
+ </g>
403
+ <g>
404
+ <rect data-type="rect" data-label="netId: GND
405
+ globalConnNetId: connectivity_net6" data-x="1.7000000000000002" data-y="-1.94" x="560.8749764284368" y="401.04846313407506" width="10.56006034320194" height="25.3441448236847" fill="#00000066" stroke="#000000" stroke-width="0.018939285714285714" />
406
+ </g>
407
+ <g>
408
+ <rect data-type="rect" data-label="netId: GND
409
+ globalConnNetId: connectivity_net6" data-x="-5.8" data-y="-1.9900000000000002" x="164.87271355836322" y="403.6884782198756" width="10.56006034320194" height="25.3441448236847" fill="#00000066" stroke="#000000" stroke-width="0.018939285714285714" />
410
+ </g>
411
+ <g id="crosshair" style="display: none">
412
+ <line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
413
+ <line id="crosshair-v" x1="0" x2="640" stroke="#666" stroke-width="0.5" /><text id="coordinates" font-family="monospace" font-size="12" fill="#666"></text>
414
+ </g>
415
+ <script>
416
+ <![CDATA[
417
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
418
+ const svg = e.currentTarget;
419
+ const rect = svg.getBoundingClientRect();
420
+ const x = e.clientX - rect.left;
421
+ const y = e.clientY - rect.top;
422
+ const crosshair = svg.getElementById('crosshair');
423
+ const h = svg.getElementById('crosshair-h');
424
+ const v = svg.getElementById('crosshair-v');
425
+ const coords = svg.getElementById('coordinates');
426
+
427
+ crosshair.style.display = 'block';
428
+ h.setAttribute('x1', '0');
429
+ h.setAttribute('x2', '640');
430
+ h.setAttribute('y1', y);
431
+ h.setAttribute('y2', y);
432
+ v.setAttribute('x1', x);
433
+ v.setAttribute('x2', x);
434
+ v.setAttribute('y1', '0');
435
+ v.setAttribute('y2', '640');
436
+
437
+ // Calculate real coordinates using inverse transformation
438
+ const matrix = {
439
+ "a": 52.800301716009805,
440
+ "c": 0,
441
+ "e": 476.39449368282106,
442
+ "b": 0,
443
+ "d": -52.800301716009805,
444
+ "f": 311.2879502168584
445
+ };
446
+ // Manually invert and apply the affine transform
447
+ // Since we only use translate and scale, we can directly compute:
448
+ // x' = (x - tx) / sx
449
+ // y' = (y - ty) / sy
450
+ const sx = matrix.a;
451
+ const sy = matrix.d;
452
+ const tx = matrix.e;
453
+ const ty = matrix.f;
454
+ const realPoint = {
455
+ x: (x - tx) / sx,
456
+ y: (y - ty) / sy // Flip y back since we used negative scale
457
+ }
458
+
459
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
460
+ coords.setAttribute('x', (x + 5).toString());
461
+ coords.setAttribute('y', (y - 5).toString());
462
+ });
463
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
464
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
465
+ });
466
+ ]]>
467
+ </script>
468
+ </svg>
@@ -138,7 +138,7 @@ orientation: x+" data-x="-4.7" data-y="-0.3999999999999999" cx="202.273458966275
138
138
  </g>
139
139
  <g>
140
140
  <circle data-type="point" data-label="anchorPoint
141
- orientation: x-" data-x="-3" data-y="-0.3999999999999999" cx="258.57241411784" cy="290.1946708021127" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
141
+ orientation: x-" data-x="-3" data-y="-2.75" cx="258.57241411784" cy="368.01969704104056" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
142
142
  </g>
143
143
  <g>
144
144
  <circle data-type="point" data-label="anchorPoint
@@ -318,7 +318,7 @@ orientation: x-" data-x="6" data-y="4.3" cx="556.6257060967127" cy="134.54461832
318
318
  <polyline data-points="4.950000000000001,-4.8 5.150000000000001,-4.8 5.150000000000001,-0.42499999999999993 2.6999999999999997,-0.42499999999999993" data-type="line" data-label="" points="521.8528220325109,435.9096135473393 528.4762285209304,435.9096135473393 528.4762285209304,291.0225966131651 447.3394990377927,291.0225966131651" fill="none" stroke="purple" stroke-width="1" />
319
319
  </g>
320
320
  <g>
321
- <polyline data-points="-2.7,1.0999999999999996 -4.9,1.0999999999999996 -4.9,-2.2 -4.7,-2.2 -4.7,-2" data-type="line" data-label="" points="268.50752385046906,240.51912213896725 195.65005247785575,240.51912213896725 195.65005247785575,349.8053291978872 202.27345896627517,349.8053291978872 202.27345896627517,343.1819227094678" fill="none" stroke="purple" stroke-width="1" />
321
+ <polyline data-points="-2.7,1.0999999999999996 -3.7,1.0999999999999996 -3.7,-2.2 -4.7,-2.2 -4.7,-2" data-type="line" data-label="" points="268.50752385046906,240.51912213896725 235.39049140837213,240.51912213896725 235.39049140837213,349.8053291978872 202.27345896627517,349.8053291978872 202.27345896627517,343.1819227094678" fill="none" stroke="purple" stroke-width="1" />
322
322
  </g>
323
323
  <g>
324
324
  <polyline data-points="0,-1.3499999999999999 0,-1.5499999999999998 -2.8,-1.5499999999999998 -2.8,1.1 -2.6999999999999997,1.1" data-type="line" data-label="" points="357.9235114441309,321.6558516221048 357.9235114441309,328.2792581105242 265.1958206062594,328.2792581105242 265.1958206062594,240.51912213896725 268.5075238504691,240.51912213896725" fill="none" stroke="purple" stroke-width="1" />
@@ -374,7 +374,7 @@ globalConnNetId: connectivity_net6" data-x="-4.4750000000000005" data-y="-0.3999
374
374
  </g>
375
375
  <g>
376
376
  <rect data-type="rect" data-label="netId: PACKP
377
- globalConnNetId: connectivity_net7" data-x="-3.36" data-y="-0.3999999999999999" x="234.7281507595302" y="286.882967557903" width="23.84426335830983" height="6.623406488419391" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.030195942276785723" />
377
+ globalConnNetId: connectivity_net7" data-x="-3.36" data-y="-2.75" x="234.7281507595302" y="364.70799379683086" width="23.84426335830983" height="6.623406488419391" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.030195942276785723" />
378
378
  </g>
379
379
  <g>
380
380
  <rect data-type="rect" data-label="netId: PACKP
@@ -0,0 +1,258 @@
1
+ {
2
+ "chips": [
3
+ {
4
+ "chipId": "schematic_component_0",
5
+ "center": {
6
+ "x": 0,
7
+ "y": 0
8
+ },
9
+ "width": 2.2,
10
+ "height": 3,
11
+ "pins": [
12
+ {
13
+ "pinId": "U1.1",
14
+ "x": -1.5,
15
+ "y": 0.10000000000000009
16
+ },
17
+ {
18
+ "pinId": "U1.8",
19
+ "x": 1.5,
20
+ "y": 1.3
21
+ },
22
+ {
23
+ "pinId": "U1.11",
24
+ "x": -1.5,
25
+ "y": 1.3
26
+ },
27
+ {
28
+ "pinId": "U1.12",
29
+ "x": -1.5,
30
+ "y": 1.1
31
+ },
32
+ {
33
+ "pinId": "U1.17",
34
+ "x": 1.5,
35
+ "y": 1.0999999999999999
36
+ },
37
+ {
38
+ "pinId": "U1.25",
39
+ "x": -1.5,
40
+ "y": 0.9
41
+ },
42
+ {
43
+ "pinId": "U1.26",
44
+ "x": -1.5,
45
+ "y": -0.4999999999999998
46
+ },
47
+ {
48
+ "pinId": "U1.27",
49
+ "x": -1.5,
50
+ "y": -0.6999999999999997
51
+ },
52
+ {
53
+ "pinId": "U1.28",
54
+ "x": -1.5,
55
+ "y": -1.0999999999999999
56
+ },
57
+ {
58
+ "pinId": "U1.30",
59
+ "x": -1.5,
60
+ "y": 0.5
61
+ },
62
+ {
63
+ "pinId": "U1.31",
64
+ "x": 1.5,
65
+ "y": 0.8999999999999997
66
+ },
67
+ {
68
+ "pinId": "U1.34",
69
+ "x": -1.5,
70
+ "y": -0.09999999999999987
71
+ },
72
+ {
73
+ "pinId": "U1.35",
74
+ "x": 1.5,
75
+ "y": -1.1
76
+ },
77
+ {
78
+ "pinId": "U1.36",
79
+ "x": 1.5,
80
+ "y": -1.3
81
+ },
82
+ {
83
+ "pinId": "U1.37",
84
+ "x": -1.5,
85
+ "y": -0.8999999999999997
86
+ },
87
+ {
88
+ "pinId": "U1.38",
89
+ "x": 1.5,
90
+ "y": 0.6999999999999997
91
+ },
92
+ {
93
+ "pinId": "U1.39",
94
+ "x": 1.5,
95
+ "y": -2.220446049250313e-16
96
+ },
97
+ {
98
+ "pinId": "U1.40",
99
+ "x": 1.5,
100
+ "y": -0.40000000000000013
101
+ },
102
+ {
103
+ "pinId": "U1.41",
104
+ "x": -1.5,
105
+ "y": -1.3
106
+ }
107
+ ]
108
+ },
109
+ {
110
+ "chipId": "schematic_component_1",
111
+ "center": {
112
+ "x": -5.5,
113
+ "y": 0.6
114
+ },
115
+ "width": 1.16,
116
+ "height": 0.46,
117
+ "pins": [
118
+ {
119
+ "pinId": "L1.1",
120
+ "x": -6.05,
121
+ "y": 0.58
122
+ },
123
+ {
124
+ "pinId": "L1.2",
125
+ "x": -4.95,
126
+ "y": 0.57
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ "chipId": "schematic_component_2",
132
+ "center": {
133
+ "x": -8,
134
+ "y": -1
135
+ },
136
+ "width": 0.53,
137
+ "height": 1.1,
138
+ "pins": [
139
+ {
140
+ "pinId": "C105.1",
141
+ "x": -8,
142
+ "y": -0.44999999999999996
143
+ },
144
+ {
145
+ "pinId": "C105.2",
146
+ "x": -8,
147
+ "y": -1.55
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ "chipId": "schematic_component_3",
153
+ "center": {
154
+ "x": -4.3,
155
+ "y": -1
156
+ },
157
+ "width": 0.53,
158
+ "height": 1.1,
159
+ "pins": [
160
+ {
161
+ "pinId": "C106.1",
162
+ "x": -4.3,
163
+ "y": -0.44999999999999996
164
+ },
165
+ {
166
+ "pinId": "C106.2",
167
+ "x": -4.3,
168
+ "y": -1.55
169
+ }
170
+ ]
171
+ },
172
+ {
173
+ "chipId": "schematic_component_4",
174
+ "center": {
175
+ "x": -5.8,
176
+ "y": -1
177
+ },
178
+ "width": 0.53,
179
+ "height": 1.1,
180
+ "pins": [
181
+ {
182
+ "pinId": "C107.1",
183
+ "x": -5.8,
184
+ "y": -0.44999999999999996
185
+ },
186
+ {
187
+ "pinId": "C107.2",
188
+ "x": -5.8,
189
+ "y": -1.55
190
+ }
191
+ ]
192
+ }
193
+ ],
194
+ "directConnections": [
195
+ {
196
+ "pinIds": ["U1.30", "L1.2"],
197
+ "netId": ".U1 > .DCDC to L1.pin2"
198
+ },
199
+ {
200
+ "pinIds": ["U1.1", "U1.34"],
201
+ "netId": ".U1 > .pin1 to U1.pin34"
202
+ },
203
+ {
204
+ "pinIds": ["C106.1", "L1.1"],
205
+ "netId": ".C106 > .pin1 to L1.pin1"
206
+ },
207
+ {
208
+ "pinIds": ["C107.1", "C106.1"],
209
+ "netId": ".C107 > .pin1 to C106.pin1"
210
+ }
211
+ ],
212
+ "netConnections": [
213
+ {
214
+ "netId": "VDDS",
215
+ "pinIds": [
216
+ "U1.1",
217
+ "U1.8",
218
+ "U1.17",
219
+ "U1.31",
220
+ "U1.34",
221
+ "U1.38",
222
+ "L1.1",
223
+ "C105.1",
224
+ "C106.1",
225
+ "C107.1"
226
+ ],
227
+ "netLabelWidth": 0.6
228
+ },
229
+ {
230
+ "netId": "WMCU_SWDIO",
231
+ "pinIds": ["U1.11"],
232
+ "netLabelWidth": 1.32
233
+ },
234
+ {
235
+ "netId": "WMCU_SWDCK",
236
+ "pinIds": ["U1.12"],
237
+ "netLabelWidth": 1.32
238
+ },
239
+ {
240
+ "netId": "ANT_RF",
241
+ "pinIds": ["U1.39"],
242
+ "netLabelWidth": 0.84
243
+ },
244
+ {
245
+ "netId": "GND",
246
+ "pinIds": ["U1.40", "U1.41", "C105.2", "C106.2", "C107.2"],
247
+ "netLabelWidth": 0.48
248
+ }
249
+ ],
250
+ "availableNetLabelOrientations": {
251
+ "WMCU_SWDIO": ["x-", "x+"],
252
+ "WMCU_SWDCK": ["x-", "x+"],
253
+ "VDDS": ["y+"],
254
+ "GND": ["y-"],
255
+ "ANT_RF": ["x-", "x+"]
256
+ },
257
+ "maxMspPairDistance": 2.4
258
+ }
@@ -0,0 +1,11 @@
1
+ import { expect, test } from "bun:test"
2
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
3
+ import inputProblem from "./assets/repro-cc2340r5.input.json"
4
+ import "tests/fixtures/matcher"
5
+
6
+ test("repro cc2340r5 VDDS trace overlaps its own net label", () => {
7
+ const solver = new SchematicTracePipelineSolver(inputProblem as any)
8
+ solver.solve()
9
+
10
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
11
+ })
@@ -36,7 +36,7 @@ const pathIntersectsRect = (path: Array<{ x: number; y: number }>, rect: any) =>
36
36
  return segmentIntersectsRect(path[index - 1], point, rect)
37
37
  })
38
38
 
39
- test("repro130 bq27441 fuel gauge trace crosses C1 obstacle", () => {
39
+ test("repro130 bq27441 fuel gauge trace does not cross C1 obstacle", () => {
40
40
  const solver = new SchematicTracePipelineSolver(inputProblem as any)
41
41
  solver.solve()
42
42
 
@@ -54,7 +54,7 @@ test("repro130 bq27441 fuel gauge trace crosses C1 obstacle", () => {
54
54
  expect(c1).toBeDefined()
55
55
  expect(traceThroughC1).toBeDefined()
56
56
  expect(pathIntersectsRect(traceThroughC1!.tracePath, getChipRect(c1))).toBe(
57
- true,
57
+ false,
58
58
  )
59
59
  expect(solver).toMatchSolverSnapshot(import.meta.path)
60
60
  })