@tscircuit/schematic-trace-solver 0.0.57 → 0.0.60

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
@@ -271,19 +271,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
271
271
  chipMap
272
272
  });
273
273
  if (restrictedCenterLines.size === 0) return false;
274
- const EPS9 = 1e-9;
274
+ const EPS10 = 1e-9;
275
275
  const crossesSegment = (a, b) => {
276
276
  for (const [, rcl] of restrictedCenterLines) {
277
277
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
278
- if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS9) return true;
278
+ if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS10) return true;
279
279
  }
280
280
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
281
- if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS9) return true;
281
+ if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS10) return true;
282
282
  }
283
283
  }
284
284
  return false;
285
285
  };
286
- if (Math.abs(p1.x - p2.x) < EPS9 || Math.abs(p1.y - p2.y) < EPS9) {
286
+ if (Math.abs(p1.x - p2.x) < EPS10 || Math.abs(p1.y - p2.y) < EPS10) {
287
287
  return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
288
288
  }
289
289
  const elbowHV = { x: p2.x, y: p1.y };
@@ -850,8 +850,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
850
850
  if (!collision) {
851
851
  const first = path[0];
852
852
  const last = path[path.length - 1];
853
- const EPS9 = 1e-9;
854
- const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS9 && Math.abs(p.y - q.y) < EPS9;
853
+ const EPS10 = 1e-9;
854
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS10 && Math.abs(p.y - q.y) < EPS10;
855
855
  if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
856
856
  this.solvedTracePath = path;
857
857
  this.solved = true;
@@ -1050,13 +1050,13 @@ var applyJogToTerminalSegment = ({
1050
1050
  segmentIndex: si,
1051
1051
  offset,
1052
1052
  JOG_SIZE,
1053
- EPS: EPS9 = 1e-6
1053
+ EPS: EPS10 = 1e-6
1054
1054
  }) => {
1055
1055
  if (si !== 0 && si !== pts.length - 2) return;
1056
1056
  const start = pts[si];
1057
1057
  const end = pts[si + 1];
1058
- const isVertical4 = Math.abs(start.x - end.x) < EPS9;
1059
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS9;
1058
+ const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1059
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1060
1060
  if (!isVertical4 && !isHorizontal3) return;
1061
1061
  const segDir = isVertical4 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
1062
1062
  if (si === 0) {
@@ -1123,13 +1123,13 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1123
1123
  }
1124
1124
  }
1125
1125
  _step() {
1126
- const EPS9 = 1e-6;
1126
+ const EPS10 = 1e-6;
1127
1127
  const offsets = this.overlappingTraceSegments.map((_, idx) => {
1128
1128
  const n = Math.floor(idx / 2) + 1;
1129
1129
  const signed = idx % 2 === 0 ? -n : n;
1130
1130
  return signed * this.SHIFT_DISTANCE;
1131
1131
  });
1132
- const eq = (a, b) => Math.abs(a - b) < EPS9;
1132
+ const eq = (a, b) => Math.abs(a - b) < EPS10;
1133
1133
  const samePoint = (p, q) => !!p && !!q && eq(p.x, q.x) && eq(p.y, q.y);
1134
1134
  this.overlappingTraceSegments.forEach((group, gidx) => {
1135
1135
  const offset = offsets[gidx];
@@ -1155,13 +1155,13 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1155
1155
  segmentIndex: si,
1156
1156
  offset,
1157
1157
  JOG_SIZE,
1158
- EPS: EPS9
1158
+ EPS: EPS10
1159
1159
  });
1160
1160
  } else {
1161
1161
  const start = pts[si];
1162
1162
  const end = pts[si + 1];
1163
- const isVertical4 = Math.abs(start.x - end.x) < EPS9;
1164
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS9;
1163
+ const isVertical4 = Math.abs(start.x - end.x) < EPS10;
1164
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS10;
1165
1165
  if (!isVertical4 && !isHorizontal3) continue;
1166
1166
  if (isVertical4) {
1167
1167
  start.x += offset;
@@ -1258,7 +1258,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1258
1258
  return islands;
1259
1259
  }
1260
1260
  findNextOverlapIssue() {
1261
- const EPS9 = 2e-3;
1261
+ const EPS10 = 2e-3;
1262
1262
  const netIds = Object.keys(this.traceNetIslands);
1263
1263
  for (let i = 0; i < netIds.length; i++) {
1264
1264
  for (let j = i + 1; j < netIds.length; j++) {
@@ -1276,7 +1276,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1276
1276
  const minB = Math.min(b1, b2);
1277
1277
  const maxB = Math.max(b1, b2);
1278
1278
  const overlap = Math.min(maxA, maxB) - Math.max(minA, minB);
1279
- return overlap > EPS9;
1279
+ return overlap > EPS10;
1280
1280
  };
1281
1281
  for (let pa = 0; pa < pathsA.length; pa++) {
1282
1282
  const pathA = pathsA[pa];
@@ -1284,8 +1284,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1284
1284
  for (let sa = 0; sa < ptsA.length - 1; sa++) {
1285
1285
  const a1 = ptsA[sa];
1286
1286
  const a2 = ptsA[sa + 1];
1287
- const aVert = Math.abs(a1.x - a2.x) < EPS9;
1288
- const aHorz = Math.abs(a1.y - a2.y) < EPS9;
1287
+ const aVert = Math.abs(a1.x - a2.x) < EPS10;
1288
+ const aHorz = Math.abs(a1.y - a2.y) < EPS10;
1289
1289
  if (!aVert && !aHorz) continue;
1290
1290
  for (let pb = 0; pb < pathsB.length; pb++) {
1291
1291
  const pathB = pathsB[pb];
@@ -1293,11 +1293,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1293
1293
  for (let sb = 0; sb < ptsB.length - 1; sb++) {
1294
1294
  const b1 = ptsB[sb];
1295
1295
  const b2 = ptsB[sb + 1];
1296
- const bVert = Math.abs(b1.x - b2.x) < EPS9;
1297
- const bHorz = Math.abs(b1.y - b2.y) < EPS9;
1296
+ const bVert = Math.abs(b1.x - b2.x) < EPS10;
1297
+ const bHorz = Math.abs(b1.y - b2.y) < EPS10;
1298
1298
  if (!bVert && !bHorz) continue;
1299
1299
  if (aVert && bVert) {
1300
- if (Math.abs(a1.x - b1.x) < EPS9) {
1300
+ if (Math.abs(a1.x - b1.x) < EPS10) {
1301
1301
  if (overlaps1D(a1.y, a2.y, b1.y, b2.y)) {
1302
1302
  const keyA = `${pa}:${sa}`;
1303
1303
  const keyB = `${pb}:${sb}`;
@@ -1318,7 +1318,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1318
1318
  }
1319
1319
  }
1320
1320
  } else if (aHorz && bHorz) {
1321
- if (Math.abs(a1.y - b1.y) < EPS9) {
1321
+ if (Math.abs(a1.y - b1.y) < EPS10) {
1322
1322
  if (overlaps1D(a1.x, a2.x, b1.x, b2.x)) {
1323
1323
  const keyA = `${pa}:${sa}`;
1324
1324
  const keyB = `${pb}:${sb}`;
@@ -1356,14 +1356,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1356
1356
  return null;
1357
1357
  }
1358
1358
  findNextDiagonalSegment() {
1359
- const EPS9 = 2e-3;
1359
+ const EPS10 = 2e-3;
1360
1360
  for (const mspPairId in this.correctedTraceMap) {
1361
1361
  const tracePath = this.correctedTraceMap[mspPairId].tracePath;
1362
1362
  for (let i = 0; i < tracePath.length - 1; i++) {
1363
1363
  const p1 = tracePath[i];
1364
1364
  const p2 = tracePath[i + 1];
1365
- const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS9;
1366
- const isVertical4 = Math.abs(p1.x - p2.x) < EPS9;
1365
+ const isHorizontal3 = Math.abs(p1.y - p2.y) < EPS10;
1366
+ const isVertical4 = Math.abs(p1.x - p2.x) < EPS10;
1367
1367
  if (!isHorizontal3 && !isVertical4) {
1368
1368
  return { mspPairId, tracePath, i, p1, p2 };
1369
1369
  }
@@ -1377,13 +1377,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1377
1377
  return false;
1378
1378
  }
1379
1379
  const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
1380
- const EPS9 = 2e-3;
1380
+ const EPS10 = 2e-3;
1381
1381
  const p0 = i > 0 ? tracePath[i - 1] : null;
1382
1382
  const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
1383
- const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS9 : false;
1384
- const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS9 : false;
1385
- const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS9 : false;
1386
- const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS9 : false;
1383
+ const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS10 : false;
1384
+ const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS10 : false;
1385
+ const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS10 : false;
1386
+ const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS10 : false;
1387
1387
  const elbow1 = { x: p1.x, y: p2.y };
1388
1388
  const elbow2 = { x: p2.x, y: p1.y };
1389
1389
  let score1 = 0;
@@ -1547,24 +1547,24 @@ function getRectBounds(center, w, h) {
1547
1547
  }
1548
1548
 
1549
1549
  // lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
1550
- function segmentIntersectsRect2(p1, p2, rect, EPS9 = 1e-9) {
1551
- const isVert = Math.abs(p1.x - p2.x) < EPS9;
1552
- const isHorz = Math.abs(p1.y - p2.y) < EPS9;
1550
+ function segmentIntersectsRect2(p1, p2, rect, EPS10 = 1e-9) {
1551
+ const isVert = Math.abs(p1.x - p2.x) < EPS10;
1552
+ const isHorz = Math.abs(p1.y - p2.y) < EPS10;
1553
1553
  if (!isVert && !isHorz) return false;
1554
1554
  if (isVert) {
1555
1555
  const x = p1.x;
1556
- if (x < rect.minX - EPS9 || x > rect.maxX + EPS9) return false;
1556
+ if (x < rect.minX - EPS10 || x > rect.maxX + EPS10) return false;
1557
1557
  const segMinY = Math.min(p1.y, p2.y);
1558
1558
  const segMaxY = Math.max(p1.y, p2.y);
1559
1559
  const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
1560
- return overlap > EPS9;
1560
+ return overlap > EPS10;
1561
1561
  } else {
1562
1562
  const y = p1.y;
1563
- if (y < rect.minY - EPS9 || y > rect.maxY + EPS9) return false;
1563
+ if (y < rect.minY - EPS10 || y > rect.maxY + EPS10) return false;
1564
1564
  const segMinX = Math.min(p1.x, p2.x);
1565
1565
  const segMaxX = Math.max(p1.x, p2.x);
1566
1566
  const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
1567
- return overlap > EPS9;
1567
+ return overlap > EPS10;
1568
1568
  }
1569
1569
  }
1570
1570
  function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
@@ -1942,14 +1942,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
1942
1942
  };
1943
1943
  let bestCandidate = null;
1944
1944
  let bestScore = -Infinity;
1945
- const EPS9 = 1e-6;
1945
+ const EPS10 = 1e-6;
1946
1946
  for (const curr of tracesToScan) {
1947
1947
  const pts = curr.tracePath.slice();
1948
1948
  for (let si = 0; si < pts.length - 1; si++) {
1949
1949
  const a = pts[si];
1950
1950
  const b = pts[si + 1];
1951
- const isH = Math.abs(a.y - b.y) < EPS9;
1952
- const isV = Math.abs(a.x - b.x) < EPS9;
1951
+ const isH = Math.abs(a.y - b.y) < EPS10;
1952
+ const isV = Math.abs(a.x - b.x) < EPS10;
1953
1953
  if (!isH && !isV) continue;
1954
1954
  const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
1955
1955
  const candidateOrients = orientations.filter(
@@ -2227,6 +2227,29 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2227
2227
  }
2228
2228
  return groups;
2229
2229
  }
2230
+ getNetLabelWidthForGroup(group) {
2231
+ if (group.netId) {
2232
+ const ncWidth = this.inputProblem.netConnections.find(
2233
+ (nc) => nc.netId === group.netId
2234
+ )?.netLabelWidth;
2235
+ if (ncWidth !== void 0) return ncWidth;
2236
+ const dcWidthByNetId = this.inputProblem.directConnections.find(
2237
+ (dc) => dc.netId === group.netId
2238
+ )?.netLabelWidth;
2239
+ if (dcWidthByNetId !== void 0) return dcWidthByNetId;
2240
+ }
2241
+ const pinIds = group.overlappingTraces?.pins.map((p) => p.pinId) ?? [];
2242
+ if (group.portOnlyPinId) {
2243
+ pinIds.push(group.portOnlyPinId);
2244
+ }
2245
+ const dcWidthByPinId = this.inputProblem.directConnections.find(
2246
+ (dc) => dc.pinIds.some((pid) => pinIds.includes(pid))
2247
+ )?.netLabelWidth;
2248
+ if (dcWidthByPinId !== void 0) return dcWidthByPinId;
2249
+ return this.inputProblem.netConnections.find(
2250
+ (nc) => nc.pinIds.some((pid) => pinIds.includes(pid))
2251
+ )?.netLabelWidth;
2252
+ }
2230
2253
  _step() {
2231
2254
  if (this.activeSubSolver?.solved) {
2232
2255
  this.netLabelPlacements.push(this.activeSubSolver.netLabelPlacement);
@@ -2241,9 +2264,7 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2241
2264
  const isAlreadyFull = currOrients.length === 4 && fullOrients.every((o) => currOrients.includes(o));
2242
2265
  if (!this.triedAnyOrientationFallbackForCurrentGroup && !isAlreadyFull && this.currentGroup) {
2243
2266
  this.triedAnyOrientationFallbackForCurrentGroup = true;
2244
- const netLabelWidth2 = this.currentGroup.netId ? this.inputProblem.netConnections.find(
2245
- (nc) => nc.netId === this.currentGroup.netId
2246
- )?.netLabelWidth : void 0;
2267
+ const netLabelWidth2 = this.getNetLabelWidthForGroup(this.currentGroup);
2247
2268
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
2248
2269
  inputProblem: this.inputProblem,
2249
2270
  inputTraceMap: this.inputTraceMap,
@@ -2269,9 +2290,7 @@ var NetLabelPlacementSolver = class extends BaseSolver {
2269
2290
  const netId = nextOverlappingSameNetTraceGroup.netId ?? nextOverlappingSameNetTraceGroup.globalConnNetId;
2270
2291
  this.currentGroup = nextOverlappingSameNetTraceGroup;
2271
2292
  this.triedAnyOrientationFallbackForCurrentGroup = false;
2272
- const netLabelWidth = this.currentGroup.netId ? this.inputProblem.netConnections.find(
2273
- (nc) => nc.netId === this.currentGroup.netId
2274
- )?.netLabelWidth : void 0;
2293
+ const netLabelWidth = this.getNetLabelWidthForGroup(this.currentGroup);
2275
2294
  this.activeSubSolver = new SingleNetLabelPlacementSolver({
2276
2295
  inputProblem: this.inputProblem,
2277
2296
  inputTraceMap: this.inputTraceMap,
@@ -4621,11 +4640,14 @@ var UntangleTraceSubsolver = class extends BaseSolver {
4621
4640
  };
4622
4641
 
4623
4642
  // lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
4643
+ var EPS5 = 1e-6;
4644
+ var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS5;
4645
+ var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS5;
4624
4646
  var is4PointRectangle = (path) => {
4625
4647
  if (path.length !== 4) return false;
4626
4648
  const [p0, p1, p2, p3] = path;
4627
- const isHVHC = p0.y === p1.y && p1.x === p2.x && p2.y === p3.y && p0.x === p3.x;
4628
- const isVHVC = p0.x === p1.x && p1.y === p2.y && p2.x === p3.x && p0.y === p3.y;
4649
+ const isHVHC = sameY(p0, p1) && sameX(p1, p2) && sameY(p2, p3) && sameX(p0, p3);
4650
+ const isVHVC = sameX(p0, p1) && sameY(p1, p2) && sameX(p2, p3) && sameY(p0, p3);
4629
4651
  return isHVHC || isVHVC;
4630
4652
  };
4631
4653
 
@@ -4754,7 +4776,7 @@ var TraceCleanupSolver = class extends BaseSolver {
4754
4776
  };
4755
4777
 
4756
4778
  // lib/solvers/Example28Solver/types.ts
4757
- var EPS5 = 1e-9;
4779
+ var EPS6 = 1e-9;
4758
4780
 
4759
4781
  // lib/solvers/Example28Solver/geometry.ts
4760
4782
  var getPathKey = (path) => path.map((point) => `${point.x},${point.y}`).join(";");
@@ -4766,10 +4788,10 @@ var getPathLength = (path) => {
4766
4788
  return length;
4767
4789
  };
4768
4790
  var getDistance = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
4769
- var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS5 || Math.abs(start.y - end.y) < EPS5;
4770
- var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS5 ? "horizontal" : "vertical";
4791
+ var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS6 || Math.abs(start.y - end.y) < EPS6;
4792
+ var getSegmentOrientation = (start, end) => Math.abs(start.y - end.y) < EPS6 ? "horizontal" : "vertical";
4771
4793
  var projectPointToSegment = (point, start, end) => {
4772
- if (Math.abs(start.x - end.x) < EPS5) {
4794
+ if (Math.abs(start.x - end.x) < EPS6) {
4773
4795
  return {
4774
4796
  x: start.x,
4775
4797
  y: Math.min(
@@ -4778,7 +4800,7 @@ var projectPointToSegment = (point, start, end) => {
4778
4800
  )
4779
4801
  };
4780
4802
  }
4781
- if (Math.abs(start.y - end.y) < EPS5) {
4803
+ if (Math.abs(start.y - end.y) < EPS6) {
4782
4804
  return {
4783
4805
  x: Math.min(
4784
4806
  Math.max(point.x, Math.min(start.x, end.x)),
@@ -4821,9 +4843,9 @@ var findSegmentContainingPoint = (path, point) => {
4821
4843
  };
4822
4844
  var isPointWithinSegmentPrimaryRange = (point, segment) => {
4823
4845
  if (segment.orientation === "horizontal") {
4824
- return point.x >= Math.min(segment.start.x, segment.end.x) - EPS5 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS5;
4846
+ return point.x >= Math.min(segment.start.x, segment.end.x) - EPS6 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS6;
4825
4847
  }
4826
- return point.y >= Math.min(segment.start.y, segment.end.y) - EPS5 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS5;
4848
+ return point.y >= Math.min(segment.start.y, segment.end.y) - EPS6 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS6;
4827
4849
  };
4828
4850
  var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
4829
4851
  const matchingSegments = getSegments(path).filter(
@@ -4851,18 +4873,18 @@ var projectPointToPath = (point, path) => {
4851
4873
  return bestPoint;
4852
4874
  };
4853
4875
  var segmentsIntersect = (a1, a2, b1, b2) => {
4854
- const aVertical = Math.abs(a1.x - a2.x) < EPS5;
4855
- const bVertical = Math.abs(b1.x - b2.x) < EPS5;
4856
- const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS5 && value <= Math.max(p1, p2) + EPS5;
4876
+ const aVertical = Math.abs(a1.x - a2.x) < EPS6;
4877
+ const bVertical = Math.abs(b1.x - b2.x) < EPS6;
4878
+ const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS6 && value <= Math.max(p1, p2) + EPS6;
4857
4879
  if (aVertical && bVertical) {
4858
- if (Math.abs(a1.x - b1.x) > EPS5) return false;
4880
+ if (Math.abs(a1.x - b1.x) > EPS6) return false;
4859
4881
  const overlap = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y)) - Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
4860
- return overlap > EPS5;
4882
+ return overlap > EPS6;
4861
4883
  }
4862
4884
  if (!aVertical && !bVertical) {
4863
- if (Math.abs(a1.y - b1.y) > EPS5) return false;
4885
+ if (Math.abs(a1.y - b1.y) > EPS6) return false;
4864
4886
  const overlap = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x)) - Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
4865
- return overlap > EPS5;
4887
+ return overlap > EPS6;
4866
4888
  }
4867
4889
  const verticalA = aVertical ? a1 : b1;
4868
4890
  const verticalB = aVertical ? a2 : b2;
@@ -4894,13 +4916,13 @@ var isPathCollidingWithChipInterior = (path, chipObstacles) => {
4894
4916
  return false;
4895
4917
  };
4896
4918
  var segmentRunsAlongRectBoundary = (start, end, rect) => {
4897
- const isVertical4 = Math.abs(start.x - end.x) < EPS5;
4898
- const isHorizontal3 = Math.abs(start.y - end.y) < EPS5;
4919
+ const isVertical4 = Math.abs(start.x - end.x) < EPS6;
4920
+ const isHorizontal3 = Math.abs(start.y - end.y) < EPS6;
4899
4921
  if (isVertical4) {
4900
- return Math.abs(start.x - rect.minX) < EPS5 || Math.abs(start.x - rect.maxX) < EPS5;
4922
+ return Math.abs(start.x - rect.minX) < EPS6 || Math.abs(start.x - rect.maxX) < EPS6;
4901
4923
  }
4902
4924
  if (isHorizontal3) {
4903
- return Math.abs(start.y - rect.minY) < EPS5 || Math.abs(start.y - rect.maxY) < EPS5;
4925
+ return Math.abs(start.y - rect.minY) < EPS6 || Math.abs(start.y - rect.maxY) < EPS6;
4904
4926
  }
4905
4927
  return false;
4906
4928
  };
@@ -5008,9 +5030,37 @@ var generateRerouteCandidateResults = ({
5008
5030
  outputNetLabelPlacements,
5009
5031
  chipObstacles
5010
5032
  }) => {
5011
- const rawCandidates = generateCandidatePaths(trace, label, inputProblem);
5012
5033
  const seen = /* @__PURE__ */ new Set();
5013
5034
  const candidateResults = [];
5035
+ const horizontalSegmentPushCandidate = generateHorizontalSegmentPushCandidate(
5036
+ trace,
5037
+ label
5038
+ );
5039
+ if (horizontalSegmentPushCandidate) {
5040
+ candidateResults.push(
5041
+ createCandidateResult({
5042
+ trace,
5043
+ obstacleLabel: label,
5044
+ path: horizontalSegmentPushCandidate,
5045
+ seen,
5046
+ outputTraces,
5047
+ outputNetLabelPlacements,
5048
+ chipObstacles,
5049
+ usesHorizontalSegmentPush: true
5050
+ })
5051
+ );
5052
+ }
5053
+ const rawCandidates = [
5054
+ ...generateLabelHugCandidates(trace, label),
5055
+ ...generateRerouteCandidates({
5056
+ trace,
5057
+ label,
5058
+ problem: inputProblem,
5059
+ paddingBuffer: LABEL_SIDE_CLEARANCE,
5060
+ detourCount: 0
5061
+ }),
5062
+ ...generateEndpointDetourCandidates(trace, label)
5063
+ ];
5014
5064
  for (const rawCandidate of rawCandidates) {
5015
5065
  candidateResults.push(
5016
5066
  createCandidateResult({
@@ -5026,17 +5076,6 @@ var generateRerouteCandidateResults = ({
5026
5076
  }
5027
5077
  return candidateResults;
5028
5078
  };
5029
- var generateCandidatePaths = (trace, label, inputProblem) => [
5030
- ...generateLabelHugCandidates(trace, label),
5031
- ...generateRerouteCandidates({
5032
- trace,
5033
- label,
5034
- problem: inputProblem,
5035
- paddingBuffer: LABEL_SIDE_CLEARANCE,
5036
- detourCount: 0
5037
- }),
5038
- ...generateEndpointDetourCandidates(trace, label)
5039
- ];
5040
5079
  var createCandidateResult = ({
5041
5080
  trace,
5042
5081
  obstacleLabel,
@@ -5044,13 +5083,15 @@ var createCandidateResult = ({
5044
5083
  seen,
5045
5084
  outputTraces,
5046
5085
  outputNetLabelPlacements,
5047
- chipObstacles
5086
+ chipObstacles,
5087
+ usesHorizontalSegmentPush
5048
5088
  }) => {
5049
5089
  const key = getPathKey(path);
5050
5090
  if (seen.has(key)) {
5051
5091
  return {
5052
5092
  path,
5053
5093
  status: "duplicate",
5094
+ usesHorizontalSegmentPush,
5054
5095
  selected: false
5055
5096
  };
5056
5097
  }
@@ -5059,6 +5100,7 @@ var createCandidateResult = ({
5059
5100
  return {
5060
5101
  path,
5061
5102
  status: "chip-collision",
5103
+ usesHorizontalSegmentPush,
5062
5104
  selected: false
5063
5105
  };
5064
5106
  }
@@ -5072,6 +5114,7 @@ var createCandidateResult = ({
5072
5114
  outputNetLabelPlacements
5073
5115
  }),
5074
5116
  status: "valid",
5117
+ usesHorizontalSegmentPush,
5075
5118
  selected: false
5076
5119
  };
5077
5120
  };
@@ -5148,6 +5191,12 @@ var selectBestReroutePath = ({
5148
5191
  outputNetLabelPlacements,
5149
5192
  candidateResults
5150
5193
  }) => {
5194
+ for (const candidate of candidateResults) {
5195
+ if (!candidate.usesHorizontalSegmentPush) continue;
5196
+ if (candidate.status !== "valid") continue;
5197
+ if (!candidate.score) continue;
5198
+ return candidate.path;
5199
+ }
5151
5200
  let bestPath = null;
5152
5201
  let bestScore = scoreTracePath({
5153
5202
  trace,
@@ -5164,6 +5213,71 @@ var selectBestReroutePath = ({
5164
5213
  }
5165
5214
  return bestPath;
5166
5215
  };
5216
+ var generateHorizontalSegmentPushCandidate = (trace, label) => {
5217
+ const labelDirection = dir(label.orientation);
5218
+ if (labelDirection.x === 0) return null;
5219
+ const path = trace.tracePath;
5220
+ const bounds = getRectBounds(label.center, label.width, label.height);
5221
+ const collidingVerticalSegmentIndex = path.findIndex((start, index) => {
5222
+ const end = path[index + 1];
5223
+ if (!end) return false;
5224
+ if (Math.abs(start.x - end.x) >= 1e-9) return false;
5225
+ return segmentIntersectsRect2(start, end, bounds);
5226
+ });
5227
+ if (collidingVerticalSegmentIndex <= 0 || collidingVerticalSegmentIndex >= path.length - 2) {
5228
+ return null;
5229
+ }
5230
+ const previousAnchor = path[collidingVerticalSegmentIndex - 1];
5231
+ const verticalStart = path[collidingVerticalSegmentIndex];
5232
+ const verticalEnd = path[collidingVerticalSegmentIndex + 1];
5233
+ const nextAnchor = path[collidingVerticalSegmentIndex + 2];
5234
+ if (Math.abs(previousAnchor.y - verticalStart.y) >= 1e-9 || Math.abs(verticalEnd.y - nextAnchor.y) >= 1e-9) {
5235
+ return null;
5236
+ }
5237
+ let segmentPushX = bounds.minX - LABEL_SIDE_CLEARANCE;
5238
+ if (labelDirection.x > 0) {
5239
+ segmentPushX = bounds.maxX + LABEL_SIDE_CLEARANCE;
5240
+ }
5241
+ const segmentPushStartY = getClearedHorizontalY({
5242
+ start: previousAnchor,
5243
+ end: { x: segmentPushX, y: verticalStart.y },
5244
+ labelBounds: bounds
5245
+ });
5246
+ const segmentPushEndY = getClearedHorizontalY({
5247
+ start: { x: segmentPushX, y: verticalEnd.y },
5248
+ end: nextAnchor,
5249
+ labelBounds: bounds
5250
+ });
5251
+ const segmentPushPath = [
5252
+ ...path.slice(0, collidingVerticalSegmentIndex - 1),
5253
+ previousAnchor
5254
+ ];
5255
+ if (Math.abs(previousAnchor.y - segmentPushStartY) >= 1e-9) {
5256
+ segmentPushPath.push({ x: previousAnchor.x, y: segmentPushStartY });
5257
+ }
5258
+ segmentPushPath.push({ x: segmentPushX, y: segmentPushStartY });
5259
+ segmentPushPath.push({ x: segmentPushX, y: segmentPushEndY });
5260
+ if (Math.abs(nextAnchor.y - segmentPushEndY) >= 1e-9) {
5261
+ segmentPushPath.push({ x: nextAnchor.x, y: segmentPushEndY });
5262
+ }
5263
+ segmentPushPath.push(
5264
+ nextAnchor,
5265
+ ...path.slice(collidingVerticalSegmentIndex + 3)
5266
+ );
5267
+ return simplifyPath(segmentPushPath);
5268
+ };
5269
+ var getClearedHorizontalY = ({
5270
+ start,
5271
+ end,
5272
+ labelBounds
5273
+ }) => {
5274
+ if (!segmentIntersectsRect2(start, end, labelBounds)) return start.y;
5275
+ const labelCenterY = (labelBounds.minY + labelBounds.maxY) / 2;
5276
+ if (start.y >= labelCenterY) {
5277
+ return labelBounds.maxY + LABEL_HUG_CLEARANCE;
5278
+ }
5279
+ return labelBounds.minY - LABEL_HUG_CLEARANCE;
5280
+ };
5167
5281
  var markSelectedCandidate = (candidateResults, bestPath) => {
5168
5282
  if (!bestPath) return;
5169
5283
  for (const candidate of candidateResults) {
@@ -5432,16 +5546,16 @@ var Example28Solver = class extends BaseSolver {
5432
5546
  // lib/solvers/AvailableNetOrientationSolver/constants.ts
5433
5547
  var LABEL_SEARCH_STEP = 0.05;
5434
5548
  var WICK_CLEARANCE = 1e-3;
5435
- var EPS6 = 1e-9;
5436
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS6;
5549
+ var EPS7 = 1e-9;
5550
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS7;
5437
5551
  var CANDIDATE_SELECTED_COLOR2 = "blue";
5438
5552
  var CANDIDATE_REJECTED_COLOR2 = "red";
5439
5553
 
5440
5554
  // lib/solvers/AvailableNetOrientationSolver/geometry.ts
5441
5555
  var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
5442
5556
  var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
5443
- var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS6 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS6;
5444
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS6;
5557
+ var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS7 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS7;
5558
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS7;
5445
5559
  var traceCrossesBoundsInterior = (bounds, traceMap) => {
5446
5560
  for (const trace of Object.values(traceMap)) {
5447
5561
  const points = trace.tracePath;
@@ -5463,8 +5577,8 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5463
5577
  if (interiorBounds.minX >= interiorBounds.maxX || interiorBounds.minY >= interiorBounds.maxY) {
5464
5578
  return false;
5465
5579
  }
5466
- if (sameX(p1, p2)) {
5467
- if (p1.x <= interiorBounds.minX + EPS6 || p1.x >= interiorBounds.maxX - EPS6) {
5580
+ if (sameX2(p1, p2)) {
5581
+ if (p1.x <= interiorBounds.minX + EPS7 || p1.x >= interiorBounds.maxX - EPS7) {
5468
5582
  return false;
5469
5583
  }
5470
5584
  return rangesOverlap(
@@ -5474,8 +5588,8 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
5474
5588
  interiorBounds.maxY
5475
5589
  );
5476
5590
  }
5477
- if (sameY(p1, p2)) {
5478
- if (p1.y <= interiorBounds.minY + EPS6 || p1.y >= interiorBounds.maxY - EPS6) {
5591
+ if (sameY2(p1, p2)) {
5592
+ if (p1.y <= interiorBounds.minY + EPS7 || p1.y >= interiorBounds.maxY - EPS7) {
5479
5593
  return false;
5480
5594
  }
5481
5595
  return rangesOverlap(
@@ -5514,11 +5628,11 @@ var tracePathCrossesAnyTrace = (tracePath, traceMap) => {
5514
5628
  return false;
5515
5629
  };
5516
5630
  var segmentsStrictlyCross = (a1, a2, b1, b2) => {
5517
- if (sameX(a1, a2) && sameY(b1, b2)) {
5518
- return a1.x > Math.min(b1.x, b2.x) + EPS6 && a1.x < Math.max(b1.x, b2.x) - EPS6 && b1.y > Math.min(a1.y, a2.y) + EPS6 && b1.y < Math.max(a1.y, a2.y) - EPS6;
5631
+ if (sameX2(a1, a2) && sameY2(b1, b2)) {
5632
+ return a1.x > Math.min(b1.x, b2.x) + EPS7 && a1.x < Math.max(b1.x, b2.x) - EPS7 && b1.y > Math.min(a1.y, a2.y) + EPS7 && b1.y < Math.max(a1.y, a2.y) - EPS7;
5519
5633
  }
5520
- if (sameY(a1, a2) && sameX(b1, b2)) {
5521
- return b1.x > Math.min(a1.x, a2.x) + EPS6 && b1.x < Math.max(a1.x, a2.x) - EPS6 && a1.y > Math.min(b1.y, b2.y) + EPS6 && a1.y < Math.max(b1.y, b2.y) - EPS6;
5634
+ if (sameY2(a1, a2) && sameX2(b1, b2)) {
5635
+ return b1.x > Math.min(a1.x, a2.x) + EPS7 && b1.x < Math.max(a1.x, a2.x) - EPS7 && a1.y > Math.min(b1.y, b2.y) + EPS7 && a1.y < Math.max(b1.y, b2.y) - EPS7;
5522
5636
  }
5523
5637
  return false;
5524
5638
  };
@@ -5541,7 +5655,7 @@ var simplifyOrthogonalPath = (path) => {
5541
5655
  const prev = simplified[simplified.length - 1];
5542
5656
  const point = deduped[i];
5543
5657
  const next = deduped[i + 1];
5544
- if (sameX(prev, point) && sameX(point, next) || sameY(prev, point) && sameY(point, next)) {
5658
+ if (sameX2(prev, point) && sameX2(point, next) || sameY2(prev, point) && sameY2(point, next)) {
5545
5659
  continue;
5546
5660
  }
5547
5661
  simplified.push(point);
@@ -5549,9 +5663,9 @@ var simplifyOrthogonalPath = (path) => {
5549
5663
  simplified.push(deduped[deduped.length - 1]);
5550
5664
  return simplified;
5551
5665
  };
5552
- var pointsEqual = (a, b) => sameX(a, b) && sameY(a, b);
5553
- var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS6;
5554
- var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS6;
5666
+ var pointsEqual = (a, b) => sameX2(a, b) && sameY2(a, b);
5667
+ var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS7;
5668
+ var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS7;
5555
5669
  var getMaxSearchDistance = (inputProblem) => {
5556
5670
  const maxChipWidth = Math.max(
5557
5671
  ...inputProblem.chips.map((chip) => chip.width),
@@ -5832,7 +5946,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
5832
5946
  );
5833
5947
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
5834
5948
  const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
5835
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS6; outwardDistance += LABEL_SEARCH_STEP) {
5949
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS7; outwardDistance += LABEL_SEARCH_STEP) {
5836
5950
  const baseAnchor = {
5837
5951
  x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
5838
5952
  y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
@@ -5860,7 +5974,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
5860
5974
  maxSearchDistance,
5861
5975
  outwardDistance
5862
5976
  } = params;
5863
- for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS6; distance3 += LABEL_SEARCH_STEP) {
5977
+ for (let distance3 = LABEL_SEARCH_STEP; distance3 <= maxSearchDistance + EPS7; distance3 += LABEL_SEARCH_STEP) {
5864
5978
  const anchorPoint = {
5865
5979
  x: baseAnchor.x + direction.x * distance3,
5866
5980
  y: baseAnchor.y + direction.y * distance3
@@ -5965,9 +6079,22 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
5965
6079
  };
5966
6080
  }
5967
6081
  getNetLabelWidth(label) {
5968
- if (!label.netId) return void 0;
6082
+ if (label.netId) {
6083
+ const ncWidth = this.inputProblem.netConnections.find(
6084
+ (connection) => connection.netId === label.netId
6085
+ )?.netLabelWidth;
6086
+ if (ncWidth !== void 0) return ncWidth;
6087
+ const dcWidthByNetId = this.inputProblem.directConnections.find(
6088
+ (dc) => dc.netId === label.netId
6089
+ )?.netLabelWidth;
6090
+ if (dcWidthByNetId !== void 0) return dcWidthByNetId;
6091
+ }
6092
+ const dcWidthByPinId = this.inputProblem.directConnections.find(
6093
+ (dc) => dc.pinIds.some((pid) => label.pinIds.includes(pid))
6094
+ )?.netLabelWidth;
6095
+ if (dcWidthByPinId !== void 0) return dcWidthByPinId;
5969
6096
  return this.inputProblem.netConnections.find(
5970
- (connection) => connection.netId === label.netId
6097
+ (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
5971
6098
  )?.netLabelWidth;
5972
6099
  }
5973
6100
  getCandidateStatus(candidate, label, labelIndex) {
@@ -6023,8 +6150,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6023
6150
  sharesChipBoundary(bounds) {
6024
6151
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6025
6152
  const chipBounds = chip.bounds;
6026
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS6 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS6;
6027
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS6 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS6;
6153
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS7;
6154
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS7 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS7;
6028
6155
  if (adjacentToVerticalSide && rangesOverlap(
6029
6156
  bounds.minY,
6030
6157
  bounds.maxY,
@@ -6072,7 +6199,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6072
6199
  let nearestDistance = Number.POSITIVE_INFINITY;
6073
6200
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6074
6201
  const bounds = chip.bounds;
6075
- if (point.x < bounds.minX - EPS6 || point.x > bounds.maxX + EPS6 || point.y < bounds.minY - EPS6 || point.y > bounds.maxY + EPS6) {
6202
+ if (point.x < bounds.minX - EPS7 || point.x > bounds.maxX + EPS7 || point.y < bounds.minY - EPS7 || point.y > bounds.maxY + EPS7) {
6076
6203
  continue;
6077
6204
  }
6078
6205
  for (const [side, distance3] of getSideDistances(point, bounds)) {
@@ -6089,8 +6216,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6089
6216
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
6090
6217
  for (const chip of this.chipObstacleSpatialIndex.chips) {
6091
6218
  const bounds = chip.bounds;
6092
- const dx = point.x < bounds.minX - EPS6 ? bounds.minX - point.x : point.x > bounds.maxX + EPS6 ? point.x - bounds.maxX : 0;
6093
- const dy = point.y < bounds.minY - EPS6 ? bounds.minY - point.y : point.y > bounds.maxY + EPS6 ? point.y - bounds.maxY : 0;
6219
+ const dx = point.x < bounds.minX - EPS7 ? bounds.minX - point.x : point.x > bounds.maxX + EPS7 ? point.x - bounds.maxX : 0;
6220
+ const dy = point.y < bounds.minY - EPS7 ? bounds.minY - point.y : point.y > bounds.maxY + EPS7 ? point.y - bounds.maxY : 0;
6094
6221
  if (dx === 0 && dy === 0) continue;
6095
6222
  const distanceSq = dx ** 2 + dy ** 2;
6096
6223
  if (distanceSq >= nearestDistanceSq) continue;
@@ -6129,9 +6256,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
6129
6256
  };
6130
6257
 
6131
6258
  // lib/solvers/VccNetLabelCornerPlacementSolver/geometry.ts
6132
- var EPS7 = 1e-6;
6259
+ var EPS8 = 1e-6;
6133
6260
  var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
6134
- var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS7 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS7;
6261
+ var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
6135
6262
  var getTraceCorners = (path) => {
6136
6263
  const corners = [];
6137
6264
  for (let i = 1; i < path.length - 1; i++) {
@@ -6155,11 +6282,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
6155
6282
  var isTraceCorner = (a, b, c) => getSegmentOrientation2(a, b) !== getSegmentOrientation2(b, c);
6156
6283
  var isPointOnSegment = (point, start, end) => {
6157
6284
  if (getSegmentOrientation2(start, end) === "horizontal") {
6158
- return Math.abs(point.y - start.y) <= EPS7 && point.x >= Math.min(start.x, end.x) - EPS7 && point.x <= Math.max(start.x, end.x) + EPS7;
6285
+ return Math.abs(point.y - start.y) <= EPS8 && point.x >= Math.min(start.x, end.x) - EPS8 && point.x <= Math.max(start.x, end.x) + EPS8;
6159
6286
  }
6160
- return Math.abs(point.x - start.x) <= EPS7 && point.y >= Math.min(start.y, end.y) - EPS7 && point.y <= Math.max(start.y, end.y) + EPS7;
6287
+ return Math.abs(point.x - start.x) <= EPS8 && point.y >= Math.min(start.y, end.y) - EPS8 && point.y <= Math.max(start.y, end.y) + EPS8;
6161
6288
  };
6162
- var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS7 ? "horizontal" : "vertical";
6289
+ var getSegmentOrientation2 = (a, b) => Math.abs(a.y - b.y) <= EPS8 ? "horizontal" : "vertical";
6163
6290
 
6164
6291
  // lib/solvers/VccNetLabelCornerPlacementSolver/visualize.ts
6165
6292
  var CANDIDATE_SELECTED_COLOR3 = "blue";
@@ -6437,11 +6564,11 @@ var VccNetLabelCornerPlacementSolver = class extends BaseSolver {
6437
6564
  };
6438
6565
 
6439
6566
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
6440
- var EPS8 = 1e-6;
6567
+ var EPS9 = 1e-6;
6441
6568
  var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
6442
6569
  var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
6443
- var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS8;
6444
- var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS8 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS8;
6570
+ var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS9;
6571
+ var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS9 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS9;
6445
6572
  var traceCrossesBoundsInterior2 = (bounds, traces) => {
6446
6573
  for (const trace of traces) {
6447
6574
  const points = trace.tracePath;
@@ -6487,7 +6614,7 @@ var getPointAtTraceDistance = (trace, distance3) => {
6487
6614
  const end = trace.tracePath[i + 1];
6488
6615
  const segmentLength = getManhattanDistance(start, end);
6489
6616
  const nextDistance = pathDistance + segmentLength;
6490
- if (distance3 <= nextDistance + EPS8) {
6617
+ if (distance3 <= nextDistance + EPS9) {
6491
6618
  const offset = Math.max(
6492
6619
  0,
6493
6620
  Math.min(segmentLength, distance3 - pathDistance)
@@ -6526,7 +6653,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6526
6653
  return false;
6527
6654
  }
6528
6655
  if (isVertical3(start, end)) {
6529
- if (start.x <= interior.minX + EPS8 || start.x >= interior.maxX - EPS8) {
6656
+ if (start.x <= interior.minX + EPS9 || start.x >= interior.maxX - EPS9) {
6530
6657
  return false;
6531
6658
  }
6532
6659
  return rangesOverlap2(
@@ -6537,7 +6664,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6537
6664
  );
6538
6665
  }
6539
6666
  if (isHorizontal2(start, end)) {
6540
- if (start.y <= interior.minY + EPS8 || start.y >= interior.maxY - EPS8) {
6667
+ if (start.y <= interior.minY + EPS9 || start.y >= interior.maxY - EPS9) {
6541
6668
  return false;
6542
6669
  }
6543
6670
  return rangesOverlap2(
@@ -6551,10 +6678,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
6551
6678
  };
6552
6679
  var isPointOnSegment2 = (point, start, end) => {
6553
6680
  if (isHorizontal2(start, end)) {
6554
- return Math.abs(point.y - start.y) <= EPS8 && point.x >= Math.min(start.x, end.x) - EPS8 && point.x <= Math.max(start.x, end.x) + EPS8;
6681
+ return Math.abs(point.y - start.y) <= EPS9 && point.x >= Math.min(start.x, end.x) - EPS9 && point.x <= Math.max(start.x, end.x) + EPS9;
6555
6682
  }
6556
6683
  if (isVertical3(start, end)) {
6557
- return Math.abs(point.x - start.x) <= EPS8 && point.y >= Math.min(start.y, end.y) - EPS8 && point.y <= Math.max(start.y, end.y) + EPS8;
6684
+ return Math.abs(point.x - start.x) <= EPS9 && point.y >= Math.min(start.y, end.y) - EPS9 && point.y <= Math.max(start.y, end.y) + EPS9;
6558
6685
  }
6559
6686
  return false;
6560
6687
  };
@@ -6562,9 +6689,9 @@ var getSegmentDirection = (start, end) => ({
6562
6689
  x: isVertical3(start, end) ? 0 : Math.sign(end.x - start.x),
6563
6690
  y: isHorizontal2(start, end) ? 0 : Math.sign(end.y - start.y)
6564
6691
  });
6565
- var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS8;
6566
- var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS8;
6567
- var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS8;
6692
+ var isHorizontal2 = (start, end) => Math.abs(start.y - end.y) <= EPS9;
6693
+ var isVertical3 = (start, end) => Math.abs(start.x - end.x) <= EPS9;
6694
+ var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS9;
6568
6695
  var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
6569
6696
 
6570
6697
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
@@ -6619,7 +6746,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
6619
6746
  for (const distance3 of vertexDistances) {
6620
6747
  distances.add(roundDistance(distance3));
6621
6748
  }
6622
- return [...distances].filter((distance3) => distance3 >= -EPS8 && distance3 <= traceLength + EPS8).sort((a, b) => a - b);
6749
+ return [...distances].filter((distance3) => distance3 >= -EPS9 && distance3 <= traceLength + EPS9).sort((a, b) => a - b);
6623
6750
  };
6624
6751
  var getOrientationsForPoint = (params) => {
6625
6752
  const { inputProblem, label, point, orientationConstraint } = params;
@@ -6726,13 +6853,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
6726
6853
  };
6727
6854
  var getOutwardAxisOption = (params) => {
6728
6855
  const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
6729
- if (value > max + EPS8) {
6856
+ if (value > max + EPS9) {
6730
6857
  return {
6731
6858
  orientation: positiveOrientation,
6732
6859
  outwardScore: 1 + value - max
6733
6860
  };
6734
6861
  }
6735
- if (value < min - EPS8) {
6862
+ if (value < min - EPS9) {
6736
6863
  return {
6737
6864
  orientation: negativeOrientation,
6738
6865
  outwardScore: 1 + min - value
@@ -6743,7 +6870,7 @@ var getOutwardAxisOption = (params) => {
6743
6870
  outwardScore: getNormalizedCenterDistance(value, center, max - min)
6744
6871
  };
6745
6872
  };
6746
- var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS8, span / 2);
6873
+ var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS9, span / 2);
6747
6874
  var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
6748
6875
  var getFlippedOrientation = (orientation) => {
6749
6876
  switch (orientation) {
@@ -6789,11 +6916,22 @@ var getChipBounds = (inputProblem) => {
6789
6916
  };
6790
6917
  };
6791
6918
  var getNetLabelWidth = (inputProblem, label) => {
6792
- const configuredWidth = inputProblem.netConnections.find(
6919
+ const ncWidthByNetId = inputProblem.netConnections.find(
6793
6920
  (connection) => connection.netId === label.netId
6794
6921
  )?.netLabelWidth;
6795
- if (configuredWidth !== void 0) return configuredWidth;
6796
- return label.orientation === "y+" || label.orientation === "y-" ? label.height : label.width;
6922
+ if (ncWidthByNetId !== void 0) return ncWidthByNetId;
6923
+ const dcWidth = inputProblem.directConnections.find(
6924
+ (dc) => dc.pinIds.some((pid) => label.pinIds.includes(pid))
6925
+ )?.netLabelWidth;
6926
+ if (dcWidth !== void 0) return dcWidth;
6927
+ const ncWidthByPinId = inputProblem.netConnections.find(
6928
+ (nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
6929
+ )?.netLabelWidth;
6930
+ if (ncWidthByPinId !== void 0) return ncWidthByPinId;
6931
+ if (label.orientation === "y+" || label.orientation === "y-") {
6932
+ return label.height;
6933
+ }
6934
+ return label.width;
6797
6935
  };
6798
6936
  var roundDistance = (distance3) => Number(distance3.toFixed(6));
6799
6937
  var dedupeOrientations = (orientations) => [
@@ -6818,7 +6956,7 @@ var normalizeFacingDirection = (value) => {
6818
6956
  var dedupeStrings = (values) => [
6819
6957
  ...new Set(values.filter((value) => value !== void 0))
6820
6958
  ];
6821
- var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS8 && Math.abs(point.y - label.anchorPoint.y) <= EPS8 && orientation === label.orientation;
6959
+ var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS9 && Math.abs(point.y - label.anchorPoint.y) <= EPS9 && orientation === label.orientation;
6822
6960
 
6823
6961
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
6824
6962
  var CANDIDATE_SELECTED_COLOR4 = "blue";