@tscircuit/core 0.0.2118 → 0.0.2120

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
@@ -84,6 +84,7 @@ __export(components_exports, {
84
84
  PcbNotePath: () => PcbNotePath,
85
85
  PcbNoteRect: () => PcbNoteRect,
86
86
  PcbNoteText: () => PcbNoteText,
87
+ PcbReturnCurrentSimulation: () => PcbReturnCurrentSimulation,
87
88
  PcbSoldermaskOpening: () => PcbSoldermaskOpening,
88
89
  PcbStiffener: () => PcbStiffener,
89
90
  PcbTrace: () => PcbTrace,
@@ -93724,6 +93725,265 @@ var balanceZShapes = ({
93724
93725
  tracePath: finalSimplifiedPath
93725
93726
  };
93726
93727
  };
93728
+ var LABEL_SEARCH_STEP = 0.05;
93729
+ var MAX_RECORDED_CANDIDATES = 2e3;
93730
+ var WICK_CLEARANCE = 1e-3;
93731
+ var EPS8 = 1e-9;
93732
+ var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS8;
93733
+ var CANDIDATE_SELECTED_COLOR = "blue";
93734
+ var CANDIDATE_REJECTED_COLOR = "red";
93735
+ var isYOrientation = (orientation2) => orientation2 === "y+" || orientation2 === "y-";
93736
+ var isXOrientation = (orientation2) => orientation2 === "x+" || orientation2 === "x-";
93737
+ var rectsOverlap = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS8 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS8;
93738
+ var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS8;
93739
+ var traceCrossesBoundsInterior = (bounds, traceMap) => {
93740
+ for (const trace of Object.values(traceMap)) {
93741
+ const points = trace.tracePath;
93742
+ for (let i2 = 0; i2 < points.length - 1; i2++) {
93743
+ if (segmentCrossesBoundsInterior(points[i2], points[i2 + 1], bounds)) {
93744
+ return true;
93745
+ }
93746
+ }
93747
+ }
93748
+ return false;
93749
+ };
93750
+ var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
93751
+ const interiorBounds = {
93752
+ minX: bounds.minX + TRACE_BOUNDARY_TOLERANCE,
93753
+ minY: bounds.minY + TRACE_BOUNDARY_TOLERANCE,
93754
+ maxX: bounds.maxX - TRACE_BOUNDARY_TOLERANCE,
93755
+ maxY: bounds.maxY - TRACE_BOUNDARY_TOLERANCE
93756
+ };
93757
+ if (interiorBounds.minX >= interiorBounds.maxX || interiorBounds.minY >= interiorBounds.maxY) {
93758
+ return false;
93759
+ }
93760
+ if (sameX(p1, p2)) {
93761
+ if (p1.x <= interiorBounds.minX + EPS8 || p1.x >= interiorBounds.maxX - EPS8) {
93762
+ return false;
93763
+ }
93764
+ return rangesOverlap(
93765
+ Math.min(p1.y, p2.y),
93766
+ Math.max(p1.y, p2.y),
93767
+ interiorBounds.minY,
93768
+ interiorBounds.maxY
93769
+ );
93770
+ }
93771
+ if (sameY(p1, p2)) {
93772
+ if (p1.y <= interiorBounds.minY + EPS8 || p1.y >= interiorBounds.maxY - EPS8) {
93773
+ return false;
93774
+ }
93775
+ return rangesOverlap(
93776
+ Math.min(p1.x, p2.x),
93777
+ Math.max(p1.x, p2.x),
93778
+ interiorBounds.minX,
93779
+ interiorBounds.maxX
93780
+ );
93781
+ }
93782
+ return false;
93783
+ };
93784
+ var tracePathCrossesAnyBounds = (tracePath, bounds) => {
93785
+ for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
93786
+ if (segmentCrossesBoundsInterior(tracePath[i2], tracePath[i2 + 1], bounds)) {
93787
+ return true;
93788
+ }
93789
+ }
93790
+ return false;
93791
+ };
93792
+ var tracePathIntersectsBounds = (tracePath, bounds) => {
93793
+ for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
93794
+ if (segmentIntersectsRect2(tracePath[i2], tracePath[i2 + 1], bounds)) {
93795
+ return true;
93796
+ }
93797
+ }
93798
+ return false;
93799
+ };
93800
+ var getSideDistances = (point6, bounds) => [
93801
+ ["left", Math.abs(point6.x - bounds.minX)],
93802
+ ["right", Math.abs(point6.x - bounds.maxX)],
93803
+ ["bottom", Math.abs(point6.y - bounds.minY)],
93804
+ ["top", Math.abs(point6.y - bounds.maxY)]
93805
+ ];
93806
+ var getConnectorTracePath = (source, target, orientation2) => simplifyOrthogonalPath(
93807
+ isYOrientation(orientation2) ? [source, { x: target.x, y: source.y }, target] : [source, { x: source.x, y: target.y }, target]
93808
+ );
93809
+ var simplifyOrthogonalPath = (path) => {
93810
+ const deduped = path.filter(
93811
+ (point6, index2) => index2 === 0 || !pointsEqual3(point6, path[index2 - 1])
93812
+ );
93813
+ if (deduped.length < 3) return deduped;
93814
+ const simplified = [deduped[0]];
93815
+ for (let i2 = 1; i2 < deduped.length - 1; i2++) {
93816
+ const prev = simplified[simplified.length - 1];
93817
+ const point6 = deduped[i2];
93818
+ const next = deduped[i2 + 1];
93819
+ if (sameX(prev, point6) && sameX(point6, next) || sameY(prev, point6) && sameY(point6, next)) {
93820
+ continue;
93821
+ }
93822
+ simplified.push(point6);
93823
+ }
93824
+ simplified.push(deduped[deduped.length - 1]);
93825
+ return simplified;
93826
+ };
93827
+ var pointsEqual3 = (a2, b2) => sameX(a2, b2) && sameY(a2, b2);
93828
+ var sameX = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS8;
93829
+ var sameY = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS8;
93830
+ var getMaxSearchDistance = (inputProblem) => {
93831
+ const maxChipWidth = Math.max(
93832
+ ...inputProblem.chips.map((chip) => chip.width),
93833
+ 1
93834
+ );
93835
+ return maxChipWidth * 3;
93836
+ };
93837
+ var EPS9 = 1e-6;
93838
+ var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
93839
+ var rectsOverlap2 = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS9 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS9;
93840
+ var getTraceCorners = (path) => {
93841
+ const corners = [];
93842
+ for (let i2 = 1; i2 < path.length - 1; i2++) {
93843
+ const previousPoint = path[i2 - 1];
93844
+ const cornerPoint = path[i2];
93845
+ const nextPoint = path[i2 + 1];
93846
+ if (isTraceCorner(previousPoint, cornerPoint, nextPoint)) {
93847
+ corners.push(cornerPoint);
93848
+ }
93849
+ }
93850
+ return corners;
93851
+ };
93852
+ var tracePathContainsPoint = (path, point6) => {
93853
+ for (let i2 = 0; i2 < path.length - 1; i2++) {
93854
+ if (isPointOnSegment(point6, path[i2], path[i2 + 1])) return true;
93855
+ }
93856
+ return false;
93857
+ };
93858
+ var getDistance2 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
93859
+ var getUniquePinCount = (pinIds) => new Set(pinIds).size;
93860
+ var isTraceCorner = (a2, b2, c2) => getSegmentOrientation(a2, b2) !== getSegmentOrientation(b2, c2);
93861
+ var isPointOnSegment = (point6, start, end) => {
93862
+ if (getSegmentOrientation(start, end) === "horizontal") {
93863
+ return Math.abs(point6.y - start.y) <= EPS9 && point6.x >= Math.min(start.x, end.x) - EPS9 && point6.x <= Math.max(start.x, end.x) + EPS9;
93864
+ }
93865
+ return Math.abs(point6.x - start.x) <= EPS9 && point6.y >= Math.min(start.y, end.y) - EPS9 && point6.y <= Math.max(start.y, end.y) + EPS9;
93866
+ };
93867
+ var getSegmentOrientation = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS9 ? "horizontal" : "vertical";
93868
+ var getGroundNetIds = (inputProblem, netConnMap) => {
93869
+ const groundNetIds = /* @__PURE__ */ new Set();
93870
+ for (const connection of inputProblem.netConnections) {
93871
+ if (!connection.isGround) continue;
93872
+ const netId = netConnMap.getNetConnectedToId(connection.netId);
93873
+ if (netId) groundNetIds.add(netId);
93874
+ }
93875
+ return groundNetIds;
93876
+ };
93877
+ var placeGroundRailLabelsAtOuterEnd = ({
93878
+ inputProblem,
93879
+ traces,
93880
+ netLabelPlacements
93881
+ }) => {
93882
+ const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
93883
+ const groundNetIds = getGroundNetIds(inputProblem, netConnMap);
93884
+ if (groundNetIds.size === 0) return netLabelPlacements;
93885
+ const chipMap = new Map(inputProblem.chips.map((chip) => [chip.chipId, chip]));
93886
+ const traceMap = Object.fromEntries(
93887
+ traces.map((trace) => [trace.mspPairId, trace])
93888
+ );
93889
+ const obstacles = getObstacleRects(inputProblem);
93890
+ const output = [...netLabelPlacements];
93891
+ for (const rail of traces) {
93892
+ if (!groundNetIds.has(rail.globalConnNetId)) continue;
93893
+ const [a2, b2] = rail.pins;
93894
+ if (a2.chipId === b2.chipId || !nearlyEqual(a2.y, b2.y) || ![a2, b2].every(
93895
+ (pin) => pin._facingDirection === "y-" && chipMap.get(pin.chipId)?.pins.length === 2
93896
+ ))
93897
+ continue;
93898
+ const path = simplifyPath(rail.tracePath);
93899
+ if (path.length !== 4 || !isVertical2(path[0], path[1]) || !isHorizontal22(path[1], path[2]) || !isVertical2(path[2], path[3]) || path[1].y >= a2.y)
93900
+ continue;
93901
+ for (const feed of traces) {
93902
+ if (feed.globalConnNetId !== rail.globalConnNetId) continue;
93903
+ const shared = feed.pins.find((pin) => rail.pinIds.includes(pin.pinId));
93904
+ const icPin = feed.pins.find(
93905
+ (pin) => !rail.pinIds.includes(pin.pinId) && (chipMap.get(pin.chipId)?.pins.length ?? 0) > 2
93906
+ );
93907
+ if (!shared || !icPin || !nearlyEqual(icPin.y, path[1].y)) continue;
93908
+ const outer = shared.pinId === a2.pinId ? b2 : a2;
93909
+ if (Math.abs(outer.x - icPin.x) <= Math.abs(shared.x - icPin.x)) continue;
93910
+ const anchorPoint = { x: outer.x, y: path[1].y };
93911
+ if (!tracePathContainsPoint(rail.tracePath, anchorPoint)) continue;
93912
+ for (let index2 = 0; index2 < output.length; index2++) {
93913
+ const label = output[index2];
93914
+ if (label.globalConnNetId !== rail.globalConnNetId || label.orientation !== "y-" || !label.mspConnectionPairIds.some(
93915
+ (id) => id === feed.mspPairId || id === rail.mspPairId
93916
+ ) || !tracePathContainsPoint(feed.tracePath, label.anchorPoint) && !tracePathContainsPoint(rail.tracePath, label.anchorPoint))
93917
+ continue;
93918
+ const center = getCenterFromAnchor(
93919
+ anchorPoint,
93920
+ label.orientation,
93921
+ label.width,
93922
+ label.height
93923
+ );
93924
+ const bounds = getRectBounds(center, label.width, label.height);
93925
+ if (obstacles.some((obstacle) => rectsOverlap2(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
93926
+ (other, otherIndex) => otherIndex !== index2 && rectsOverlap2(
93927
+ bounds,
93928
+ getRectBounds(other.center, other.width, other.height)
93929
+ )
93930
+ ))
93931
+ continue;
93932
+ output[index2] = {
93933
+ ...label,
93934
+ anchorPoint,
93935
+ center,
93936
+ mspConnectionPairIds: [rail.mspPairId],
93937
+ pinIds: [...rail.pinIds]
93938
+ };
93939
+ }
93940
+ }
93941
+ }
93942
+ for (let index2 = 0; index2 < output.length; index2++) {
93943
+ const label = output[index2];
93944
+ if (label.orientation !== "y-" || !groundNetIds.has(label.globalConnNetId))
93945
+ continue;
93946
+ const hasSharedRail = inputProblem.netConnections.some(
93947
+ (candidate) => candidate.pinIds.length > 2 && netConnMap.getNetConnectedToId(candidate.netId) === label.globalConnNetId
93948
+ );
93949
+ if (!hasSharedRail) continue;
93950
+ const columnSegments = traces.filter((trace) => trace.globalConnNetId === label.globalConnNetId).flatMap(
93951
+ (trace) => trace.tracePath.slice(1).flatMap((end, pointIndex) => {
93952
+ const start = trace.tracePath[pointIndex];
93953
+ return nearlyEqual(start.x, label.anchorPoint.x) && nearlyEqual(end.x, label.anchorPoint.x) ? [
93954
+ {
93955
+ minY: Math.min(start.y, end.y),
93956
+ maxY: Math.max(start.y, end.y)
93957
+ }
93958
+ ] : [];
93959
+ })
93960
+ ).sort((a2, b2) => b2.maxY - a2.maxY);
93961
+ let lowestY = label.anchorPoint.y;
93962
+ for (const segment2 of columnSegments) {
93963
+ if (segment2.maxY + RAIL_ALIGNMENT_EPSILON >= lowestY && segment2.minY < lowestY) {
93964
+ lowestY = segment2.minY;
93965
+ }
93966
+ }
93967
+ if (nearlyEqual(lowestY, label.anchorPoint.y)) continue;
93968
+ const anchorPoint = { x: label.anchorPoint.x, y: lowestY };
93969
+ const center = getCenterFromAnchor(
93970
+ anchorPoint,
93971
+ label.orientation,
93972
+ label.width,
93973
+ label.height
93974
+ );
93975
+ const bounds = getRectBounds(center, label.width, label.height);
93976
+ if (obstacles.some((obstacle) => rectsOverlap2(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
93977
+ (other, otherIndex) => otherIndex !== index2 && rectsOverlap2(
93978
+ bounds,
93979
+ getRectBounds(other.center, other.width, other.height)
93980
+ )
93981
+ ))
93982
+ continue;
93983
+ output[index2] = { ...label, anchorPoint, center };
93984
+ }
93985
+ return output;
93986
+ };
93727
93987
  var getAlongBounds = (orientation2, minAlong, maxAlong) => orientation2 === "vertical" ? { minX: 0, maxX: 0, minY: minAlong, maxY: maxAlong } : { minX: minAlong, maxX: maxAlong, minY: 0, maxY: 0 };
93728
93988
  var hasPositiveAlongOverlap = (orientation2, first, second) => {
93729
93989
  const overlap = boundsIntersection(first, second);
@@ -93768,37 +94028,6 @@ var getRailAlignmentFallbackCoordinates = ({
93768
94028
  }
93769
94029
  return getDistinctCoordinates(coordinates);
93770
94030
  };
93771
- var EPS8 = 1e-6;
93772
- var isTraceLine = (trace) => getUniquePinCount(trace.pinIds) >= 2;
93773
- var rectsOverlap = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS8 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS8;
93774
- var getTraceCorners = (path) => {
93775
- const corners = [];
93776
- for (let i2 = 1; i2 < path.length - 1; i2++) {
93777
- const previousPoint = path[i2 - 1];
93778
- const cornerPoint = path[i2];
93779
- const nextPoint = path[i2 + 1];
93780
- if (isTraceCorner(previousPoint, cornerPoint, nextPoint)) {
93781
- corners.push(cornerPoint);
93782
- }
93783
- }
93784
- return corners;
93785
- };
93786
- var tracePathContainsPoint = (path, point6) => {
93787
- for (let i2 = 0; i2 < path.length - 1; i2++) {
93788
- if (isPointOnSegment(point6, path[i2], path[i2 + 1])) return true;
93789
- }
93790
- return false;
93791
- };
93792
- var getDistance2 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
93793
- var getUniquePinCount = (pinIds) => new Set(pinIds).size;
93794
- var isTraceCorner = (a2, b2, c2) => getSegmentOrientation(a2, b2) !== getSegmentOrientation(b2, c2);
93795
- var isPointOnSegment = (point6, start, end) => {
93796
- if (getSegmentOrientation(start, end) === "horizontal") {
93797
- return Math.abs(point6.y - start.y) <= EPS8 && point6.x >= Math.min(start.x, end.x) - EPS8 && point6.x <= Math.max(start.x, end.x) + EPS8;
93798
- }
93799
- return Math.abs(point6.x - start.x) <= EPS8 && point6.y >= Math.min(start.y, end.y) - EPS8 && point6.y <= Math.max(start.y, end.y) + EPS8;
93800
- };
93801
- var getSegmentOrientation = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS8 ? "horizontal" : "vertical";
93802
94031
  var hasLabelOnAdjacentInteriorLeg = (segment2, trace, anchorPoint) => {
93803
94032
  const pathsFromRailEnds = [
93804
94033
  trace.tracePath.slice(0, segment2.segmentIndex + 1).reverse(),
@@ -93937,15 +94166,15 @@ var preservesLabelAnchors = (labels, before, after) => labels.every((label) => {
93937
94166
  const anchoredAfter = getAnchoredTraceIds(label, after);
93938
94167
  return [...anchoredBefore].every((traceId) => anchoredAfter.has(traceId));
93939
94168
  });
93940
- var EPS9 = 1e-9;
94169
+ var EPS10 = 1e-9;
93941
94170
  var segmentRunsAlongRectBoundary = (start, end, rect) => {
93942
- const isVertical6 = Math.abs(start.x - end.x) < EPS9;
93943
- const isHorizontal5 = Math.abs(start.y - end.y) < EPS9;
94171
+ const isVertical6 = Math.abs(start.x - end.x) < EPS10;
94172
+ const isHorizontal5 = Math.abs(start.y - end.y) < EPS10;
93944
94173
  if (isVertical6) {
93945
- return Math.abs(start.x - rect.minX) < EPS9 || Math.abs(start.x - rect.maxX) < EPS9;
94174
+ return Math.abs(start.x - rect.minX) < EPS10 || Math.abs(start.x - rect.maxX) < EPS10;
93946
94175
  }
93947
94176
  if (isHorizontal5) {
93948
- return Math.abs(start.y - rect.minY) < EPS9 || Math.abs(start.y - rect.maxY) < EPS9;
94177
+ return Math.abs(start.y - rect.minY) < EPS10 || Math.abs(start.y - rect.maxY) < EPS10;
93949
94178
  }
93950
94179
  return false;
93951
94180
  };
@@ -93958,10 +94187,10 @@ var getPathLength4 = (path) => {
93958
94187
  return length8;
93959
94188
  };
93960
94189
  var getDistance22 = (a2, b2) => Math.abs(a2.x - b2.x) + Math.abs(a2.y - b2.y);
93961
- var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS9 || Math.abs(start.y - end.y) < EPS9;
93962
- var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS9 ? "horizontal" : "vertical";
94190
+ var isAxisAlignedSegment = (start, end) => Math.abs(start.x - end.x) < EPS10 || Math.abs(start.y - end.y) < EPS10;
94191
+ var getSegmentOrientation2 = (start, end) => Math.abs(start.y - end.y) < EPS10 ? "horizontal" : "vertical";
93963
94192
  var projectPointToSegment = (point6, start, end) => {
93964
- if (Math.abs(start.x - end.x) < EPS9) {
94193
+ if (Math.abs(start.x - end.x) < EPS10) {
93965
94194
  return {
93966
94195
  x: start.x,
93967
94196
  y: Math.min(
@@ -93970,7 +94199,7 @@ var projectPointToSegment = (point6, start, end) => {
93970
94199
  )
93971
94200
  };
93972
94201
  }
93973
- if (Math.abs(start.y - end.y) < EPS9) {
94202
+ if (Math.abs(start.y - end.y) < EPS10) {
93974
94203
  return {
93975
94204
  x: Math.min(
93976
94205
  Math.max(point6.x, Math.min(start.x, end.x)),
@@ -94013,9 +94242,9 @@ var findSegmentContainingPoint = (path, point6) => {
94013
94242
  };
94014
94243
  var isPointWithinSegmentPrimaryRange = (point6, segment2) => {
94015
94244
  if (segment2.orientation === "horizontal") {
94016
- return point6.x >= Math.min(segment2.start.x, segment2.end.x) - EPS9 && point6.x <= Math.max(segment2.start.x, segment2.end.x) + EPS9;
94245
+ return point6.x >= Math.min(segment2.start.x, segment2.end.x) - EPS10 && point6.x <= Math.max(segment2.start.x, segment2.end.x) + EPS10;
94017
94246
  }
94018
- return point6.y >= Math.min(segment2.start.y, segment2.end.y) - EPS9 && point6.y <= Math.max(segment2.start.y, segment2.end.y) + EPS9;
94247
+ return point6.y >= Math.min(segment2.start.y, segment2.end.y) - EPS10 && point6.y <= Math.max(segment2.start.y, segment2.end.y) + EPS10;
94019
94248
  };
94020
94249
  var findPreferredReroutedSegment = (path, originalSegmentIndex, originalSegmentCount, orientation2, anchorPoint) => {
94021
94250
  const matchingSegments = getSegments3(path).filter(
@@ -94043,18 +94272,18 @@ var projectPointToPath = (point6, path) => {
94043
94272
  return bestPoint;
94044
94273
  };
94045
94274
  var segmentsIntersect2 = (a1, a2, b1, b2) => {
94046
- const aVertical = Math.abs(a1.x - a2.x) < EPS9;
94047
- const bVertical = Math.abs(b1.x - b2.x) < EPS9;
94048
- const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS9 && value <= Math.max(p1, p2) + EPS9;
94275
+ const aVertical = Math.abs(a1.x - a2.x) < EPS10;
94276
+ const bVertical = Math.abs(b1.x - b2.x) < EPS10;
94277
+ const between2 = (value, p1, p2) => value >= Math.min(p1, p2) - EPS10 && value <= Math.max(p1, p2) + EPS10;
94049
94278
  if (aVertical && bVertical) {
94050
- if (Math.abs(a1.x - b1.x) > EPS9) return false;
94279
+ if (Math.abs(a1.x - b1.x) > EPS10) return false;
94051
94280
  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));
94052
- return overlap > EPS9;
94281
+ return overlap > EPS10;
94053
94282
  }
94054
94283
  if (!aVertical && !bVertical) {
94055
- if (Math.abs(a1.y - b1.y) > EPS9) return false;
94284
+ if (Math.abs(a1.y - b1.y) > EPS10) return false;
94056
94285
  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));
94057
- return overlap > EPS9;
94286
+ return overlap > EPS10;
94058
94287
  }
94059
94288
  const verticalA = aVertical ? a1 : b1;
94060
94289
  const verticalB = aVertical ? a2 : b2;
@@ -94125,6 +94354,7 @@ var tracePathChanged = (original, candidate) => original.tracePath.length !== ca
94125
94354
  (point6, index2) => !pointsEqual22(point6, original.tracePath[index2])
94126
94355
  );
94127
94356
  var evaluateRailGroup = ({
94357
+ inputProblem,
94128
94358
  group,
94129
94359
  traces,
94130
94360
  netLabelPlacements,
@@ -94147,6 +94377,11 @@ var evaluateRailGroup = ({
94147
94377
  const otherNetTraces = traces.filter(
94148
94378
  (trace) => trace.globalConnNetId !== group[0].globalConnNetId
94149
94379
  );
94380
+ const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
94381
+ const groundNetIds = getGroundNetIds(inputProblem, netConnMap);
94382
+ const groundLabelIndices = netLabelPlacements.flatMap(
94383
+ (label, index2) => label.globalConnNetId === group[0].globalConnNetId && groundNetIds.has(label.globalConnNetId) ? [index2] : []
94384
+ );
94150
94385
  const immutableSameNetTraces = traces.filter(
94151
94386
  (trace) => trace.globalConnNetId === group[0].globalConnNetId && !eligibleTraceIds.has(trace.mspPairId)
94152
94387
  );
@@ -94166,11 +94401,24 @@ var evaluateRailGroup = ({
94166
94401
  const allCandidateTraces = traces.map(
94167
94402
  (trace) => candidateMap.get(trace.mspPairId) ?? trace
94168
94403
  );
94404
+ const placedGroundLabels = groundLabelIndices.length ? placeGroundRailLabelsAtOuterEnd({
94405
+ inputProblem,
94406
+ traces: allCandidateTraces,
94407
+ netLabelPlacements
94408
+ }) : netLabelPlacements;
94409
+ const groundLabelBounds = groundLabelIndices.map((index2) => {
94410
+ const label = placedGroundLabels[index2];
94411
+ return getRectBounds(label.center, label.width, label.height);
94412
+ });
94169
94413
  const candidatesAreClear = candidateTraces.every(
94170
94414
  (candidate2) => !isPathCollidingWithObstacles(candidate2.tracePath, obstacles) && detectTraceLabelOverlap({
94171
94415
  traces: [candidate2],
94172
94416
  netLabels: netLabelPlacements
94173
- }).length === 0 && !doesPathOverlapTraceStrokes(candidate2.tracePath, otherNetTraces) && !doesPathCoincideWithTraces(
94417
+ }).length === 0 && // Ground labels may move to the new rail end later in the pipeline.
94418
+ // Reject alignment if even that placement leaves a symbol crossed.
94419
+ !groundLabelBounds.some(
94420
+ (bounds) => tracePathCrossesAnyBounds(candidate2.tracePath, bounds)
94421
+ ) && !doesPathOverlapTraceStrokes(candidate2.tracePath, otherNetTraces) && !doesPathCoincideWithTraces(
94174
94422
  candidate2.tracePath,
94175
94423
  immutableSameNetTraces.filter(
94176
94424
  (trace) => trace.mspPairId !== candidate2.mspPairId
@@ -94439,6 +94687,7 @@ var alignSameNetRails = ({
94439
94687
  let applied = null;
94440
94688
  for (const group of groups) {
94441
94689
  applied = evaluateRailGroup({
94690
+ inputProblem,
94442
94691
  group,
94443
94692
  traces: outputTraces,
94444
94693
  netLabelPlacements,
@@ -94493,7 +94742,7 @@ var getTraceObstacles = (allTraces, excludeTraceId) => {
94493
94742
  }
94494
94743
  return obstacles;
94495
94744
  };
94496
- var EPS10 = 1e-6;
94745
+ var EPS11 = 1e-6;
94497
94746
  var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
94498
94747
  const intersections2 = [];
94499
94748
  for (const obstacle of obstacles) {
@@ -94512,7 +94761,7 @@ var findIntersectionsWithObstacles = (p1, p2, obstacles) => {
94512
94761
  }
94513
94762
  return intersections2;
94514
94763
  };
94515
- var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS10 && Math.abs(first.y - second.y) < EPS10;
94764
+ var isSamePoint = (first, second) => Math.abs(first.x - second.x) < EPS11 && Math.abs(first.y - second.y) < EPS11;
94516
94765
  var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
94517
94766
  const crossings = [];
94518
94767
  const firstPathSegmentIndex = options.includeTerminalSegments ? 0 : 1;
@@ -94522,11 +94771,11 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
94522
94771
  for (let pathSegmentIndex = firstPathSegmentIndex; pathSegmentIndex < lastPathSegmentIndex; pathSegmentIndex++) {
94523
94772
  const start = path[pathSegmentIndex];
94524
94773
  const end = path[pathSegmentIndex + 1];
94525
- const isVertical6 = Math.abs(start.x - end.x) < EPS10;
94774
+ const isVertical6 = Math.abs(start.x - end.x) < EPS11;
94526
94775
  for (let otherPathSegmentIndex = firstOtherPathSegmentIndex; otherPathSegmentIndex < lastOtherPathSegmentIndex; otherPathSegmentIndex++) {
94527
94776
  const otherStart = otherPath[otherPathSegmentIndex];
94528
94777
  const otherEnd = otherPath[otherPathSegmentIndex + 1];
94529
- const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS10;
94778
+ const otherIsVertical = Math.abs(otherStart.x - otherEnd.x) < EPS11;
94530
94779
  if (isVertical6 === otherIsVertical) continue;
94531
94780
  const intersection2 = getSegmentIntersection(
94532
94781
  start,
@@ -94544,8 +94793,8 @@ var findPerpendicularPathCrossings = (path, otherPath, options = {}) => {
94544
94793
  }
94545
94794
  return crossings;
94546
94795
  };
94547
- var EPS11 = 1e-6;
94548
- var isVertical3 = (a2, b2, eps = EPS11) => Math.abs(a2.x - b2.x) < eps;
94796
+ var EPS12 = 1e-6;
94797
+ var isVertical3 = (a2, b2, eps = EPS12) => Math.abs(a2.x - b2.x) < eps;
94549
94798
  var generateLShapeRerouteCandidates = ({
94550
94799
  lShape,
94551
94800
  rectangle,
@@ -94558,7 +94807,7 @@ var generateLShapeRerouteCandidates = ({
94558
94807
  let c2;
94559
94808
  let i1_padded = interactionPoint1;
94560
94809
  let i2_padded = interactionPoint2;
94561
- if (Math.abs(p2.x - x2) < EPS11 && Math.abs(p2.y - (y2 + height)) < EPS11) {
94810
+ if (Math.abs(p2.x - x2) < EPS12 && Math.abs(p2.y - (y2 + height)) < EPS12) {
94562
94811
  c2 = { x: x2 + width + padding, y: y2 - padding };
94563
94812
  if (isVertical3(p1, p2)) {
94564
94813
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -94570,7 +94819,7 @@ var generateLShapeRerouteCandidates = ({
94570
94819
  } else {
94571
94820
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
94572
94821
  }
94573
- } else if (Math.abs(p2.x - (x2 + width)) < EPS11 && Math.abs(p2.y - (y2 + height)) < EPS11) {
94822
+ } else if (Math.abs(p2.x - (x2 + width)) < EPS12 && Math.abs(p2.y - (y2 + height)) < EPS12) {
94574
94823
  c2 = { x: x2 - padding, y: y2 - padding };
94575
94824
  if (isVertical3(p1, p2)) {
94576
94825
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y - padding };
@@ -94582,7 +94831,7 @@ var generateLShapeRerouteCandidates = ({
94582
94831
  } else {
94583
94832
  i2_padded = { x: interactionPoint2.x - padding, y: interactionPoint2.y };
94584
94833
  }
94585
- } else if (Math.abs(p2.x - x2) < EPS11 && Math.abs(p2.y - y2) < EPS11) {
94834
+ } else if (Math.abs(p2.x - x2) < EPS12 && Math.abs(p2.y - y2) < EPS12) {
94586
94835
  c2 = { x: x2 + width + padding, y: y2 + height + padding };
94587
94836
  if (isVertical3(p1, p2)) {
94588
94837
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -94594,7 +94843,7 @@ var generateLShapeRerouteCandidates = ({
94594
94843
  } else {
94595
94844
  i2_padded = { x: interactionPoint2.x + padding, y: interactionPoint2.y };
94596
94845
  }
94597
- } else if (Math.abs(p2.x - (x2 + width)) < EPS11 && Math.abs(p2.y - y2) < EPS11) {
94846
+ } else if (Math.abs(p2.x - (x2 + width)) < EPS12 && Math.abs(p2.y - y2) < EPS12) {
94598
94847
  c2 = { x: x2 - padding, y: y2 + height + padding };
94599
94848
  if (isVertical3(p1, p2)) {
94600
94849
  i1_padded = { x: interactionPoint1.x, y: interactionPoint1.y + padding };
@@ -94668,7 +94917,7 @@ var generatePerpendicularTraceDetours = ({
94668
94917
  const buildDetours = (path, index2) => {
94669
94918
  const start = path[index2];
94670
94919
  const end = path[index2 + 1];
94671
- const movingAxis = Math.abs(start.x - end.x) < EPS11 ? "y" : "x";
94920
+ const movingAxis = Math.abs(start.x - end.x) < EPS12 ? "y" : "x";
94672
94921
  const detourAxis = movingAxis === "x" ? "y" : "x";
94673
94922
  const bounds = obstacleBounds ?? {
94674
94923
  minX: Math.min(obstacleStart.x, obstacleEnd.x),
@@ -95274,14 +95523,14 @@ var UntangleTraceSubsolver = class extends BaseSolver10 {
95274
95523
  }
95275
95524
  }
95276
95525
  };
95277
- var EPS12 = 1e-6;
95278
- var sameX = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS12;
95279
- var sameY = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS12;
95526
+ var EPS13 = 1e-6;
95527
+ var sameX2 = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS13;
95528
+ var sameY2 = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS13;
95280
95529
  var is4PointRectangle = (path) => {
95281
95530
  if (path.length !== 4) return false;
95282
95531
  const [p0, p1, p2, p3] = path;
95283
- const isHVHC = sameY(p0, p1) && sameX(p1, p2) && sameY(p2, p3) && sameX(p0, p3);
95284
- const isVHVC = sameX(p0, p1) && sameY(p1, p2) && sameX(p2, p3) && sameY(p0, p3);
95532
+ const isHVHC = sameY2(p0, p1) && sameX2(p1, p2) && sameY2(p2, p3) && sameX2(p0, p3);
95533
+ const isVHVC = sameX2(p0, p1) && sameY2(p1, p2) && sameX2(p2, p3) && sameY2(p0, p3);
95285
95534
  return isHVHC || isVHVC;
95286
95535
  };
95287
95536
  var getInteriorShortcutPaths = (path) => {
@@ -95312,7 +95561,7 @@ var getInteriorShortcutPaths = (path) => {
95312
95561
  }
95313
95562
  return candidates;
95314
95563
  };
95315
- var EPS13 = 1e-6;
95564
+ var EPS14 = 1e-6;
95316
95565
  var getConnectorObstacleBounds = (connector, segmentIndex, labels) => {
95317
95566
  const start = connector.tracePath[segmentIndex];
95318
95567
  const end = connector.tracePath[segmentIndex + 1];
@@ -95409,7 +95658,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
95409
95658
  path
95410
95659
  }))
95411
95660
  ).filter(
95412
- (candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) + EPS13 && countTurns(candidate.path) <= countTurns(trace.tracePath) + 2 && !isPathCollidingWithObstacles(
95661
+ (candidate) => getPathLength4(candidate.path) <= getPathLength4(trace.tracePath) + EPS14 && countTurns(candidate.path) <= countTurns(trace.tracePath) + 2 && !isPathCollidingWithObstacles(
95413
95662
  candidate.path,
95414
95663
  componentAndTextObstacles
95415
95664
  ) && !hasCollisionsWithLabels(candidate.path, foreignLabelBounds) && !isPathColliding(candidate.path, foreignTraces, trace.mspPairId).isColliding && !doesPathCoincideWithTraces(candidate.path, foreignTraces)
@@ -95420,7 +95669,7 @@ var rerouteGeneratedNetLabelConnectorCrossings = ({
95420
95669
  });
95421
95670
  candidates.sort((first, second) => {
95422
95671
  const lengthDifference = getPathLength4(first.path) - getPathLength4(second.path);
95423
- return Math.abs(lengthDifference) > EPS13 ? lengthDifference : countTurns(first.path) - countTurns(second.path);
95672
+ return Math.abs(lengthDifference) > EPS14 ? lengthDifference : countTurns(first.path) - countTurns(second.path);
95424
95673
  });
95425
95674
  const bestCandidate = candidates[0];
95426
95675
  if (!bestCandidate) break;
@@ -95788,7 +96037,7 @@ var doesPathRunAlongChipBoundary = (path, chipObstacles) => {
95788
96037
  const end = path[i2 + 1];
95789
96038
  for (const obstacle of chipObstacles) {
95790
96039
  if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
95791
- if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS9) {
96040
+ if (getSegmentOverlapWithRectSpan(start, end, obstacle) > EPS10) {
95792
96041
  return true;
95793
96042
  }
95794
96043
  }
@@ -95803,13 +96052,13 @@ var getChipBoundaryOverlap = (path, chipObstacles) => {
95803
96052
  for (const obstacle of chipObstacles) {
95804
96053
  if (!segmentRunsAlongRectBoundary(start, end, obstacle)) continue;
95805
96054
  const overlap = getSegmentOverlapWithRectSpan(start, end, obstacle);
95806
- if (overlap > EPS9) total += overlap;
96055
+ if (overlap > EPS10) total += overlap;
95807
96056
  }
95808
96057
  }
95809
96058
  return total;
95810
96059
  };
95811
96060
  var getSegmentOverlapWithRectSpan = (start, end, rect) => {
95812
- const isVertical6 = Math.abs(start.x - end.x) < EPS9;
96061
+ const isVertical6 = Math.abs(start.x - end.x) < EPS10;
95813
96062
  if (isVertical6) {
95814
96063
  return Math.min(Math.max(start.y, end.y), rect.maxY) - Math.max(Math.min(start.y, end.y), rect.minY);
95815
96064
  }
@@ -96255,8 +96504,8 @@ var scoreSolutionTracePath = (params) => {
96255
96504
  }
96256
96505
  return { chipEdgeRuns, traceCrossings };
96257
96506
  };
96258
- var CANDIDATE_SELECTED_COLOR = "blue";
96259
- var CANDIDATE_REJECTED_COLOR = "red";
96507
+ var CANDIDATE_SELECTED_COLOR2 = "blue";
96508
+ var CANDIDATE_REJECTED_COLOR2 = "red";
96260
96509
  var visualizeExample28Solver = (state) => {
96261
96510
  const graphics = visualizeInputProblem(state.inputProblem);
96262
96511
  drawTraces(graphics, state);
@@ -96302,7 +96551,7 @@ label intersections: ${candidate.score.labelIntersections}
96302
96551
  trace intersections: ${candidate.score.traceIntersections}` : "";
96303
96552
  graphics.lines.push({
96304
96553
  points: candidate.path,
96305
- strokeColor: candidate.selected ? CANDIDATE_SELECTED_COLOR : CANDIDATE_REJECTED_COLOR,
96554
+ strokeColor: candidate.selected ? CANDIDATE_SELECTED_COLOR2 : CANDIDATE_REJECTED_COLOR2,
96306
96555
  strokeDash: candidate.selected ? void 0 : "4 2",
96307
96556
  label: `${candidate.selected ? "selected" : candidate.status} reroute${scoreLabel}`
96308
96557
  });
@@ -96316,7 +96565,7 @@ var drawCurrentOverlap = (graphics, state) => {
96316
96565
  width: label.width,
96317
96566
  height: label.height,
96318
96567
  fill: "rgba(255, 0, 0, 0.2)",
96319
- strokeColor: CANDIDATE_REJECTED_COLOR,
96568
+ strokeColor: CANDIDATE_REJECTED_COLOR2,
96320
96569
  label: `overlap target
96321
96570
  ${label.netId ?? label.globalConnNetId}`
96322
96571
  });
@@ -96559,107 +96808,6 @@ var createPortOnlyLabelConnectorTrace = ({
96559
96808
  pinIds: label.pinIds
96560
96809
  };
96561
96810
  };
96562
- var LABEL_SEARCH_STEP = 0.05;
96563
- var MAX_RECORDED_CANDIDATES = 2e3;
96564
- var WICK_CLEARANCE = 1e-3;
96565
- var EPS14 = 1e-9;
96566
- var TRACE_BOUNDARY_TOLERANCE = WICK_CLEARANCE + EPS14;
96567
- var CANDIDATE_SELECTED_COLOR2 = "blue";
96568
- var CANDIDATE_REJECTED_COLOR2 = "red";
96569
- var isYOrientation = (orientation2) => orientation2 === "y+" || orientation2 === "y-";
96570
- var isXOrientation = (orientation2) => orientation2 === "x+" || orientation2 === "x-";
96571
- var rectsOverlap2 = (a2, b2) => Math.min(a2.maxX, b2.maxX) - Math.max(a2.minX, b2.minX) > EPS14 && Math.min(a2.maxY, b2.maxY) - Math.max(a2.minY, b2.minY) > EPS14;
96572
- var rangesOverlap = (minA, maxA, minB, maxB) => Math.min(maxA, maxB) - Math.max(minA, minB) > EPS14;
96573
- var traceCrossesBoundsInterior = (bounds, traceMap) => {
96574
- for (const trace of Object.values(traceMap)) {
96575
- const points = trace.tracePath;
96576
- for (let i2 = 0; i2 < points.length - 1; i2++) {
96577
- if (segmentCrossesBoundsInterior(points[i2], points[i2 + 1], bounds)) {
96578
- return true;
96579
- }
96580
- }
96581
- }
96582
- return false;
96583
- };
96584
- var segmentCrossesBoundsInterior = (p1, p2, bounds) => {
96585
- const interiorBounds = {
96586
- minX: bounds.minX + TRACE_BOUNDARY_TOLERANCE,
96587
- minY: bounds.minY + TRACE_BOUNDARY_TOLERANCE,
96588
- maxX: bounds.maxX - TRACE_BOUNDARY_TOLERANCE,
96589
- maxY: bounds.maxY - TRACE_BOUNDARY_TOLERANCE
96590
- };
96591
- if (interiorBounds.minX >= interiorBounds.maxX || interiorBounds.minY >= interiorBounds.maxY) {
96592
- return false;
96593
- }
96594
- if (sameX2(p1, p2)) {
96595
- if (p1.x <= interiorBounds.minX + EPS14 || p1.x >= interiorBounds.maxX - EPS14) {
96596
- return false;
96597
- }
96598
- return rangesOverlap(
96599
- Math.min(p1.y, p2.y),
96600
- Math.max(p1.y, p2.y),
96601
- interiorBounds.minY,
96602
- interiorBounds.maxY
96603
- );
96604
- }
96605
- if (sameY2(p1, p2)) {
96606
- if (p1.y <= interiorBounds.minY + EPS14 || p1.y >= interiorBounds.maxY - EPS14) {
96607
- return false;
96608
- }
96609
- return rangesOverlap(
96610
- Math.min(p1.x, p2.x),
96611
- Math.max(p1.x, p2.x),
96612
- interiorBounds.minX,
96613
- interiorBounds.maxX
96614
- );
96615
- }
96616
- return false;
96617
- };
96618
- var tracePathIntersectsBounds = (tracePath, bounds) => {
96619
- for (let i2 = 0; i2 < tracePath.length - 1; i2++) {
96620
- if (segmentIntersectsRect2(tracePath[i2], tracePath[i2 + 1], bounds)) {
96621
- return true;
96622
- }
96623
- }
96624
- return false;
96625
- };
96626
- var getSideDistances = (point6, bounds) => [
96627
- ["left", Math.abs(point6.x - bounds.minX)],
96628
- ["right", Math.abs(point6.x - bounds.maxX)],
96629
- ["bottom", Math.abs(point6.y - bounds.minY)],
96630
- ["top", Math.abs(point6.y - bounds.maxY)]
96631
- ];
96632
- var getConnectorTracePath = (source, target, orientation2) => simplifyOrthogonalPath(
96633
- isYOrientation(orientation2) ? [source, { x: target.x, y: source.y }, target] : [source, { x: source.x, y: target.y }, target]
96634
- );
96635
- var simplifyOrthogonalPath = (path) => {
96636
- const deduped = path.filter(
96637
- (point6, index2) => index2 === 0 || !pointsEqual3(point6, path[index2 - 1])
96638
- );
96639
- if (deduped.length < 3) return deduped;
96640
- const simplified = [deduped[0]];
96641
- for (let i2 = 1; i2 < deduped.length - 1; i2++) {
96642
- const prev = simplified[simplified.length - 1];
96643
- const point6 = deduped[i2];
96644
- const next = deduped[i2 + 1];
96645
- if (sameX2(prev, point6) && sameX2(point6, next) || sameY2(prev, point6) && sameY2(point6, next)) {
96646
- continue;
96647
- }
96648
- simplified.push(point6);
96649
- }
96650
- simplified.push(deduped[deduped.length - 1]);
96651
- return simplified;
96652
- };
96653
- var pointsEqual3 = (a2, b2) => sameX2(a2, b2) && sameY2(a2, b2);
96654
- var sameX2 = (a2, b2) => Math.abs(a2.x - b2.x) <= EPS14;
96655
- var sameY2 = (a2, b2) => Math.abs(a2.y - b2.y) <= EPS14;
96656
- var getMaxSearchDistance = (inputProblem) => {
96657
- const maxChipWidth = Math.max(
96658
- ...inputProblem.chips.map((chip) => chip.width),
96659
- 1
96660
- );
96661
- return maxChipWidth * 3;
96662
- };
96663
96811
  var isPortOnlyLabel = (label) => label.mspConnectionPairIds.length === 0;
96664
96812
  var orderRoutedLabelsBeforeOverlappingPortLabels = ({
96665
96813
  labelIndices,
@@ -96685,7 +96833,7 @@ var orderRoutedLabelsBeforeOverlappingPortLabels = ({
96685
96833
  portOnlyLabel.width,
96686
96834
  portOnlyLabel.height
96687
96835
  );
96688
- return rectsOverlap2(routedBounds, portOnlyBounds);
96836
+ return rectsOverlap(routedBounds, portOnlyBounds);
96689
96837
  });
96690
96838
  const routedPosition = orderedLabelIndices.indexOf(routedLabelIndex);
96691
96839
  if (blockingPosition === -1 || blockingPosition > routedPosition) continue;
@@ -96738,7 +96886,7 @@ var drawCurrentLabel = (graphics, currentLabel, solved) => {
96738
96886
  width: currentLabel.width,
96739
96887
  height: currentLabel.height,
96740
96888
  fill: "rgba(255, 0, 0, 0.2)",
96741
- strokeColor: CANDIDATE_REJECTED_COLOR2,
96889
+ strokeColor: CANDIDATE_REJECTED_COLOR,
96742
96890
  label: `available orientation target
96743
96891
  ${currentLabel.netId ?? currentLabel.globalConnNetId}`
96744
96892
  });
@@ -96746,7 +96894,7 @@ ${currentLabel.netId ?? currentLabel.globalConnNetId}`
96746
96894
  var drawCurrentCandidates2 = (graphics, candidates, solved) => {
96747
96895
  if (solved) return;
96748
96896
  for (const candidate of candidates) {
96749
- const color3 = candidate.selected ? CANDIDATE_SELECTED_COLOR2 : CANDIDATE_REJECTED_COLOR2;
96897
+ const color3 = candidate.selected ? CANDIDATE_SELECTED_COLOR : CANDIDATE_REJECTED_COLOR;
96750
96898
  const distanceLabel = candidate.distance === void 0 ? "" : `
96751
96899
  distance: ${candidate.distance.toFixed(3)}`;
96752
96900
  const outwardDistanceLabel = candidate.outwardDistance === void 0 || candidate.outwardDistance === 0 ? "" : `
@@ -96804,7 +96952,7 @@ var AvailableNetOrientationObstacleIndex = class {
96804
96952
  }
96805
96953
  getTraceSegmentsInBounds(bounds) {
96806
96954
  if (!this.traceSegmentIndex) return [];
96807
- const searchBounds = getPaddedBounds(bounds, EPS14);
96955
+ const searchBounds = getPaddedBounds(bounds, EPS8);
96808
96956
  return this.traceSegmentIndex.search(
96809
96957
  searchBounds.minX,
96810
96958
  searchBounds.minY,
@@ -96817,7 +96965,7 @@ var AvailableNetOrientationObstacleIndex = class {
96817
96965
  for (let pointIndex = 0; pointIndex < tracePath.length - 1; pointIndex++) {
96818
96966
  const segmentBounds = getPaddedBounds(
96819
96967
  getSegmentBounds(tracePath[pointIndex], tracePath[pointIndex + 1]),
96820
- EPS14
96968
+ EPS8
96821
96969
  );
96822
96970
  for (const labelIndex of this.getLabelIndicesInBounds(segmentBounds)) {
96823
96971
  labelIndices.add(labelIndex);
@@ -96830,7 +96978,7 @@ var AvailableNetOrientationObstacleIndex = class {
96830
96978
  const start = tracePath[pointIndex];
96831
96979
  const end = tracePath[pointIndex + 1];
96832
96980
  const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(
96833
- getPaddedBounds(getSegmentBounds(start, end), EPS14)
96981
+ getPaddedBounds(getSegmentBounds(start, end), EPS8)
96834
96982
  );
96835
96983
  for (const chip of nearbyChips) {
96836
96984
  if (segmentCrossesBoundsInterior(start, end, chip.bounds)) return true;
@@ -97088,7 +97236,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97088
97236
  if (otherIndex === labelIndex) return false;
97089
97237
  if (otherLabel.globalConnNetId === label.globalConnNetId) return false;
97090
97238
  const otherBounds = this.getHorizontalConstraintMismatchBounds(otherLabel);
97091
- return otherBounds ? rectsOverlap2(bounds2, otherBounds) : false;
97239
+ return otherBounds ? rectsOverlap(bounds2, otherBounds) : false;
97092
97240
  });
97093
97241
  if (overlapsHorizontalConstraintMismatch) return true;
97094
97242
  }
@@ -97097,7 +97245,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97097
97245
  return this.outputNetLabelPlacements.some((otherLabel, otherIndex) => {
97098
97246
  if (otherIndex === labelIndex) return false;
97099
97247
  if (otherLabel.globalConnNetId === label.globalConnNetId) return false;
97100
- return rectsOverlap2(
97248
+ return rectsOverlap(
97101
97249
  bounds,
97102
97250
  getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height)
97103
97251
  );
@@ -97134,7 +97282,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97134
97282
  const bounds = getRectBounds(label.center, label.width, label.height);
97135
97283
  return labelIndices.slice(position + 1).some((otherIndex) => {
97136
97284
  const other = this.outputNetLabelPlacements[otherIndex];
97137
- return rectsOverlap2(
97285
+ return rectsOverlap(
97138
97286
  bounds,
97139
97287
  getRectBounds(other.center, other.width, other.height)
97140
97288
  );
@@ -97285,7 +97433,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97285
97433
  labelIndex,
97286
97434
  orientations
97287
97435
  );
97288
- const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) > EPS14;
97436
+ const rotatedCandidateNeedsLateralBranch = rotatedCandidate !== null && Math.abs(rotatedCandidate.anchorPoint.x - label.anchorPoint.x) > EPS8;
97289
97437
  if (isDownwardGroundRail && rotatedCandidateNeedsLateralBranch) {
97290
97438
  const downwardRailCandidate = this.findValidCandidateInShiftColumn({
97291
97439
  label,
@@ -97344,7 +97492,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97344
97492
  index: index2,
97345
97493
  pin: this.pinMap[otherLabel.pinIds[0]]
97346
97494
  })).filter(
97347
- ({ index: index2, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index2) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS14
97495
+ ({ index: index2, pin: otherPin }) => this.crowdedPortOnlyLabelIndices.has(index2) && otherPin?.chipId === pin.chipId && otherPin.x > pin.x + EPS8
97348
97496
  ).sort((a2, b2) => a2.pin.x - b2.pin.x)[0]?.pin;
97349
97497
  if (orientation2 === "y-" && nextPinToRight) return null;
97350
97498
  const anchorX = orientation2 === "y-" ? Math.max(
@@ -97377,7 +97525,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97377
97525
  const centeredAnchorY = hasUpFacingStack ? (lowestUpFacingLabelY + highestUpFacingLabelY) / 2 : stackedAnchorY;
97378
97526
  const anchorYs = orientation2 === "y-" ? [centeredAnchorY, stackedAnchorY] : [stackedAnchorY];
97379
97527
  for (const anchorY of anchorYs) {
97380
- if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS14) {
97528
+ if (anchorY - label.anchorPoint.y > this.maxSearchDistance + EPS8) {
97381
97529
  continue;
97382
97530
  }
97383
97531
  const candidate = this.createCandidate(
@@ -97406,11 +97554,11 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97406
97554
  if (trace.globalConnNetId !== label.globalConnNetId) return false;
97407
97555
  const path = trace.tracePath;
97408
97556
  return path.some((point6, pointIndex) => {
97409
- if (Math.abs(point6.x - label.anchorPoint.x) > EPS14 || Math.abs(point6.y - label.anchorPoint.y) > EPS14) {
97557
+ if (Math.abs(point6.x - label.anchorPoint.x) > EPS8 || Math.abs(point6.y - label.anchorPoint.y) > EPS8) {
97410
97558
  return false;
97411
97559
  }
97412
97560
  return [path[pointIndex - 1], path[pointIndex + 1]].some(
97413
- (neighbor) => neighbor && Math.abs(neighbor.x - point6.x) <= EPS14 && (neighbor.y - point6.y) * direction.y > EPS14
97561
+ (neighbor) => neighbor && Math.abs(neighbor.x - point6.x) <= EPS8 && (neighbor.y - point6.y) * direction.y > EPS8
97414
97562
  );
97415
97563
  });
97416
97564
  });
@@ -97500,7 +97648,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97500
97648
  orientation2
97501
97649
  );
97502
97650
  if (outwardDirection2.x === 0 && outwardDirection2.y === 0) continue;
97503
- for (let distance33 = LABEL_SEARCH_STEP; distance33 <= this.maxSearchDistance + EPS14; distance33 += LABEL_SEARCH_STEP) {
97651
+ for (let distance33 = LABEL_SEARCH_STEP; distance33 <= this.maxSearchDistance + EPS8; distance33 += LABEL_SEARCH_STEP) {
97504
97652
  const anchorPoint = {
97505
97653
  x: connectorSource.x + outwardDirection2.x * distance33,
97506
97654
  y: connectorSource.y + outwardDirection2.y * distance33
@@ -97578,7 +97726,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97578
97726
  const furthestRowPoints = points.filter(
97579
97727
  (point6) => Math.abs(
97580
97728
  point6.x * direction.x + point6.y * direction.y - furthestAlong
97581
- ) <= EPS14
97729
+ ) <= EPS8
97582
97730
  );
97583
97731
  const directHostPinIds = new Set(
97584
97732
  [...directHostTraceIds].flatMap(
@@ -97599,7 +97747,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97599
97747
  preferNearestBendOnOutwardRow: adjacentTraces.some(
97600
97748
  (trace) => furthestRowPoints.some(
97601
97749
  (point6) => trace.tracePath.some(
97602
- (tracePoint) => Math.abs(tracePoint.x - point6.x) <= EPS14 && Math.abs(tracePoint.y - point6.y) <= EPS14
97750
+ (tracePoint) => Math.abs(tracePoint.x - point6.x) <= EPS8 && Math.abs(tracePoint.y - point6.y) <= EPS8
97603
97751
  )
97604
97752
  )
97605
97753
  )
@@ -97611,7 +97759,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97611
97759
  for (let i2 = 0; i2 < otherTrace.tracePath.length - 1; i2++) {
97612
97760
  const start = otherTrace.tracePath[i2];
97613
97761
  const end = otherTrace.tracePath[i2 + 1];
97614
- if (Math.abs(start.x - end.x) <= EPS14 && Math.abs(start.y - end.y) > EPS14) {
97762
+ if (Math.abs(start.x - end.x) <= EPS8 && Math.abs(start.y - end.y) > EPS8) {
97615
97763
  verticalRailXs.add(start.x);
97616
97764
  }
97617
97765
  }
@@ -97619,7 +97767,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97619
97767
  for (let i2 = 0; i2 < trace.tracePath.length - 1; i2++) {
97620
97768
  const start = trace.tracePath[i2];
97621
97769
  const end = trace.tracePath[i2 + 1];
97622
- if (Math.abs(start.x - end.x) <= EPS14 && Math.abs(start.y - end.y) > EPS14 && [...verticalRailXs].some((x2) => Math.abs(x2 - start.x) <= EPS14)) {
97770
+ if (Math.abs(start.x - end.x) <= EPS8 && Math.abs(start.y - end.y) > EPS8 && [...verticalRailXs].some((x2) => Math.abs(x2 - start.x) <= EPS8)) {
97623
97771
  return true;
97624
97772
  }
97625
97773
  }
@@ -97638,7 +97786,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97638
97786
  );
97639
97787
  const maxSearchDistance = this.getSearchDistanceLimit(label, orientation2);
97640
97788
  const maxOutwardDistance = outwardDirection2.x === 0 && outwardDirection2.y === 0 ? 0 : this.maxSearchDistance;
97641
- for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS14; outwardDistance += LABEL_SEARCH_STEP) {
97789
+ for (let outwardDistance = 0; outwardDistance <= maxOutwardDistance + EPS8; outwardDistance += LABEL_SEARCH_STEP) {
97642
97790
  const baseAnchor = {
97643
97791
  x: initialBaseAnchor.x + outwardDirection2.x * outwardDistance,
97644
97792
  y: initialBaseAnchor.y + outwardDirection2.y * outwardDistance
@@ -97714,7 +97862,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97714
97862
  connectorSource,
97715
97863
  startDistance = LABEL_SEARCH_STEP
97716
97864
  } = params;
97717
- for (let distance33 = startDistance; distance33 <= maxSearchDistance + EPS14; distance33 += LABEL_SEARCH_STEP) {
97865
+ for (let distance33 = startDistance; distance33 <= maxSearchDistance + EPS8; distance33 += LABEL_SEARCH_STEP) {
97718
97866
  const anchorPoint = {
97719
97867
  x: baseAnchor.x + direction.x * distance33,
97720
97868
  y: baseAnchor.y + direction.y * distance33
@@ -97828,14 +97976,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
97828
97976
  for (let pointIndex = 0; pointIndex < hostTrace.tracePath.length - 1; pointIndex++) {
97829
97977
  const start = hostTrace.tracePath[pointIndex];
97830
97978
  const end = hostTrace.tracePath[pointIndex + 1];
97831
- const segmentIsPerpendicularToLabel = isYOrientation(orientation2) ? Math.abs(start.y - end.y) <= EPS14 : Math.abs(start.x - end.x) <= EPS14;
97979
+ const segmentIsPerpendicularToLabel = isYOrientation(orientation2) ? Math.abs(start.y - end.y) <= EPS8 : Math.abs(start.x - end.x) <= EPS8;
97832
97980
  if (!segmentIsPerpendicularToLabel) continue;
97833
97981
  const source = isYOrientation(orientation2) ? { x: targetAnchor.x, y: start.y } : { x: start.x, y: targetAnchor.y };
97834
97982
  if (!tracePathContainsPoint([start, end], label.anchorPoint) || !tracePathContainsPoint([start, end], source)) {
97835
97983
  continue;
97836
97984
  }
97837
97985
  const targetDistanceAlongOrientation = (targetAnchor.x - source.x) * orientationDirection.x + (targetAnchor.y - source.y) * orientationDirection.y;
97838
- if (targetDistanceAlongOrientation >= -EPS14) {
97986
+ if (targetDistanceAlongOrientation >= -EPS8) {
97839
97987
  projectedSources.push(source);
97840
97988
  }
97841
97989
  }
@@ -98094,9 +98242,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98094
98242
  const { anchorPoint, orientation: orientation2 } = candidate;
98095
98243
  const chipBounds = chip.bounds;
98096
98244
  if (isYOrientation(orientation2)) {
98097
- return anchorPoint.x < chipBounds.minX - EPS14 || anchorPoint.x > chipBounds.maxX + EPS14;
98245
+ return anchorPoint.x < chipBounds.minX - EPS8 || anchorPoint.x > chipBounds.maxX + EPS8;
98098
98246
  }
98099
- return anchorPoint.y < chipBounds.minY - EPS14 || anchorPoint.y > chipBounds.maxY + EPS14;
98247
+ return anchorPoint.y < chipBounds.minY - EPS8 || anchorPoint.y > chipBounds.maxY + EPS8;
98100
98248
  });
98101
98249
  }
98102
98250
  staysOutsideConnectedPinRow(params) {
@@ -98104,9 +98252,9 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98104
98252
  const pin = this.pinMap[label.pinIds[0]];
98105
98253
  if (!pin || !isYOrientation(candidate.orientation)) return false;
98106
98254
  if (candidate.anchorPoint.x < pin.x) {
98107
- return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE + EPS14;
98255
+ return bounds.maxX <= pin.x + CONNECTED_PIN_ROW_OVERLAP_TOLERANCE + EPS8;
98108
98256
  }
98109
- return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE - EPS14;
98257
+ return bounds.minX >= pin.x - CONNECTED_PIN_ROW_OVERLAP_TOLERANCE - EPS8;
98110
98258
  }
98111
98259
  getBoundsStatus(candidateBoundsCheck) {
98112
98260
  const { bounds, labelIndex, label, ignoreChipCollisions } = candidateBoundsCheck;
@@ -98187,14 +98335,14 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98187
98335
  candidate.width,
98188
98336
  candidate.height
98189
98337
  );
98190
- if (labelBounds.minY < chip.bounds.minY - EPS14 || labelBounds.maxY > chip.bounds.maxY + EPS14) {
98338
+ if (labelBounds.minY < chip.bounds.minY - EPS8 || labelBounds.maxY > chip.bounds.maxY + EPS8) {
98191
98339
  return false;
98192
98340
  }
98193
- if (candidate.anchorPoint.x >= chip.bounds.minX - EPS14 && candidate.anchorPoint.x <= chip.bounds.maxX + EPS14) {
98341
+ if (candidate.anchorPoint.x >= chip.bounds.minX - EPS8 && candidate.anchorPoint.x <= chip.bounds.maxX + EPS8) {
98194
98342
  return false;
98195
98343
  }
98196
98344
  return chip.pins.every(
98197
- (pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY + EPS14 || pin.y >= labelBounds.maxY - EPS14
98345
+ (pin) => label.pinIds.includes(pin.pinId) || pin.y <= labelBounds.minY + EPS8 || pin.y >= labelBounds.maxY - EPS8
98198
98346
  );
98199
98347
  }
98200
98348
  getTextBlockedMultiPinRailTraces(label, orientation2) {
@@ -98221,20 +98369,20 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98221
98369
  const pins = [...connectedPinIds].map((pinId) => this.pinMap[pinId]);
98222
98370
  const direction = dir(orientation2);
98223
98371
  const pinX = pins[0].x;
98224
- if (pins.some((pin) => Math.abs(pin.x - pinX) > EPS14)) return null;
98225
- const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <= EPS14);
98372
+ if (pins.some((pin) => Math.abs(pin.x - pinX) > EPS8)) return null;
98373
+ const sidePins = this.inputProblem.chips.find((chip) => chip.chipId === componentId).pins.filter((pin) => Math.abs(pin.x - pinX) <= EPS8);
98226
98374
  const minY = Math.min(...pins.map((pin) => pin.y));
98227
98375
  const maxY = Math.max(...pins.map((pin) => pin.y));
98228
98376
  if (sidePins.some(
98229
- (pin) => pin.y >= minY - EPS14 && pin.y <= maxY + EPS14 && !connectedPinIds.has(pin.pinId)
98230
- ) || orientation2 === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) + EPS14 || orientation2 === "y+" && maxY < Math.max(...sidePins.map((pin) => pin.y)) - EPS14) {
98377
+ (pin) => pin.y >= minY - EPS8 && pin.y <= maxY + EPS8 && !connectedPinIds.has(pin.pinId)
98378
+ ) || orientation2 === "y-" && minY > Math.min(...sidePins.map((pin) => pin.y)) + EPS8 || orientation2 === "y+" && maxY < Math.max(...sidePins.map((pin) => pin.y)) - EPS8) {
98231
98379
  return null;
98232
98380
  }
98233
98381
  const outerPinPosition = Math.max(
98234
98382
  ...pins.map((pin) => pin.x * direction.x + pin.y * direction.y)
98235
98383
  );
98236
98384
  const blockedByText = (this.inputProblem.textBoxes ?? []).some(
98237
- (textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition + EPS14
98385
+ (textBox) => textBox.chipId === componentId && textBox.center.x * direction.x + textBox.center.y * direction.y > outerPinPosition + EPS8
98238
98386
  );
98239
98387
  return blockedByText ? [...connectedTraces] : null;
98240
98388
  }
@@ -98250,7 +98398,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98250
98398
  ...new Set(
98251
98399
  localTraces.flatMap((trace) => trace.tracePath.map((point6) => point6.x))
98252
98400
  )
98253
- ].filter((x2) => Math.abs(x2 - pinX) > EPS14).sort((a2, b2) => Math.abs(a2 - pinX) - Math.abs(b2 - pinX));
98401
+ ].filter((x2) => Math.abs(x2 - pinX) > EPS8).sort((a2, b2) => Math.abs(a2 - pinX) - Math.abs(b2 - pinX));
98254
98402
  for (const x2 of railXs) {
98255
98403
  const connectorSource = { x: x2, y: connectorY };
98256
98404
  if (!Object.values(this.traceMap).some(
@@ -98313,8 +98461,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98313
98461
  if (!chip) return null;
98314
98462
  const sides = new Set(
98315
98463
  pins.map((pin) => {
98316
- if (Math.abs(pin.x - chip.bounds.minX) <= EPS14) return "left";
98317
- if (Math.abs(pin.x - chip.bounds.maxX) <= EPS14) return "right";
98464
+ if (Math.abs(pin.x - chip.bounds.minX) <= EPS8) return "left";
98465
+ if (Math.abs(pin.x - chip.bounds.maxX) <= EPS8) return "right";
98318
98466
  return null;
98319
98467
  })
98320
98468
  );
@@ -98351,7 +98499,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98351
98499
  return null;
98352
98500
  }
98353
98501
  const renderedWidth = this.getNetConnectionForLabel(label)?.netLabelHeight;
98354
- if (renderedWidth === void 0 || renderedWidth <= label.width + label.height + EPS14) {
98502
+ if (renderedWidth === void 0 || renderedWidth <= label.width + label.height + EPS8) {
98355
98503
  return null;
98356
98504
  }
98357
98505
  const placementBaseCenter = getCenterFromAnchor(
@@ -98420,22 +98568,22 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98420
98568
  otherBounds.minX -= LABEL_SEARCH_STEP;
98421
98569
  otherBounds.maxX += LABEL_SEARCH_STEP;
98422
98570
  }
98423
- if (rectsOverlap2(bounds, otherBounds)) return true;
98571
+ if (rectsOverlap(bounds, otherBounds)) return true;
98424
98572
  }
98425
98573
  return false;
98426
98574
  }
98427
98575
  sharesChipBoundary(bounds) {
98428
98576
  const boundarySearchBounds = {
98429
- minX: bounds.minX - WICK_CLEARANCE - EPS14,
98430
- minY: bounds.minY - WICK_CLEARANCE - EPS14,
98431
- maxX: bounds.maxX + WICK_CLEARANCE + EPS14,
98432
- maxY: bounds.maxY + WICK_CLEARANCE + EPS14
98577
+ minX: bounds.minX - WICK_CLEARANCE - EPS8,
98578
+ minY: bounds.minY - WICK_CLEARANCE - EPS8,
98579
+ maxX: bounds.maxX + WICK_CLEARANCE + EPS8,
98580
+ maxY: bounds.maxY + WICK_CLEARANCE + EPS8
98433
98581
  };
98434
98582
  const nearbyChips = this.chipObstacleSpatialIndex.getChipsInBounds(boundarySearchBounds);
98435
98583
  for (const chip of nearbyChips) {
98436
98584
  const chipBounds = chip.bounds;
98437
- const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS14 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS14;
98438
- const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS14 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS14;
98585
+ const adjacentToVerticalSide = Math.abs(bounds.minX - chipBounds.maxX) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxX - chipBounds.minX) <= WICK_CLEARANCE + EPS8;
98586
+ const adjacentToHorizontalSide = Math.abs(bounds.minY - chipBounds.maxY) <= WICK_CLEARANCE + EPS8 || Math.abs(bounds.maxY - chipBounds.minY) <= WICK_CLEARANCE + EPS8;
98439
98587
  if (adjacentToVerticalSide && rangesOverlap(
98440
98588
  bounds.minY,
98441
98589
  bounds.maxY,
@@ -98497,7 +98645,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98497
98645
  let nearestDistance = Number.POSITIVE_INFINITY;
98498
98646
  for (const chip of this.chipObstacleSpatialIndex.chips) {
98499
98647
  const bounds = chip.bounds;
98500
- if (point6.x < bounds.minX - EPS14 || point6.x > bounds.maxX + EPS14 || point6.y < bounds.minY - EPS14 || point6.y > bounds.maxY + EPS14) {
98648
+ if (point6.x < bounds.minX - EPS8 || point6.x > bounds.maxX + EPS8 || point6.y < bounds.minY - EPS8 || point6.y > bounds.maxY + EPS8) {
98501
98649
  continue;
98502
98650
  }
98503
98651
  for (const [side, distance33] of getSideDistances(point6, bounds)) {
@@ -98514,8 +98662,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver10 {
98514
98662
  let nearestDistanceSq = Number.POSITIVE_INFINITY;
98515
98663
  for (const chip of this.chipObstacleSpatialIndex.chips) {
98516
98664
  const bounds = chip.bounds;
98517
- const dx2 = point6.x < bounds.minX - EPS14 ? bounds.minX - point6.x : point6.x > bounds.maxX + EPS14 ? point6.x - bounds.maxX : 0;
98518
- const dy2 = point6.y < bounds.minY - EPS14 ? bounds.minY - point6.y : point6.y > bounds.maxY + EPS14 ? point6.y - bounds.maxY : 0;
98665
+ const dx2 = point6.x < bounds.minX - EPS8 ? bounds.minX - point6.x : point6.x > bounds.maxX + EPS8 ? point6.x - bounds.maxX : 0;
98666
+ const dy2 = point6.y < bounds.minY - EPS8 ? bounds.minY - point6.y : point6.y > bounds.maxY + EPS8 ? point6.y - bounds.maxY : 0;
98519
98667
  if (dx2 === 0 && dy2 === 0) continue;
98520
98668
  const distanceSq = dx2 ** 2 + dy2 ** 2;
98521
98669
  if (distanceSq >= nearestDistanceSq) continue;
@@ -98667,7 +98815,7 @@ var getRemovableRailLabelConnectors = ({
98667
98815
  const endpoints = [connector.tracePath[0], connector.tracePath.at(-1)];
98668
98816
  if (!endpoints[0] || !endpoints[1]) continue;
98669
98817
  const labelEnd = endpoints.findIndex(
98670
- (point6) => getDistance2(point6, label.anchorPoint) <= EPS8
98818
+ (point6) => getDistance2(point6, label.anchorPoint) <= EPS9
98671
98819
  );
98672
98820
  if (labelEnd === -1) continue;
98673
98821
  const source = endpoints[1 - labelEnd];
@@ -98714,11 +98862,11 @@ var getStraightPortConnectorCandidate = ({
98714
98862
  continue;
98715
98863
  const path = simplifyPath(connector.tracePath);
98716
98864
  if (path.length < 4) continue;
98717
- if (getDistance2(path.at(-1), pin) <= EPS8) path.reverse();
98718
- if (getDistance2(path[0], pin) > EPS8 || getDistance2(path.at(-1), label.anchorPoint) > EPS8 || Math.abs(path[1].y - pin.y) > EPS8)
98865
+ if (getDistance2(path.at(-1), pin) <= EPS9) path.reverse();
98866
+ if (getDistance2(path[0], pin) > EPS9 || getDistance2(path.at(-1), label.anchorPoint) > EPS9 || Math.abs(path[1].y - pin.y) > EPS9)
98719
98867
  continue;
98720
98868
  const anchorPoint = { x: label.anchorPoint.x, y: pin.y };
98721
- if ((anchorPoint.x - pin.x) * (path[1].x - pin.x) <= EPS8) continue;
98869
+ if ((anchorPoint.x - pin.x) * (path[1].x - pin.x) <= EPS9) continue;
98722
98870
  const reroutedTracePath = [path[0], anchorPoint];
98723
98871
  const protectedPoints = [
98724
98872
  ...getSameNetJunctions(connector, traces),
@@ -98756,13 +98904,13 @@ var getSimplifiedRailConnectorCandidates = (params) => {
98756
98904
  if (countTurns(path) < 2) continue;
98757
98905
  for (const source of getTraceCorners(simplifyPath(rail.tracePath))) {
98758
98906
  const anchor = label.anchorPoint;
98759
- if ((anchor.y - source.y) * direction < -EPS8) continue;
98907
+ if ((anchor.y - source.y) * direction < -EPS9) continue;
98760
98908
  const reroutedTracePath = simplifyPath([
98761
98909
  source,
98762
98910
  { x: anchor.x, y: source.y },
98763
98911
  anchor
98764
98912
  ]);
98765
- if (countTurns(reroutedTracePath) >= countTurns(path) || getPathLength4(reroutedTracePath) > getPathLength4(path) + EPS8)
98913
+ if (countTurns(reroutedTracePath) >= countTurns(path) || getPathLength4(reroutedTracePath) > getPathLength4(path) + EPS9)
98766
98914
  continue;
98767
98915
  if (traces.some(
98768
98916
  (other) => other.globalConnNetId !== connector.globalConnNetId && countPathIntersections(reroutedTracePath, other.tracePath) > countPathIntersections(path, other.tracePath)
@@ -98996,13 +99144,13 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
98996
99144
  }
98997
99145
  intersectsAnyChip(bounds) {
98998
99146
  return this.inputProblem.chips.some(
98999
- (chip) => rectsOverlap(bounds, getRectBounds(chip.center, chip.width, chip.height))
99147
+ (chip) => rectsOverlap2(bounds, getRectBounds(chip.center, chip.width, chip.height))
99000
99148
  );
99001
99149
  }
99002
99150
  intersectsAnyOtherNetLabel(bounds, labelIndex) {
99003
99151
  return this.outputNetLabelPlacements.some((label, index2) => {
99004
99152
  if (index2 === labelIndex) return false;
99005
- return rectsOverlap(
99153
+ return rectsOverlap2(
99006
99154
  bounds,
99007
99155
  getRectBounds(label.center, label.width, label.height)
99008
99156
  );
@@ -99023,7 +99171,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99023
99171
  for (const anchorPoint of getTraceCorners(path)) {
99024
99172
  const cornerIndex = path.indexOf(anchorPoint);
99025
99173
  const anchorAlignedToPin = pins.some(
99026
- (pin) => Math.abs(pin.x - anchorPoint.x) <= EPS8
99174
+ (pin) => Math.abs(pin.x - anchorPoint.x) <= EPS9
99027
99175
  );
99028
99176
  const pinAligned = anchorAlignedToPin || allowRailAlignedFallback && this.isPinAlignedCorner(path, cornerIndex);
99029
99177
  if (!pinAligned) continue;
@@ -99116,7 +99264,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99116
99264
  return [];
99117
99265
  }
99118
99266
  const pins = this.inputProblem.chips.flatMap((chip) => chip.pins).filter((pin) => label.pinIds.includes(pin.pinId));
99119
- if (pins.length !== 2 || pins[0]._facingDirection !== pins[1]._facingDirection || pins[0]._facingDirection !== "x+" && pins[0]._facingDirection !== "x-" || Math.abs(pins[0].y - pins[1].y) > EPS8) {
99267
+ if (pins.length !== 2 || pins[0]._facingDirection !== pins[1]._facingDirection || pins[0]._facingDirection !== "x+" && pins[0]._facingDirection !== "x-" || Math.abs(pins[0].y - pins[1].y) > EPS9) {
99120
99268
  return [];
99121
99269
  }
99122
99270
  const configuredOrientations = this.inputProblem.availableNetLabelOrientations[label.netId];
@@ -99141,7 +99289,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99141
99289
  getMaxSearchDistance(this.inputProblem),
99142
99290
  label.height * 2
99143
99291
  );
99144
- for (let distance33 = WICK_CLEARANCE + LABEL_SEARCH_STEP; distance33 <= maxSearchDistance + EPS8; distance33 += LABEL_SEARCH_STEP) {
99292
+ for (let distance33 = WICK_CLEARANCE + LABEL_SEARCH_STEP; distance33 <= maxSearchDistance + EPS9; distance33 += LABEL_SEARCH_STEP) {
99145
99293
  const anchorPoint = {
99146
99294
  x: sourcePoint.x,
99147
99295
  y: sourcePoint.y + direction * distance33
@@ -99193,12 +99341,12 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99193
99341
  return traceCrossesBoundsInterior(bounds, this.traceMap);
99194
99342
  }
99195
99343
  pointsEqual(a2, b2) {
99196
- return Math.abs(a2.x - b2.x) <= EPS8 && Math.abs(a2.y - b2.y) <= EPS8;
99344
+ return Math.abs(a2.x - b2.x) <= EPS9 && Math.abs(a2.y - b2.y) <= EPS9;
99197
99345
  }
99198
99346
  getVerticalSegmentPointIndices(path, cornerIndex) {
99199
99347
  const corner = path[cornerIndex];
99200
- const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS8;
99201
- const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS8;
99348
+ const previousIsVertical = Math.abs(path[cornerIndex - 1].x - corner.x) <= EPS9;
99349
+ const nextIsVertical = Math.abs(path[cornerIndex + 1].x - corner.x) <= EPS9;
99202
99350
  if (previousIsVertical === nextIsVertical) return null;
99203
99351
  const indices = previousIsVertical ? [cornerIndex - 1, cornerIndex] : [cornerIndex, cornerIndex + 1];
99204
99352
  return indices;
@@ -99235,7 +99383,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99235
99383
  label.height
99236
99384
  );
99237
99385
  const labelBounds = getRectBounds(center, label.width, label.height);
99238
- const collidingChipBounds = this.inputProblem.chips.map((chip) => getRectBounds(chip.center, chip.width, chip.height)).filter((chipBounds) => rectsOverlap(labelBounds, chipBounds));
99386
+ const collidingChipBounds = this.inputProblem.chips.map((chip) => getRectBounds(chip.center, chip.width, chip.height)).filter((chipBounds) => rectsOverlap2(labelBounds, chipBounds));
99239
99387
  const shiftedCoordinates = /* @__PURE__ */ new Set();
99240
99388
  for (const chipBounds of collidingChipBounds) {
99241
99389
  shiftedCoordinates.add(chipBounds.minX - label.width / 2);
@@ -99248,7 +99396,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99248
99396
  const end = otherTrace.tracePath[i2 + 1];
99249
99397
  if (!segmentCrossesBoundsInterior(start, end, labelBounds)) continue;
99250
99398
  const halfLabelWidth = label.width / 2;
99251
- if (Math.abs(start.x - end.x) <= EPS8) {
99399
+ if (Math.abs(start.x - end.x) <= EPS9) {
99252
99400
  shiftedCoordinates.add(
99253
99401
  start.x - halfLabelWidth - LABEL_TRACE_CLEARANCE3
99254
99402
  );
@@ -99266,7 +99414,7 @@ var RailNetLabelCornerPlacementSolver = class extends BaseSolver10 {
99266
99414
  }
99267
99415
  }
99268
99416
  return [...shiftedCoordinates].flatMap((x2) => {
99269
- if (Math.abs(x2 - corner.x) <= EPS8) return [];
99417
+ if (Math.abs(x2 - corner.x) <= EPS9) return [];
99270
99418
  const reroutedTracePath = simplifyPath(
99271
99419
  path.map(
99272
99420
  (point6, pointIndex) => verticalPointIndices.includes(pointIndex) ? { ...point6, x: x2 } : point6
@@ -102705,7 +102853,7 @@ var candidateIsClear = ({
102705
102853
  }
102706
102854
  }
102707
102855
  for (const obstacle of obstacles) {
102708
- if (rectsOverlap(candidateBounds, obstacle) && !rectsOverlap(originalBounds, obstacle)) {
102856
+ if (rectsOverlap2(candidateBounds, obstacle) && !rectsOverlap2(originalBounds, obstacle)) {
102709
102857
  return false;
102710
102858
  }
102711
102859
  }
@@ -102723,7 +102871,7 @@ var candidateIsClear = ({
102723
102871
  candidateOther.width,
102724
102872
  candidateOther.height
102725
102873
  );
102726
- if (rectsOverlap(candidateBounds, candidateOtherBounds) && !rectsOverlap(originalBounds, originalOtherBounds)) {
102874
+ if (rectsOverlap2(candidateBounds, candidateOtherBounds) && !rectsOverlap2(originalBounds, originalOtherBounds)) {
102727
102875
  return false;
102728
102876
  }
102729
102877
  }
@@ -103036,100 +103184,6 @@ var alignSameNetJunctions = ({
103036
103184
  collapsedCycleCount: cycleCollapse.collapsedCycleCount
103037
103185
  };
103038
103186
  };
103039
- var placeGroundRailLabelsAtOuterEnd = ({
103040
- inputProblem,
103041
- traces,
103042
- netLabelPlacements
103043
- }) => {
103044
- const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
103045
- const groundNetId = netConnMap.getNetConnectedToId("GND");
103046
- if (!groundNetId) return netLabelPlacements;
103047
- const chipMap = new Map(inputProblem.chips.map((chip) => [chip.chipId, chip]));
103048
- const traceMap = Object.fromEntries(
103049
- traces.map((trace) => [trace.mspPairId, trace])
103050
- );
103051
- const obstacles = getObstacleRects(inputProblem);
103052
- const output = [...netLabelPlacements];
103053
- for (const rail of traces) {
103054
- if (rail.globalConnNetId !== groundNetId) continue;
103055
- const [a2, b2] = rail.pins;
103056
- if (a2.chipId === b2.chipId || !nearlyEqual(a2.y, b2.y) || ![a2, b2].every(
103057
- (pin) => pin._facingDirection === "y-" && chipMap.get(pin.chipId)?.pins.length === 2
103058
- ))
103059
- continue;
103060
- const path = simplifyPath(rail.tracePath);
103061
- if (path.length !== 4 || !isVertical2(path[0], path[1]) || !isHorizontal22(path[1], path[2]) || !isVertical2(path[2], path[3]) || path[1].y >= a2.y)
103062
- continue;
103063
- for (const feed of traces) {
103064
- if (feed.globalConnNetId !== groundNetId) continue;
103065
- const shared = feed.pins.find((pin) => rail.pinIds.includes(pin.pinId));
103066
- const icPin = feed.pins.find(
103067
- (pin) => !rail.pinIds.includes(pin.pinId) && (chipMap.get(pin.chipId)?.pins.length ?? 0) > 2
103068
- );
103069
- if (!shared || !icPin || !nearlyEqual(icPin.y, path[1].y)) continue;
103070
- const outer = shared.pinId === a2.pinId ? b2 : a2;
103071
- if (Math.abs(outer.x - icPin.x) <= Math.abs(shared.x - icPin.x)) continue;
103072
- const anchorPoint = { x: outer.x, y: path[1].y };
103073
- if (!tracePathContainsPoint(rail.tracePath, anchorPoint)) continue;
103074
- for (let index2 = 0; index2 < output.length; index2++) {
103075
- const label = output[index2];
103076
- if (label.globalConnNetId !== groundNetId || label.orientation !== "y-" || !label.mspConnectionPairIds.some(
103077
- (id) => id === feed.mspPairId || id === rail.mspPairId
103078
- ) || !tracePathContainsPoint(feed.tracePath, label.anchorPoint) && !tracePathContainsPoint(rail.tracePath, label.anchorPoint))
103079
- continue;
103080
- const center = getCenterFromAnchor(
103081
- anchorPoint,
103082
- label.orientation,
103083
- label.width,
103084
- label.height
103085
- );
103086
- const bounds = getRectBounds(center, label.width, label.height);
103087
- if (obstacles.some((obstacle) => rectsOverlap(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
103088
- (other, otherIndex) => otherIndex !== index2 && rectsOverlap(
103089
- bounds,
103090
- getRectBounds(other.center, other.width, other.height)
103091
- )
103092
- ))
103093
- continue;
103094
- output[index2] = {
103095
- ...label,
103096
- anchorPoint,
103097
- center,
103098
- mspConnectionPairIds: [rail.mspPairId],
103099
- pinIds: [...rail.pinIds]
103100
- };
103101
- }
103102
- }
103103
- }
103104
- for (let index2 = 0; index2 < output.length; index2++) {
103105
- const label = output[index2];
103106
- if (label.orientation !== "y-") continue;
103107
- const connection = inputProblem.netConnections.find(
103108
- (candidate) => candidate.isGround && candidate.netId === label.netId && candidate.pinIds.length > 2
103109
- );
103110
- if (!connection) continue;
103111
- const anchorPoint = traces.filter((trace) => trace.globalConnNetId === label.globalConnNetId).flatMap((trace) => trace.tracePath).filter(
103112
- (point6) => nearlyEqual(point6.x, label.anchorPoint.x) && point6.y < label.anchorPoint.y
103113
- ).sort((a2, b2) => a2.y - b2.y)[0];
103114
- if (!anchorPoint) continue;
103115
- const center = getCenterFromAnchor(
103116
- anchorPoint,
103117
- label.orientation,
103118
- label.width,
103119
- label.height
103120
- );
103121
- const bounds = getRectBounds(center, label.width, label.height);
103122
- if (obstacles.some((obstacle) => rectsOverlap(bounds, obstacle)) || traceCrossesBoundsInterior(bounds, traceMap) || output.some(
103123
- (other, otherIndex) => otherIndex !== index2 && rectsOverlap(
103124
- bounds,
103125
- getRectBounds(other.center, other.width, other.height)
103126
- )
103127
- ))
103128
- continue;
103129
- output[index2] = { ...label, anchorPoint, center };
103130
- }
103131
- return output;
103132
- };
103133
103187
  var MAX_LOCAL_RAIL_SHIFT = 0.5;
103134
103188
  var MIN_ESCAPE_LENGTH = 1;
103135
103189
  var shortenSameSideRailToLabelAnchor = ({
@@ -118287,7 +118341,7 @@ function Group_getRoutingPhasePlans(group) {
118287
118341
  var package_default = {
118288
118342
  name: "@tscircuit/core",
118289
118343
  type: "module",
118290
- version: "0.0.2117",
118344
+ version: "0.0.2119",
118291
118345
  types: "dist/index.d.ts",
118292
118346
  main: "dist/index.js",
118293
118347
  module: "dist/index.js",
@@ -118346,9 +118400,9 @@ var package_default = {
118346
118400
  "@tscircuit/miniflex": "^0.0.4",
118347
118401
  "@tscircuit/modelprinter": "^0.0.18",
118348
118402
  "@tscircuit/ngspice-spice-engine": "^0.0.20",
118349
- "@tscircuit/props": "^0.0.697",
118403
+ "@tscircuit/props": "^0.0.698",
118350
118404
  "@tscircuit/schematic-match-adapt": "^0.0.18",
118351
- "@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.229.tgz",
118405
+ "@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.230.tgz",
118352
118406
  "@tscircuit/solver-utils": "^0.0.16",
118353
118407
  "@tscircuit/soup-util": "^0.0.41",
118354
118408
  "@tscircuit/via-stitch-solver": "github:tscircuit/via-stitch-solver#64f2ac7781b795bdc0d74ba411988e60767fa653",
@@ -118430,7 +118484,7 @@ var package_default = {
118430
118484
  },
118431
118485
  overrides: {
118432
118486
  "@tscircuit/circuit-json-util": "^0.0.119",
118433
- "@tscircuit/props": "^0.0.697",
118487
+ "@tscircuit/props": "^0.0.698",
118434
118488
  "circuit-json": "^0.0.525",
118435
118489
  "@tscircuit/cableprinter": "^0.0.6"
118436
118490
  }
@@ -133037,6 +133091,49 @@ var AnalogSweepParameter = class extends PrimitiveComponent2 {
133037
133091
  }
133038
133092
  };
133039
133093
 
133094
+ // lib/components/primitive-components/PcbReturnCurrentSimulation.ts
133095
+ import { pcbReturnCurrentSimulationProps } from "@tscircuit/props";
133096
+ var PcbReturnCurrentSimulation = class extends PrimitiveComponent2 {
133097
+ simulation_experiment_id = null;
133098
+ get config() {
133099
+ return {
133100
+ componentName: "PcbReturnCurrentSimulation",
133101
+ zodProps: pcbReturnCurrentSimulationProps
133102
+ };
133103
+ }
133104
+ doInitialSimulationRender() {
133105
+ if (this.root?.pcbDisabled) return;
133106
+ if (this.parent?.componentName === "PcbReturnCurrentSimulation") {
133107
+ this.renderError(
133108
+ "A PCB return-current simulation cannot contain another simulation."
133109
+ );
133110
+ }
133111
+ if (this.children.some(
133112
+ (child) => child.componentName !== "PcbReturnCurrentExcitation"
133113
+ )) {
133114
+ this.renderError(
133115
+ "A PCB return-current simulation can contain only return-current excitations."
133116
+ );
133117
+ }
133118
+ const experiment = this.root.db.simulation_experiment.insert({
133119
+ name: this._parsedProps.name ?? "PCB return current",
133120
+ experiment_type: "pcb_return_current"
133121
+ });
133122
+ this.simulation_experiment_id = experiment.simulation_experiment_id;
133123
+ }
133124
+ updateSimulationRender() {
133125
+ if (!this.simulation_experiment_id) return;
133126
+ this.root.db.simulation_experiment.update(this.simulation_experiment_id, {
133127
+ name: this._parsedProps.name ?? "PCB return current"
133128
+ });
133129
+ }
133130
+ removeSimulationRender() {
133131
+ if (!this.simulation_experiment_id) return;
133132
+ this.root.db.simulation_experiment.delete(this.simulation_experiment_id);
133133
+ this.simulation_experiment_id = null;
133134
+ }
133135
+ };
133136
+
133040
133137
  // lib/components/primitive-components/VoltageProbe.ts
133041
133138
  import { voltageProbeProps } from "@tscircuit/props";
133042
133139
 
@@ -134491,6 +134588,13 @@ var enclosure = {
134491
134588
  }
134492
134589
  };
134493
134590
 
134591
+ // lib/namespaced-elements/simulation.ts
134592
+ var simulation = {
134593
+ pcbreturncurrentsimulation: createNamespacedElement(
134594
+ "pcbreturncurrentsimulation"
134595
+ )
134596
+ };
134597
+
134494
134598
  // lib/RootCircuit.ts
134495
134599
  var RootCircuit = class extends IsolatedCircuit {
134496
134600
  isRootCircuit = true;
@@ -134808,6 +134912,7 @@ export {
134808
134912
  PcbNotePath,
134809
134913
  PcbNoteRect,
134810
134914
  PcbNoteText,
134915
+ PcbReturnCurrentSimulation,
134811
134916
  PcbSoldermaskOpening,
134812
134917
  PcbStiffener,
134813
134918
  PcbTrace,
@@ -134879,6 +134984,7 @@ export {
134879
134984
  renderPhaseIndexMap,
134880
134985
  resolveStaticFileImport,
134881
134986
  sel,
134987
+ simulation,
134882
134988
  unrouteCircuitJson,
134883
134989
  useCapacitor,
134884
134990
  useChip,