@tscircuit/schematic-trace-solver 0.0.116 → 0.0.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +79 -1
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +115 -1
- package/package.json +1 -1
- package/site/bug-reports/bug-report-20260731T052229Z.page.tsx +4 -0
- package/tests/bug-reports/bug-report-20260731T052229Z/__snapshots__/bug-report-20260731T052229Z.snap.svg +93 -0
- package/tests/bug-reports/bug-report-20260731T052229Z/bug-report-20260731T052229Z.json +299 -0
- package/tests/bug-reports/bug-report-20260731T052229Z/bug-report-20260731T052229Z.test.ts +61 -0
package/dist/index.d.ts
CHANGED
|
@@ -744,6 +744,8 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
744
744
|
currentLabelIndex: number | null;
|
|
745
745
|
currentLabel: NetLabelPlacement | null;
|
|
746
746
|
currentCandidateResults: EvaluatedCandidate[];
|
|
747
|
+
blockedStandaloneLabelIndex: number | null;
|
|
748
|
+
blockedStandaloneLabelTargetAnchorX: number | null;
|
|
747
749
|
private traceMap;
|
|
748
750
|
private chipObstacleSpatialIndex;
|
|
749
751
|
private maxSearchDistance;
|
|
@@ -782,6 +784,8 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
782
784
|
private findValidCandidateInShiftColumn;
|
|
783
785
|
private evaluateCandidate;
|
|
784
786
|
private getCandidateConnectorTrace;
|
|
787
|
+
private isStandaloneSinglePinNetLabel;
|
|
788
|
+
private labelIntersectsDifferentNetTrace;
|
|
785
789
|
private getSearchStartAnchor;
|
|
786
790
|
private getWickOffsetAnchor;
|
|
787
791
|
private getSideOffsetAnchor;
|
package/dist/index.js
CHANGED
|
@@ -7848,6 +7848,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
7848
7848
|
currentLabelIndex = null;
|
|
7849
7849
|
currentLabel = null;
|
|
7850
7850
|
currentCandidateResults = [];
|
|
7851
|
+
blockedStandaloneLabelIndex = null;
|
|
7852
|
+
blockedStandaloneLabelTargetAnchorX = null;
|
|
7851
7853
|
traceMap;
|
|
7852
7854
|
chipObstacleSpatialIndex;
|
|
7853
7855
|
maxSearchDistance;
|
|
@@ -7895,6 +7897,52 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
7895
7897
|
indices.push(i);
|
|
7896
7898
|
}
|
|
7897
7899
|
}
|
|
7900
|
+
const blockedStandaloneLabelIndex = indices.find((index) => {
|
|
7901
|
+
const label = this.outputNetLabelPlacements[index];
|
|
7902
|
+
const orientations = this.getAvailableOrientations(label);
|
|
7903
|
+
return this.isPortOnlyLabel(label) && this.isStandaloneSinglePinNetLabel(label) && orientations.length === 1 && isYOrientation(orientations[0]) && this.labelIntersectsDifferentNetTrace(label);
|
|
7904
|
+
});
|
|
7905
|
+
if (blockedStandaloneLabelIndex === void 0) return indices;
|
|
7906
|
+
this.blockedStandaloneLabelIndex = blockedStandaloneLabelIndex;
|
|
7907
|
+
this.blockedStandaloneLabelTargetAnchorX = null;
|
|
7908
|
+
const blockedLabel = this.outputNetLabelPlacements[blockedStandaloneLabelIndex];
|
|
7909
|
+
const requiredOrientation = this.getAvailableOrientations(blockedLabel)[0];
|
|
7910
|
+
const chipSide = this.getChipSideForPoint(blockedLabel.anchorPoint);
|
|
7911
|
+
const affectedSlots = [];
|
|
7912
|
+
const labelsToOrder = [];
|
|
7913
|
+
for (let slot = 0; slot < indices.length; slot++) {
|
|
7914
|
+
const index = indices[slot];
|
|
7915
|
+
const label = this.outputNetLabelPlacements[index];
|
|
7916
|
+
const orientations = this.getAvailableOrientations(label);
|
|
7917
|
+
if (this.getChipSideForPoint(label.anchorPoint) === chipSide && orientations.length === 1 && orientations[0] === requiredOrientation) {
|
|
7918
|
+
affectedSlots.push(slot);
|
|
7919
|
+
labelsToOrder.push(index);
|
|
7920
|
+
}
|
|
7921
|
+
}
|
|
7922
|
+
labelsToOrder.sort((a, b) => {
|
|
7923
|
+
const aY = this.outputNetLabelPlacements[a].anchorPoint.y;
|
|
7924
|
+
const bY = this.outputNetLabelPlacements[b].anchorPoint.y;
|
|
7925
|
+
return requiredOrientation === "y+" ? bY - aY : aY - bY;
|
|
7926
|
+
});
|
|
7927
|
+
const blockedLabelWidth = this.getNetLabelWidth(blockedLabel);
|
|
7928
|
+
let columnLabelIndex;
|
|
7929
|
+
if (blockedLabelWidth !== void 0) {
|
|
7930
|
+
columnLabelIndex = labelsToOrder.find((index) => {
|
|
7931
|
+
if (index === blockedStandaloneLabelIndex) return false;
|
|
7932
|
+
const label = this.outputNetLabelPlacements[index];
|
|
7933
|
+
return this.getNetLabelWidth(label) === blockedLabelWidth;
|
|
7934
|
+
});
|
|
7935
|
+
}
|
|
7936
|
+
if (columnLabelIndex !== void 0) {
|
|
7937
|
+
const columnLabel = this.outputNetLabelPlacements[columnLabelIndex];
|
|
7938
|
+
this.blockedStandaloneLabelTargetAnchorX = this.getSearchStartAnchor(
|
|
7939
|
+
columnLabel,
|
|
7940
|
+
requiredOrientation
|
|
7941
|
+
).x;
|
|
7942
|
+
}
|
|
7943
|
+
for (let i = 0; i < affectedSlots.length; i++) {
|
|
7944
|
+
indices[affectedSlots[i]] = labelsToOrder[i];
|
|
7945
|
+
}
|
|
7898
7946
|
return indices;
|
|
7899
7947
|
}
|
|
7900
7948
|
shouldProcessLabel(label) {
|
|
@@ -8213,6 +8261,28 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8213
8261
|
candidate.orientation
|
|
8214
8262
|
);
|
|
8215
8263
|
}
|
|
8264
|
+
isStandaloneSinglePinNetLabel(label) {
|
|
8265
|
+
return this.inputProblem.netConnections.some(
|
|
8266
|
+
(connection) => connection.netId === label.netId && connection.pinIds.length === 1 && connection.pinIds[0] === label.pinIds[0]
|
|
8267
|
+
);
|
|
8268
|
+
}
|
|
8269
|
+
labelIntersectsDifferentNetTrace(label) {
|
|
8270
|
+
const { width, height } = getDimsForOrientation({
|
|
8271
|
+
orientation: label.orientation,
|
|
8272
|
+
netLabelWidth: this.getNetLabelWidth(label),
|
|
8273
|
+
netLabelHeight: this.getNetLabelHeight(label)
|
|
8274
|
+
});
|
|
8275
|
+
const center = getCenterFromAnchor(
|
|
8276
|
+
label.anchorPoint,
|
|
8277
|
+
label.orientation,
|
|
8278
|
+
width,
|
|
8279
|
+
height
|
|
8280
|
+
);
|
|
8281
|
+
const bounds = getRectBounds(center, width, height);
|
|
8282
|
+
return Object.values(this.traceMap).some(
|
|
8283
|
+
(trace) => trace.globalConnNetId !== label.globalConnNetId && tracePathIntersectsBounds(trace.tracePath, bounds)
|
|
8284
|
+
);
|
|
8285
|
+
}
|
|
8216
8286
|
getSearchStartAnchor(label, orientation) {
|
|
8217
8287
|
const anchorPoint = this.getWickOffsetAnchor(label.anchorPoint, orientation);
|
|
8218
8288
|
const { width, height } = getDimsForOrientation({
|
|
@@ -8220,13 +8290,17 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8220
8290
|
netLabelWidth: this.getNetLabelWidth(label),
|
|
8221
8291
|
netLabelHeight: this.getNetLabelHeight(label)
|
|
8222
8292
|
});
|
|
8223
|
-
|
|
8293
|
+
const searchStartAnchor = this.getSideOffsetAnchor({
|
|
8224
8294
|
anchorPoint,
|
|
8225
8295
|
labelAnchorPoint: label.anchorPoint,
|
|
8226
8296
|
orientation,
|
|
8227
8297
|
width,
|
|
8228
8298
|
height
|
|
8229
8299
|
});
|
|
8300
|
+
if (this.blockedStandaloneLabelIndex !== null && label === this.outputNetLabelPlacements[this.blockedStandaloneLabelIndex] && isYOrientation(orientation) && this.blockedStandaloneLabelTargetAnchorX !== null) {
|
|
8301
|
+
searchStartAnchor.x = this.blockedStandaloneLabelTargetAnchorX;
|
|
8302
|
+
}
|
|
8303
|
+
return searchStartAnchor;
|
|
8230
8304
|
}
|
|
8231
8305
|
getWickOffsetAnchor(anchorPoint, orientation) {
|
|
8232
8306
|
const direction = dir(orientation);
|
|
@@ -8486,6 +8560,10 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
8486
8560
|
if (i === labelIndex) continue;
|
|
8487
8561
|
const label = this.outputNetLabelPlacements[i];
|
|
8488
8562
|
const otherBounds = getRectBounds(label.center, label.width, label.height);
|
|
8563
|
+
if (i === this.blockedStandaloneLabelIndex && isYOrientation(label.orientation)) {
|
|
8564
|
+
otherBounds.minX -= LABEL_SEARCH_STEP;
|
|
8565
|
+
otherBounds.maxX += LABEL_SEARCH_STEP;
|
|
8566
|
+
}
|
|
8489
8567
|
if (rectsOverlap2(bounds, otherBounds)) return true;
|
|
8490
8568
|
}
|
|
8491
8569
|
return false;
|
|
@@ -51,6 +51,8 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
51
51
|
currentLabel: NetLabelPlacement | null = null
|
|
52
52
|
currentCandidateResults: EvaluatedCandidate[] = []
|
|
53
53
|
|
|
54
|
+
blockedStandaloneLabelIndex: number | null = null
|
|
55
|
+
blockedStandaloneLabelTargetAnchorX: number | null = null
|
|
54
56
|
private traceMap: Record<string, SolvedTracePath>
|
|
55
57
|
private chipObstacleSpatialIndex: ChipObstacleSpatialIndex
|
|
56
58
|
private maxSearchDistance: number
|
|
@@ -110,6 +112,71 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
115
|
+
const blockedStandaloneLabelIndex = indices.find((index) => {
|
|
116
|
+
const label = this.outputNetLabelPlacements[index]!
|
|
117
|
+
const orientations = this.getAvailableOrientations(label)
|
|
118
|
+
return (
|
|
119
|
+
this.isPortOnlyLabel(label) &&
|
|
120
|
+
this.isStandaloneSinglePinNetLabel(label) &&
|
|
121
|
+
orientations.length === 1 &&
|
|
122
|
+
isYOrientation(orientations[0]!) &&
|
|
123
|
+
this.labelIntersectsDifferentNetTrace(label)
|
|
124
|
+
)
|
|
125
|
+
})
|
|
126
|
+
if (blockedStandaloneLabelIndex === undefined) return indices
|
|
127
|
+
this.blockedStandaloneLabelIndex = blockedStandaloneLabelIndex
|
|
128
|
+
this.blockedStandaloneLabelTargetAnchorX = null
|
|
129
|
+
|
|
130
|
+
const blockedLabel =
|
|
131
|
+
this.outputNetLabelPlacements[blockedStandaloneLabelIndex]!
|
|
132
|
+
const requiredOrientation = this.getAvailableOrientations(blockedLabel)[0]!
|
|
133
|
+
const chipSide = this.getChipSideForPoint(blockedLabel.anchorPoint)
|
|
134
|
+
const affectedSlots: number[] = []
|
|
135
|
+
const labelsToOrder: number[] = []
|
|
136
|
+
|
|
137
|
+
for (let slot = 0; slot < indices.length; slot++) {
|
|
138
|
+
const index = indices[slot]!
|
|
139
|
+
const label = this.outputNetLabelPlacements[index]!
|
|
140
|
+
const orientations = this.getAvailableOrientations(label)
|
|
141
|
+
if (
|
|
142
|
+
this.getChipSideForPoint(label.anchorPoint) === chipSide &&
|
|
143
|
+
orientations.length === 1 &&
|
|
144
|
+
orientations[0] === requiredOrientation
|
|
145
|
+
) {
|
|
146
|
+
affectedSlots.push(slot)
|
|
147
|
+
labelsToOrder.push(index)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Place vertical labels on the same chip side from the outward end inward.
|
|
152
|
+
// The standalone label is corrected first, then a lower neighbor yields
|
|
153
|
+
// space during its own placement, keeping the standalone connector direct.
|
|
154
|
+
labelsToOrder.sort((a, b) => {
|
|
155
|
+
const aY = this.outputNetLabelPlacements[a]!.anchorPoint.y
|
|
156
|
+
const bY = this.outputNetLabelPlacements[b]!.anchorPoint.y
|
|
157
|
+
return requiredOrientation === "y+" ? bY - aY : aY - bY
|
|
158
|
+
})
|
|
159
|
+
const blockedLabelWidth = this.getNetLabelWidth(blockedLabel)
|
|
160
|
+
let columnLabelIndex: number | undefined
|
|
161
|
+
if (blockedLabelWidth !== undefined) {
|
|
162
|
+
columnLabelIndex = labelsToOrder.find((index) => {
|
|
163
|
+
if (index === blockedStandaloneLabelIndex) return false
|
|
164
|
+
const label = this.outputNetLabelPlacements[index]!
|
|
165
|
+
return this.getNetLabelWidth(label) === blockedLabelWidth
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
if (columnLabelIndex !== undefined) {
|
|
169
|
+
const columnLabel = this.outputNetLabelPlacements[columnLabelIndex]!
|
|
170
|
+
// Reuse the established same-width column instead of a nearby search step.
|
|
171
|
+
this.blockedStandaloneLabelTargetAnchorX = this.getSearchStartAnchor(
|
|
172
|
+
columnLabel,
|
|
173
|
+
requiredOrientation,
|
|
174
|
+
).x
|
|
175
|
+
}
|
|
176
|
+
for (let i = 0; i < affectedSlots.length; i++) {
|
|
177
|
+
indices[affectedSlots[i]!] = labelsToOrder[i]!
|
|
178
|
+
}
|
|
179
|
+
|
|
113
180
|
return indices
|
|
114
181
|
}
|
|
115
182
|
|
|
@@ -551,6 +618,35 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
551
618
|
)
|
|
552
619
|
}
|
|
553
620
|
|
|
621
|
+
private isStandaloneSinglePinNetLabel(label: NetLabelPlacement) {
|
|
622
|
+
return this.inputProblem.netConnections.some(
|
|
623
|
+
(connection) =>
|
|
624
|
+
connection.netId === label.netId &&
|
|
625
|
+
connection.pinIds.length === 1 &&
|
|
626
|
+
connection.pinIds[0] === label.pinIds[0],
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
private labelIntersectsDifferentNetTrace(label: NetLabelPlacement) {
|
|
631
|
+
const { width, height } = getDimsForOrientation({
|
|
632
|
+
orientation: label.orientation,
|
|
633
|
+
netLabelWidth: this.getNetLabelWidth(label),
|
|
634
|
+
netLabelHeight: this.getNetLabelHeight(label),
|
|
635
|
+
})
|
|
636
|
+
const center = getCenterFromAnchor(
|
|
637
|
+
label.anchorPoint,
|
|
638
|
+
label.orientation,
|
|
639
|
+
width,
|
|
640
|
+
height,
|
|
641
|
+
)
|
|
642
|
+
const bounds = getRectBounds(center, width, height)
|
|
643
|
+
return Object.values(this.traceMap).some(
|
|
644
|
+
(trace) =>
|
|
645
|
+
trace.globalConnNetId !== label.globalConnNetId &&
|
|
646
|
+
tracePathIntersectsBounds(trace.tracePath, bounds),
|
|
647
|
+
)
|
|
648
|
+
}
|
|
649
|
+
|
|
554
650
|
private getSearchStartAnchor(
|
|
555
651
|
label: NetLabelPlacement,
|
|
556
652
|
orientation: FacingDirection,
|
|
@@ -562,13 +658,23 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
562
658
|
netLabelHeight: this.getNetLabelHeight(label),
|
|
563
659
|
})
|
|
564
660
|
|
|
565
|
-
|
|
661
|
+
const searchStartAnchor = this.getSideOffsetAnchor({
|
|
566
662
|
anchorPoint,
|
|
567
663
|
labelAnchorPoint: label.anchorPoint,
|
|
568
664
|
orientation,
|
|
569
665
|
width,
|
|
570
666
|
height,
|
|
571
667
|
})
|
|
668
|
+
if (
|
|
669
|
+
this.blockedStandaloneLabelIndex !== null &&
|
|
670
|
+
label ===
|
|
671
|
+
this.outputNetLabelPlacements[this.blockedStandaloneLabelIndex] &&
|
|
672
|
+
isYOrientation(orientation) &&
|
|
673
|
+
this.blockedStandaloneLabelTargetAnchorX !== null
|
|
674
|
+
) {
|
|
675
|
+
searchStartAnchor.x = this.blockedStandaloneLabelTargetAnchorX
|
|
676
|
+
}
|
|
677
|
+
return searchStartAnchor
|
|
572
678
|
}
|
|
573
679
|
|
|
574
680
|
private getWickOffsetAnchor(
|
|
@@ -932,6 +1038,14 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
932
1038
|
if (i === labelIndex) continue
|
|
933
1039
|
const label = this.outputNetLabelPlacements[i]!
|
|
934
1040
|
const otherBounds = getRectBounds(label.center, label.width, label.height)
|
|
1041
|
+
if (
|
|
1042
|
+
i === this.blockedStandaloneLabelIndex &&
|
|
1043
|
+
isYOrientation(label.orientation)
|
|
1044
|
+
) {
|
|
1045
|
+
// Keep later labels one search step away from the blocked label.
|
|
1046
|
+
otherBounds.minX -= LABEL_SEARCH_STEP
|
|
1047
|
+
otherBounds.maxX += LABEL_SEARCH_STEP
|
|
1048
|
+
}
|
|
935
1049
|
if (rectsOverlap(bounds, otherBounds)) return true
|
|
936
1050
|
}
|
|
937
1051
|
return false
|
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="-1.9,2.550000000000001 -1.9,2.350000000000001" data-type="line" data-label="" points="219.27392739273924,85.28052805280515 219.27392739273924,103.76237623762367" fill="none" stroke="hsl(124, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,2.550000000000001 -1.9,2.1500000000000012" data-type="line" data-label="" points="219.27392739273924,85.28052805280515 219.27392739273924,122.24422442244213" fill="none" stroke="hsl(124, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,2.350000000000001 -1.9,2.1500000000000012" data-type="line" data-label="" points="219.27392739273924,103.76237623762367 219.27392739273924,122.24422442244213" fill="none" stroke="hsl(124, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,0.7500000000000013 -1.9,0.5500000000000014" data-type="line" data-label="" points="219.27392739273924,251.6171617161715 219.27392739273924,270.09900990099" fill="none" stroke="hsl(44, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.950000000000001 -1.9,1.750000000000001" data-type="line" data-label="" points="219.27392739273924,140.72607260726062 219.27392739273924,159.2079207920791" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.950000000000001 -1.9,1.5500000000000012" data-type="line" data-label="" points="219.27392739273924,140.72607260726062 219.27392739273924,177.68976897689757" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.950000000000001 -1.9,1.3500000000000012" data-type="line" data-label="" points="219.27392739273924,140.72607260726062 219.27392739273924,196.17161716171606" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.750000000000001 -1.9,1.5500000000000012" data-type="line" data-label="" points="219.27392739273924,159.2079207920791 219.27392739273924,177.68976897689757" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.750000000000001 -1.9,1.3500000000000012" data-type="line" data-label="" points="219.27392739273924,159.2079207920791 219.27392739273924,196.17161716171606" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,1.5500000000000012 -1.9,1.3500000000000012" data-type="line" data-label="" points="219.27392739273924,177.68976897689757 219.27392739273924,196.17161716171606" fill="none" stroke="hsl(125, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.9,2.350000000000001 -2.0999999999999996,2.350000000000001 -2.0999999999999996,2.550000000000001 -1.9,2.550000000000001" data-type="line" data-label="" points="219.27392739273924,103.76237623762367 200.79207920792078,103.76237623762367 200.79207920792078,85.28052805280515 219.27392739273924,85.28052805280515" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,2.1500000000000012 -2.0999999999999996,2.1500000000000012 -2.0999999999999996,2.350000000000001 -1.9,2.350000000000001" data-type="line" data-label="" points="219.27392739273924,122.24422442244213 200.79207920792078,122.24422442244213 200.79207920792078,103.76237623762367 219.27392739273924,103.76237623762367" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,0.7500000000000013 -2.0999999999999996,0.7500000000000013 -2.0999999999999996,0.5500000000000014 -1.9,0.5500000000000014" data-type="line" data-label="" points="219.27392739273924,251.6171617161715 200.79207920792078,251.6171617161715 200.79207920792078,270.09900990099 219.27392739273924,270.09900990099" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,1.750000000000001 -2.0999999999999996,1.750000000000001 -2.0999999999999996,1.950000000000001 -1.9,1.950000000000001" data-type="line" data-label="" points="219.27392739273924,159.2079207920791 200.79207920792078,159.2079207920791 200.79207920792078,140.72607260726062 219.27392739273924,140.72607260726062" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,1.5500000000000012 -2.0999999999999996,1.5500000000000012 -2.0999999999999996,1.750000000000001 -1.9,1.750000000000001" data-type="line" data-label="" points="219.27392739273924,177.68976897689757 200.79207920792078,177.68976897689757 200.79207920792078,159.2079207920791 219.27392739273924,159.2079207920791" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,1.3500000000000012 -2.0999999999999996,1.3500000000000012 -2.0999999999999996,1.5500000000000012 -1.9,1.5500000000000012" data-type="line" data-label="" points="219.27392739273924,196.17161716171606 200.79207920792078,196.17161716171606 200.79207920792078,177.68976897689757 219.27392739273924,177.68976897689757" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.0999999999999996,2.350000000000001 -2.4499999999999993,2.350000000000001 -2.4499999999999993,2.351000000000001" data-type="line" data-label="" points="200.79207920792078,103.76237623762367 168.44884488448847,103.76237623762367 168.44884488448847,103.66996699669957" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.0999999999999996,1.750000000000001 -2.4499999999999993,1.750000000000001 -2.4499999999999993,1.751000000000001" data-type="line" data-label="" points="200.79207920792078,159.2079207920791 168.44884488448847,159.2079207920791 168.44884488448847,159.115511551155" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.9,1.1500000000000012 -2.4499999999999993,1.1500000000000012 -2.4499999999999993,1.1510000000000011" data-type="line" data-label="" points="219.27392739273924,214.65346534653452 168.44884488448847,214.65346534653452 168.44884488448847,214.56105610561045" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-2.0999999999999996,0.7500000000000013 -3.1599999999999993,0.7500000000000013 -3.1599999999999993,0.8010000000000014" data-type="line" data-label="" points="200.79207920792078,251.6171617161715 102.83828382838288,251.6171617161715 102.83828382838288,246.90429042904276" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="219.2739273927392" y="62.1782178217822" width="351.15511551155123" height="517.4917491749175" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="CC2745R10E0WRHARQ1" data-x="-0.41999999999999993" data-y="-2.9299999999999997" x="256.2376237623762" y="583.3663366336633" width="199.60396039603967" height="16.633663366336577" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="U1" data-x="-1.38" data-y="2.915" x="250.69306930693068" y="39.99999999999997" width="33.2673267326733" height="23.10231023102307" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="netId: VDDR
|
|
2
|
+
globalConnNetId: connectivity_net0" data-x="-2.4499999999999993" data-y="2.561000000000001" x="140.72607260726076" y="64.85808580858078" width="55.44554455445541" height="38.811881188118804" fill="#ef444466" stroke="#ef4444" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="netId: VDDIO
|
|
3
|
+
globalConnNetId: connectivity_net1" data-x="-3.1599999999999993" data-y="1.0110000000000015" x="69.57095709570964" y="208.09240924092393" width="66.53465346534648" height="38.811881188118804" fill="#ef444466" stroke="#ef4444" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="netId: VDDS
|
|
4
|
+
globalConnNetId: connectivity_net2" data-x="-2.4499999999999993" data-y="1.961000000000001" x="140.72607260726076" y="120.3036303630362" width="55.44554455445541" height="38.81188118811883" fill="#ef444466" stroke="#ef4444" stroke-width="0.01082142857142857"/></g><g><rect data-type="rect" data-label="netId: VDDD
|
|
5
|
+
globalConnNetId: connectivity_net3" data-x="-2.4499999999999993" data-y="1.361000000000001" x="140.72607260726076" y="175.74917491749164" width="55.44554455445541" height="38.811881188118804" fill="#ef444466" stroke="#ef4444" stroke-width="0.01082142857142857"/></g><g><circle data-type="point" data-label="schematic_port_0
|
|
6
|
+
x-" data-x="-1.9" data-y="2.550000000000001" cx="219.27392739273924" cy="85.28052805280515" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_1
|
|
7
|
+
x-" data-x="-1.9" data-y="2.350000000000001" cx="219.27392739273924" cy="103.76237623762367" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_2
|
|
8
|
+
x+" data-x="1.9" data-y="1.7500000000000004" cx="570.4290429042904" cy="159.20792079207916" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_3
|
|
9
|
+
x+" data-x="1.9" data-y="1.5500000000000003" cx="570.4290429042904" cy="177.68976897689765" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_4
|
|
10
|
+
x+" data-x="1.9" data-y="1.3500000000000005" cx="570.4290429042904" cy="196.1716171617161" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_5
|
|
11
|
+
x+" data-x="1.9" data-y="1.1500000000000004" cx="570.4290429042904" cy="214.65346534653463" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_6
|
|
12
|
+
x+" data-x="1.9" data-y="0.9500000000000002" cx="570.4290429042904" cy="233.13531353135312" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_7
|
|
13
|
+
x+" data-x="1.9" data-y="0.75" cx="570.4290429042904" cy="251.6171617161716" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_8
|
|
14
|
+
x-" data-x="-1.9" data-y="0.7500000000000013" cx="219.27392739273924" cy="251.6171617161715" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_9
|
|
15
|
+
x+" data-x="1.9" data-y="0.5499999999999998" cx="570.4290429042904" cy="270.0990099009901" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_10
|
|
16
|
+
x+" data-x="1.9" data-y="0.34999999999999964" cx="570.4290429042904" cy="288.5808580858086" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_11
|
|
17
|
+
x+" data-x="1.9" data-y="0.14999999999999947" cx="570.4290429042904" cy="307.06270627062713" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_12
|
|
18
|
+
x+" data-x="1.9" data-y="-0.05000000000000071" cx="570.4290429042904" cy="325.5445544554456" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_13
|
|
19
|
+
x+" data-x="1.9" data-y="-0.2500000000000009" cx="570.4290429042904" cy="344.0264026402641" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_14
|
|
20
|
+
x+" data-x="1.9" data-y="-0.45000000000000107" cx="570.4290429042904" cy="362.5082508250826" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_15
|
|
21
|
+
x+" data-x="1.9" data-y="-0.6500000000000012" cx="570.4290429042904" cy="380.9900990099011" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_16
|
|
22
|
+
x-" data-x="-1.9" data-y="0.5500000000000014" cx="219.27392739273924" cy="270.09900990099" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_17
|
|
23
|
+
x-" data-x="-1.9" data-y="1.950000000000001" cx="219.27392739273924" cy="140.72607260726062" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_18
|
|
24
|
+
x-" data-x="-1.9" data-y="0.15000000000000124" cx="219.27392739273924" cy="307.06270627062696" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_19
|
|
25
|
+
x-" data-x="-1.9" data-y="-0.049999999999998934" cx="219.27392739273924" cy="325.54455445544545" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_20
|
|
26
|
+
x-" data-x="-1.9" data-y="-0.2499999999999991" cx="219.27392739273924" cy="344.02640264026394" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_21
|
|
27
|
+
x-" data-x="-1.9" data-y="-0.4499999999999993" cx="219.27392739273924" cy="362.5082508250824" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_22
|
|
28
|
+
x-" data-x="-1.9" data-y="-0.6499999999999995" cx="219.27392739273924" cy="380.990099009901" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_23
|
|
29
|
+
x-" data-x="-1.9" data-y="-0.8499999999999996" cx="219.27392739273924" cy="399.47194719471946" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_24
|
|
30
|
+
x+" data-x="1.9" data-y="2.150000000000001" cx="570.4290429042904" cy="122.24422442244216" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_25
|
|
31
|
+
x-" data-x="-1.9" data-y="-1.65" cx="219.27392739273924" cy="473.3993399339934" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_26
|
|
32
|
+
x-" data-x="-1.9" data-y="-2.2500000000000004" cx="219.27392739273924" cy="528.8448844884489" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_27
|
|
33
|
+
x-" data-x="-1.9" data-y="1.1500000000000012" cx="219.27392739273924" cy="214.65346534653452" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_28
|
|
34
|
+
x-" data-x="-1.9" data-y="1.750000000000001" cx="219.27392739273924" cy="159.2079207920791" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_29
|
|
35
|
+
x-" data-x="-1.9" data-y="-2.650000000000001" cx="219.27392739273924" cy="565.8085808580859" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_30
|
|
36
|
+
x-" data-x="-1.9" data-y="1.5500000000000012" cx="219.27392739273924" cy="177.68976897689757" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_31
|
|
37
|
+
x-" data-x="-1.9" data-y="-1.0499999999999998" cx="219.27392739273924" cy="417.95379537953795" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_32
|
|
38
|
+
x-" data-x="-1.9" data-y="-1.25" cx="219.27392739273924" cy="436.43564356435644" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_33
|
|
39
|
+
x-" data-x="-1.9" data-y="2.1500000000000012" cx="219.27392739273924" cy="122.24422442244213" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_34
|
|
40
|
+
x+" data-x="1.9" data-y="-1.0500000000000012" cx="570.4290429042904" cy="417.95379537953806" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_35
|
|
41
|
+
x+" data-x="1.9" data-y="-1.6500000000000012" cx="570.4290429042904" cy="473.39933993399353" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_36
|
|
42
|
+
x+" data-x="1.9" data-y="-2.050000000000001" cx="570.4290429042904" cy="510.36303630363045" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_37
|
|
43
|
+
x-" data-x="-1.9" data-y="1.3500000000000012" cx="219.27392739273924" cy="196.17161716171606" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_38
|
|
44
|
+
x+" data-x="1.9" data-y="2.550000000000001" cx="570.4290429042904" cy="85.28052805280515" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_39
|
|
45
|
+
x+" data-x="1.9" data-y="-2.450000000000001" cx="570.4290429042904" cy="547.3267326732674" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="schematic_port_40
|
|
46
|
+
x+" data-x="1.9" data-y="-2.6500000000000012" cx="570.4290429042904" cy="565.808580858086" r="3" fill="hsl(184, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
47
|
+
orientation: y+" data-x="-2.4499999999999993" data-y="2.351000000000001" cx="168.44884488448847" cy="103.66996699669957" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
48
|
+
orientation: y+" data-x="-3.1599999999999993" data-y="0.8010000000000014" cx="102.83828382838288" cy="246.90429042904276" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
49
|
+
orientation: y+" data-x="-2.4499999999999993" data-y="1.751000000000001" cx="168.44884488448847" cy="159.115511551155" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
50
|
+
orientation: y+" data-x="-2.4499999999999993" data-y="1.1510000000000011" cx="168.44884488448847" cy="214.56105610561045" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><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></g><script><![CDATA[
|
|
51
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
52
|
+
const svg = e.currentTarget;
|
|
53
|
+
const rect = svg.getBoundingClientRect();
|
|
54
|
+
const x = e.clientX - rect.left;
|
|
55
|
+
const y = e.clientY - rect.top;
|
|
56
|
+
const crosshair = svg.getElementById('crosshair');
|
|
57
|
+
const h = svg.getElementById('crosshair-h');
|
|
58
|
+
const v = svg.getElementById('crosshair-v');
|
|
59
|
+
const coords = svg.getElementById('coordinates');
|
|
60
|
+
|
|
61
|
+
crosshair.style.display = 'block';
|
|
62
|
+
h.setAttribute('x1', '0');
|
|
63
|
+
h.setAttribute('x2', '640');
|
|
64
|
+
h.setAttribute('y1', y);
|
|
65
|
+
h.setAttribute('y2', y);
|
|
66
|
+
v.setAttribute('x1', x);
|
|
67
|
+
v.setAttribute('x2', x);
|
|
68
|
+
v.setAttribute('y1', '0');
|
|
69
|
+
v.setAttribute('y2', '640');
|
|
70
|
+
|
|
71
|
+
// Calculate real coordinates using inverse transformation
|
|
72
|
+
const matrix = {"a":92.40924092409242,"c":0,"e":394.8514851485148,"b":0,"d":-92.40924092409242,"f":320.9240924092409};
|
|
73
|
+
// Manually invert and apply the affine transform
|
|
74
|
+
// Since we only use translate and scale, we can directly compute:
|
|
75
|
+
// x' = (x - tx) / sx
|
|
76
|
+
// y' = (y - ty) / sy
|
|
77
|
+
const sx = matrix.a;
|
|
78
|
+
const sy = matrix.d;
|
|
79
|
+
const tx = matrix.e;
|
|
80
|
+
const ty = matrix.f;
|
|
81
|
+
const realPoint = {
|
|
82
|
+
x: (x - tx) / sx,
|
|
83
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
87
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
88
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
89
|
+
});
|
|
90
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
91
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
92
|
+
});
|
|
93
|
+
]]></script></svg>
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_0",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": 0,
|
|
7
|
+
"y": 0
|
|
8
|
+
},
|
|
9
|
+
"width": 3.8,
|
|
10
|
+
"height": 5.6,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "schematic_port_0",
|
|
14
|
+
"x": -1.9,
|
|
15
|
+
"y": 2.550000000000001
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "schematic_port_1",
|
|
19
|
+
"x": -1.9,
|
|
20
|
+
"y": 2.350000000000001
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"pinId": "schematic_port_2",
|
|
24
|
+
"x": 1.9,
|
|
25
|
+
"y": 1.7500000000000004
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"pinId": "schematic_port_3",
|
|
29
|
+
"x": 1.9,
|
|
30
|
+
"y": 1.5500000000000003
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"pinId": "schematic_port_4",
|
|
34
|
+
"x": 1.9,
|
|
35
|
+
"y": 1.3500000000000005
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"pinId": "schematic_port_5",
|
|
39
|
+
"x": 1.9,
|
|
40
|
+
"y": 1.1500000000000004
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"pinId": "schematic_port_6",
|
|
44
|
+
"x": 1.9,
|
|
45
|
+
"y": 0.9500000000000002
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"pinId": "schematic_port_7",
|
|
49
|
+
"x": 1.9,
|
|
50
|
+
"y": 0.75
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"pinId": "schematic_port_8",
|
|
54
|
+
"x": -1.9,
|
|
55
|
+
"y": 0.7500000000000013
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"pinId": "schematic_port_9",
|
|
59
|
+
"x": 1.9,
|
|
60
|
+
"y": 0.5499999999999998
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"pinId": "schematic_port_10",
|
|
64
|
+
"x": 1.9,
|
|
65
|
+
"y": 0.34999999999999964
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"pinId": "schematic_port_11",
|
|
69
|
+
"x": 1.9,
|
|
70
|
+
"y": 0.14999999999999947
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"pinId": "schematic_port_12",
|
|
74
|
+
"x": 1.9,
|
|
75
|
+
"y": -0.05000000000000071
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"pinId": "schematic_port_13",
|
|
79
|
+
"x": 1.9,
|
|
80
|
+
"y": -0.2500000000000009
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"pinId": "schematic_port_14",
|
|
84
|
+
"x": 1.9,
|
|
85
|
+
"y": -0.45000000000000107
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"pinId": "schematic_port_15",
|
|
89
|
+
"x": 1.9,
|
|
90
|
+
"y": -0.6500000000000012
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"pinId": "schematic_port_16",
|
|
94
|
+
"x": -1.9,
|
|
95
|
+
"y": 0.5500000000000014
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"pinId": "schematic_port_17",
|
|
99
|
+
"x": -1.9,
|
|
100
|
+
"y": 1.950000000000001
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"pinId": "schematic_port_18",
|
|
104
|
+
"x": -1.9,
|
|
105
|
+
"y": 0.15000000000000124
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"pinId": "schematic_port_19",
|
|
109
|
+
"x": -1.9,
|
|
110
|
+
"y": -0.049999999999998934
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"pinId": "schematic_port_20",
|
|
114
|
+
"x": -1.9,
|
|
115
|
+
"y": -0.2499999999999991
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"pinId": "schematic_port_21",
|
|
119
|
+
"x": -1.9,
|
|
120
|
+
"y": -0.4499999999999993
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"pinId": "schematic_port_22",
|
|
124
|
+
"x": -1.9,
|
|
125
|
+
"y": -0.6499999999999995
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"pinId": "schematic_port_23",
|
|
129
|
+
"x": -1.9,
|
|
130
|
+
"y": -0.8499999999999996
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"pinId": "schematic_port_24",
|
|
134
|
+
"x": 1.9,
|
|
135
|
+
"y": 2.150000000000001
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"pinId": "schematic_port_25",
|
|
139
|
+
"x": -1.9,
|
|
140
|
+
"y": -1.65
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"pinId": "schematic_port_26",
|
|
144
|
+
"x": -1.9,
|
|
145
|
+
"y": -2.2500000000000004
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"pinId": "schematic_port_27",
|
|
149
|
+
"x": -1.9,
|
|
150
|
+
"y": 1.1500000000000012
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"pinId": "schematic_port_28",
|
|
154
|
+
"x": -1.9,
|
|
155
|
+
"y": 1.750000000000001
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"pinId": "schematic_port_29",
|
|
159
|
+
"x": -1.9,
|
|
160
|
+
"y": -2.650000000000001
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"pinId": "schematic_port_30",
|
|
164
|
+
"x": -1.9,
|
|
165
|
+
"y": 1.5500000000000012
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"pinId": "schematic_port_31",
|
|
169
|
+
"x": -1.9,
|
|
170
|
+
"y": -1.0499999999999998
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"pinId": "schematic_port_32",
|
|
174
|
+
"x": -1.9,
|
|
175
|
+
"y": -1.25
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"pinId": "schematic_port_33",
|
|
179
|
+
"x": -1.9,
|
|
180
|
+
"y": 2.1500000000000012
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"pinId": "schematic_port_34",
|
|
184
|
+
"x": 1.9,
|
|
185
|
+
"y": -1.0500000000000012
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"pinId": "schematic_port_35",
|
|
189
|
+
"x": 1.9,
|
|
190
|
+
"y": -1.6500000000000012
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"pinId": "schematic_port_36",
|
|
194
|
+
"x": 1.9,
|
|
195
|
+
"y": -2.050000000000001
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"pinId": "schematic_port_37",
|
|
199
|
+
"x": -1.9,
|
|
200
|
+
"y": 1.3500000000000012
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"pinId": "schematic_port_38",
|
|
204
|
+
"x": 1.9,
|
|
205
|
+
"y": 2.550000000000001
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"pinId": "schematic_port_39",
|
|
209
|
+
"x": 1.9,
|
|
210
|
+
"y": -2.450000000000001
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"pinId": "schematic_port_40",
|
|
214
|
+
"x": 1.9,
|
|
215
|
+
"y": -2.6500000000000012
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"directConnections": [],
|
|
221
|
+
"netConnections": [
|
|
222
|
+
{
|
|
223
|
+
"netId": "VDDR",
|
|
224
|
+
"netLabelWidth": 0.42,
|
|
225
|
+
"netLabelHeight": 0.6,
|
|
226
|
+
"pinIds": [
|
|
227
|
+
"schematic_port_0",
|
|
228
|
+
"schematic_port_1",
|
|
229
|
+
"schematic_port_33"
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"netId": "VDDIO",
|
|
234
|
+
"netLabelWidth": 0.42,
|
|
235
|
+
"netLabelHeight": 0.72,
|
|
236
|
+
"pinIds": [
|
|
237
|
+
"schematic_port_8",
|
|
238
|
+
"schematic_port_16"
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"netId": "VDDS",
|
|
243
|
+
"netLabelWidth": 0.42,
|
|
244
|
+
"netLabelHeight": 0.6,
|
|
245
|
+
"pinIds": [
|
|
246
|
+
"schematic_port_17",
|
|
247
|
+
"schematic_port_28",
|
|
248
|
+
"schematic_port_30",
|
|
249
|
+
"schematic_port_37"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"netId": "VDDD",
|
|
254
|
+
"netLabelWidth": 0.42,
|
|
255
|
+
"netLabelHeight": 0.6,
|
|
256
|
+
"pinIds": [
|
|
257
|
+
"schematic_port_27"
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
"textBoxes": [
|
|
262
|
+
{
|
|
263
|
+
"chipId": "schematic_component_0",
|
|
264
|
+
"center": {
|
|
265
|
+
"x": -0.41999999999999993,
|
|
266
|
+
"y": -2.9299999999999997
|
|
267
|
+
},
|
|
268
|
+
"width": 2.16,
|
|
269
|
+
"height": 0.17999999999999972,
|
|
270
|
+
"text": "CC2745R10E0WRHARQ1"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"chipId": "schematic_component_0",
|
|
274
|
+
"center": {
|
|
275
|
+
"x": -1.38,
|
|
276
|
+
"y": 2.915
|
|
277
|
+
},
|
|
278
|
+
"width": 0.3600000000000001,
|
|
279
|
+
"height": 0.24999999999999956,
|
|
280
|
+
"text": "U1"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"availableNetLabelOrientations": {
|
|
284
|
+
"VDDR": [
|
|
285
|
+
"y+"
|
|
286
|
+
],
|
|
287
|
+
"VDDS": [
|
|
288
|
+
"y+"
|
|
289
|
+
],
|
|
290
|
+
"VDDD": [
|
|
291
|
+
"y+"
|
|
292
|
+
],
|
|
293
|
+
"VDDIO": [
|
|
294
|
+
"y+"
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
"maxMspPairDistance": 2.4,
|
|
298
|
+
"_hideRatsNet": false
|
|
299
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { LABEL_SEARCH_STEP } from "lib/solvers/AvailableNetOrientationSolver/constants"
|
|
3
|
+
import { segmentIntersectsRect } from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions"
|
|
4
|
+
import { getRectBounds } from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry"
|
|
5
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
6
|
+
import inputProblem from "./bug-report-20260731T052229Z.json"
|
|
7
|
+
import "tests/fixtures/matcher"
|
|
8
|
+
|
|
9
|
+
test("bug-report-20260731T052229Z", () => {
|
|
10
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
11
|
+
|
|
12
|
+
solver.solve()
|
|
13
|
+
|
|
14
|
+
const output = solver.sameNetJunctionAlignmentSolver!.getOutput()
|
|
15
|
+
const vdddLabel = output.netLabelPlacements.find(
|
|
16
|
+
(placement) => placement.netId === "VDDD",
|
|
17
|
+
)!
|
|
18
|
+
const vdddBounds = getRectBounds(
|
|
19
|
+
vdddLabel.center,
|
|
20
|
+
vdddLabel.width,
|
|
21
|
+
vdddLabel.height,
|
|
22
|
+
)
|
|
23
|
+
const intersectingDifferentNetTraceIds = output.traces
|
|
24
|
+
.filter((trace) => trace.globalConnNetId !== vdddLabel.globalConnNetId)
|
|
25
|
+
.filter((trace) =>
|
|
26
|
+
trace.tracePath.some(
|
|
27
|
+
(point, index) =>
|
|
28
|
+
index < trace.tracePath.length - 1 &&
|
|
29
|
+
segmentIntersectsRect(point, trace.tracePath[index + 1]!, vdddBounds),
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
.map((trace) => trace.mspPairId)
|
|
33
|
+
const vdddConnector = output.traces.find(
|
|
34
|
+
(trace) =>
|
|
35
|
+
trace.userNetId === "VDDD" &&
|
|
36
|
+
trace.mspPairId.startsWith("available-net-orientation-"),
|
|
37
|
+
)!
|
|
38
|
+
const alignedLabelXs = ["VDDR", "VDDS", "VDDD"].map(
|
|
39
|
+
(netId) =>
|
|
40
|
+
output.netLabelPlacements.find((placement) => placement.netId === netId)!
|
|
41
|
+
.anchorPoint.x,
|
|
42
|
+
)
|
|
43
|
+
const vddioLabel = output.netLabelPlacements.find(
|
|
44
|
+
(placement) => placement.netId === "VDDIO",
|
|
45
|
+
)!
|
|
46
|
+
const vddioBounds = getRectBounds(
|
|
47
|
+
vddioLabel.center,
|
|
48
|
+
vddioLabel.width,
|
|
49
|
+
vddioLabel.height,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
expect(vdddLabel.orientation).toBe("y+")
|
|
53
|
+
expect(new Set(alignedLabelXs)).toHaveLength(1)
|
|
54
|
+
expect(vdddBounds.minX - vddioBounds.maxX).toBeGreaterThanOrEqual(
|
|
55
|
+
LABEL_SEARCH_STEP,
|
|
56
|
+
)
|
|
57
|
+
expect(intersectingDifferentNetTraceIds).toEqual([])
|
|
58
|
+
expect(vdddConnector.tracePath).toHaveLength(3)
|
|
59
|
+
expect(vdddConnector.tracePath[0]!.y).toBe(vdddConnector.tracePath[1]!.y)
|
|
60
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
61
|
+
})
|