@tscircuit/schematic-trace-solver 0.0.185 → 0.0.187

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 CHANGED
@@ -936,6 +936,16 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
936
936
  private hasOppositeVerticalRailOnSameChipSide;
937
937
  private getSingleChipSideForNetConnection;
938
938
  private isPortOnlyLabel;
939
+ private getNetConnectionForLabel;
940
+ private isGroundLabel;
941
+ /**
942
+ * A vertical-only input stores its text extent in netLabelHeight. If its
943
+ * initial port-only placement is horizontal, use that extent for collision
944
+ * checks without changing the placement dimensions returned by the solver.
945
+ */
946
+ private getHorizontalConstraintMismatchBounds;
947
+ private includeHorizontalConstraintMismatches;
948
+ private getLabelBoundsForCollisionWithGround;
939
949
  private shouldIgnorePendingCrowdedLabel;
940
950
  private intersectsAnyOtherNetLabel;
941
951
  private sharesChipBoundary;
package/dist/index.js CHANGED
@@ -9413,6 +9413,17 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
9413
9413
  if (this.getTextBlockedMultiPinRailTraces(label, orientations[0])) {
9414
9414
  return true;
9415
9415
  }
9416
+ const hasSingleVerticalOrientation = orientations.length === 1 && isYOrientation(orientations[0]);
9417
+ if (hasSingleVerticalOrientation && this.isGroundLabel(label)) {
9418
+ const bounds2 = getRectBounds(label.center, label.width, label.height);
9419
+ const overlapsHorizontalConstraintMismatch = this.outputNetLabelPlacements.some((otherLabel, otherIndex) => {
9420
+ if (otherIndex === labelIndex) return false;
9421
+ if (otherLabel.globalConnNetId === label.globalConnNetId) return false;
9422
+ const otherBounds = this.getHorizontalConstraintMismatchBounds(otherLabel);
9423
+ return otherBounds ? rectsOverlap2(bounds2, otherBounds) : false;
9424
+ });
9425
+ if (overlapsHorizontalConstraintMismatch) return true;
9426
+ }
9416
9427
  if (!this.crowdedPortOnlyLabelIndices.has(labelIndex)) return false;
9417
9428
  const bounds = getRectBounds(label.center, label.width, label.height);
9418
9429
  return this.outputNetLabelPlacements.some((otherLabel, otherIndex) => {
@@ -10386,15 +10397,17 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
10386
10397
  return "text-collision";
10387
10398
  }
10388
10399
  }
10389
- for (const i of this.obstacleIndex.getLabelIndicesNearTracePath(
10390
- connectorTrace
10391
- )) {
10400
+ const nearbyLabelIndices = this.includeHorizontalConstraintMismatches(
10401
+ this.obstacleIndex.getLabelIndicesNearTracePath(connectorTrace),
10402
+ this.isGroundLabel(label)
10403
+ );
10404
+ for (const i of nearbyLabelIndices) {
10392
10405
  if (i === labelIndex) continue;
10393
10406
  if (this.shouldIgnorePendingCrowdedLabel(labelIndex, i)) continue;
10394
10407
  const otherLabel = this.outputNetLabelPlacements[i];
10395
10408
  if (tracePathIntersectsBounds(
10396
10409
  connectorTrace,
10397
- getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height)
10410
+ this.getLabelBoundsForCollisionWithGround(otherLabel, label)
10398
10411
  )) {
10399
10412
  return "netlabel-collision";
10400
10413
  }
@@ -10445,7 +10458,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
10445
10458
  if (this.isTraceTooCloseToLabel(bounds, label)) {
10446
10459
  return "trace-clearance-violation";
10447
10460
  }
10448
- if (this.intersectsAnyOtherNetLabel(bounds, labelIndex)) {
10461
+ if (this.intersectsAnyOtherNetLabel(bounds, labelIndex, label)) {
10449
10462
  return "netlabel-collision";
10450
10463
  }
10451
10464
  return "valid";
@@ -10645,22 +10658,95 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
10645
10658
  isPortOnlyLabel(label) {
10646
10659
  return label.mspConnectionPairIds.length === 0;
10647
10660
  }
10661
+ getNetConnectionForLabel(label) {
10662
+ return label.netId ? this.inputProblem.netConnections.find(
10663
+ (connection) => connection.netId === label.netId
10664
+ ) : this.inputProblem.netConnections.find(
10665
+ (connection) => connection.pinIds.some((pinId) => label.pinIds.includes(pinId))
10666
+ );
10667
+ }
10668
+ isGroundLabel(label) {
10669
+ return this.getNetConnectionForLabel(label)?.isGround === true;
10670
+ }
10671
+ /**
10672
+ * A vertical-only input stores its text extent in netLabelHeight. If its
10673
+ * initial port-only placement is horizontal, use that extent for collision
10674
+ * checks without changing the placement dimensions returned by the solver.
10675
+ */
10676
+ getHorizontalConstraintMismatchBounds(label) {
10677
+ if (!this.isPortOnlyLabel(label)) return null;
10678
+ if (label.orientation !== "x+" && label.orientation !== "x-") return null;
10679
+ const effectiveNetId = label.netId ?? label.globalConnNetId;
10680
+ const orientations = this.inputProblem.availableNetLabelOrientations[effectiveNetId] ?? [];
10681
+ if (orientations.length === 0 || orientations.some((orientation) => !isYOrientation(orientation))) {
10682
+ return null;
10683
+ }
10684
+ const renderedWidth = this.getNetConnectionForLabel(label)?.netLabelHeight;
10685
+ if (renderedWidth === void 0 || renderedWidth <= label.width + label.height + EPS13) {
10686
+ return null;
10687
+ }
10688
+ const placementBaseCenter = getCenterFromAnchor(
10689
+ label.anchorPoint,
10690
+ label.orientation,
10691
+ label.width,
10692
+ label.height
10693
+ );
10694
+ const renderedBaseCenter = getCenterFromAnchor(
10695
+ label.anchorPoint,
10696
+ label.orientation,
10697
+ renderedWidth,
10698
+ label.height
10699
+ );
10700
+ return getRectBounds(
10701
+ {
10702
+ x: renderedBaseCenter.x + label.center.x - placementBaseCenter.x,
10703
+ y: renderedBaseCenter.y + label.center.y - placementBaseCenter.y
10704
+ },
10705
+ renderedWidth,
10706
+ label.height
10707
+ );
10708
+ }
10709
+ includeHorizontalConstraintMismatches(labelIndices, include) {
10710
+ if (!include) return [...labelIndices].sort((a, b) => a - b);
10711
+ const result = new Set(labelIndices);
10712
+ for (let index = 0; index < this.outputNetLabelPlacements.length; index++) {
10713
+ if (this.getHorizontalConstraintMismatchBounds(
10714
+ this.outputNetLabelPlacements[index]
10715
+ )) {
10716
+ result.add(index);
10717
+ }
10718
+ }
10719
+ return [...result].sort((a, b) => a - b);
10720
+ }
10721
+ getLabelBoundsForCollisionWithGround(label, currentLabel) {
10722
+ if (this.isGroundLabel(currentLabel)) {
10723
+ const adjustedBounds = this.getHorizontalConstraintMismatchBounds(label);
10724
+ if (adjustedBounds) return adjustedBounds;
10725
+ }
10726
+ return getRectBounds(label.center, label.width, label.height);
10727
+ }
10648
10728
  shouldIgnorePendingCrowdedLabel(labelIndex, otherLabelIndex) {
10649
10729
  return this.crowdedPortOnlyLabelIndices.has(labelIndex) && this.crowdedPortOnlyLabelIndices.has(otherLabelIndex) && this.queuedLabelIndices.includes(otherLabelIndex);
10650
10730
  }
10651
- intersectsAnyOtherNetLabel(bounds, labelIndex) {
10731
+ intersectsAnyOtherNetLabel(bounds, labelIndex, currentLabel) {
10652
10732
  const searchBounds = {
10653
10733
  minX: bounds.minX - LABEL_SEARCH_STEP,
10654
10734
  minY: bounds.minY - LABEL_SEARCH_STEP,
10655
10735
  maxX: bounds.maxX + LABEL_SEARCH_STEP,
10656
10736
  maxY: bounds.maxY + LABEL_SEARCH_STEP
10657
10737
  };
10658
- const nearbyLabelIndices = this.obstacleIndex.getLabelIndicesInBounds(searchBounds).sort((a, b) => a - b);
10738
+ const nearbyLabelIndices = this.includeHorizontalConstraintMismatches(
10739
+ this.obstacleIndex.getLabelIndicesInBounds(searchBounds),
10740
+ this.isGroundLabel(currentLabel)
10741
+ );
10659
10742
  for (const i of nearbyLabelIndices) {
10660
10743
  if (i === labelIndex) continue;
10661
10744
  if (this.shouldIgnorePendingCrowdedLabel(labelIndex, i)) continue;
10662
10745
  const label = this.outputNetLabelPlacements[i];
10663
- const otherBounds = getRectBounds(label.center, label.width, label.height);
10746
+ const otherBounds = this.getLabelBoundsForCollisionWithGround(
10747
+ label,
10748
+ currentLabel
10749
+ );
10664
10750
  if (i === this.blockedStandaloneLabelIndex && isYOrientation(label.orientation)) {
10665
10751
  otherBounds.minX -= LABEL_SEARCH_STEP;
10666
10752
  otherBounds.maxX += LABEL_SEARCH_STEP;
@@ -13829,17 +13915,16 @@ var pathsIntersect = (firstPath, secondPath) => {
13829
13915
  }
13830
13916
  return false;
13831
13917
  };
13832
- var preserveAttachedLabelConnectorJunctions = ({
13918
+ var preserveAttachedTraceJunctions = ({
13833
13919
  originalTrace,
13834
13920
  candidateTrace,
13835
- traces,
13836
- netLabelConnectorTraceIds
13921
+ traces
13837
13922
  }) => {
13838
13923
  let outputTraces = traces.map(
13839
13924
  (trace) => trace.mspPairId === originalTrace.mspPairId ? candidateTrace : trace
13840
13925
  );
13841
13926
  for (const connector of traces) {
13842
- if (connector.mspPairId === originalTrace.mspPairId || !netLabelConnectorTraceIds.has(connector.mspPairId) || connector.globalConnNetId !== originalTrace.globalConnNetId || !pathsIntersect(originalTrace.tracePath, connector.tracePath) || pathsIntersect(candidateTrace.tracePath, connector.tracePath)) {
13927
+ if (connector.mspPairId === originalTrace.mspPairId || connector.globalConnNetId !== originalTrace.globalConnNetId || !pathsIntersect(originalTrace.tracePath, connector.tracePath) || pathsIntersect(candidateTrace.tracePath, connector.tracePath)) {
13843
13928
  continue;
13844
13929
  }
13845
13930
  const endpointIndex = [0, connector.tracePath.length - 1].find(
@@ -13850,6 +13935,11 @@ var preserveAttachedLabelConnectorJunctions = ({
13850
13935
  );
13851
13936
  if (endpointIndex === void 0) return null;
13852
13937
  const originalJunction = connector.tracePath[endpointIndex];
13938
+ if (connector.pins.some(
13939
+ (pin) => nearlyEqual(pin.x, originalJunction.x) && nearlyEqual(pin.y, originalJunction.y)
13940
+ )) {
13941
+ return null;
13942
+ }
13853
13943
  const movedJunction = getMovedAnchorPointForReroute(
13854
13944
  originalJunction,
13855
13945
  originalTrace.tracePath,
@@ -14228,11 +14318,10 @@ var alignSameNetJunctions = ({
14228
14318
  netLabelPlacements: outputNetLabelPlacements,
14229
14319
  attachedLabelIndexes
14230
14320
  });
14231
- const candidateTraces = preserveAttachedLabelConnectorJunctions({
14321
+ const candidateTraces = preserveAttachedTraceJunctions({
14232
14322
  originalTrace: branchTrace,
14233
14323
  candidateTrace,
14234
- traces: outputTraces,
14235
- netLabelConnectorTraceIds
14324
+ traces: outputTraces
14236
14325
  });
14237
14326
  if (!candidateTraces) continue;
14238
14327
  if (!candidateIsClear({
@@ -14247,7 +14336,7 @@ var alignSameNetJunctions = ({
14247
14336
  continue;
14248
14337
  }
14249
14338
  const movedConnectorsAreClear = candidateTraces.every((trace) => {
14250
- if (trace.mspPairId === branchTrace.mspPairId || !netLabelConnectorTraceIds.has(trace.mspPairId)) {
14339
+ if (trace.mspPairId === branchTrace.mspPairId) {
14251
14340
  return true;
14252
14341
  }
14253
14342
  const originalConnector = outputTraces.find(
@@ -268,6 +268,22 @@ export class AvailableNetOrientationSolver extends BaseSolver {
268
268
  if (this.getTextBlockedMultiPinRailTraces(label, orientations[0]!)) {
269
269
  return true
270
270
  }
271
+
272
+ const hasSingleVerticalOrientation =
273
+ orientations.length === 1 && isYOrientation(orientations[0]!)
274
+ if (hasSingleVerticalOrientation && this.isGroundLabel(label)) {
275
+ const bounds = getRectBounds(label.center, label.width, label.height)
276
+ const overlapsHorizontalConstraintMismatch =
277
+ this.outputNetLabelPlacements.some((otherLabel, otherIndex) => {
278
+ if (otherIndex === labelIndex) return false
279
+ if (otherLabel.globalConnNetId === label.globalConnNetId) return false
280
+ const otherBounds =
281
+ this.getHorizontalConstraintMismatchBounds(otherLabel)
282
+ return otherBounds ? rectsOverlap(bounds, otherBounds) : false
283
+ })
284
+ if (overlapsHorizontalConstraintMismatch) return true
285
+ }
286
+
271
287
  if (!this.crowdedPortOnlyLabelIndices.has(labelIndex)) return false
272
288
 
273
289
  const bounds = getRectBounds(label.center, label.width, label.height)
@@ -1627,16 +1643,18 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1627
1643
  }
1628
1644
  }
1629
1645
 
1630
- for (const i of this.obstacleIndex.getLabelIndicesNearTracePath(
1631
- connectorTrace,
1632
- )) {
1646
+ const nearbyLabelIndices = this.includeHorizontalConstraintMismatches(
1647
+ this.obstacleIndex.getLabelIndicesNearTracePath(connectorTrace),
1648
+ this.isGroundLabel(label),
1649
+ )
1650
+ for (const i of nearbyLabelIndices) {
1633
1651
  if (i === labelIndex) continue
1634
1652
  if (this.shouldIgnorePendingCrowdedLabel(labelIndex, i)) continue
1635
1653
  const otherLabel = this.outputNetLabelPlacements[i]!
1636
1654
  if (
1637
1655
  tracePathIntersectsBounds(
1638
1656
  connectorTrace,
1639
- getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height),
1657
+ this.getLabelBoundsForCollisionWithGround(otherLabel, label),
1640
1658
  )
1641
1659
  ) {
1642
1660
  return "netlabel-collision"
@@ -1719,7 +1737,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
1719
1737
  if (this.isTraceTooCloseToLabel(bounds, label)) {
1720
1738
  return "trace-clearance-violation"
1721
1739
  }
1722
- if (this.intersectsAnyOtherNetLabel(bounds, labelIndex)) {
1740
+ if (this.intersectsAnyOtherNetLabel(bounds, labelIndex, label)) {
1723
1741
  return "netlabel-collision"
1724
1742
  }
1725
1743
  return "valid"
@@ -2020,6 +2038,99 @@ export class AvailableNetOrientationSolver extends BaseSolver {
2020
2038
  return label.mspConnectionPairIds.length === 0
2021
2039
  }
2022
2040
 
2041
+ private getNetConnectionForLabel(label: NetLabelPlacement) {
2042
+ return label.netId
2043
+ ? this.inputProblem.netConnections.find(
2044
+ (connection) => connection.netId === label.netId,
2045
+ )
2046
+ : this.inputProblem.netConnections.find((connection) =>
2047
+ connection.pinIds.some((pinId) => label.pinIds.includes(pinId)),
2048
+ )
2049
+ }
2050
+
2051
+ private isGroundLabel(label: NetLabelPlacement) {
2052
+ return this.getNetConnectionForLabel(label)?.isGround === true
2053
+ }
2054
+
2055
+ /**
2056
+ * A vertical-only input stores its text extent in netLabelHeight. If its
2057
+ * initial port-only placement is horizontal, use that extent for collision
2058
+ * checks without changing the placement dimensions returned by the solver.
2059
+ */
2060
+ private getHorizontalConstraintMismatchBounds(label: NetLabelPlacement) {
2061
+ if (!this.isPortOnlyLabel(label)) return null
2062
+ if (label.orientation !== "x+" && label.orientation !== "x-") return null
2063
+
2064
+ const effectiveNetId = label.netId ?? label.globalConnNetId
2065
+ const orientations =
2066
+ this.inputProblem.availableNetLabelOrientations[effectiveNetId] ?? []
2067
+ if (
2068
+ orientations.length === 0 ||
2069
+ orientations.some((orientation) => !isYOrientation(orientation))
2070
+ ) {
2071
+ return null
2072
+ }
2073
+
2074
+ const renderedWidth = this.getNetConnectionForLabel(label)?.netLabelHeight
2075
+ if (
2076
+ renderedWidth === undefined ||
2077
+ renderedWidth <= label.width + label.height + EPS
2078
+ ) {
2079
+ return null
2080
+ }
2081
+
2082
+ const placementBaseCenter = getCenterFromAnchor(
2083
+ label.anchorPoint,
2084
+ label.orientation,
2085
+ label.width,
2086
+ label.height,
2087
+ )
2088
+ const renderedBaseCenter = getCenterFromAnchor(
2089
+ label.anchorPoint,
2090
+ label.orientation,
2091
+ renderedWidth,
2092
+ label.height,
2093
+ )
2094
+ return getRectBounds(
2095
+ {
2096
+ x: renderedBaseCenter.x + label.center.x - placementBaseCenter.x,
2097
+ y: renderedBaseCenter.y + label.center.y - placementBaseCenter.y,
2098
+ },
2099
+ renderedWidth,
2100
+ label.height,
2101
+ )
2102
+ }
2103
+
2104
+ private includeHorizontalConstraintMismatches(
2105
+ labelIndices: number[],
2106
+ include: boolean,
2107
+ ) {
2108
+ if (!include) return [...labelIndices].sort((a, b) => a - b)
2109
+
2110
+ const result = new Set(labelIndices)
2111
+ for (let index = 0; index < this.outputNetLabelPlacements.length; index++) {
2112
+ if (
2113
+ this.getHorizontalConstraintMismatchBounds(
2114
+ this.outputNetLabelPlacements[index]!,
2115
+ )
2116
+ ) {
2117
+ result.add(index)
2118
+ }
2119
+ }
2120
+ return [...result].sort((a, b) => a - b)
2121
+ }
2122
+
2123
+ private getLabelBoundsForCollisionWithGround(
2124
+ label: NetLabelPlacement,
2125
+ currentLabel: NetLabelPlacement,
2126
+ ) {
2127
+ if (this.isGroundLabel(currentLabel)) {
2128
+ const adjustedBounds = this.getHorizontalConstraintMismatchBounds(label)
2129
+ if (adjustedBounds) return adjustedBounds
2130
+ }
2131
+ return getRectBounds(label.center, label.width, label.height)
2132
+ }
2133
+
2023
2134
  private shouldIgnorePendingCrowdedLabel(
2024
2135
  labelIndex: number,
2025
2136
  otherLabelIndex: number,
@@ -2031,22 +2142,30 @@ export class AvailableNetOrientationSolver extends BaseSolver {
2031
2142
  )
2032
2143
  }
2033
2144
 
2034
- private intersectsAnyOtherNetLabel(bounds: Bounds, labelIndex: number) {
2145
+ private intersectsAnyOtherNetLabel(
2146
+ bounds: Bounds,
2147
+ labelIndex: number,
2148
+ currentLabel: NetLabelPlacement,
2149
+ ) {
2035
2150
  const searchBounds = {
2036
2151
  minX: bounds.minX - LABEL_SEARCH_STEP,
2037
2152
  minY: bounds.minY - LABEL_SEARCH_STEP,
2038
2153
  maxX: bounds.maxX + LABEL_SEARCH_STEP,
2039
2154
  maxY: bounds.maxY + LABEL_SEARCH_STEP,
2040
2155
  }
2041
- const nearbyLabelIndices = this.obstacleIndex
2042
- .getLabelIndicesInBounds(searchBounds)
2043
- .sort((a, b) => a - b)
2156
+ const nearbyLabelIndices = this.includeHorizontalConstraintMismatches(
2157
+ this.obstacleIndex.getLabelIndicesInBounds(searchBounds),
2158
+ this.isGroundLabel(currentLabel),
2159
+ )
2044
2160
 
2045
2161
  for (const i of nearbyLabelIndices) {
2046
2162
  if (i === labelIndex) continue
2047
2163
  if (this.shouldIgnorePendingCrowdedLabel(labelIndex, i)) continue
2048
2164
  const label = this.outputNetLabelPlacements[i]!
2049
- const otherBounds = getRectBounds(label.center, label.width, label.height)
2165
+ const otherBounds = this.getLabelBoundsForCollisionWithGround(
2166
+ label,
2167
+ currentLabel,
2168
+ )
2050
2169
  if (
2051
2170
  i === this.blockedStandaloneLabelIndex &&
2052
2171
  isYOrientation(label.orientation)
@@ -648,20 +648,18 @@ const pathsIntersect = (firstPath: Point[], secondPath: Point[]) => {
648
648
  }
649
649
 
650
650
  /**
651
- * Keep generated label connectors joined when their host trace moves. Only a
651
+ * Keep same-net branches joined when their host trace moves. Only a
652
652
  * connector endpoint is projected, and only along its existing first/last
653
653
  * segment, so the label and the rest of its route stay fixed.
654
654
  */
655
- const preserveAttachedLabelConnectorJunctions = ({
655
+ const preserveAttachedTraceJunctions = ({
656
656
  originalTrace,
657
657
  candidateTrace,
658
658
  traces,
659
- netLabelConnectorTraceIds,
660
659
  }: {
661
660
  originalTrace: SolvedTracePath
662
661
  candidateTrace: SolvedTracePath
663
662
  traces: SolvedTracePath[]
664
- netLabelConnectorTraceIds: ReadonlySet<MspConnectionPairId>
665
663
  }): SolvedTracePath[] | null => {
666
664
  let outputTraces = traces.map((trace) =>
667
665
  trace.mspPairId === originalTrace.mspPairId ? candidateTrace : trace,
@@ -670,7 +668,6 @@ const preserveAttachedLabelConnectorJunctions = ({
670
668
  for (const connector of traces) {
671
669
  if (
672
670
  connector.mspPairId === originalTrace.mspPairId ||
673
- !netLabelConnectorTraceIds.has(connector.mspPairId) ||
674
671
  connector.globalConnNetId !== originalTrace.globalConnNetId ||
675
672
  !pathsIntersect(originalTrace.tracePath, connector.tracePath) ||
676
673
  pathsIntersect(candidateTrace.tracePath, connector.tracePath)
@@ -686,6 +683,16 @@ const preserveAttachedLabelConnectorJunctions = ({
686
683
  )
687
684
  if (endpointIndex === undefined) return null
688
685
  const originalJunction = connector.tracePath[endpointIndex]!
686
+ // Component pins are fixed; reject a rail move that would detach one.
687
+ if (
688
+ connector.pins.some(
689
+ (pin) =>
690
+ nearlyEqual(pin.x, originalJunction.x) &&
691
+ nearlyEqual(pin.y, originalJunction.y),
692
+ )
693
+ ) {
694
+ return null
695
+ }
689
696
  const movedJunction = getMovedAnchorPointForReroute(
690
697
  originalJunction,
691
698
  originalTrace.tracePath,
@@ -1250,11 +1257,10 @@ export const alignSameNetJunctions = ({
1250
1257
  netLabelPlacements: outputNetLabelPlacements,
1251
1258
  attachedLabelIndexes,
1252
1259
  })
1253
- const candidateTraces = preserveAttachedLabelConnectorJunctions({
1260
+ const candidateTraces = preserveAttachedTraceJunctions({
1254
1261
  originalTrace: branchTrace,
1255
1262
  candidateTrace,
1256
1263
  traces: outputTraces,
1257
- netLabelConnectorTraceIds,
1258
1264
  })
1259
1265
  if (!candidateTraces) continue
1260
1266
  if (
@@ -1272,10 +1278,7 @@ export const alignSameNetJunctions = ({
1272
1278
  }
1273
1279
 
1274
1280
  const movedConnectorsAreClear = candidateTraces.every((trace) => {
1275
- if (
1276
- trace.mspPairId === branchTrace.mspPairId ||
1277
- !netLabelConnectorTraceIds.has(trace.mspPairId)
1278
- ) {
1281
+ if (trace.mspPairId === branchTrace.mspPairId) {
1279
1282
  return true
1280
1283
  }
1281
1284
  const originalConnector = outputTraces.find(
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/tscircuit/schematic-trace-solver.git"
6
6
  },
7
7
  "main": "dist/index.js",
8
- "version": "0.0.185",
8
+ "version": "0.0.187",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "start": "cosmos",
@@ -0,0 +1,4 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import inputProblem from "../../tests/bug-reports/bug-report-20260907T083336Z/bug-report-20260907T083336Z.json"
3
+
4
+ export default () => <PipelineDebugger inputProblem={inputProblem as any} />