@cardenelabs/cdl 0.123.0 → 0.124.0

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/react.cjs CHANGED
@@ -9107,6 +9107,55 @@ function bowSharedStraightPaths(edges, nodes, skipIds, textMetrics = "proportion
9107
9107
  function nodeRect(n) {
9108
9108
  return { x: n.cx - n.w / 2, y: n.cy - n.h / 2, w: n.w, h: n.h };
9109
9109
  }
9110
+ function countPathObstacleCrossings(d, obstacles) {
9111
+ const segments = flattenPathSegments(extractPathSegments(d));
9112
+ return obstacles.filter((obstacle) => segmentsCrossRect(segments, nodeRect(obstacle))).length;
9113
+ }
9114
+ function makeBackDetourCandidate(A, B, from, to, obstacles, detourY, side) {
9115
+ const lowIsA = A.y >= B.y;
9116
+ const low = lowIsA ? A : B;
9117
+ const lowBendY = low.y - VERTICAL_DETOUR_EXIT;
9118
+ const bandTop = Math.min(detourY, lowBendY);
9119
+ const bandBottom = Math.max(detourY, lowBendY);
9120
+ const bandObstacles = obstacles.map(nodeRect).filter((rect) => rect.y + rect.h >= bandTop && rect.y <= bandBottom);
9121
+ let columnX = detourColumnFor([from, to], side);
9122
+ while (true) {
9123
+ const blockers = bandObstacles.filter(
9124
+ (rect) => rect.x - VERTICAL_DETOUR_GAP < columnX && columnX < rect.x + rect.w + VERTICAL_DETOUR_GAP
9125
+ );
9126
+ if (blockers.length === 0) break;
9127
+ columnX = side === "left" ? Math.min(...blockers.map((rect) => rect.x - VERTICAL_DETOUR_GAP)) : Math.max(...blockers.map((rect) => rect.x + rect.w + VERTICAL_DETOUR_GAP));
9128
+ }
9129
+ const bendAY = lowIsA ? lowBendY : detourY;
9130
+ const bendBY = lowIsA ? detourY : lowBendY;
9131
+ const vertices = [
9132
+ A,
9133
+ { x: A.x, y: bendAY },
9134
+ { x: columnX, y: bendAY },
9135
+ { x: columnX, y: bendBY },
9136
+ { x: B.x, y: bendBY },
9137
+ B
9138
+ ];
9139
+ const d = verticesToPath(vertices);
9140
+ const high = lowIsA ? B : A;
9141
+ return {
9142
+ d,
9143
+ labelX: (high.x + columnX) / 2,
9144
+ crossings: countPathObstacleCrossings(d, obstacles),
9145
+ length: vertices.slice(1).reduce((sum, vertex, index) => {
9146
+ const previous = vertices[index];
9147
+ return sum + Math.hypot(vertex.x - previous.x, vertex.y - previous.y);
9148
+ }, 0)
9149
+ };
9150
+ }
9151
+ function chooseBackDetourCandidate(A, B, from, to, obstacles, detourY) {
9152
+ const left = makeBackDetourCandidate(A, B, from, to, obstacles, detourY, "left");
9153
+ const right = makeBackDetourCandidate(A, B, from, to, obstacles, detourY, "right");
9154
+ if (left.crossings !== right.crossings) return left.crossings < right.crossings ? left : right;
9155
+ if (Math.abs(left.length - right.length) >= 0.5) return left.length < right.length ? left : right;
9156
+ const preferred = Math.abs(A.x - B.x) < 0.5 ? "right" : A.x < B.x ? "left" : "right";
9157
+ return preferred === "left" ? left : right;
9158
+ }
9110
9159
  function rectGap(a, b) {
9111
9160
  const dx = Math.max(0, a.x - (b.x + b.w), b.x - (a.x + a.w));
9112
9161
  const dy = Math.max(0, a.y - (b.y + b.h), b.y - (a.y + a.h));
@@ -9557,7 +9606,7 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
9557
9606
  const detourY = Math.min(A.y, B.y) - 100;
9558
9607
  const corner = 14;
9559
9608
  const xDir = B.x > A.x ? 1 : -1;
9560
- return {
9609
+ const existing = {
9561
9610
  d: `M ${A.x} ${A.y}
9562
9611
  L ${A.x} ${detourY + corner}
9563
9612
  Q ${A.x} ${detourY}, ${A.x + xDir * corner} ${detourY}
@@ -9571,6 +9620,16 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
9571
9620
  labelY: detourY - labelInit,
9572
9621
  labelAnchor: "middle"
9573
9622
  };
9623
+ const existingCrossings = countPathObstacleCrossings(existing.d, obstacles);
9624
+ if (existingCrossings === 0) return existing;
9625
+ const candidate = chooseBackDetourCandidate(A, B, from, to, obstacles, detourY);
9626
+ if (candidate.crossings >= existingCrossings) return existing;
9627
+ return {
9628
+ d: candidate.d,
9629
+ labelX: candidate.labelX,
9630
+ labelY: detourY - labelInit,
9631
+ labelAnchor: "middle"
9632
+ };
9574
9633
  }
9575
9634
  const midX = fromSide === "left" || fromSide === "right" ? B.x : A.x;
9576
9635
  const midY = fromSide === "top" || fromSide === "bottom" ? B.y : A.y;