@tscircuit/schematic-trace-solver 0.0.107 → 0.0.108

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
@@ -325,19 +325,19 @@ var doesPairCrossRestrictedCenterLines = (params) => {
325
325
  chipMap
326
326
  });
327
327
  if (restrictedCenterLines.size === 0) return false;
328
- const EPS12 = 1e-9;
328
+ const EPS13 = 1e-9;
329
329
  const crossesSegment = (a, b) => {
330
330
  for (const [, rcl] of restrictedCenterLines) {
331
331
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
332
- if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS12) return true;
332
+ if ((a.x - rcl.x) * (b.x - rcl.x) < -EPS13) return true;
333
333
  }
334
334
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
335
- if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS12) return true;
335
+ if ((a.y - rcl.y) * (b.y - rcl.y) < -EPS13) return true;
336
336
  }
337
337
  }
338
338
  return false;
339
339
  };
340
- if (Math.abs(p1.x - p2.x) < EPS12 || Math.abs(p1.y - p2.y) < EPS12) {
340
+ if (Math.abs(p1.x - p2.x) < EPS13 || Math.abs(p1.y - p2.y) < EPS13) {
341
341
  return crossesSegment({ x: p1.x, y: p1.y }, { x: p2.x, y: p2.y });
342
342
  }
343
343
  const elbowHV = { x: p2.x, y: p1.y };
@@ -630,6 +630,25 @@ function getRectBounds(center, w, h) {
630
630
  };
631
631
  }
632
632
 
633
+ // lib/utils/textBoxBounds.ts
634
+ function getTextBoxBounds(textBox, padding = {}) {
635
+ return {
636
+ minX: textBox.center.x - textBox.width / 2 - (padding.minX ?? 0),
637
+ minY: textBox.center.y - textBox.height / 2 - (padding.minY ?? 0),
638
+ maxX: textBox.center.x + textBox.width / 2 + (padding.maxX ?? 0),
639
+ maxY: textBox.center.y + textBox.height / 2 + (padding.maxY ?? 0)
640
+ };
641
+ }
642
+ function boundsOverlap(a, b, eps = 1e-9) {
643
+ return a.minX < b.maxX - eps && a.maxX > b.minX + eps && a.minY < b.maxY - eps && a.maxY > b.minY + eps;
644
+ }
645
+ function rectIntersectsAnyTextBox(bounds, inputProblem) {
646
+ for (const textBox of inputProblem.textBoxes ?? []) {
647
+ if (boundsOverlap(bounds, getTextBoxBounds(textBox))) return true;
648
+ }
649
+ return false;
650
+ }
651
+
633
652
  // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/calculateDirectShortPath.ts
634
653
  import { calculateElbow } from "calculate-elbow";
635
654
  var MAX_SHORT_TRACE_DISTANCE = 0.15;
@@ -875,12 +894,8 @@ var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, opts = {}) =>
875
894
  }
876
895
  };
877
896
 
878
- // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateEndpointCollisionDetours.ts
879
- var getSegmentAxis = (start, end) => {
880
- if (isVertical(start, end)) return "x";
881
- if (isHorizontal(start, end)) return "y";
882
- return null;
883
- };
897
+ // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/pathOps.ts
898
+ var EPS3 = 1e-9;
884
899
  var hasOnlyNonzeroOrthogonalSegments = (path) => path.every((point, index) => {
885
900
  const nextPoint = path[index + 1];
886
901
  if (!nextPoint) return true;
@@ -889,57 +904,6 @@ var hasOnlyNonzeroOrthogonalSegments = (path) => path.every((point, index) => {
889
904
  }
890
905
  return Math.abs(point.x - nextPoint.x) + Math.abs(point.y - nextPoint.y) > 0;
891
906
  });
892
- var generateEndpointCollisionDetours = ({
893
- path,
894
- collidingSegmentIndex,
895
- obstacle
896
- }) => {
897
- if (path.length < 3 || path.length > 4) return [];
898
- const lastSegmentIndex = path.length - 2;
899
- if (collidingSegmentIndex !== 0 && collidingSegmentIndex !== lastSegmentIndex) {
900
- return [];
901
- }
902
- const shouldReverse = collidingSegmentIndex === lastSegmentIndex;
903
- const orderedPath = shouldReverse ? [...path].reverse() : path;
904
- const [start, corner, end] = orderedPath;
905
- const firstSegmentAxis = getSegmentAxis(start, corner);
906
- const secondSegmentAxis = getSegmentAxis(corner, end);
907
- if (!firstSegmentAxis || !secondSegmentAxis) return [];
908
- if (firstSegmentAxis === secondSegmentAxis) return [];
909
- const escapeCoordinates = [
910
- ...midBetweenPointAndRect(secondSegmentAxis, start, obstacle),
911
- ...midBetweenPointAndRect(secondSegmentAxis, end, obstacle)
912
- ];
913
- const detourCoordinates = [
914
- ...midBetweenPointAndRect(firstSegmentAxis, start, obstacle),
915
- ...midBetweenPointAndRect(firstSegmentAxis, end, obstacle)
916
- ];
917
- const detours = [];
918
- for (const escapeCoordinate of [...new Set(escapeCoordinates)]) {
919
- for (const detourCoordinate of [...new Set(detourCoordinates)]) {
920
- const orderedDetourPrefix = firstSegmentAxis === "y" ? [
921
- start,
922
- { x: escapeCoordinate, y: start.y },
923
- { x: escapeCoordinate, y: detourCoordinate },
924
- { x: end.x, y: detourCoordinate },
925
- end
926
- ] : [
927
- start,
928
- { x: start.x, y: escapeCoordinate },
929
- { x: detourCoordinate, y: escapeCoordinate },
930
- { x: detourCoordinate, y: end.y },
931
- end
932
- ];
933
- const orderedDetour = [...orderedDetourPrefix, ...orderedPath.slice(3)];
934
- const detour = shouldReverse ? orderedDetour.reverse() : orderedDetour;
935
- if (hasOnlyNonzeroOrthogonalSegments(detour)) detours.push(detour);
936
- }
937
- }
938
- return detours;
939
- };
940
-
941
- // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/pathOps.ts
942
- var EPS3 = 1e-9;
943
907
  var shiftSegmentOrth = (pts, segIndex, axis, newCoord, eps = EPS3) => {
944
908
  if (segIndex < 0 || segIndex >= pts.length - 1) {
945
909
  return null;
@@ -1001,6 +965,121 @@ var pathKey = (pts, decimals = 6) => {
1001
965
  return key;
1002
966
  };
1003
967
 
968
+ // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateEndpointCollisionDetours.ts
969
+ var getSegmentAxis = (start, end) => {
970
+ if (isVertical(start, end)) return "x";
971
+ if (isHorizontal(start, end)) return "y";
972
+ return null;
973
+ };
974
+ var generateEndpointCollisionDetours = ({
975
+ path,
976
+ collidingSegmentIndex,
977
+ obstacle
978
+ }) => {
979
+ if (path.length < 3 || path.length > 4) return [];
980
+ const lastSegmentIndex = path.length - 2;
981
+ if (collidingSegmentIndex !== 0 && collidingSegmentIndex !== lastSegmentIndex) {
982
+ return [];
983
+ }
984
+ const shouldReverse = collidingSegmentIndex === lastSegmentIndex;
985
+ const orderedPath = shouldReverse ? [...path].reverse() : path;
986
+ const [start, corner, end] = orderedPath;
987
+ const firstSegmentAxis = getSegmentAxis(start, corner);
988
+ const secondSegmentAxis = getSegmentAxis(corner, end);
989
+ if (!firstSegmentAxis || !secondSegmentAxis) return [];
990
+ if (firstSegmentAxis === secondSegmentAxis) return [];
991
+ const escapeCoordinates = [
992
+ ...midBetweenPointAndRect(secondSegmentAxis, start, obstacle),
993
+ ...midBetweenPointAndRect(secondSegmentAxis, end, obstacle)
994
+ ];
995
+ const detourCoordinates = [
996
+ ...midBetweenPointAndRect(firstSegmentAxis, start, obstacle),
997
+ ...midBetweenPointAndRect(firstSegmentAxis, end, obstacle)
998
+ ];
999
+ const detours = [];
1000
+ for (const escapeCoordinate of [...new Set(escapeCoordinates)]) {
1001
+ for (const detourCoordinate of [...new Set(detourCoordinates)]) {
1002
+ const orderedDetourPrefix = firstSegmentAxis === "y" ? [
1003
+ start,
1004
+ { x: escapeCoordinate, y: start.y },
1005
+ { x: escapeCoordinate, y: detourCoordinate },
1006
+ { x: end.x, y: detourCoordinate },
1007
+ end
1008
+ ] : [
1009
+ start,
1010
+ { x: start.x, y: escapeCoordinate },
1011
+ { x: detourCoordinate, y: escapeCoordinate },
1012
+ { x: detourCoordinate, y: end.y },
1013
+ end
1014
+ ];
1015
+ const orderedDetour = [...orderedDetourPrefix, ...orderedPath.slice(3)];
1016
+ const detour = shouldReverse ? orderedDetour.reverse() : orderedDetour;
1017
+ if (hasOnlyNonzeroOrthogonalSegments(detour)) detours.push(detour);
1018
+ }
1019
+ }
1020
+ return detours;
1021
+ };
1022
+
1023
+ // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateInternalSegmentCollisionDetours.ts
1024
+ var EPS4 = 1e-9;
1025
+ var DEFAULT_CLEARANCE = 0.2;
1026
+ var isStrictlyBetween = (value, a, b) => value > Math.min(a, b) + EPS4 && value < Math.max(a, b) - EPS4;
1027
+ var generateInternalSegmentCollisionDetours = ({
1028
+ path,
1029
+ collidingSegmentIndex,
1030
+ obstacle,
1031
+ clearance = DEFAULT_CLEARANCE
1032
+ }) => {
1033
+ if (collidingSegmentIndex <= 0 || collidingSegmentIndex >= path.length - 2) {
1034
+ return [];
1035
+ }
1036
+ const start = path[collidingSegmentIndex];
1037
+ const end = path[collidingSegmentIndex + 1];
1038
+ const detourPoints = [];
1039
+ if (isHorizontal(start, end)) {
1040
+ const movingRight = start.x < end.x;
1041
+ const entryX = movingRight ? obstacle.minX - clearance : obstacle.maxX + clearance;
1042
+ const exitX = movingRight ? obstacle.maxX + clearance : obstacle.minX - clearance;
1043
+ if (!isStrictlyBetween(entryX, start.x, end.x) || !isStrictlyBetween(exitX, start.x, end.x)) {
1044
+ return [];
1045
+ }
1046
+ for (const detourY of [
1047
+ obstacle.minY - clearance,
1048
+ obstacle.maxY + clearance
1049
+ ]) {
1050
+ detourPoints.push([
1051
+ { x: entryX, y: start.y },
1052
+ { x: entryX, y: detourY },
1053
+ { x: exitX, y: detourY },
1054
+ { x: exitX, y: end.y }
1055
+ ]);
1056
+ }
1057
+ } else if (isVertical(start, end)) {
1058
+ const movingUp = start.y < end.y;
1059
+ const entryY = movingUp ? obstacle.minY - clearance : obstacle.maxY + clearance;
1060
+ const exitY = movingUp ? obstacle.maxY + clearance : obstacle.minY - clearance;
1061
+ if (!isStrictlyBetween(entryY, start.y, end.y) || !isStrictlyBetween(exitY, start.y, end.y)) {
1062
+ return [];
1063
+ }
1064
+ for (const detourX of [
1065
+ obstacle.minX - clearance,
1066
+ obstacle.maxX + clearance
1067
+ ]) {
1068
+ detourPoints.push([
1069
+ { x: start.x, y: entryY },
1070
+ { x: detourX, y: entryY },
1071
+ { x: detourX, y: exitY },
1072
+ { x: end.x, y: exitY }
1073
+ ]);
1074
+ }
1075
+ }
1076
+ return detourPoints.map((points) => [
1077
+ ...path.slice(0, collidingSegmentIndex + 1),
1078
+ ...points,
1079
+ ...path.slice(collidingSegmentIndex + 1)
1080
+ ]).filter(hasOnlyNonzeroOrthogonalSegments);
1081
+ };
1082
+
1004
1083
  // lib/solvers/GuidelinesSolver/getInputChipBounds.ts
1005
1084
  function getInputChipBounds(chip) {
1006
1085
  const halfWidth = chip.width / 2;
@@ -1013,26 +1092,8 @@ function getInputChipBounds(chip) {
1013
1092
  };
1014
1093
  }
1015
1094
 
1016
- // lib/utils/textBoxBounds.ts
1017
- function getTextBoxBounds(textBox, padding = {}) {
1018
- return {
1019
- minX: textBox.center.x - textBox.width / 2 - (padding.minX ?? 0),
1020
- minY: textBox.center.y - textBox.height / 2 - (padding.minY ?? 0),
1021
- maxX: textBox.center.x + textBox.width / 2 + (padding.maxX ?? 0),
1022
- maxY: textBox.center.y + textBox.height / 2 + (padding.maxY ?? 0)
1023
- };
1024
- }
1025
- function boundsOverlap(a, b, eps = 1e-9) {
1026
- return a.minX < b.maxX - eps && a.maxX > b.minX + eps && a.minY < b.maxY - eps && a.maxY > b.minY + eps;
1027
- }
1028
- function rectIntersectsAnyTextBox(bounds, inputProblem) {
1029
- for (const textBox of inputProblem.textBoxes ?? []) {
1030
- if (boundsOverlap(bounds, getTextBoxBounds(textBox))) return true;
1031
- }
1032
- return false;
1033
- }
1034
-
1035
1095
  // lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts
1096
+ var isTextBoxObstacle = (obstacle) => obstacle.kind === "text_box";
1036
1097
  var chipToRect = (chip) => {
1037
1098
  const b = getInputChipBounds(chip);
1038
1099
  return { kind: "chip", chipId: chip.chipId, ...b };
@@ -1096,13 +1157,11 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1096
1157
  this.obstacles = getObstacleRects(this.inputProblem, {
1097
1158
  textBoxPadding: this.getTextBoxPaddingForConnectionPair()
1098
1159
  });
1099
- this.textObstacles = new Set(
1100
- this.obstacles.filter((r) => r.kind === "text_box")
1101
- );
1160
+ this.textObstacles = new Set(this.obstacles.filter(isTextBoxObstacle));
1102
1161
  const endpointChipIds = new Set(this.pins.map((pin) => pin.chipId));
1103
1162
  this.endpointTextObstacles = new Set(
1104
- endpointChipIds.size > 1 ? this.obstacles.filter(
1105
- (r) => r.kind === "text_box" && r.textBox.chipId !== void 0 && endpointChipIds.has(r.textBox.chipId)
1163
+ endpointChipIds.size > 1 ? this.obstacles.filter(isTextBoxObstacle).filter(
1164
+ (obstacle) => obstacle.textBox.chipId !== void 0 && endpointChipIds.has(obstacle.textBox.chipId)
1106
1165
  ) : []
1107
1166
  );
1108
1167
  const [pin1, pin2] = this.pins;
@@ -1290,7 +1349,10 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1290
1349
  path[adjacentEndpointSegIndex + 1]
1291
1350
  )) {
1292
1351
  for (const textObstacle of this.endpointTextObstacles) {
1293
- excludedRects.add(textObstacle);
1352
+ const textBounds = getTextBoxBounds(textObstacle.textBox);
1353
+ if (!segmentIntersectsRect(segmentStart, segmentEnd, textBounds)) {
1354
+ excludedRects.add(textObstacle);
1355
+ }
1294
1356
  }
1295
1357
  }
1296
1358
  return excludedRects;
@@ -1299,8 +1361,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1299
1361
  if (!collision) {
1300
1362
  const first = path[0];
1301
1363
  const last = path[path.length - 1];
1302
- const EPS12 = 1e-9;
1303
- const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS12 && Math.abs(p.y - q.y) < EPS12;
1364
+ const EPS13 = 1e-9;
1365
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS13 && Math.abs(p.y - q.y) < EPS13;
1304
1366
  if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
1305
1367
  this.solvedTracePath = path;
1306
1368
  this.solved = true;
@@ -1373,14 +1435,7 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1373
1435
  candidates.push(...mids);
1374
1436
  }
1375
1437
  const newStates = [];
1376
- const addShiftedCandidate = (candidateSegIndex, candidateAxis, coord) => {
1377
- const newPath = shiftSegmentOrth(
1378
- path,
1379
- candidateSegIndex,
1380
- candidateAxis,
1381
- coord
1382
- );
1383
- if (!newPath) return;
1438
+ const addPathCandidate = (newPath) => {
1384
1439
  const key = pathKey(newPath);
1385
1440
  if (this.visited.has(key)) return;
1386
1441
  this.visited.add(key);
@@ -1393,10 +1448,28 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
1393
1448
  pinBandPenalty: this.getPinBandPenalty(newPath)
1394
1449
  });
1395
1450
  };
1451
+ const addShiftedCandidate = (candidateSegIndex, candidateAxis, coord) => {
1452
+ const newPath = shiftSegmentOrth(
1453
+ path,
1454
+ candidateSegIndex,
1455
+ candidateAxis,
1456
+ coord
1457
+ );
1458
+ if (newPath) addPathCandidate(newPath);
1459
+ };
1460
+ const lastSegIndex = path.length - 2;
1461
+ if (this.connectionPair === void 0 && rect.kind === "text_box" && this.endpointTextObstacles.has(rect) && !collisionRects.has(rect) && originalSegIndex > 0 && originalSegIndex < lastSegIndex) {
1462
+ for (const detour of generateInternalSegmentCollisionDetours({
1463
+ path,
1464
+ collidingSegmentIndex: originalSegIndex,
1465
+ obstacle: rect
1466
+ })) {
1467
+ addPathCandidate(detour);
1468
+ }
1469
+ }
1396
1470
  for (const coord of candidates) {
1397
1471
  addShiftedCandidate(segIndex, axis, coord);
1398
1472
  }
1399
- const lastSegIndex = path.length - 2;
1400
1473
  const adjacentSegmentIndexes = originalSegIndex === 1 ? [2] : originalSegIndex === lastSegIndex - 1 ? [lastSegIndex - 2] : [];
1401
1474
  for (const adjacentSegIndex of adjacentSegmentIndexes) {
1402
1475
  if (adjacentSegIndex < 0 || adjacentSegIndex >= lastSegIndex) continue;
@@ -1573,13 +1646,13 @@ var applyJogToTerminalSegment = ({
1573
1646
  segmentIndex: si,
1574
1647
  offset,
1575
1648
  JOG_SIZE,
1576
- EPS: EPS12 = 1e-6
1649
+ EPS: EPS13 = 1e-6
1577
1650
  }) => {
1578
1651
  if (si !== 0 && si !== pts.length - 2) return;
1579
1652
  const start = pts[si];
1580
1653
  const end = pts[si + 1];
1581
- const isVertical5 = Math.abs(start.x - end.x) < EPS12;
1582
- const isHorizontal4 = Math.abs(start.y - end.y) < EPS12;
1654
+ const isVertical5 = Math.abs(start.x - end.x) < EPS13;
1655
+ const isHorizontal4 = Math.abs(start.y - end.y) < EPS13;
1583
1656
  if (!isVertical5 && !isHorizontal4) return;
1584
1657
  const segDir = isVertical5 ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
1585
1658
  if (pts.length === 2) {
@@ -1652,7 +1725,7 @@ var applyJogToTerminalSegment = ({
1652
1725
  };
1653
1726
 
1654
1727
  // lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
1655
- var EPS4 = 1e-6;
1728
+ var EPS5 = 1e-6;
1656
1729
  var TraceOverlapIssueSolver = class extends BaseSolver {
1657
1730
  overlappingTraceSegments;
1658
1731
  interactionKind;
@@ -1741,7 +1814,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1741
1814
  }
1742
1815
  applyOffsets(offsets) {
1743
1816
  const correctedTraceMap = { ...this.correctedTraceMap };
1744
- const eq = (a, b) => Math.abs(a - b) < EPS4;
1817
+ const eq = (a, b) => Math.abs(a - b) < EPS5;
1745
1818
  const samePoint = (p, q) => !!p && !!q && eq(p.x, q.x) && eq(p.y, q.y);
1746
1819
  this.overlappingTraceSegments.forEach((group, groupIndex) => {
1747
1820
  const offset = offsets[groupIndex];
@@ -1763,9 +1836,9 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1763
1836
  const start = pts[si];
1764
1837
  const end = pts[si + 1];
1765
1838
  if (!start || !end) continue;
1766
- if (Math.abs(start.x - end.x) < EPS4) {
1839
+ if (Math.abs(start.x - end.x) < EPS5) {
1767
1840
  segmentAxes.set(si, "vertical");
1768
- } else if (Math.abs(start.y - end.y) < EPS4) {
1841
+ } else if (Math.abs(start.y - end.y) < EPS5) {
1769
1842
  segmentAxes.set(si, "horizontal");
1770
1843
  }
1771
1844
  }
@@ -1780,7 +1853,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1780
1853
  segmentIndex: si,
1781
1854
  offset,
1782
1855
  JOG_SIZE,
1783
- EPS: EPS4
1856
+ EPS: EPS5
1784
1857
  });
1785
1858
  } else {
1786
1859
  const start = pts[si];
@@ -1867,7 +1940,7 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1867
1940
  max = obstacle.maxY;
1868
1941
  }
1869
1942
  const next = orig + candidateOffset;
1870
- return orig <= min + EPS4 && next >= max - EPS4 || orig >= max - EPS4 && next <= min + EPS4;
1943
+ return orig <= min + EPS5 && next >= max - EPS5 || orig >= max - EPS5 && next <= min + EPS5;
1871
1944
  });
1872
1945
  const edges = blockingCollisions.map(({ start, isVertical: isVertical5, obstacle }) => {
1873
1946
  if (isVertical5) {
@@ -1904,8 +1977,8 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
1904
1977
  const start = trace.tracePath[traceSegmentIndex];
1905
1978
  const end = trace.tracePath[traceSegmentIndex + 1];
1906
1979
  if (!start || !end) continue;
1907
- const isVertical5 = Math.abs(start.x - end.x) < EPS4;
1908
- const isHorizontal4 = Math.abs(start.y - end.y) < EPS4;
1980
+ const isVertical5 = Math.abs(start.x - end.x) < EPS5;
1981
+ const isHorizontal4 = Math.abs(start.y - end.y) < EPS5;
1909
1982
  if (!isVertical5 && !isHorizontal4) continue;
1910
1983
  const shiftedSegment = isVertical5 ? [
1911
1984
  { ...start, x: start.x + offset },
@@ -1997,7 +2070,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
1997
2070
  return islands;
1998
2071
  }
1999
2072
  findNextOverlapIssue() {
2000
- const EPS12 = 2e-3;
2073
+ const EPS13 = 2e-3;
2001
2074
  const netIds = Object.keys(this.traceNetIslands);
2002
2075
  for (let i = 0; i < netIds.length; i++) {
2003
2076
  for (let j = i + 1; j < netIds.length; j++) {
@@ -2024,7 +2097,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2024
2097
  segmentBIndex,
2025
2098
  rangeOverlap
2026
2099
  }) => {
2027
- if (rangeOverlap > EPS12) {
2100
+ if (rangeOverlap > EPS13) {
2028
2101
  const keyA = `${pathAIndex}:${segmentAIndex}`;
2029
2102
  const keyB = `${pathBIndex}:${segmentBIndex}`;
2030
2103
  if (!seenA.has(keyA)) {
@@ -2043,7 +2116,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2043
2116
  }
2044
2117
  return;
2045
2118
  }
2046
- if (rangeOverlap < -EPS12) return;
2119
+ if (rangeOverlap < -EPS13) return;
2047
2120
  const pathA = pathsA[pathAIndex].tracePath;
2048
2121
  const pathB = pathsB[pathBIndex].tracePath;
2049
2122
  const segmentAStart = pathA[segmentAIndex];
@@ -2066,8 +2139,8 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2066
2139
  for (let sa = 0; sa < ptsA.length - 1; sa++) {
2067
2140
  const a1 = ptsA[sa];
2068
2141
  const a2 = ptsA[sa + 1];
2069
- const aVert = Math.abs(a1.x - a2.x) < EPS12;
2070
- const aHorz = Math.abs(a1.y - a2.y) < EPS12;
2142
+ const aVert = Math.abs(a1.x - a2.x) < EPS13;
2143
+ const aHorz = Math.abs(a1.y - a2.y) < EPS13;
2071
2144
  if (!aVert && !aHorz) continue;
2072
2145
  for (let pb = 0; pb < pathsB.length; pb++) {
2073
2146
  const pathB = pathsB[pb];
@@ -2075,11 +2148,11 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2075
2148
  for (let sb = 0; sb < ptsB.length - 1; sb++) {
2076
2149
  const b1 = ptsB[sb];
2077
2150
  const b2 = ptsB[sb + 1];
2078
- const bVert = Math.abs(b1.x - b2.x) < EPS12;
2079
- const bHorz = Math.abs(b1.y - b2.y) < EPS12;
2151
+ const bVert = Math.abs(b1.x - b2.x) < EPS13;
2152
+ const bHorz = Math.abs(b1.y - b2.y) < EPS13;
2080
2153
  if (!bVert && !bHorz) continue;
2081
2154
  if (aVert && bVert) {
2082
- if (Math.abs(a1.x - b1.x) < EPS12) {
2155
+ if (Math.abs(a1.x - b1.x) < EPS13) {
2083
2156
  recordCollinearInteraction({
2084
2157
  pathAIndex: pa,
2085
2158
  segmentAIndex: sa,
@@ -2089,7 +2162,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2089
2162
  });
2090
2163
  }
2091
2164
  } else if (aHorz && bHorz) {
2092
- if (Math.abs(a1.y - b1.y) < EPS12) {
2165
+ if (Math.abs(a1.y - b1.y) < EPS13) {
2093
2166
  recordCollinearInteraction({
2094
2167
  pathAIndex: pa,
2095
2168
  segmentAIndex: sa,
@@ -2145,14 +2218,14 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2145
2218
  return null;
2146
2219
  }
2147
2220
  findNextDiagonalSegment() {
2148
- const EPS12 = 2e-3;
2221
+ const EPS13 = 2e-3;
2149
2222
  for (const mspPairId in this.correctedTraceMap) {
2150
2223
  const tracePath = this.correctedTraceMap[mspPairId].tracePath;
2151
2224
  for (let i = 0; i < tracePath.length - 1; i++) {
2152
2225
  const p1 = tracePath[i];
2153
2226
  const p2 = tracePath[i + 1];
2154
- const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS12;
2155
- const isVertical5 = Math.abs(p1.x - p2.x) < EPS12;
2227
+ const isHorizontal4 = Math.abs(p1.y - p2.y) < EPS13;
2228
+ const isVertical5 = Math.abs(p1.x - p2.x) < EPS13;
2156
2229
  if (!isHorizontal4 && !isVertical5) {
2157
2230
  return { mspPairId, tracePath, i, p1, p2 };
2158
2231
  }
@@ -2166,13 +2239,13 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
2166
2239
  return false;
2167
2240
  }
2168
2241
  const { mspPairId, tracePath, i, p1, p2 } = diagonalInfo;
2169
- const EPS12 = 2e-3;
2242
+ const EPS13 = 2e-3;
2170
2243
  const p0 = i > 0 ? tracePath[i - 1] : null;
2171
2244
  const p3 = i + 2 < tracePath.length ? tracePath[i + 2] : null;
2172
- const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS12 : false;
2173
- const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS12 : false;
2174
- const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS12 : false;
2175
- const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS12 : false;
2245
+ const prevIsVertical = p0 ? Math.abs(p0.x - p1.x) < EPS13 : false;
2246
+ const prevIsHorizontal = p0 ? Math.abs(p0.y - p1.y) < EPS13 : false;
2247
+ const nextIsVertical = p3 ? Math.abs(p2.x - p3.x) < EPS13 : false;
2248
+ const nextIsHorizontal = p3 ? Math.abs(p2.y - p3.y) < EPS13 : false;
2176
2249
  const elbow1 = { x: p1.x, y: p2.y };
2177
2250
  const elbow2 = { x: p2.x, y: p1.y };
2178
2251
  let score1 = 0;
@@ -2299,24 +2372,24 @@ var ChipObstacleSpatialIndex = class {
2299
2372
  };
2300
2373
 
2301
2374
  // lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions.ts
2302
- function segmentIntersectsRect2(p1, p2, rect, EPS12 = 1e-9) {
2303
- const isVert = Math.abs(p1.x - p2.x) < EPS12;
2304
- const isHorz = Math.abs(p1.y - p2.y) < EPS12;
2375
+ function segmentIntersectsRect2(p1, p2, rect, EPS13 = 1e-9) {
2376
+ const isVert = Math.abs(p1.x - p2.x) < EPS13;
2377
+ const isHorz = Math.abs(p1.y - p2.y) < EPS13;
2305
2378
  if (!isVert && !isHorz) return false;
2306
2379
  if (isVert) {
2307
2380
  const x = p1.x;
2308
- if (x < rect.minX - EPS12 || x > rect.maxX + EPS12) return false;
2381
+ if (x < rect.minX - EPS13 || x > rect.maxX + EPS13) return false;
2309
2382
  const segMinY = Math.min(p1.y, p2.y);
2310
2383
  const segMaxY = Math.max(p1.y, p2.y);
2311
2384
  const overlap = Math.min(segMaxY, rect.maxY) - Math.max(segMinY, rect.minY);
2312
- return overlap > EPS12;
2385
+ return overlap > EPS13;
2313
2386
  } else {
2314
2387
  const y = p1.y;
2315
- if (y < rect.minY - EPS12 || y > rect.maxY + EPS12) return false;
2388
+ if (y < rect.minY - EPS13 || y > rect.maxY + EPS13) return false;
2316
2389
  const segMinX = Math.min(p1.x, p2.x);
2317
2390
  const segMaxX = Math.max(p1.x, p2.x);
2318
2391
  const overlap = Math.min(segMaxX, rect.maxX) - Math.max(segMinX, rect.minX);
2319
- return overlap > EPS12;
2392
+ return overlap > EPS13;
2320
2393
  }
2321
2394
  }
2322
2395
  function rectIntersectsAnyTrace(bounds, inputTraceMap, hostPathId, hostSegIndex) {
@@ -2713,14 +2786,14 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
2713
2786
  };
2714
2787
  let bestCandidate = null;
2715
2788
  let bestScore = -Infinity;
2716
- const EPS12 = 1e-6;
2789
+ const EPS13 = 1e-6;
2717
2790
  for (const curr of tracesToScan) {
2718
2791
  const pts = curr.tracePath.slice();
2719
2792
  for (let si = 0; si < pts.length - 1; si++) {
2720
2793
  const a = pts[si];
2721
2794
  const b = pts[si + 1];
2722
- const isH = Math.abs(a.y - b.y) < EPS12;
2723
- const isV = Math.abs(a.x - b.x) < EPS12;
2795
+ const isH = Math.abs(a.y - b.y) < EPS13;
2796
+ const isV = Math.abs(a.x - b.x) < EPS13;
2724
2797
  if (!isH && !isV) continue;
2725
2798
  const segmentAllowed = isH ? ["y+", "y-"] : ["x+", "x-"];
2726
2799
  const candidateOrients = orientations.filter(
@@ -5123,9 +5196,9 @@ var moveRailSegments = (trace, segments, coordinate) => {
5123
5196
  };
5124
5197
 
5125
5198
  // lib/solvers/RailNetLabelCornerPlacementSolver/geometry.ts
5126
- var EPS5 = 1e-6;
5199
+ var EPS6 = 1e-6;
5127
5200
  var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
5128
- var rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS5 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS5;
5201
+ 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;
5129
5202
  var getTraceCorners = (path) => {
5130
5203
  const corners = [];
5131
5204
  for (let i = 1; i < path.length - 1; i++) {
@@ -5149,11 +5222,11 @@ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
5149
5222
  var isTraceCorner = (a, b, c) => getSegmentOrientation(a, b) !== getSegmentOrientation(b, c);
5150
5223
  var isPointOnSegment = (point, start, end) => {
5151
5224
  if (getSegmentOrientation(start, end) === "horizontal") {
5152
- return Math.abs(point.y - start.y) <= EPS5 && point.x >= Math.min(start.x, end.x) - EPS5 && point.x <= Math.max(start.x, end.x) + EPS5;
5225
+ return Math.abs(point.y - start.y) <= EPS6 && point.x >= Math.min(start.x, end.x) - EPS6 && point.x <= Math.max(start.x, end.x) + EPS6;
5153
5226
  }
5154
- return Math.abs(point.x - start.x) <= EPS5 && point.y >= Math.min(start.y, end.y) - EPS5 && point.y <= Math.max(start.y, end.y) + EPS5;
5227
+ return Math.abs(point.x - start.x) <= EPS6 && point.y >= Math.min(start.y, end.y) - EPS6 && point.y <= Math.max(start.y, end.y) + EPS6;
5155
5228
  };
5156
- var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <= EPS5 ? "horizontal" : "vertical";
5229
+ var getSegmentOrientation = (a, b) => Math.abs(a.y - b.y) <= EPS6 ? "horizontal" : "vertical";
5157
5230
 
5158
5231
  // lib/solvers/TraceCleanupSolver/sameNetRailAlignment/preservesLabelAnchors.ts
5159
5232
  var getAnchoredTraceIds = (label, traces) => new Set(
@@ -5169,17 +5242,17 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
5169
5242
  });
5170
5243
 
5171
5244
  // lib/solvers/Example28Solver/types.ts
5172
- var EPS6 = 1e-9;
5245
+ var EPS7 = 1e-9;
5173
5246
 
5174
5247
  // lib/solvers/Example28Solver/segmentRunsAlongRectBoundary.ts
5175
5248
  var segmentRunsAlongRectBoundary = (start, end, rect) => {
5176
- const isVertical5 = Math.abs(start.x - end.x) < EPS6;
5177
- const isHorizontal4 = Math.abs(start.y - end.y) < EPS6;
5249
+ const isVertical5 = Math.abs(start.x - end.x) < EPS7;
5250
+ const isHorizontal4 = Math.abs(start.y - end.y) < EPS7;
5178
5251
  if (isVertical5) {
5179
- return Math.abs(start.x - rect.minX) < EPS6 || Math.abs(start.x - rect.maxX) < EPS6;
5252
+ return Math.abs(start.x - rect.minX) < EPS7 || Math.abs(start.x - rect.maxX) < EPS7;
5180
5253
  }
5181
5254
  if (isHorizontal4) {
5182
- return Math.abs(start.y - rect.minY) < EPS6 || Math.abs(start.y - rect.maxY) < EPS6;
5255
+ return Math.abs(start.y - rect.minY) < EPS7 || Math.abs(start.y - rect.maxY) < EPS7;
5183
5256
  }
5184
5257
  return false;
5185
5258
  };
@@ -5194,10 +5267,10 @@ var getPathLength = (path) => {
5194
5267
  return length;
5195
5268
  };
5196
5269
  var getDistance2 = (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
5197
- var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS6 || Math.abs(start.y - end.y) < EPS6;
5198
- var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS6 ? "horizontal" : "vertical";
5270
+ var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS7 || Math.abs(start.y - end.y) < EPS7;
5271
+ var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS7 ? "horizontal" : "vertical";
5199
5272
  var projectPointToSegment = (point, start, end) => {
5200
- if (Math.abs(start.x - end.x) < EPS6) {
5273
+ if (Math.abs(start.x - end.x) < EPS7) {
5201
5274
  return {
5202
5275
  x: start.x,
5203
5276
  y: Math.min(
@@ -5206,7 +5279,7 @@ var projectPointToSegment = (point, start, end) => {
5206
5279
  )
5207
5280
  };
5208
5281
  }
5209
- if (Math.abs(start.y - end.y) < EPS6) {
5282
+ if (Math.abs(start.y - end.y) < EPS7) {
5210
5283
  return {
5211
5284
  x: Math.min(
5212
5285
  Math.max(point.x, Math.min(start.x, end.x)),
@@ -5249,9 +5322,9 @@ var findSegmentContainingPoint = (path, point) => {
5249
5322
  };
5250
5323
  var isPointWithinSegmentPrimaryRange = (point, segment) => {
5251
5324
  if (segment.orientation === "horizontal") {
5252
- return point.x >= Math.min(segment.start.x, segment.end.x) - EPS6 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS6;
5325
+ return point.x >= Math.min(segment.start.x, segment.end.x) - EPS7 && point.x <= Math.max(segment.start.x, segment.end.x) + EPS7;
5253
5326
  }
5254
- return point.y >= Math.min(segment.start.y, segment.end.y) - EPS6 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS6;
5327
+ return point.y >= Math.min(segment.start.y, segment.end.y) - EPS7 && point.y <= Math.max(segment.start.y, segment.end.y) + EPS7;
5255
5328
  };
5256
5329
  var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation, anchorPoint) => {
5257
5330
  const matchingSegments = getSegments(path).filter(
@@ -5279,18 +5352,18 @@ var projectPointToPath = (point, path) => {
5279
5352
  return bestPoint;
5280
5353
  };
5281
5354
  var segmentsIntersect = (a1, a2, b1, b2) => {
5282
- const aVertical = Math.abs(a1.x - a2.x) < EPS6;
5283
- const bVertical = Math.abs(b1.x - b2.x) < EPS6;
5284
- const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS6 && value <= Math.max(p1, p2) + EPS6;
5355
+ const aVertical = Math.abs(a1.x - a2.x) < EPS7;
5356
+ const bVertical = Math.abs(b1.x - b2.x) < EPS7;
5357
+ const between = (value, p1, p2) => value >= Math.min(p1, p2) - EPS7 && value <= Math.max(p1, p2) + EPS7;
5285
5358
  if (aVertical && bVertical) {
5286
- if (Math.abs(a1.x - b1.x) > EPS6) return false;
5359
+ if (Math.abs(a1.x - b1.x) > EPS7) return false;
5287
5360
  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));
5288
- return overlap > EPS6;
5361
+ return overlap > EPS7;
5289
5362
  }
5290
5363
  if (!aVertical && !bVertical) {
5291
- if (Math.abs(a1.y - b1.y) > EPS6) return false;
5364
+ if (Math.abs(a1.y - b1.y) > EPS7) return false;
5292
5365
  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));
5293
- return overlap > EPS6;
5366
+ return overlap > EPS7;
5294
5367
  }
5295
5368
  const verticalA = aVertical ? a1 : b1;
5296
5369
  const verticalB = aVertical ? a2 : b2;
@@ -5652,7 +5725,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
5652
5725
 
5653
5726
  // lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts
5654
5727
  import { getSegmentIntersection } from "@tscircuit/math-utils/line-intersections";
5655
- var EPS7 = 1e-6;
5728
+ var EPS8 = 1e-6;
5656
5729
  var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
5657
5730
  const intersections = [];
5658
5731
  for (const obstacle of obstacles) {
@@ -5671,17 +5744,17 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
5671
5744
  }
5672
5745
  return intersections;
5673
5746
  };
5674
- var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS7 && Math.abs(first.y - second.y) < EPS7;
5747
+ var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS8 && Math.abs(first.y - second.y) < EPS8;
5675
5748
  var findPerpendicularPathCrossings = (path, otherPath) => {
5676
5749
  const crossings = [];
5677
5750
  for (let pathSegmentIndex = 1; pathSegmentIndex < path.length - 2; pathSegmentIndex++) {
5678
5751
  const start = path[pathSegmentIndex];
5679
5752
  const end = path[pathSegmentIndex + 1];
5680
- const isVertical5 = Math.abs(start.x - end.x) < EPS7;
5753
+ const isVertical5 = Math.abs(start.x - end.x) < EPS8;
5681
5754
  for (let otherPathSegmentIndex = 1; otherPathSegmentIndex < otherPath.length - 2; otherPathSegmentIndex++) {
5682
5755
  const otherStart = otherPath[otherPathSegmentIndex];
5683
5756
  const otherEnd = otherPath[otherPathSegmentIndex + 1];
5684
- const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS7;
5757
+ const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS8;
5685
5758
  if (isVertical5 === otherIsVertical) continue;
5686
5759
  const intersection = getSegmentIntersection(
5687
5760
  start,
@@ -5701,8 +5774,8 @@ var findPerpendicularPathCrossings = (path, otherPath) => {
5701
5774
  };
5702
5775
 
5703
5776
  // lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts
5704
- var EPS8 = 1e-6;
5705
- var isVertical3 = (a, b, eps = EPS8) => Math.abs(a.x - b.x) < eps;
5777
+ var EPS9 = 1e-6;
5778
+ var isVertical3 = (a, b, eps = EPS9) => Math.abs(a.x - b.x) < eps;
5706
5779
  var generateLShapeRerouteCandidates = ({
5707
5780
  lShape,
5708
5781
  rectangle,
@@ -5715,7 +5788,7 @@ var generateLShapeRerouteCandidates = ({
5715
5788
  let c2;
5716
5789
  let i1_padded = interactionPoint1;
5717
5790
  let i2_padded = interactionPoint2;
5718
- if (Math.abs(p2.x - x) < EPS8 && Math.abs(p2.y - (y + height)) < EPS8) {
5791
+ if (Math.abs(p2.x - x) < EPS9 && Math.abs(p2.y - (y + height)) < EPS9) {
5719
5792
  c2 = { x: x + width + padding, y: y - padding };
5720
5793
  if (isVertical3(p1, p2)) {
5721
5794
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -5727,7 +5800,7 @@ var generateLShapeRerouteCandidates = ({
5727
5800
  } else {
5728
5801
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
5729
5802
  }
5730
- } else if (Math.abs(p2.x - (x + width)) < EPS8 && Math.abs(p2.y - (y + height)) < EPS8) {
5803
+ } else if (Math.abs(p2.x - (x + width)) < EPS9 && Math.abs(p2.y - (y + height)) < EPS9) {
5731
5804
  c2 = { x: x - padding, y: y - padding };
5732
5805
  if (isVertical3(p1, p2)) {
5733
5806
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -5739,7 +5812,7 @@ var generateLShapeRerouteCandidates = ({
5739
5812
  } else {
5740
5813
  i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
5741
5814
  }
5742
- } else if (Math.abs(p2.x - x) < EPS8 && Math.abs(p2.y - y) < EPS8) {
5815
+ } else if (Math.abs(p2.x - x) < EPS9 && Math.abs(p2.y - y) < EPS9) {
5743
5816
  c2 = { x: x + width + padding, y: y + height + padding };
5744
5817
  if (isVertical3(p1, p2)) {
5745
5818
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -5751,7 +5824,7 @@ var generateLShapeRerouteCandidates = ({
5751
5824
  } else {
5752
5825
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
5753
5826
  }
5754
- } else if (Math.abs(p2.x - (x + width)) < EPS8 && Math.abs(p2.y - y) < EPS8) {
5827
+ } else if (Math.abs(p2.x - (x + width)) < EPS9 && Math.abs(p2.y - y) < EPS9) {
5755
5828
  c2 = { x: x - padding, y: y + height + padding };
5756
5829
  if (isVertical3(p1, p2)) {
5757
5830
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -5779,7 +5852,7 @@ var generatePerpendicularTraceDetours = ({
5779
5852
  const buildDetours = (path, index) => {
5780
5853
  const start = path[index];
5781
5854
  const end = path[index + 1];
5782
- const movingAxis = Math.abs(start.x - end.x) < EPS8 ? "y" : "x";
5855
+ const movingAxis = Math.abs(start.x - end.x) < EPS9 ? "y" : "x";
5783
5856
  const detourAxis = movingAxis === "x" ? "y" : "x";
5784
5857
  const gate = obstacleStart[movingAxis] + Math.sign(start[movingAxis] - obstacleStart[movingAxis]) * clearance;
5785
5858
  const obstacleRange = [obstacleStart[detourAxis], obstacleEnd[detourAxis]];
@@ -6377,9 +6450,9 @@ var UntangleTraceSubsolver = class extends BaseSolver {
6377
6450
  };
6378
6451
 
6379
6452
  // lib/solvers/TraceCleanupSolver/is4PointRectangle.ts
6380
- var EPS9 = 1e-6;
6381
- var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS9;
6382
- var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS9;
6453
+ var EPS10 = 1e-6;
6454
+ var sameX = (a, b) => Math.abs(a.x - b.x) <= EPS10;
6455
+ var sameY = (a, b) => Math.abs(a.y - b.y) <= EPS10;
6383
6456
  var is4PointRectangle = (path) => {
6384
6457
  if (path.length !== 4) return false;
6385
6458
  const [p0, p1, p2, p3] = path;
@@ -6654,7 +6727,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
6654
6727
  const end = path[i + 1];
6655
6728
  for (const obstacle of chipObstacles) {
6656
6729
  if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
6657
- if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS6) {
6730
+ if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS7) {
6658
6731
  return true;
6659
6732
  }
6660
6733
  }
@@ -6669,13 +6742,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
6669
6742
  for (const obstacle of chipObstacles) {
6670
6743
  if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
6671
6744
  const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
6672
- if (overlap > EPS6) total += overlap;
6745
+ if (overlap > EPS7) total += overlap;
6673
6746
  }
6674
6747
  }
6675
6748
  return total;
6676
6749
  };
6677
6750
  var getSegmentOverlapWithRectSpan = (start, end, rect) => {
6678
- const isVertical5 = Math.abs(start.x - end.x) < EPS6;
6751
+ const isVertical5 = Math.abs(start.x - end.x) < EPS7;
6679
6752
  if (isVertical5) {
6680
6753
  return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
6681
6754
  }
@@ -7439,16 +7512,16 @@ var createPortOnlyLabelConnectorTrace = ({
7439
7512
  // lib/solvers/AvailableNetOrientationSolver/constants.ts
7440
7513
  var LABEL_SEARCH_STEP = 0.05;
7441
7514
  var WICK_CLEARANCE = 1e-3;
7442
- var EPS10 = 1e-9;
7443
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS10;
7515
+ var EPS11 = 1e-9;
7516
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS11;
7444
7517
  var CANDIDATE_SELECTED_COLOR2 = "blue";
7445
7518
  var CANDIDATE_REJECTED_COLOR2 = "red";
7446
7519
 
7447
7520
  // lib/solvers/AvailableNetOrientationSolver/geometry.ts
7448
7521
  var isYOrientation = (orientation) => orientation === "y+" || orientation === "y-";
7449
7522
  var isXOrientation = (orientation) => orientation === "x+" || orientation === "x-";
7450
- var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS10 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS10;
7451
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS10;
7523
+ var rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS11 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS11;
7524
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS11;
7452
7525
  var traceCrossesBoundsInterior = (bounds, traceMap) => {
7453
7526
  for (const trace of Object.values(traceMap)) {
7454
7527
  const points = trace.tracePath;
@@ -7471,7 +7544,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
7471
7544
  return false;
7472
7545
  }
7473
7546
  if (sameX2(p1, p2)) {
7474
- if (p1.x <= interiorBounds.minX + EPS10 || p1.x >= interiorBounds.maxX - EPS10) {
7547
+ if (p1.x <= interiorBounds.minX + EPS11 || p1.x >= interiorBounds.maxX - EPS11) {
7475
7548
  return false;
7476
7549
  }
7477
7550
  return rangesOverlap(
@@ -7482,7 +7555,7 @@ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
7482
7555
  );
7483
7556
  }
7484
7557
  if (sameY2(p1, p2)) {
7485
- if (p1.y <= interiorBounds.minY + EPS10 || p1.y >= interiorBounds.maxY - EPS10) {
7558
+ if (p1.y <= interiorBounds.minY + EPS11 || p1.y >= interiorBounds.maxY - EPS11) {
7486
7559
  return false;
7487
7560
  }
7488
7561
  return rangesOverlap(
@@ -7538,8 +7611,8 @@ var simplifyOrthogonalPath = (path) => {
7538
7611
  return simplified;
7539
7612
  };
7540
7613
  var pointsEqual2 = (a, b) => sameX2(a, b) && sameY2(a, b);
7541
- var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS10;
7542
- var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS10;
7614
+ var sameX2 = (a, b) => Math.abs(a.x - b.x) <= EPS11;
7615
+ var sameY2 = (a, b) => Math.abs(a.y - b.y) <= EPS11;
7543
7616
  var getMaxSearchDistance = (inputProblem) => {
7544
7617
  const maxChipWidth = Math.max(
7545
7618
  ...inputProblem.chips.map((chip) => chip.width),
@@ -7794,11 +7867,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7794
7867
  if (trace.globalConnNetId !== label.globalConnNetId) return false;
7795
7868
  const path = trace.tracePath;
7796
7869
  return path.some((point, pointIndex) => {
7797
- if (Math.abs(point.x - label.anchorPoint.x) > EPS10 || Math.abs(point.y - label.anchorPoint.y) > EPS10) {
7870
+ if (Math.abs(point.x - label.anchorPoint.x) > EPS11 || Math.abs(point.y - label.anchorPoint.y) > EPS11) {
7798
7871
  return false;
7799
7872
  }
7800
7873
  return [path[pointIndex - 1], path[pointIndex + 1]].some(
7801
- (neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS10 && (neighbor.y - point.y) * direction.y > EPS10
7874
+ (neighbor) => neighbor && Math.abs(neighbor.x - point.x) <= EPS11 && (neighbor.y - point.y) * direction.y > EPS11
7802
7875
  );
7803
7876
  });
7804
7877
  });
@@ -7877,7 +7950,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7877
7950
  );
7878
7951
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation);
7879
7952
  const maxOutwardDistance = outwardDirection.x === 0 && outwardDirection.y === 0 ? 0 : this.maxSearchDistance;
7880
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS10; outwardDistance += LABEL_SEARCH_STEP) {
7953
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS11; outwardDistance += LABEL_SEARCH_STEP) {
7881
7954
  const baseAnchor = {
7882
7955
  x: initialBaseAnchor.x + outwardDirection.x * outwardDistance,
7883
7956
  y: initialBaseAnchor.y + outwardDirection.y * outwardDistance
@@ -7951,7 +8024,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
7951
8024
  phase = "shift",
7952
8025
  stopOnTraceCollision = true
7953
8026
  } = params;
7954
- for (let distance4 = LABEL_SEARCH_STEP; distance4 <= maxSearchDistance + EPS10; distance4 += LABEL_SEARCH_STEP) {
8027
+ for (let distance4 = LABEL_SEARCH_STEP; distance4 <= maxSearchDistance + EPS11; distance4 += LABEL_SEARCH_STEP) {
7955
8028
  const anchorPoint = {
7956
8029
  x: baseAnchor.x + direction.x * distance4,
7957
8030
  y: baseAnchor.y + direction.y * distance4
@@ -8188,9 +8261,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8188
8261
  const { anchorPoint, orientation } = candidate;
8189
8262
  const chipBounds = chip.bounds;
8190
8263
  if (isYOrientation(orientation)) {
8191
- return anchorPoint.x < chipBounds.minX - EPS10 || anchorPoint.x > chipBounds.maxX + EPS10;
8264
+ return anchorPoint.x < chipBounds.minX - EPS11 || anchorPoint.x > chipBounds.maxX + EPS11;
8192
8265
  }
8193
- return anchorPoint.y < chipBounds.minY - EPS10 || anchorPoint.y > chipBounds.maxY + EPS10;
8266
+ return anchorPoint.y < chipBounds.minY - EPS11 || anchorPoint.y > chipBounds.maxY + EPS11;
8194
8267
  });
8195
8268
  }
8196
8269
  getBoundsStatus(candidateBoundsCheck) {
@@ -8264,8 +8337,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8264
8337
  sharesChipBoundary(bounds) {
8265
8338
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8266
8339
  const chipBounds = chip.bounds;
8267
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS10 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS10;
8268
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS10 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS10;
8340
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS11 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS11;
8341
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS11 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS11;
8269
8342
  if (adjacentToVerticalSide && rangesOverlap(
8270
8343
  bounds.minY,
8271
8344
  bounds.maxY,
@@ -8313,7 +8386,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8313
8386
  let nearestDistance = Number.POSITIVE_INFINITY;
8314
8387
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8315
8388
  const bounds = chip.bounds;
8316
- if (point.x < bounds.minX - EPS10 || point.x > bounds.maxX + EPS10 || point.y < bounds.minY - EPS10 || point.y > bounds.maxY + EPS10) {
8389
+ if (point.x < bounds.minX - EPS11 || point.x > bounds.maxX + EPS11 || point.y < bounds.minY - EPS11 || point.y > bounds.maxY + EPS11) {
8317
8390
  continue;
8318
8391
  }
8319
8392
  for (const [side, distance4] of getSideDistances(point, bounds)) {
@@ -8330,8 +8403,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
8330
8403
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
8331
8404
  for (const chip of this.chipObstacleSpatialIndex.chips) {
8332
8405
  const bounds = chip.bounds;
8333
- const dx = point.x < bounds.minX - EPS10 ? bounds.minX - point.x : point.x > bounds.maxX + EPS10 ? point.x - bounds.maxX : 0;
8334
- const dy = point.y < bounds.minY - EPS10 ? bounds.minY - point.y : point.y > bounds.maxY + EPS10 ? point.y - bounds.maxY : 0;
8406
+ const dx = point.x < bounds.minX - EPS11 ? bounds.minX - point.x : point.x > bounds.maxX + EPS11 ? point.x - bounds.maxX : 0;
8407
+ const dy = point.y < bounds.minY - EPS11 ? bounds.minY - point.y : point.y > bounds.maxY + EPS11 ? point.y - bounds.maxY : 0;
8335
8408
  if (dx === 0 && dy === 0) continue;
8336
8409
  const distanceSq = dx ** 2 + dy ** 2;
8337
8410
  if (distanceSq >= nearestDistanceSq) continue;
@@ -8615,8 +8688,8 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver {
8615
8688
  if (seenCornerKeys.has(key)) continue;
8616
8689
  seenCornerKeys.add(key);
8617
8690
  const pinAligned = pins.some((pin) => {
8618
- if (isVertical5) return Math.abs(pin.x - anchorPoint.x) < EPS5;
8619
- return Math.abs(pin.y - anchorPoint.y) < EPS5;
8691
+ if (isVertical5) return Math.abs(pin.x - anchorPoint.x) < EPS6;
8692
+ return Math.abs(pin.y - anchorPoint.y) < EPS6;
8620
8693
  });
8621
8694
  if (!pinAligned) continue;
8622
8695
  candidates.push({
@@ -8709,11 +8782,11 @@ var getOrientationConstraint = (inputProblem, label) => {
8709
8782
  };
8710
8783
 
8711
8784
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/geometry.ts
8712
- var EPS11 = 1e-6;
8785
+ var EPS12 = 1e-6;
8713
8786
  var TRACE_BOUNDARY_TOLERANCE2 = 1e-6;
8714
8787
  var getLabelBounds = (label) => getRectBounds(label.center, label.width, label.height);
8715
- var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS11 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS11;
8716
- var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS11 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS11;
8788
+ var rectsOverlap3 = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) > EPS12 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) > EPS12;
8789
+ var rectsTouchOrOverlap = (a, b) => Math.min(a.maxX, b.maxX) - Math.max(a.minX, b.minX) >= -EPS12 && Math.min(a.maxY, b.maxY) - Math.max(a.minY, b.minY) >= -EPS12;
8717
8790
  var traceCrossesBoundsInterior2 = (bounds, traces) => {
8718
8791
  for (const trace of traces) {
8719
8792
  const points = trace.tracePath;
@@ -8759,7 +8832,7 @@ var getPointAtTraceDistance = (trace, distance4) => {
8759
8832
  const end = trace.tracePath[i + 1];
8760
8833
  const segmentLength = getManhattanDistance(start, end);
8761
8834
  const nextDistance = pathDistance + segmentLength;
8762
- if (distance4 <= nextDistance + EPS11) {
8835
+ if (distance4 <= nextDistance + EPS12) {
8763
8836
  const offset = Math.max(
8764
8837
  0,
8765
8838
  Math.min(segmentLength, distance4 - pathDistance)
@@ -8798,7 +8871,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8798
8871
  return false;
8799
8872
  }
8800
8873
  if (isVertical4(start, end)) {
8801
- if (start.x <= interior.minX + EPS11 || start.x >= interior.maxX - EPS11) {
8874
+ if (start.x <= interior.minX + EPS12 || start.x >= interior.maxX - EPS12) {
8802
8875
  return false;
8803
8876
  }
8804
8877
  return rangesOverlap2(
@@ -8809,7 +8882,7 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8809
8882
  );
8810
8883
  }
8811
8884
  if (isHorizontal3(start, end)) {
8812
- if (start.y <= interior.minY + EPS11 || start.y >= interior.maxY - EPS11) {
8885
+ if (start.y <= interior.minY + EPS12 || start.y >= interior.maxY - EPS12) {
8813
8886
  return false;
8814
8887
  }
8815
8888
  return rangesOverlap2(
@@ -8823,10 +8896,10 @@ var segmentCrossesBoundsInterior2 = (start, end, bounds) => {
8823
8896
  };
8824
8897
  var isPointOnSegment2 = (point, start, end) => {
8825
8898
  if (isHorizontal3(start, end)) {
8826
- return Math.abs(point.y - start.y) <= EPS11 && point.x >= Math.min(start.x, end.x) - EPS11 && point.x <= Math.max(start.x, end.x) + EPS11;
8899
+ return Math.abs(point.y - start.y) <= EPS12 && point.x >= Math.min(start.x, end.x) - EPS12 && point.x <= Math.max(start.x, end.x) + EPS12;
8827
8900
  }
8828
8901
  if (isVertical4(start, end)) {
8829
- return Math.abs(point.x - start.x) <= EPS11 && point.y >= Math.min(start.y, end.y) - EPS11 && point.y <= Math.max(start.y, end.y) + EPS11;
8902
+ return Math.abs(point.x - start.x) <= EPS12 && point.y >= Math.min(start.y, end.y) - EPS12 && point.y <= Math.max(start.y, end.y) + EPS12;
8830
8903
  }
8831
8904
  return false;
8832
8905
  };
@@ -8834,9 +8907,9 @@ var getSegmentDirection = (start, end) => ({
8834
8907
  x: isVertical4(start, end) ? 0 : Math.sign(end.x - start.x),
8835
8908
  y: isHorizontal3(start, end) ? 0 : Math.sign(end.y - start.y)
8836
8909
  });
8837
- var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS11;
8838
- var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS11;
8839
- var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS11;
8910
+ var isHorizontal3 = (start, end) => Math.abs(start.y - end.y) <= EPS12;
8911
+ var isVertical4 = (start, end) => Math.abs(start.x - end.x) <= EPS12;
8912
+ var rangesOverlap2 = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS12;
8840
8913
  var getUniquePinCount2 = (pinIds) => new Set(pinIds).size;
8841
8914
 
8842
8915
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/candidates.ts
@@ -8893,7 +8966,7 @@ var getCandidateDistances = (traceLength, vertexDistances) => {
8893
8966
  for (const distance4 of vertexDistances) {
8894
8967
  distances.add(roundDistance(distance4));
8895
8968
  }
8896
- return [...distances].filter((distance4) => distance4 >= -EPS11 && distance4 <= traceLength + EPS11).sort((a, b) => a - b);
8969
+ return [...distances].filter((distance4) => distance4 >= -EPS12 && distance4 <= traceLength + EPS12).sort((a, b) => a - b);
8897
8970
  };
8898
8971
  var getOrientationsForPoint = (params) => {
8899
8972
  const { inputProblem, label, point, orientationConstraint } = params;
@@ -8982,13 +9055,13 @@ var getOutwardOrientationOptions = (point, chipBounds) => {
8982
9055
  };
8983
9056
  var getOutwardAxisOption = (params) => {
8984
9057
  const { value, min, max, center, positiveOrientation, negativeOrientation } = params;
8985
- if (value > max + EPS11) {
9058
+ if (value > max + EPS12) {
8986
9059
  return {
8987
9060
  orientation: positiveOrientation,
8988
9061
  outwardScore: 1 + value - max
8989
9062
  };
8990
9063
  }
8991
- if (value < min - EPS11) {
9064
+ if (value < min - EPS12) {
8992
9065
  return {
8993
9066
  orientation: negativeOrientation,
8994
9067
  outwardScore: 1 + min - value
@@ -8999,7 +9072,7 @@ var getOutwardAxisOption = (params) => {
8999
9072
  outwardScore: getNormalizedCenterDistance(value, center, max - min)
9000
9073
  };
9001
9074
  };
9002
- var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS11, span / 2);
9075
+ var getNormalizedCenterDistance = (value, center, span) => Math.abs(value - center) / Math.max(EPS12, span / 2);
9003
9076
  var ALL_ORIENTATIONS = ["x+", "x-", "y+", "y-"];
9004
9077
  var getFlippedOrientation = (orientation) => {
9005
9078
  switch (orientation) {
@@ -9072,7 +9145,7 @@ var getNetLabelHeight = (inputProblem, label) => {
9072
9145
  )?.netLabelHeight;
9073
9146
  };
9074
9147
  var roundDistance = (distance4) => Number(distance4.toFixed(6));
9075
- var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS11 && Math.abs(point.y - label.anchorPoint.y) <= EPS11 && orientation === label.orientation;
9148
+ var isSamePlacement = (label, point, orientation) => Math.abs(point.x - label.anchorPoint.x) <= EPS12 && Math.abs(point.y - label.anchorPoint.y) <= EPS12 && orientation === label.orientation;
9076
9149
 
9077
9150
  // lib/solvers/TraceAnchoredNetLabelOverlapSolver/visualize.ts
9078
9151
  var CANDIDATE_SELECTED_COLOR4 = "blue";