@crazyhappyone/auto-graph 0.2.9 → 0.2.11

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.cjs CHANGED
@@ -5384,7 +5384,7 @@ function segmentCrossesAnyObstacle(a, b, obstacles) {
5384
5384
  }
5385
5385
 
5386
5386
  // src/routing/routes.ts
5387
- function checkBacktracking(points, source, target, diagnostics) {
5387
+ function checkBacktracking(points, source, target, diagnostics, maxRatio) {
5388
5388
  if (points.length < 2) return;
5389
5389
  const direct = Math.hypot(target.x - source.x, target.y - source.y);
5390
5390
  if (direct <= 0) return;
@@ -5394,7 +5394,7 @@ function checkBacktracking(points, source, target, diagnostics) {
5394
5394
  const b = points[i + 1];
5395
5395
  routeLen += Math.hypot(b.x - a.x, b.y - a.y);
5396
5396
  }
5397
- const threshold = 10;
5397
+ const threshold = maxRatio ?? 20;
5398
5398
  if (routeLen > direct * threshold) {
5399
5399
  diagnostics.push({
5400
5400
  severity: "warning",
@@ -5412,8 +5412,20 @@ function routeEdge(input) {
5412
5412
  const diagnostics = [];
5413
5413
  const softObstacles = input.obstacles ?? [];
5414
5414
  const hardObstacles = input.hardObstacles ?? [];
5415
+ let bestRejectedPath;
5416
+ let bestRejectedCrossings = Number.POSITIVE_INFINITY;
5415
5417
  const softObstacleIndex = input.obstacleIndex ?? createBoxSpatialIndex(indexedBoxes(softObstacles));
5416
5418
  const hardObstacleIndex = input.hardObstacleIndex ?? createBoxSpatialIndex(indexedBoxes(hardObstacles));
5419
+ const recordRejected = (candidate) => {
5420
+ if (routeIntersectsObstacles(candidate, hardObstacles, hardObstacleIndex)) {
5421
+ return;
5422
+ }
5423
+ const crossings = countObstacleCrossings(candidate, softObstacles);
5424
+ if (crossings < bestRejectedCrossings) {
5425
+ bestRejectedCrossings = crossings;
5426
+ bestRejectedPath = candidate;
5427
+ }
5428
+ };
5417
5429
  const maxAttempts = input.maxRoutingAttempts ?? 5;
5418
5430
  const defaultAnchors = defaultAnchorsForGeometry(
5419
5431
  input.source.box,
@@ -5473,13 +5485,14 @@ function routeEdge(input) {
5473
5485
  targetAnchor
5474
5486
  );
5475
5487
  const allObstacles = [...softObstacles, ...hardObstacles];
5488
+ const corridorMargin = input.corridorMargin ?? 32;
5476
5489
  const corridorObstacles = filterObstaclesByCorridor(
5477
5490
  source,
5478
5491
  target,
5479
5492
  allObstacles,
5480
5493
  [],
5481
5494
  // endpointObstacles passed separately via options
5482
- 32
5495
+ corridorMargin
5483
5496
  );
5484
5497
  const cornerObstacles = corridorObstacles.length === 0 && allObstacles.length > 0 ? allObstacles : corridorObstacles;
5485
5498
  let cornerPath = findCornerGraphPath(
@@ -5502,7 +5515,7 @@ function routeEdge(input) {
5502
5515
  source,
5503
5516
  target,
5504
5517
  allObstacles,
5505
- { endpointObstacles, margin: 0 },
5518
+ { endpointObstacles, margin: 0, corridorMargin },
5506
5519
  diagnostics
5507
5520
  );
5508
5521
  if (path !== null && path.length >= 2) {
@@ -5519,9 +5532,16 @@ function routeEdge(input) {
5519
5532
  softObstacles,
5520
5533
  softObstacleIndex
5521
5534
  ) && !routeIntersectsObstacles(finalized, hardObstacles, hardObstacleIndex)) {
5522
- checkBacktracking(finalized, source, target, diagnostics);
5535
+ checkBacktracking(
5536
+ finalized,
5537
+ source,
5538
+ target,
5539
+ diagnostics,
5540
+ input.maxBacktrackingRatio
5541
+ );
5523
5542
  return { points: finalized, diagnostics };
5524
5543
  }
5544
+ recordRejected(finalized);
5525
5545
  if (cornerPath !== null) {
5526
5546
  const fullCornerPath = cornerObstacles.length < allObstacles.length ? findCornerGraphPath(
5527
5547
  source,
@@ -5548,15 +5568,22 @@ function routeEdge(input) {
5548
5568
  hardObstacles,
5549
5569
  hardObstacleIndex
5550
5570
  )) {
5551
- checkBacktracking(fullFinalized, source, target, diagnostics);
5571
+ checkBacktracking(
5572
+ fullFinalized,
5573
+ source,
5574
+ target,
5575
+ diagnostics,
5576
+ input.maxBacktrackingRatio
5577
+ );
5552
5578
  return { points: fullFinalized, diagnostics };
5553
5579
  }
5580
+ recordRejected(fullFinalized);
5554
5581
  }
5555
5582
  const gridPath = findObstacleFreePath(
5556
5583
  source,
5557
5584
  target,
5558
5585
  allObstacles,
5559
- { endpointObstacles, margin: 0 },
5586
+ { endpointObstacles, margin: 0, corridorMargin },
5560
5587
  diagnostics
5561
5588
  );
5562
5589
  if (gridPath !== null && gridPath.length >= 2) {
@@ -5577,9 +5604,16 @@ function routeEdge(input) {
5577
5604
  hardObstacles,
5578
5605
  hardObstacleIndex
5579
5606
  )) {
5580
- checkBacktracking(gridFinalized, source, target, diagnostics);
5607
+ checkBacktracking(
5608
+ gridFinalized,
5609
+ source,
5610
+ target,
5611
+ diagnostics,
5612
+ input.maxBacktrackingRatio
5613
+ );
5581
5614
  return { points: gridFinalized, diagnostics };
5582
5615
  }
5616
+ recordRejected(gridFinalized);
5583
5617
  }
5584
5618
  }
5585
5619
  }
@@ -5643,7 +5677,8 @@ function routeEdge(input) {
5643
5677
  finalizedClean,
5644
5678
  candidate.points[0],
5645
5679
  candidate.points[candidate.points.length - 1],
5646
- diagnostics
5680
+ diagnostics,
5681
+ input.maxBacktrackingRatio
5647
5682
  );
5648
5683
  return { points: finalizedClean, diagnostics };
5649
5684
  }
@@ -5709,13 +5744,41 @@ function routeEdge(input) {
5709
5744
  code: "routing.obstacle.unavoidable",
5710
5745
  message: "No bounded orthogonal route candidate avoided all soft obstacles."
5711
5746
  });
5712
- return {
5713
- points: finalizeRoute(
5714
- bestPoints2,
5747
+ const finalizedSoftBest = finalizeRoute(
5748
+ bestPoints2,
5749
+ softObstacles,
5750
+ hardObstacles,
5751
+ diagnostics
5752
+ );
5753
+ let softFallback = finalizedSoftBest;
5754
+ if (bestRejectedPath !== void 0) {
5755
+ const finalizedRejected = finalizeRoute(
5756
+ bestRejectedPath,
5715
5757
  softObstacles,
5716
5758
  hardObstacles,
5717
5759
  diagnostics
5718
- ),
5760
+ );
5761
+ const rejectedCrossings = countObstacleCrossings(
5762
+ finalizedRejected,
5763
+ softObstacles
5764
+ );
5765
+ const heuristicCrossings = countObstacleCrossings(
5766
+ finalizedSoftBest,
5767
+ softObstacles
5768
+ );
5769
+ if (rejectedCrossings < heuristicCrossings) {
5770
+ softFallback = finalizedRejected;
5771
+ }
5772
+ }
5773
+ checkBacktracking(
5774
+ softFallback,
5775
+ softFallback[0],
5776
+ softFallback[softFallback.length - 1],
5777
+ diagnostics,
5778
+ input.maxBacktrackingRatio
5779
+ );
5780
+ return {
5781
+ points: softFallback,
5719
5782
  diagnostics
5720
5783
  };
5721
5784
  }
@@ -5747,6 +5810,22 @@ function routeEdge(input) {
5747
5810
  maxAttempts
5748
5811
  );
5749
5812
  }
5813
+ if (bestRejectedPath !== void 0) {
5814
+ diagnostics.push({
5815
+ severity: "warning",
5816
+ code: "routing.obstacle.unavoidable",
5817
+ message: "Using A* route with minor soft-obstacle crossings to avoid hard evidence obstacles."
5818
+ });
5819
+ return {
5820
+ points: finalizeRoute(
5821
+ bestRejectedPath,
5822
+ softObstacles,
5823
+ hardObstacles,
5824
+ diagnostics
5825
+ ),
5826
+ diagnostics
5827
+ };
5828
+ }
5750
5829
  diagnostics.push({
5751
5830
  severity: "error",
5752
5831
  code: "routing.evidence.crossing_forbidden",
@@ -5794,13 +5873,41 @@ function routeEdge(input) {
5794
5873
  code: "routing.obstacle.unavoidable",
5795
5874
  message: "No bounded orthogonal route candidate avoided all obstacles."
5796
5875
  });
5797
- return {
5798
- points: finalizeRoute(
5799
- bestPoints,
5876
+ const finalizedBestPoints = finalizeRoute(
5877
+ bestPoints,
5878
+ softObstacles,
5879
+ hardObstacles,
5880
+ diagnostics
5881
+ );
5882
+ let fallbackPoints = finalizedBestPoints;
5883
+ if (bestRejectedPath !== void 0) {
5884
+ const finalizedRejected = finalizeRoute(
5885
+ bestRejectedPath,
5800
5886
  softObstacles,
5801
5887
  hardObstacles,
5802
5888
  diagnostics
5803
- ),
5889
+ );
5890
+ const rejectedCrossings = countObstacleCrossings(
5891
+ finalizedRejected,
5892
+ softObstacles
5893
+ );
5894
+ const heuristicCrossings = countObstacleCrossings(
5895
+ finalizedBestPoints,
5896
+ softObstacles
5897
+ );
5898
+ if (rejectedCrossings < heuristicCrossings) {
5899
+ fallbackPoints = finalizedRejected;
5900
+ }
5901
+ }
5902
+ checkBacktracking(
5903
+ fallbackPoints,
5904
+ fallbackPoints[0],
5905
+ fallbackPoints[fallbackPoints.length - 1],
5906
+ diagnostics,
5907
+ input.maxBacktrackingRatio
5908
+ );
5909
+ return {
5910
+ points: fallbackPoints,
5804
5911
  diagnostics
5805
5912
  };
5806
5913
  }
@@ -6299,6 +6406,24 @@ function routeIntersectsObstacles(points, obstacles, spatialIndex) {
6299
6406
  }
6300
6407
  return false;
6301
6408
  }
6409
+ function countObstacleCrossings(points, obstacles) {
6410
+ let count = 0;
6411
+ for (const obstacle of obstacles) {
6412
+ validateBox(obstacle);
6413
+ for (let pointIndex = 0; pointIndex < points.length - 1; pointIndex += 1) {
6414
+ const a = points[pointIndex];
6415
+ const b = points[pointIndex + 1];
6416
+ if (a === void 0 || b === void 0) {
6417
+ continue;
6418
+ }
6419
+ if (intersectsAabb(segmentBox2(a, b), obstacle)) {
6420
+ count += 1;
6421
+ break;
6422
+ }
6423
+ }
6424
+ }
6425
+ return count;
6426
+ }
6302
6427
  function routeIntersectsEndpointInteriors(points, endpointInteriors) {
6303
6428
  for (let index = 0; index < points.length - 1; index += 1) {
6304
6429
  const a = points[index];
@@ -6744,7 +6869,8 @@ function solveDiagram(diagram, options = {}) {
6744
6869
  constrained.boxes,
6745
6870
  constrained.locks,
6746
6871
  options?.overlapSpacing ?? 40,
6747
- Math.max(0, options?.minLaneGutter ?? 0)
6872
+ Math.max(0, options?.minLaneGutter ?? 0),
6873
+ options.distributeContainedChildren ?? true
6748
6874
  );
6749
6875
  removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
6750
6876
  diagnostics.push(...swimlaneContracts.diagnostics);
@@ -6911,7 +7037,8 @@ function solveDiagram(diagram, options = {}) {
6911
7037
  diagram.direction,
6912
7038
  options,
6913
7039
  diagnostics,
6914
- coordinatedGroups
7040
+ coordinatedGroups,
7041
+ contentBounds
6915
7042
  );
6916
7043
  const edgeTextAnnotations = coordinateEdgeTextAnnotations(
6917
7044
  coordinatedEdges,
@@ -7333,7 +7460,7 @@ function reportCjkTypographyDiagnostics(path, typography, previousStyle, diagnos
7333
7460
  function containsCjk(value) {
7334
7461
  return /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/u.test(value);
7335
7462
  }
7336
- function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter) {
7463
+ function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter, distributeContainedChildren) {
7337
7464
  const layouts = /* @__PURE__ */ new Map();
7338
7465
  const diagnostics = [];
7339
7466
  const movedChildIds = /* @__PURE__ */ new Set();
@@ -7352,7 +7479,9 @@ function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottom
7352
7479
  locks,
7353
7480
  diagnostics,
7354
7481
  movedChildIds,
7355
- laneGutter
7482
+ laneGutter,
7483
+ constraints,
7484
+ distributeContainedChildren
7356
7485
  );
7357
7486
  if (layout2 !== void 0) {
7358
7487
  layouts.set(swimlane.id, layout2);
@@ -7544,7 +7673,7 @@ function isStackRunaway(boxes, nodes, direction, options) {
7544
7673
  const maxWidth = Math.max(...nodeBoxes.map((box) => box.width));
7545
7674
  return xSpread <= Math.max(maxWidth, options.overlapSpacing ?? 40);
7546
7675
  }
7547
- function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter) {
7676
+ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
7548
7677
  const headerHeight = swimlane.headerHeight ?? 28;
7549
7678
  const padding = swimlane.padding ?? 16;
7550
7679
  const laneBounds = swimlane.lanes.map((lane) => {
@@ -7569,7 +7698,9 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
7569
7698
  locks,
7570
7699
  diagnostics,
7571
7700
  movedChildIds,
7572
- laneGutter
7701
+ laneGutter,
7702
+ constraints,
7703
+ distributeContainedChildren
7573
7704
  );
7574
7705
  }
7575
7706
  return applyHorizontalSwimlaneContract(
@@ -7584,13 +7715,29 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
7584
7715
  laneGutter
7585
7716
  );
7586
7717
  }
7587
- function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter) {
7718
+ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
7588
7719
  const populatedBounds = laneBounds.filter(
7589
7720
  (box) => box !== void 0
7590
7721
  );
7591
7722
  const top = Math.min(...populatedBounds.map((box) => box.y));
7592
7723
  const left = Math.min(...populatedBounds.map((box) => box.x));
7593
7724
  const maxChildHeight = Math.max(...populatedBounds.map((box) => box.height));
7725
+ const containedChildIds = /* @__PURE__ */ new Set();
7726
+ if (distributeContainedChildren) {
7727
+ for (const c of constraints) {
7728
+ if (c.kind !== "containment") continue;
7729
+ if (nodeBoxes.get(c.containerId) === void 0) continue;
7730
+ const distributable = c.childIds.filter((childId) => {
7731
+ if (nodeBoxes.get(childId) === void 0) return false;
7732
+ const lock = locks.get(childId);
7733
+ return lock === void 0 || lock.source === "fixed-position";
7734
+ });
7735
+ if (distributable.length < 2) continue;
7736
+ for (const childId of distributable) {
7737
+ containedChildIds.add(childId);
7738
+ }
7739
+ }
7740
+ }
7594
7741
  const flowRanks = topToBottomFlow ? rankVerticalSwimlaneChildren(swimlane, edges) : /* @__PURE__ */ new Map();
7595
7742
  const maxRank = flowRanks.size === 0 ? 0 : Math.max(...Array.from(flowRanks.values()));
7596
7743
  const rankStackGap = Math.max(8, padding / 2);
@@ -7607,7 +7754,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
7607
7754
  nodeBoxes,
7608
7755
  flowRanks,
7609
7756
  locks,
7610
- rankStackGap
7757
+ rankStackGap,
7758
+ containedChildIds
7611
7759
  );
7612
7760
  const slotWidth = Math.max(
7613
7761
  Math.max(...populatedBounds.map((box) => box.width)),
@@ -7629,7 +7777,10 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
7629
7777
  const distributable = lane.children.filter(
7630
7778
  (childId) => !locks.has(childId)
7631
7779
  );
7632
- if (distributable.length >= CROSS_AXIS_SPREAD_THRESHOLD) {
7780
+ const coveredByContainment = lane.children.some(
7781
+ (childId) => containedChildIds.has(childId)
7782
+ );
7783
+ if (!coveredByContainment && distributable.length >= CROSS_AXIS_SPREAD_THRESHOLD) {
7633
7784
  moveRankedVerticalLaneChildren(
7634
7785
  lane.children,
7635
7786
  nodeBoxes,
@@ -7657,6 +7808,9 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
7657
7808
  );
7658
7809
  continue;
7659
7810
  }
7811
+ const rankedCoveredByContainment = lane.children.some(
7812
+ (childId) => containedChildIds.has(childId)
7813
+ );
7660
7814
  moveRankedVerticalLaneChildren(
7661
7815
  lane.children,
7662
7816
  nodeBoxes,
@@ -7667,7 +7821,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
7667
7821
  rankSpacing,
7668
7822
  rankStackGap,
7669
7823
  { x: target.x, y: laneContentTop },
7670
- slotWidth - padding * 2
7824
+ slotWidth - padding * 2,
7825
+ rankedCoveredByContainment
7671
7826
  );
7672
7827
  }
7673
7828
  return {
@@ -7783,9 +7938,12 @@ function crossAxisSpreadWidth(items, gap) {
7783
7938
  0
7784
7939
  );
7785
7940
  }
7786
- function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
7941
+ function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap, containedChildIds) {
7787
7942
  let maxWidth = 0;
7788
7943
  for (const lane of swimlane.lanes) {
7944
+ if (containedChildIds !== void 0 && lane.children.some((childId) => containedChildIds.has(childId))) {
7945
+ continue;
7946
+ }
7789
7947
  for (const stack of rankStacks(
7790
7948
  lane.children,
7791
7949
  nodeBoxes,
@@ -7798,7 +7956,7 @@ function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
7798
7956
  }
7799
7957
  return maxWidth;
7800
7958
  }
7801
- function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth) {
7959
+ function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth, suppressSpread) {
7802
7960
  for (const [rank, stack] of rankStacks(childIds, nodeBoxes, flowRanks)) {
7803
7961
  const unlocked = [];
7804
7962
  for (const item of stack) {
@@ -7827,7 +7985,7 @@ function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics,
7827
7985
  }
7828
7986
  nodeBoxes.set(childId, next);
7829
7987
  } else {
7830
- const shouldSpread = unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
7988
+ const shouldSpread = !suppressSpread && unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
7831
7989
  if (!shouldSpread) {
7832
7990
  let yOffset = 0;
7833
7991
  for (const { childId, box } of unlocked) {
@@ -8956,14 +9114,21 @@ function evidenceOverlapDiagnostic(block, conflict) {
8956
9114
  }
8957
9115
  };
8958
9116
  }
8959
- function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups) {
9117
+ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups, contentBounds) {
8960
9118
  const coordinated = [];
8961
9119
  const coordinatedNodeById = new Map(
8962
9120
  coordinatedNodes.map((node) => [node.id, node])
8963
9121
  );
9122
+ const corridorMarginOption = options.corridorMargin ?? "auto";
9123
+ const corridorMargin = typeof corridorMarginOption === "number" ? corridorMarginOption : Math.max(
9124
+ 200,
9125
+ Math.hypot(contentBounds.width, contentBounds.height) * 0.3
9126
+ );
9127
+ const routingGutter = options.routingGutter ?? 160;
9128
+ const queryGutter = (options.routeKind ?? "orthogonal") === "obstacle-avoiding" ? Math.max(routingGutter, corridorMargin) : routingGutter;
8964
9129
  const nodeObstacleIndex = createBoxSpatialIndex(
8965
9130
  obstacles.map((box, index) => ({ id: `node-obstacle:${index}`, box })),
8966
- options.routingGutter ?? 160
9131
+ queryGutter
8967
9132
  );
8968
9133
  for (const edge of edges) {
8969
9134
  const source = nodes.get(edge.source.nodeId);
@@ -8985,11 +9150,7 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
8985
9150
  const sourcePort = coordinatedNodeById.get(edge.source.nodeId)?.ports?.find((port) => port.id === edge.source.portId);
8986
9151
  const targetPort = coordinatedNodeById.get(edge.target.nodeId)?.ports?.find((port) => port.id === edge.target.portId);
8987
9152
  const routeTextObstacles = textObstacles.filter((annotation) => !isEdgeConnectedTextAnnotation(edge, annotation)).map((annotation) => annotation.box);
8988
- const corridor = edgeCorridorBox(
8989
- source.box,
8990
- target.box,
8991
- options.routingGutter ?? 160
8992
- );
9153
+ const corridor = edgeCorridorBox(source.box, target.box, queryGutter);
8993
9154
  const routeNodeObstacles = queryBoxSpatialIndex(nodeObstacleIndex, corridor).map((entry) => entry.box).filter(
8994
9155
  (obstacle) => !sameBox(obstacle, source.obstacleBox) && !sameBox(obstacle, target.obstacleBox)
8995
9156
  );
@@ -9007,7 +9168,9 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
9007
9168
  ...routeTextObstacles
9008
9169
  ],
9009
9170
  hardObstacles,
9010
- ...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts }
9171
+ corridorMargin,
9172
+ ...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts },
9173
+ ...options.maxBacktrackingRatio === void 0 ? {} : { maxBacktrackingRatio: options.maxBacktrackingRatio }
9011
9174
  });
9012
9175
  diagnostics.push(
9013
9176
  ...route.diagnostics.map((diagnostic) => ({