dishui 0.0.45 → 0.0.46

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.
Files changed (60) hide show
  1. package/dist/chart.js +46 -0
  2. package/dist/components/Chart/Chart.d.ts +17 -0
  3. package/dist/components/Chart/Chart.js +29 -0
  4. package/dist/components/Chart/Chart.js.map +1 -0
  5. package/dist/components/Chart/index.d.ts +15 -0
  6. package/dist/components/Input/index.js +2 -2
  7. package/dist/components/Input/index.js.map +1 -1
  8. package/dist/components/Select/index.js +1 -1
  9. package/dist/components/Select/index.js.map +1 -1
  10. package/dist/components/pro/Flow/Flow.js +492 -392
  11. package/dist/components/pro/Flow/Flow.js.map +1 -1
  12. package/dist/components/pro/Flow/FlowCanvas.js +895 -864
  13. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  14. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +2 -0
  15. package/dist/components/pro/Flow/context/FlowUIContext.js +68 -65
  16. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  17. package/dist/components/pro/Flow/edges/edgePaths.js +234 -216
  18. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  19. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js +21 -10
  20. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  21. package/dist/components/pro/Flow/hooks/useMindMap.js +138 -134
  22. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  23. package/dist/components/pro/Flow/index.d.ts +1 -1
  24. package/dist/components/pro/Flow/nodes/MediaContent.js +47 -25
  25. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  26. package/dist/components/pro/Flow/nodes/Model3DView.d.ts +7 -0
  27. package/dist/components/pro/Flow/nodes/Model3DView.js +118 -0
  28. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -0
  29. package/dist/components/pro/Flow/nodes/NodeHandles.d.ts +2 -1
  30. package/dist/components/pro/Flow/nodes/NodeHandles.js +4 -2
  31. package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
  32. package/dist/components/pro/Flow/nodes/NodeRenderer.d.ts +2 -0
  33. package/dist/components/pro/Flow/nodes/NodeRenderer.js +115 -113
  34. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  35. package/dist/components/pro/Flow/nodes/NodeText.d.ts +3 -0
  36. package/dist/components/pro/Flow/nodes/NodeText.js +26 -17
  37. package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
  38. package/dist/components/pro/Flow/panels/FlowToolbar.js +85 -79
  39. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  40. package/dist/components/pro/Flow/panels/InspectorPanel.js +618 -488
  41. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  42. package/dist/components/pro/Flow/panels/OutlinePanel.js +15 -15
  43. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  44. package/dist/components/pro/Flow/panels/ShapePalette.js +71 -55
  45. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  46. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +1 -0
  47. package/dist/components/pro/Flow/panels/toolbarIcons.js +59 -41
  48. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  49. package/dist/components/pro/Flow/types.d.ts +13 -4
  50. package/dist/components/pro/Flow/types.js.map +1 -1
  51. package/dist/dishui.css +1 -1
  52. package/dist/index-nostyled.d.ts +3 -1
  53. package/dist/index.d.ts +3 -1
  54. package/dist/index.js +145 -143
  55. package/dist/utils/i18n.d.ts +1 -0
  56. package/dist/utils/i18n.js +200 -6
  57. package/dist/utils/i18n.js.map +1 -1
  58. package/dist/utils/menu.js +26 -10
  59. package/dist/utils/menu.js.map +1 -1
  60. package/package.json +14 -3
@@ -1 +1 @@
1
- {"version":3,"file":"edgePaths.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/edgePaths.ts"],"sourcesContent":["import type { FlowEdgeTypeName, FlowBezierControl, FlowEdge, FlowNode } from '../types';\nimport { getHandlePositions, type HandleDef } from '../nodes/NodeHandles';\n\n/** Outward unit normal for a handle side */\nconst SIDE_NORMAL: Record<string, { dx: number; dy: number }> = {\n top: { dx: 0, dy: -1 },\n bottom: { dx: 0, dy: 1 },\n left: { dx: -1, dy: 0 },\n right: { dx: 1, dy: 0 },\n};\n\n/** Perpendicular clearance (px) from node edge for step / smoothstep paths */\nconst EDGE_OFFSET = 20;\n/** Bezier control-arm length multiplier (fraction of inter-node distance, clamped) */\nconst BEZ_ARM_MIN = 30;\nconst BEZ_ARM_FRAC = 0.3;\n\nexport interface EdgeEndpoints {\n sx: number; sy: number;\n tx: number; ty: number;\n /** Outward unit-normal at source handle */\n snx: number; sny: number;\n /** Outward unit-normal at target handle */\n tnx: number; tny: number;\n}\n\nexport interface PathSegment {\n type: 'M' | 'L' | 'C' | 'Q';\n x: number; y: number;\n cp1x?: number; cp1y?: number;\n cp2x?: number; cp2y?: number;\n}\n\n/**\n * Build a path (array of segments) for the given edge type.\n * Returns segments that can be drawn with PixiJS Graphics.\n */\nexport function buildEdgePath(\n type: FlowEdgeTypeName,\n endpoints: EdgeEndpoints,\n waypoints?: Array<{ x: number; y: number }>,\n bezierControls?: Array<FlowBezierControl | null> | null,\n): PathSegment[] {\n const src = { x: endpoints.sx, y: endpoints.sy };\n const tgt = { x: endpoints.tx, y: endpoints.ty };\n const wps = waypoints ?? [];\n\n switch (type) {\n case 'straight':\n return buildStraightPath([src, ...wps, tgt]);\n\n case 'step':\n case 'smoothstep': {\n const radius = type === 'smoothstep' ? 8 : 0;\n return buildStepPathWithOffsets(src, tgt, wps, endpoints, radius);\n }\n\n case 'simplebezier':\n return buildBezierPath([src, ...wps, tgt], bezierControls, endpoints);\n\n default:\n return buildStraightPath([src, ...wps, tgt]);\n }\n}\n\nfunction buildStraightPath(points: Array<{ x: number; y: number }>): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n for (let i = 1; i < points.length; i++) {\n segs.push({ type: 'L', x: points[i].x, y: points[i].y });\n }\n return segs;\n}\n\n/**\n * Step path with perpendicular exit / entry offsets.\n *\n * Produces clean orthogonal \"elbow\" routing:\n * 1. source → exit stub (perpendicular to the source face)\n * 2. exit → waypoints → approach (orthogonal)\n * 3. approach stub → target (perpendicular into the target face)\n *\n * The middle routing picks the split axis from the two handle orientations so\n * opposing/aligned handles produce a single clean bend instead of an S/Z jog,\n * and collinear points are collapsed at the end.\n */\nfunction buildStepPathWithOffsets(\n src: { x: number; y: number },\n tgt: { x: number; y: number },\n waypoints: Array<{ x: number; y: number }>,\n ep: EdgeEndpoints,\n borderRadius: number,\n): PathSegment[] {\n const dist = Math.hypot(tgt.x - src.x, tgt.y - src.y);\n const offset = Math.min(EDGE_OFFSET, dist / 4);\n\n const exitPt = { x: src.x + ep.snx * offset, y: src.y + ep.sny * offset };\n const approPt = { x: tgt.x + ep.tnx * offset, y: tgt.y + ep.tny * offset };\n\n const srcVertical = Math.abs(ep.sny) > Math.abs(ep.snx);\n const tgtVertical = Math.abs(ep.tny) > Math.abs(ep.tnx);\n\n // Build the raw corner list (no rounding yet), then simplify + round.\n const corners: Array<{ x: number; y: number }> = [{ x: src.x, y: src.y }, exitPt];\n\n const mids = [exitPt, ...waypoints, approPt];\n for (let i = 0; i < mids.length - 1; i++) {\n const a = mids[i];\n const b = mids[i + 1];\n // Orientation of this leg: first leg follows source, last leg follows target.\n const vertical = i === 0 ? srcVertical : (i === mids.length - 2 ? tgtVertical : srcVertical);\n if (vertical) {\n // V-H-V: go vertically to the mid-Y, across, then down/up.\n const midY = (a.y + b.y) / 2;\n corners.push({ x: a.x, y: midY }, { x: b.x, y: midY });\n } else {\n // H-V-H: go horizontally to the mid-X, vertically, then across.\n const midX = (a.x + b.x) / 2;\n corners.push({ x: midX, y: a.y }, { x: midX, y: b.y });\n }\n corners.push({ x: b.x, y: b.y });\n }\n corners.push({ x: tgt.x, y: tgt.y });\n\n const simplified = simplifyOrthogonal(corners);\n return roundedOrthogonalPath(simplified, borderRadius);\n}\n\n/**\n * Remove collinear / duplicate points from an orthogonal polyline so we don't\n * emit degenerate zero-length jogs (a common source of \"unnatural\" bends).\n */\nfunction simplifyOrthogonal(pts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n const out: Array<{ x: number; y: number }> = [];\n for (const p of pts) {\n const last = out[out.length - 1];\n if (last && Math.abs(last.x - p.x) < 0.01 && Math.abs(last.y - p.y) < 0.01) continue;\n out.push({ x: p.x, y: p.y });\n }\n // Drop the middle of any 3 collinear points.\n const res: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < out.length; i++) {\n const prev = res[res.length - 1];\n const cur = out[i];\n const next = out[i + 1];\n if (prev && next) {\n const collinearX = Math.abs(prev.x - cur.x) < 0.01 && Math.abs(cur.x - next.x) < 0.01;\n const collinearY = Math.abs(prev.y - cur.y) < 0.01 && Math.abs(cur.y - next.y) < 0.01;\n if (collinearX || collinearY) continue;\n }\n res.push(cur);\n }\n return res;\n}\n\n/**\n * Convert an orthogonal polyline into path segments, rounding each corner.\n */\nfunction roundedOrthogonalPath(\n pts: Array<{ x: number; y: number }>,\n borderRadius: number,\n): PathSegment[] {\n if (pts.length === 0) return [];\n const segs: PathSegment[] = [{ type: 'M', x: pts[0].x, y: pts[0].y }];\n if (pts.length === 1) return segs;\n if (borderRadius <= 0.5) {\n for (let i = 1; i < pts.length; i++) segs.push({ type: 'L', x: pts[i].x, y: pts[i].y });\n return segs;\n }\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const cur = pts[i];\n const next = pts[i + 1];\n const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);\n const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);\n const r = Math.min(borderRadius, inLen / 2, outLen / 2);\n if (r < 0.5) {\n segs.push({ type: 'L', x: cur.x, y: cur.y });\n continue;\n }\n const inDx = Math.sign(cur.x - prev.x);\n const inDy = Math.sign(cur.y - prev.y);\n const outDx = Math.sign(next.x - cur.x);\n const outDy = Math.sign(next.y - cur.y);\n segs.push({ type: 'L', x: cur.x - inDx * r, y: cur.y - inDy * r });\n segs.push({ type: 'Q', x: cur.x + outDx * r, y: cur.y + outDy * r, cp1x: cur.x, cp1y: cur.y });\n }\n const end = pts[pts.length - 1];\n segs.push({ type: 'L', x: end.x, y: end.y });\n return segs;\n}\n\n/**\n * Cubic bezier path between consecutive points.\n * Uses handle normals on the first / last segment for perpendicular exit/entry.\n */\nfunction buildBezierPath(\n points: Array<{ x: number; y: number }>,\n controls?: Array<FlowBezierControl | null> | null,\n ep?: EdgeEndpoints,\n): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n const lastIdx = points.length - 2;\n\n for (let i = 0; i <= lastIdx; i++) {\n const a = points[i];\n const b = points[i + 1];\n const ctrl = controls?.[i];\n\n if (ctrl) {\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: ctrl.c1x, cp1y: ctrl.c1y,\n cp2x: ctrl.c2x, cp2y: ctrl.c2y,\n });\n } else {\n const dist = Math.hypot(b.x - a.x, b.y - a.y);\n const arm = Math.max(BEZ_ARM_MIN, dist * BEZ_ARM_FRAC);\n\n let c1x: number, c1y: number;\n if (i === 0 && ep) {\n c1x = a.x + ep.snx * arm;\n c1y = a.y + ep.sny * arm;\n } else {\n c1x = a.x + (b.x - a.x) * 0.4;\n c1y = a.y;\n }\n\n let c2x: number, c2y: number;\n if (i === lastIdx && ep) {\n c2x = b.x + ep.tnx * arm;\n c2y = b.y + ep.tny * arm;\n } else {\n c2x = b.x - (b.x - a.x) * 0.4;\n c2y = b.y;\n }\n\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: c1x, cp1y: c1y,\n cp2x: c2x, cp2y: c2y,\n });\n }\n }\n return segs;\n}\n\n/**\n * Compute the center point of a path (for label placement).\n */\nexport function getPathCenter(segs: PathSegment[]): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const mid = Math.floor(segs.length / 2);\n const a = segs[mid - 1];\n const b = segs[mid];\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n}\n\n/**\n * Get a point on a path at parameter t (0-1), approximate.\n */\nexport function getPointOnPath(segs: PathSegment[], t: number): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const totalSegs = segs.length - 1;\n const segIdx = Math.min(Math.floor(t * totalSegs), totalSegs - 1);\n const localT = (t * totalSegs) - segIdx;\n const a = segs[segIdx];\n const b = segs[segIdx + 1];\n return {\n x: a.x + (b.x - a.x) * localT,\n y: a.y + (b.y - a.y) * localT,\n };\n}\n\n/**\n * Resolve source/target anchor positions for an edge.\n * Uses stored handle IDs when available; falls back to closest-handle heuristic.\n */\n/**\n * Transform a handle's local-space position into world space,\n * accounting for the node's rotation (degrees, stored in data.rotation).\n */\nfunction handleToWorld(\n hx: number, hy: number,\n node: FlowNode,\n): { x: number; y: number } {\n const deg = node.data.rotation ?? 0;\n if (deg === 0) {\n return { x: node.position.x + hx, y: node.position.y + hy };\n }\n const rad = (deg * Math.PI) / 180;\n const cx = node.width / 2, cy = node.height / 2;\n const dx = hx - cx, dy = hy - cy;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n x: node.position.x + cx + dx * cos - dy * sin,\n y: node.position.y + cy + dx * sin + dy * cos,\n };\n}\n\n/**\n * Compute the outward unit-normal for a handle, accounting for node rotation.\n */\nfunction handleNormal(h: HandleDef | null, node: FlowNode): { nx: number; ny: number } {\n const base = SIDE_NORMAL[h?.side ?? 'right'] ?? SIDE_NORMAL.right;\n const deg = node.data.rotation ?? 0;\n if (deg === 0) return { nx: base.dx, ny: base.dy };\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n nx: base.dx * cos - base.dy * sin,\n ny: base.dx * sin + base.dy * cos,\n };\n}\n\nexport function resolveEdgeEndpoints(\n edge: FlowEdge,\n nodeMap: Map<string, FlowNode>,\n): EdgeEndpoints | null {\n const sn = nodeMap.get(edge.source);\n const tn = nodeMap.get(edge.target);\n if (!sn || !tn) return null;\n\n const sHandles = getHandlePositions(sn.width, sn.height);\n const tHandles = getHandlePositions(tn.width, tn.height);\n\n let sx: number, sy: number, sH: HandleDef | null;\n if (edge.sourceHandle) {\n sH = sHandles.find(h => h.id === edge.sourceHandle) ?? null;\n const pos = handleToWorld(sH ? sH.x : sn.width / 2, sH ? sH.y : sn.height / 2, sn);\n sx = pos.x; sy = pos.y;\n } else {\n // Floating anchor: pick the side by direction, then slide the point along\n // that side to align with the target so aligned nodes connect with a\n // straight line instead of a forced mid-handle jog.\n const anchor = floatingAnchor(sn, tn);\n sx = anchor.x; sy = anchor.y; sH = anchor.handleLike;\n }\n\n let tx: number, ty: number, tH: HandleDef | null;\n if (edge.targetHandle) {\n tH = tHandles.find(h => h.id === edge.targetHandle) ?? null;\n const pos = handleToWorld(tH ? tH.x : tn.width / 2, tH ? tH.y : tn.height / 2, tn);\n tx = pos.x; ty = pos.y;\n } else {\n const anchor = floatingAnchor(tn, sn);\n tx = anchor.x; ty = anchor.y; tH = anchor.handleLike;\n }\n\n const sN = handleNormal(sH, sn);\n const tN = handleNormal(tH, tn);\n\n return { sx, sy, tx, ty, snx: sN.nx, sny: sN.ny, tnx: tN.nx, tny: tN.ny };\n}\n\n/**\n * Compute a floating connection anchor on `self` facing `other`.\n * Chooses the side by dominant direction, then slides the anchor along that\n * side to line up with the other node's center (clamped to the side extent).\n * Returns the world point plus a synthetic handle carrying only the `side`\n * (used for the outward normal).\n */\nfunction floatingAnchor(\n self: FlowNode,\n other: FlowNode,\n): { x: number; y: number; handleLike: HandleDef } {\n const sx = self.position.x, sy = self.position.y;\n const sw = self.width, sh = self.height;\n const sCx = sx + sw / 2, sCy = sy + sh / 2;\n const oCx = other.position.x + other.width / 2;\n const oCy = other.position.y + other.height / 2;\n\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n // Inset so the anchor never sits exactly on a corner.\n const inset = Math.min(12, sw / 2 - 1, sh / 2 - 1);\n\n let side: HandleDef['side'];\n let x: number, y: number;\n if (Math.abs(dx) >= Math.abs(dy)) {\n side = dx >= 0 ? 'right' : 'left';\n x = side === 'right' ? sx + sw : sx;\n // Slide vertically to align with the other center, clamped to the side.\n y = Math.max(sy + inset, Math.min(sy + sh - inset, oCy));\n } else {\n side = dy >= 0 ? 'bottom' : 'top';\n y = side === 'bottom' ? sy + sh : sy;\n x = Math.max(sx + inset, Math.min(sx + sw - inset, oCx));\n }\n\n // Rotation: for rotated nodes fall back to the un-slid center of the side to\n // keep the normal math simple (rare case).\n const deg = self.data.rotation ?? 0;\n if (deg !== 0) {\n const cx = side === 'right' ? sx + sw : side === 'left' ? sx : sCx;\n const cy = side === 'bottom' ? sy + sh : side === 'top' ? sy : sCy;\n return { x: cx, y: cy, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n }\n\n return { x, y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n}\n\n/**\n * Previously this pinned auto-resolved edges to a fixed middle handle at load\n * time, which forced ugly jogs between misaligned nodes. Edges without an\n * explicit handle are now left \"floating\" and resolved dynamically in\n * `resolveEdgeEndpoints` (see `floatingAnchor`), so this is a no-op that simply\n * preserves any user-pinned handles.\n */\nexport function normalizeEdgeHandles(\n edges: FlowEdge[],\n _nodeMap: Map<string, FlowNode>,\n): FlowEdge[] {\n return edges;\n}\n\n/**\n * Convert PathSegments into a polyline by sampling curves.\n */\nexport function linearizeSegments(\n segs: PathSegment[],\n samplesPerCurve = 8,\n): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n let cx = 0, cy = 0;\n for (const seg of segs) {\n switch (seg.type) {\n case 'M':\n case 'L':\n cx = seg.x; cy = seg.y;\n pts.push({ x: cx, y: cy });\n break;\n case 'Q': {\n const cpx = seg.cp1x!, cpy = seg.cp1y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt * mt * cx + 2 * mt * t * cpx + t * t * seg.x,\n y: mt * mt * cy + 2 * mt * t * cpy + t * t * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n case 'C': {\n const c1x = seg.cp1x!, c1y = seg.cp1y!, c2x = seg.cp2x!, c2y = seg.cp2y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt ** 3 * cx + 3 * mt ** 2 * t * c1x + 3 * mt * t ** 2 * c2x + t ** 3 * seg.x,\n y: mt ** 3 * cy + 3 * mt ** 2 * t * c1y + 3 * mt * t ** 2 * c2y + t ** 3 * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n }\n }\n return pts;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"edgePaths.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/edgePaths.ts"],"sourcesContent":["import type { FlowEdgeTypeName, FlowBezierControl, FlowEdge, FlowNode } from '../types';\nimport { getHandlePositions, type HandleDef } from '../nodes/NodeHandles';\n\n/** Outward unit normal for a handle side */\nconst SIDE_NORMAL: Record<string, { dx: number; dy: number }> = {\n top: { dx: 0, dy: -1 },\n bottom: { dx: 0, dy: 1 },\n left: { dx: -1, dy: 0 },\n right: { dx: 1, dy: 0 },\n};\n\n/** Perpendicular clearance (px) from node edge for step / smoothstep paths */\nconst EDGE_OFFSET = 20;\n/** Bezier control-arm length multiplier (fraction of inter-node distance, clamped) */\nconst BEZ_ARM_MIN = 30;\nconst BEZ_ARM_FRAC = 0.3;\n\nexport interface EdgeEndpoints {\n sx: number; sy: number;\n tx: number; ty: number;\n /** Outward unit-normal at source handle */\n snx: number; sny: number;\n /** Outward unit-normal at target handle */\n tnx: number; tny: number;\n}\n\nexport interface PathSegment {\n type: 'M' | 'L' | 'C' | 'Q';\n x: number; y: number;\n cp1x?: number; cp1y?: number;\n cp2x?: number; cp2y?: number;\n}\n\n/**\n * Build a path (array of segments) for the given edge type.\n * Returns segments that can be drawn with PixiJS Graphics.\n */\nexport function buildEdgePath(\n type: FlowEdgeTypeName,\n endpoints: EdgeEndpoints,\n waypoints?: Array<{ x: number; y: number }>,\n bezierControls?: Array<FlowBezierControl | null> | null,\n): PathSegment[] {\n const src = { x: endpoints.sx, y: endpoints.sy };\n const tgt = { x: endpoints.tx, y: endpoints.ty };\n const wps = waypoints ?? [];\n\n switch (type) {\n case 'straight':\n return buildStraightPath([src, ...wps, tgt]);\n\n case 'step':\n case 'smoothstep': {\n const radius = type === 'smoothstep' ? 8 : 0;\n return buildStepPathWithOffsets(src, tgt, wps, endpoints, radius);\n }\n\n case 'simplebezier':\n return buildBezierPath([src, ...wps, tgt], bezierControls, endpoints);\n\n default:\n return buildStraightPath([src, ...wps, tgt]);\n }\n}\n\nfunction buildStraightPath(points: Array<{ x: number; y: number }>): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n for (let i = 1; i < points.length; i++) {\n segs.push({ type: 'L', x: points[i].x, y: points[i].y });\n }\n return segs;\n}\n\n/**\n * Step path with perpendicular exit / entry offsets.\n *\n * Produces clean orthogonal \"elbow\" routing:\n * 1. source → exit stub (perpendicular to the source face)\n * 2. exit → waypoints → approach (orthogonal)\n * 3. approach stub → target (perpendicular into the target face)\n *\n * The middle routing picks the split axis from the two handle orientations so\n * opposing/aligned handles produce a single clean bend instead of an S/Z jog,\n * and collinear points are collapsed at the end.\n */\nfunction buildStepPathWithOffsets(\n src: { x: number; y: number },\n tgt: { x: number; y: number },\n waypoints: Array<{ x: number; y: number }>,\n ep: EdgeEndpoints,\n borderRadius: number,\n): PathSegment[] {\n const dist = Math.hypot(tgt.x - src.x, tgt.y - src.y);\n const offset = Math.min(EDGE_OFFSET, dist / 4);\n\n const exitPt = { x: src.x + ep.snx * offset, y: src.y + ep.sny * offset };\n const approPt = { x: tgt.x + ep.tnx * offset, y: tgt.y + ep.tny * offset };\n\n const srcVertical = Math.abs(ep.sny) > Math.abs(ep.snx);\n const tgtVertical = Math.abs(ep.tny) > Math.abs(ep.tnx);\n\n // Build the raw corner list (no rounding yet), then simplify + round.\n const corners: Array<{ x: number; y: number }> = [{ x: src.x, y: src.y }, exitPt];\n\n const mids = [exitPt, ...waypoints, approPt];\n for (let i = 0; i < mids.length - 1; i++) {\n const a = mids[i];\n const b = mids[i + 1];\n // Orientation of this leg: first leg follows source, last leg follows target.\n const vertical = i === 0 ? srcVertical : (i === mids.length - 2 ? tgtVertical : srcVertical);\n if (vertical) {\n // V-H-V: go vertically to the mid-Y, across, then down/up.\n const midY = (a.y + b.y) / 2;\n corners.push({ x: a.x, y: midY }, { x: b.x, y: midY });\n } else {\n // H-V-H: go horizontally to the mid-X, vertically, then across.\n const midX = (a.x + b.x) / 2;\n corners.push({ x: midX, y: a.y }, { x: midX, y: b.y });\n }\n corners.push({ x: b.x, y: b.y });\n }\n corners.push({ x: tgt.x, y: tgt.y });\n\n const simplified = simplifyOrthogonal(corners);\n return roundedOrthogonalPath(simplified, borderRadius);\n}\n\n/**\n * Remove collinear / duplicate points from an orthogonal polyline so we don't\n * emit degenerate zero-length jogs (a common source of \"unnatural\" bends).\n */\nfunction simplifyOrthogonal(pts: Array<{ x: number; y: number }>): Array<{ x: number; y: number }> {\n const out: Array<{ x: number; y: number }> = [];\n for (const p of pts) {\n const last = out[out.length - 1];\n if (last && Math.abs(last.x - p.x) < 0.01 && Math.abs(last.y - p.y) < 0.01) continue;\n out.push({ x: p.x, y: p.y });\n }\n // Drop the middle of any 3 collinear points.\n const res: Array<{ x: number; y: number }> = [];\n for (let i = 0; i < out.length; i++) {\n const prev = res[res.length - 1];\n const cur = out[i];\n const next = out[i + 1];\n if (prev && next) {\n const collinearX = Math.abs(prev.x - cur.x) < 0.01 && Math.abs(cur.x - next.x) < 0.01;\n const collinearY = Math.abs(prev.y - cur.y) < 0.01 && Math.abs(cur.y - next.y) < 0.01;\n if (collinearX || collinearY) continue;\n }\n res.push(cur);\n }\n return res;\n}\n\n/**\n * Convert an orthogonal polyline into path segments, rounding each corner.\n */\nfunction roundedOrthogonalPath(\n pts: Array<{ x: number; y: number }>,\n borderRadius: number,\n): PathSegment[] {\n if (pts.length === 0) return [];\n const segs: PathSegment[] = [{ type: 'M', x: pts[0].x, y: pts[0].y }];\n if (pts.length === 1) return segs;\n if (borderRadius <= 0.5) {\n for (let i = 1; i < pts.length; i++) segs.push({ type: 'L', x: pts[i].x, y: pts[i].y });\n return segs;\n }\n for (let i = 1; i < pts.length - 1; i++) {\n const prev = pts[i - 1];\n const cur = pts[i];\n const next = pts[i + 1];\n const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);\n const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);\n const r = Math.min(borderRadius, inLen / 2, outLen / 2);\n if (r < 0.5) {\n segs.push({ type: 'L', x: cur.x, y: cur.y });\n continue;\n }\n const inDx = Math.sign(cur.x - prev.x);\n const inDy = Math.sign(cur.y - prev.y);\n const outDx = Math.sign(next.x - cur.x);\n const outDy = Math.sign(next.y - cur.y);\n segs.push({ type: 'L', x: cur.x - inDx * r, y: cur.y - inDy * r });\n segs.push({ type: 'Q', x: cur.x + outDx * r, y: cur.y + outDy * r, cp1x: cur.x, cp1y: cur.y });\n }\n const end = pts[pts.length - 1];\n segs.push({ type: 'L', x: end.x, y: end.y });\n return segs;\n}\n\n/**\n * Cubic bezier path between consecutive points.\n * Uses handle normals on the first / last segment for perpendicular exit/entry.\n */\nfunction buildBezierPath(\n points: Array<{ x: number; y: number }>,\n controls?: Array<FlowBezierControl | null> | null,\n ep?: EdgeEndpoints,\n): PathSegment[] {\n const segs: PathSegment[] = [{ type: 'M', x: points[0].x, y: points[0].y }];\n const lastIdx = points.length - 2;\n\n for (let i = 0; i <= lastIdx; i++) {\n const a = points[i];\n const b = points[i + 1];\n const ctrl = controls?.[i];\n\n if (ctrl) {\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: ctrl.c1x, cp1y: ctrl.c1y,\n cp2x: ctrl.c2x, cp2y: ctrl.c2y,\n });\n } else {\n const dist = Math.hypot(b.x - a.x, b.y - a.y);\n const arm = Math.max(BEZ_ARM_MIN, dist * BEZ_ARM_FRAC);\n\n let c1x: number, c1y: number;\n if (i === 0 && ep) {\n c1x = a.x + ep.snx * arm;\n c1y = a.y + ep.sny * arm;\n } else {\n c1x = a.x + (b.x - a.x) * 0.4;\n c1y = a.y;\n }\n\n let c2x: number, c2y: number;\n if (i === lastIdx && ep) {\n c2x = b.x + ep.tnx * arm;\n c2y = b.y + ep.tny * arm;\n } else {\n c2x = b.x - (b.x - a.x) * 0.4;\n c2y = b.y;\n }\n\n segs.push({\n type: 'C', x: b.x, y: b.y,\n cp1x: c1x, cp1y: c1y,\n cp2x: c2x, cp2y: c2y,\n });\n }\n }\n return segs;\n}\n\n/**\n * Compute the center point of a path (for label placement).\n */\nexport function getPathCenter(segs: PathSegment[]): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const mid = Math.floor(segs.length / 2);\n const a = segs[mid - 1];\n const b = segs[mid];\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n}\n\n/**\n * Get a point on a path at parameter t (0-1), approximate.\n */\nexport function getPointOnPath(segs: PathSegment[], t: number): { x: number; y: number } {\n if (segs.length < 2) return { x: segs[0]?.x ?? 0, y: segs[0]?.y ?? 0 };\n const totalSegs = segs.length - 1;\n const segIdx = Math.min(Math.floor(t * totalSegs), totalSegs - 1);\n const localT = (t * totalSegs) - segIdx;\n const a = segs[segIdx];\n const b = segs[segIdx + 1];\n return {\n x: a.x + (b.x - a.x) * localT,\n y: a.y + (b.y - a.y) * localT,\n };\n}\n\n/**\n * Resolve source/target anchor positions for an edge.\n * Uses stored handle IDs when available; falls back to closest-handle heuristic.\n */\n/**\n * Transform a handle's local-space position into world space,\n * accounting for the node's rotation (degrees, stored in data.rotation).\n */\nfunction handleToWorld(\n hx: number, hy: number,\n node: FlowNode,\n): { x: number; y: number } {\n const deg = node.data.rotation ?? 0;\n if (deg === 0) {\n return { x: node.position.x + hx, y: node.position.y + hy };\n }\n const rad = (deg * Math.PI) / 180;\n const cx = node.width / 2, cy = node.height / 2;\n const dx = hx - cx, dy = hy - cy;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n x: node.position.x + cx + dx * cos - dy * sin,\n y: node.position.y + cy + dx * sin + dy * cos,\n };\n}\n\n/**\n * Compute the outward unit-normal for a handle, accounting for node rotation.\n */\nfunction handleNormal(h: HandleDef | null, node: FlowNode): { nx: number; ny: number } {\n const base = SIDE_NORMAL[h?.side ?? 'right'] ?? SIDE_NORMAL.right;\n const deg = node.data.rotation ?? 0;\n if (deg === 0) return { nx: base.dx, ny: base.dy };\n const rad = (deg * Math.PI) / 180;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n return {\n nx: base.dx * cos - base.dy * sin,\n ny: base.dx * sin + base.dy * cos,\n };\n}\n\nexport function resolveEdgeEndpoints(\n edge: FlowEdge,\n nodeMap: Map<string, FlowNode>,\n): EdgeEndpoints | null {\n const sn = nodeMap.get(edge.source);\n const tn = nodeMap.get(edge.target);\n if (!sn || !tn) return null;\n\n const sHandles = getHandlePositions(sn.width, sn.height);\n const tHandles = getHandlePositions(tn.width, tn.height);\n\n let sx: number, sy: number, sH: HandleDef | null;\n if (edge.sourceHandle) {\n sH = sHandles.find(h => h.id === edge.sourceHandle) ?? null;\n const pos = handleToWorld(sH ? sH.x : sn.width / 2, sH ? sH.y : sn.height / 2, sn);\n sx = pos.x; sy = pos.y;\n } else {\n // Floating anchor: pick the side by direction, then slide the point along\n // that side to align with the target so aligned nodes connect with a\n // straight line instead of a forced mid-handle jog.\n const anchor = floatingAnchor(sn, tn);\n sx = anchor.x; sy = anchor.y; sH = anchor.handleLike;\n }\n\n let tx: number, ty: number, tH: HandleDef | null;\n if (edge.targetHandle) {\n tH = tHandles.find(h => h.id === edge.targetHandle) ?? null;\n const pos = handleToWorld(tH ? tH.x : tn.width / 2, tH ? tH.y : tn.height / 2, tn);\n tx = pos.x; ty = pos.y;\n } else {\n const anchor = floatingAnchor(tn, sn);\n tx = anchor.x; ty = anchor.y; tH = anchor.handleLike;\n }\n\n const sN = handleNormal(sH, sn);\n const tN = handleNormal(tH, tn);\n\n return { sx, sy, tx, ty, snx: sN.nx, sny: sN.ny, tnx: tN.nx, tny: tN.ny };\n}\n\n/**\n * Compute a floating connection anchor on `self` facing `other`.\n * Chooses the side by dominant direction, then slides the anchor along that\n * side to line up with the other node's center (clamped to the side extent).\n * Returns the world point plus a synthetic handle carrying only the `side`\n * (used for the outward normal).\n */\nfunction floatingAnchor(\n self: FlowNode,\n other: FlowNode,\n): { x: number; y: number; handleLike: HandleDef } {\n const sx = self.position.x, sy = self.position.y;\n const sw = self.width, sh = self.height;\n const sCx = sx + sw / 2, sCy = sy + sh / 2;\n const oCx = other.position.x + other.width / 2;\n const oCy = other.position.y + other.height / 2;\n\n const dx = oCx - sCx;\n const dy = oCy - sCy;\n // Inset so the anchor never sits exactly on a corner.\n const inset = Math.min(12, sw / 2 - 1, sh / 2 - 1);\n\n let side: HandleDef['side'];\n let x: number, y: number;\n if (Math.abs(dx) >= Math.abs(dy)) {\n side = dx >= 0 ? 'right' : 'left';\n x = side === 'right' ? sx + sw : sx;\n // Slide vertically to align with the other center, clamped to the side.\n y = Math.max(sy + inset, Math.min(sy + sh - inset, oCy));\n } else {\n side = dy >= 0 ? 'bottom' : 'top';\n y = side === 'bottom' ? sy + sh : sy;\n x = Math.max(sx + inset, Math.min(sx + sw - inset, oCx));\n }\n\n // Rotation: for rotated nodes fall back to the un-slid center of the side to\n // keep the normal math simple (rare case).\n const deg = self.data.rotation ?? 0;\n if (deg !== 0) {\n const cx = side === 'right' ? sx + sw : side === 'left' ? sx : sCx;\n const cy = side === 'bottom' ? sy + sh : side === 'top' ? sy : sCy;\n return { x: cx, y: cy, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n }\n\n return { x, y, handleLike: { id: `float_${side}`, x: 0, y: 0, side } };\n}\n\n/**\n * Previously this pinned auto-resolved edges to a fixed middle handle at load\n * time, which forced ugly jogs between misaligned nodes. Edges without an\n * explicit handle are now left \"floating\" and resolved dynamically in\n * `resolveEdgeEndpoints` (see `floatingAnchor`), so this is a no-op that simply\n * preserves any user-pinned handles.\n */\nexport function normalizeEdgeHandles(\n edges: FlowEdge[],\n _nodeMap: Map<string, FlowNode>,\n): FlowEdge[] {\n const legacyOffsets = new Map([\n ['0.25', String(2 / 6)],\n ['0.5', String(3 / 6)],\n ['0.75', String(4 / 6)],\n ]);\n let changed = false;\n const migrate = (handle: string | undefined) => {\n if (!handle) return handle;\n const [side, offset] = handle.split('_');\n const nextOffset = legacyOffsets.get(offset);\n if (!nextOffset || !side) return handle;\n changed = true;\n return `${side}_${nextOffset}`;\n };\n const normalized = edges.map(edge => {\n const sourceHandle = migrate(edge.sourceHandle);\n const targetHandle = migrate(edge.targetHandle);\n return sourceHandle === edge.sourceHandle && targetHandle === edge.targetHandle\n ? edge\n : { ...edge, sourceHandle, targetHandle };\n });\n return changed ? normalized : edges;\n}\n\n/**\n * Convert PathSegments into a polyline by sampling curves.\n */\nexport function linearizeSegments(\n segs: PathSegment[],\n samplesPerCurve = 8,\n): Array<{ x: number; y: number }> {\n const pts: Array<{ x: number; y: number }> = [];\n let cx = 0, cy = 0;\n for (const seg of segs) {\n switch (seg.type) {\n case 'M':\n case 'L':\n cx = seg.x; cy = seg.y;\n pts.push({ x: cx, y: cy });\n break;\n case 'Q': {\n const cpx = seg.cp1x!, cpy = seg.cp1y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt * mt * cx + 2 * mt * t * cpx + t * t * seg.x,\n y: mt * mt * cy + 2 * mt * t * cpy + t * t * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n case 'C': {\n const c1x = seg.cp1x!, c1y = seg.cp1y!, c2x = seg.cp2x!, c2y = seg.cp2y!;\n for (let i = 1; i <= samplesPerCurve; i++) {\n const t = i / samplesPerCurve, mt = 1 - t;\n pts.push({\n x: mt ** 3 * cx + 3 * mt ** 2 * t * c1x + 3 * mt * t ** 2 * c2x + t ** 3 * seg.x,\n y: mt ** 3 * cy + 3 * mt ** 2 * t * c1y + 3 * mt * t ** 2 * c2y + t ** 3 * seg.y,\n });\n }\n cx = seg.x; cy = seg.y;\n break;\n }\n }\n }\n return pts;\n}\n"],"mappings":";AAIA,IAAM,IAA0D;AAAA,EAC9D,KAAQ;AAAA,IAAE,IAAK;AAAA,IAAG,IAAI;AAAA,EAAG;AAAA,EACzB,QAAQ;AAAA,IAAE,IAAK;AAAA,IAAG,IAAK;AAAA,EAAE;AAAA,EACzB,MAAQ;AAAA,IAAE,IAAI;AAAA,IAAI,IAAK;AAAA,EAAE;AAAA,EACzB,OAAQ;AAAA,IAAE,IAAK;AAAA,IAAG,IAAK;AAAA,EAAE;AAC3B,GAGM,IAAc,IAEd,IAAc,IACd,IAAe;AAsBrB,SAAgB,EACd,GACA,GACA,GACA,GACe;AACf,QAAM,IAAM;AAAA,IAAE,GAAG,EAAU;AAAA,IAAI,GAAG,EAAU;AAAA,EAAG,GACzC,IAAM;AAAA,IAAE,GAAG,EAAU;AAAA,IAAI,GAAG,EAAU;AAAA,EAAG,GACzC,IAAM,KAAa,CAAC;AAE1B,UAAQ,GAAR;AAAA,IACE,KAAK;AACH,aAAO,EAAkB;AAAA,QAAC;AAAA,QAAK,GAAG;AAAA,QAAK;AAAA,MAAG,CAAC;AAAA,IAE7C,KAAK;AAAA,IACL,KAAK;AAEH,aAAO,EAAyB,GAAK,GAAK,GAAK,GADhC,MAAS,eAAe,IAAI,CACqB;AAAA,IAGlE,KAAK;AACH,aAAO,EAAgB;AAAA,QAAC;AAAA,QAAK,GAAG;AAAA,QAAK;AAAA,MAAG,GAAG,GAAgB,CAAS;AAAA,IAEtE;AACE,aAAO,EAAkB;AAAA,QAAC;AAAA,QAAK,GAAG;AAAA,QAAK;AAAA,MAAG,CAAC;AAAA,EAC/C;AACF;AAEA,SAAS,EAAkB,GAAwD;AACjF,QAAM,IAAsB,CAAC;AAAA,IAAE,MAAM;AAAA,IAAK,GAAG,EAAO,CAAA,EAAG;AAAA,IAAG,GAAG,EAAO,CAAA,EAAG;AAAA,EAAE,CAAC;AAC1E,WAAS,IAAI,GAAG,IAAI,EAAO,QAAQ,IACjC,CAAA,EAAK,KAAK;AAAA,IAAE,MAAM;AAAA,IAAK,GAAG,EAAO,CAAA,EAAG;AAAA,IAAG,GAAG,EAAO,CAAA,EAAG;AAAA,EAAE,CAAC;AAEzD,SAAO;AACT;AAcA,SAAS,EACP,GACA,GACA,GACA,GACA,GACe;AACf,QAAM,IAAO,KAAK,MAAM,EAAI,IAAI,EAAI,GAAG,EAAI,IAAI,EAAI,CAAC,GAC9C,IAAS,KAAK,IAAI,GAAa,IAAO,CAAC,GAEvC,IAAS;AAAA,IAAE,GAAG,EAAI,IAAI,EAAG,MAAM;AAAA,IAAQ,GAAG,EAAI,IAAI,EAAG,MAAM;AAAA,EAAO,GAClE,IAAU;AAAA,IAAE,GAAG,EAAI,IAAI,EAAG,MAAM;AAAA,IAAQ,GAAG,EAAI,IAAI,EAAG,MAAM;AAAA,EAAO,GAEnE,IAAc,KAAK,IAAI,EAAG,GAAG,IAAI,KAAK,IAAI,EAAG,GAAG,GAChD,IAAc,KAAK,IAAI,EAAG,GAAG,IAAI,KAAK,IAAI,EAAG,GAAG,GAGhD,IAA2C,CAAC;AAAA,IAAE,GAAG,EAAI;AAAA,IAAG,GAAG,EAAI;AAAA,EAAE,GAAG,CAAM,GAE1E,IAAO;AAAA,IAAC;AAAA,IAAQ,GAAG;AAAA,IAAW;AAAA,EAAO;AAC3C,WAAS,IAAI,GAAG,IAAI,EAAK,SAAS,GAAG,KAAK;AACxC,UAAM,IAAI,EAAK,CAAA,GACT,IAAI,EAAK,IAAI,CAAA;AAGnB,QADiB,MAAM,IAAI,IAAe,MAAM,EAAK,SAAS,IAAI,IAAc,GAClE;AAEZ,YAAM,KAAQ,EAAE,IAAI,EAAE,KAAK;AAC3B,MAAA,EAAQ,KAAK;AAAA,QAAE,GAAG,EAAE;AAAA,QAAG,GAAG;AAAA,MAAK,GAAG;AAAA,QAAE,GAAG,EAAE;AAAA,QAAG,GAAG;AAAA,MAAK,CAAC;AAAA,IACvD,OAAO;AAEL,YAAM,KAAQ,EAAE,IAAI,EAAE,KAAK;AAC3B,MAAA,EAAQ,KAAK;AAAA,QAAE,GAAG;AAAA,QAAM,GAAG,EAAE;AAAA,MAAE,GAAG;AAAA,QAAE,GAAG;AAAA,QAAM,GAAG,EAAE;AAAA,MAAE,CAAC;AAAA,IACvD;AACA,IAAA,EAAQ,KAAK;AAAA,MAAE,GAAG,EAAE;AAAA,MAAG,GAAG,EAAE;AAAA,IAAE,CAAC;AAAA,EACjC;AACA,SAAA,EAAQ,KAAK;AAAA,IAAE,GAAG,EAAI;AAAA,IAAG,GAAG,EAAI;AAAA,EAAE,CAAC,GAG5B,EADY,EAAmB,CACT,GAAY,CAAY;AACvD;AAMA,SAAS,EAAmB,GAAuE;AACjG,QAAM,IAAuC,CAAC;AAC9C,aAAW,KAAK,GAAK;AACnB,UAAM,IAAO,EAAI,EAAI,SAAS,CAAA;AAC9B,IAAI,KAAQ,KAAK,IAAI,EAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAK,IAAI,EAAE,CAAC,IAAI,QACtE,EAAI,KAAK;AAAA,MAAE,GAAG,EAAE;AAAA,MAAG,GAAG,EAAE;AAAA,IAAE,CAAC;AAAA,EAC7B;AAEA,QAAM,IAAuC,CAAC;AAC9C,WAAS,IAAI,GAAG,IAAI,EAAI,QAAQ,KAAK;AACnC,UAAM,IAAO,EAAI,EAAI,SAAS,CAAA,GACxB,IAAM,EAAI,CAAA,GACV,IAAO,EAAI,IAAI,CAAA;AACrB,QAAI,KAAQ,GAAM;AAChB,YAAM,IAAa,KAAK,IAAI,EAAK,IAAI,EAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAI,IAAI,EAAK,CAAC,IAAI,MAC3E,IAAa,KAAK,IAAI,EAAK,IAAI,EAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAI,IAAI,EAAK,CAAC,IAAI;AACjF,UAAI,KAAc,EAAY;AAAA,IAChC;AACA,IAAA,EAAI,KAAK,CAAG;AAAA,EACd;AACA,SAAO;AACT;AAKA,SAAS,EACP,GACA,GACe;AACf,MAAI,EAAI,WAAW,EAAG,QAAO,CAAC;AAC9B,QAAM,IAAsB,CAAC;AAAA,IAAE,MAAM;AAAA,IAAK,GAAG,EAAI,CAAA,EAAG;AAAA,IAAG,GAAG,EAAI,CAAA,EAAG;AAAA,EAAE,CAAC;AACpE,MAAI,EAAI,WAAW,EAAG,QAAO;AAC7B,MAAI,KAAgB,KAAK;AACvB,aAAS,IAAI,GAAG,IAAI,EAAI,QAAQ,IAAK,CAAA,EAAK,KAAK;AAAA,MAAE,MAAM;AAAA,MAAK,GAAG,EAAI,CAAA,EAAG;AAAA,MAAG,GAAG,EAAI,CAAA,EAAG;AAAA,IAAE,CAAC;AACtF,WAAO;AAAA,EACT;AACA,WAAS,IAAI,GAAG,IAAI,EAAI,SAAS,GAAG,KAAK;AACvC,UAAM,IAAO,EAAI,IAAI,CAAA,GACf,IAAM,EAAI,CAAA,GACV,IAAO,EAAI,IAAI,CAAA,GACf,IAAQ,KAAK,MAAM,EAAI,IAAI,EAAK,GAAG,EAAI,IAAI,EAAK,CAAC,GACjD,IAAS,KAAK,MAAM,EAAK,IAAI,EAAI,GAAG,EAAK,IAAI,EAAI,CAAC,GAClD,IAAI,KAAK,IAAI,GAAc,IAAQ,GAAG,IAAS,CAAC;AACtD,QAAI,IAAI,KAAK;AACX,MAAA,EAAK,KAAK;AAAA,QAAE,MAAM;AAAA,QAAK,GAAG,EAAI;AAAA,QAAG,GAAG,EAAI;AAAA,MAAE,CAAC;AAC3C;AAAA,IACF;AACA,UAAM,IAAO,KAAK,KAAK,EAAI,IAAI,EAAK,CAAC,GAC/B,IAAO,KAAK,KAAK,EAAI,IAAI,EAAK,CAAC,GAC/B,IAAQ,KAAK,KAAK,EAAK,IAAI,EAAI,CAAC,GAChC,IAAQ,KAAK,KAAK,EAAK,IAAI,EAAI,CAAC;AACtC,IAAA,EAAK,KAAK;AAAA,MAAE,MAAM;AAAA,MAAK,GAAG,EAAI,IAAI,IAAO;AAAA,MAAG,GAAG,EAAI,IAAI,IAAO;AAAA,IAAE,CAAC,GACjE,EAAK,KAAK;AAAA,MAAE,MAAM;AAAA,MAAK,GAAG,EAAI,IAAI,IAAQ;AAAA,MAAG,GAAG,EAAI,IAAI,IAAQ;AAAA,MAAG,MAAM,EAAI;AAAA,MAAG,MAAM,EAAI;AAAA,IAAE,CAAC;AAAA,EAC/F;AACA,QAAM,IAAM,EAAI,EAAI,SAAS,CAAA;AAC7B,SAAA,EAAK,KAAK;AAAA,IAAE,MAAM;AAAA,IAAK,GAAG,EAAI;AAAA,IAAG,GAAG,EAAI;AAAA,EAAE,CAAC,GACpC;AACT;AAMA,SAAS,EACP,GACA,GACA,GACe;AACf,QAAM,IAAsB,CAAC;AAAA,IAAE,MAAM;AAAA,IAAK,GAAG,EAAO,CAAA,EAAG;AAAA,IAAG,GAAG,EAAO,CAAA,EAAG;AAAA,EAAE,CAAC,GACpE,IAAU,EAAO,SAAS;AAEhC,WAAS,IAAI,GAAG,KAAK,GAAS,KAAK;AACjC,UAAM,IAAI,EAAO,CAAA,GACX,IAAI,EAAO,IAAI,CAAA,GACf,IAAO,IAAW,CAAA;AAExB,QAAI,EACF,CAAA,EAAK,KAAK;AAAA,MACR,MAAM;AAAA,MAAK,GAAG,EAAE;AAAA,MAAG,GAAG,EAAE;AAAA,MACxB,MAAM,EAAK;AAAA,MAAK,MAAM,EAAK;AAAA,MAC3B,MAAM,EAAK;AAAA,MAAK,MAAM,EAAK;AAAA,IAC7B,CAAC;AAAA,SACI;AACL,YAAM,IAAO,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,GACtC,IAAM,KAAK,IAAI,GAAa,IAAO,CAAY;AAErD,UAAI,GAAa;AACjB,MAAI,MAAM,KAAK,KACb,IAAM,EAAE,IAAI,EAAG,MAAM,GACrB,IAAM,EAAE,IAAI,EAAG,MAAM,MAErB,IAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,KAC1B,IAAM,EAAE;AAGV,UAAI,GAAa;AACjB,MAAI,MAAM,KAAW,KACnB,IAAM,EAAE,IAAI,EAAG,MAAM,GACrB,IAAM,EAAE,IAAI,EAAG,MAAM,MAErB,IAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,KAC1B,IAAM,EAAE,IAGV,EAAK,KAAK;AAAA,QACR,MAAM;AAAA,QAAK,GAAG,EAAE;AAAA,QAAG,GAAG,EAAE;AAAA,QACxB,MAAM;AAAA,QAAK,MAAM;AAAA,QACjB,MAAM;AAAA,QAAK,MAAM;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAgB,EAAc,GAA+C;AAC3E,MAAI,EAAK,SAAS,EAAG,QAAO;AAAA,IAAE,GAAG,EAAK,CAAA,GAAI,KAAK;AAAA,IAAG,GAAG,EAAK,CAAA,GAAI,KAAK;AAAA,EAAE;AACrE,QAAM,IAAM,KAAK,MAAM,EAAK,SAAS,CAAC,GAChC,IAAI,EAAK,IAAM,CAAA,GACf,IAAI,EAAK,CAAA;AACf,SAAO;AAAA,IAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,IAAG,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,EAAE;AAClD;AA0BA,SAAS,EACP,GAAY,GACZ,GAC0B;AAC1B,QAAM,IAAM,EAAK,KAAK,YAAY;AAClC,MAAI,MAAQ,EACV,QAAO;AAAA,IAAE,GAAG,EAAK,SAAS,IAAI;AAAA,IAAI,GAAG,EAAK,SAAS,IAAI;AAAA,EAAG;AAE5D,QAAM,IAAO,IAAM,KAAK,KAAM,KACxB,IAAK,EAAK,QAAQ,GAAG,IAAK,EAAK,SAAS,GACxC,IAAK,IAAK,GAAI,IAAK,IAAK,GACxB,IAAM,KAAK,IAAI,CAAG,GAAG,IAAM,KAAK,IAAI,CAAG;AAC7C,SAAO;AAAA,IACL,GAAG,EAAK,SAAS,IAAI,IAAK,IAAK,IAAM,IAAK;AAAA,IAC1C,GAAG,EAAK,SAAS,IAAI,IAAK,IAAK,IAAM,IAAK;AAAA,EAC5C;AACF;AAKA,SAAS,EAAa,GAAqB,GAA4C;AACrF,QAAM,IAAO,EAAY,GAAG,QAAQ,OAAA,KAAY,EAAY,OACtD,IAAM,EAAK,KAAK,YAAY;AAClC,MAAI,MAAQ,EAAG,QAAO;AAAA,IAAE,IAAI,EAAK;AAAA,IAAI,IAAI,EAAK;AAAA,EAAG;AACjD,QAAM,IAAO,IAAM,KAAK,KAAM,KACxB,IAAM,KAAK,IAAI,CAAG,GAAG,IAAM,KAAK,IAAI,CAAG;AAC7C,SAAO;AAAA,IACL,IAAI,EAAK,KAAK,IAAM,EAAK,KAAK;AAAA,IAC9B,IAAI,EAAK,KAAK,IAAM,EAAK,KAAK;AAAA,EAChC;AACF;AAEA,SAAgB,EACd,GACA,GACsB;AACtB,QAAM,IAAK,EAAQ,IAAI,EAAK,MAAM,GAC5B,IAAK,EAAQ,IAAI,EAAK,MAAM;AAClC,MAAI,CAAC,KAAM,CAAC,EAAI,QAAO;AAEvB,QAAM,IAAW,EAAmB,EAAG,OAAO,EAAG,MAAM,GACjD,IAAW,EAAmB,EAAG,OAAO,EAAG,MAAM;AAEvD,MAAI,GAAY,GAAY;AAC5B,MAAI,EAAK,cAAc;AACrB,IAAA,IAAK,EAAS,KAAA,CAAK,MAAK,EAAE,OAAO,EAAK,YAAY,KAAK;AACvD,UAAM,IAAM,EAAc,IAAK,EAAG,IAAI,EAAG,QAAQ,GAAG,IAAK,EAAG,IAAI,EAAG,SAAS,GAAG,CAAE;AACjF,IAAA,IAAK,EAAI,GAAG,IAAK,EAAI;AAAA,EACvB,OAAO;AAIL,UAAM,IAAS,EAAe,GAAI,CAAE;AACpC,IAAA,IAAK,EAAO,GAAG,IAAK,EAAO,GAAG,IAAK,EAAO;AAAA,EAC5C;AAEA,MAAI,GAAY,GAAY;AAC5B,MAAI,EAAK,cAAc;AACrB,IAAA,IAAK,EAAS,KAAA,CAAK,MAAK,EAAE,OAAO,EAAK,YAAY,KAAK;AACvD,UAAM,IAAM,EAAc,IAAK,EAAG,IAAI,EAAG,QAAQ,GAAG,IAAK,EAAG,IAAI,EAAG,SAAS,GAAG,CAAE;AACjF,IAAA,IAAK,EAAI,GAAG,IAAK,EAAI;AAAA,EACvB,OAAO;AACL,UAAM,IAAS,EAAe,GAAI,CAAE;AACpC,IAAA,IAAK,EAAO,GAAG,IAAK,EAAO,GAAG,IAAK,EAAO;AAAA,EAC5C;AAEA,QAAM,IAAK,EAAa,GAAI,CAAE,GACxB,IAAK,EAAa,GAAI,CAAE;AAE9B,SAAO;AAAA,IAAE,IAAA;AAAA,IAAI,IAAA;AAAA,IAAI,IAAA;AAAA,IAAI,IAAA;AAAA,IAAI,KAAK,EAAG;AAAA,IAAI,KAAK,EAAG;AAAA,IAAI,KAAK,EAAG;AAAA,IAAI,KAAK,EAAG;AAAA,EAAG;AAC1E;AASA,SAAS,EACP,GACA,GACiD;AACjD,QAAM,IAAK,EAAK,SAAS,GAAG,IAAK,EAAK,SAAS,GACzC,IAAK,EAAK,OAAO,IAAK,EAAK,QAC3B,IAAM,IAAK,IAAK,GAAG,IAAM,IAAK,IAAK,GACnC,IAAM,EAAM,SAAS,IAAI,EAAM,QAAQ,GACvC,IAAM,EAAM,SAAS,IAAI,EAAM,SAAS,GAExC,IAAK,IAAM,GACX,IAAK,IAAM,GAEX,IAAQ,KAAK,IAAI,IAAI,IAAK,IAAI,GAAG,IAAK,IAAI,CAAC;AAEjD,MAAI,GACA,GAAW;AAef,SAdI,KAAK,IAAI,CAAE,KAAK,KAAK,IAAI,CAAE,KAC7B,IAAO,KAAM,IAAI,UAAU,QAC3B,IAAI,MAAS,UAAU,IAAK,IAAK,GAEjC,IAAI,KAAK,IAAI,IAAK,GAAO,KAAK,IAAI,IAAK,IAAK,GAAO,CAAG,CAAC,MAEvD,IAAO,KAAM,IAAI,WAAW,OAC5B,IAAI,MAAS,WAAW,IAAK,IAAK,GAClC,IAAI,KAAK,IAAI,IAAK,GAAO,KAAK,IAAI,IAAK,IAAK,GAAO,CAAG,CAAC,KAK7C,EAAK,KAAK,YAAY,OACtB,IAGH;AAAA,IAAE,GAFE,MAAS,UAAU,IAAK,IAAK,MAAS,SAAS,IAAK;AAAA,IAE/C,GADL,MAAS,WAAW,IAAK,IAAK,MAAS,QAAQ,IAAK;AAAA,IACxC,YAAY;AAAA,MAAE,IAAI,SAAS,CAAA;AAAA,MAAQ,GAAG;AAAA,MAAG,GAAG;AAAA,MAAG,MAAA;AAAA,IAAK;AAAA,EAAE,IAGxE;AAAA,IAAE,GAAA;AAAA,IAAG,GAAA;AAAA,IAAG,YAAY;AAAA,MAAE,IAAI,SAAS,CAAA;AAAA,MAAQ,GAAG;AAAA,MAAG,GAAG;AAAA,MAAG,MAAA;AAAA,IAAK;AAAA,EAAE;AACvE;AASA,SAAgB,EACd,GACA,GACY;AACZ,QAAM,IAAgB,oBAAI,IAAI;AAAA,IAC5B,CAAC,QAAQ,OAAO,kBAAK,CAAC;AAAA,IACtB,CAAC,OAAO,OAAO,GAAK,CAAC;AAAA,IACrB,CAAC,QAAQ,OAAO,kBAAK,CAAC;AAAA,EACxB,CAAC;AACD,MAAI,IAAU;AACd,QAAM,IAAA,CAAW,MAA+B;AAC9C,QAAI,CAAC,EAAQ,QAAO;AACpB,UAAM,CAAC,GAAM,CAAA,IAAU,EAAO,MAAM,GAAG,GACjC,IAAa,EAAc,IAAI,CAAM;AAC3C,WAAI,CAAC,KAAc,CAAC,IAAa,KACjC,IAAU,IACH,GAAG,CAAA,IAAQ,CAAA;AAAA,EACpB,GACM,IAAa,EAAM,IAAA,CAAI,MAAQ;AACnC,UAAM,IAAe,EAAQ,EAAK,YAAY,GACxC,IAAe,EAAQ,EAAK,YAAY;AAC9C,WAAO,MAAiB,EAAK,gBAAgB,MAAiB,EAAK,eAC/D,IACA;AAAA,MAAE,GAAG;AAAA,MAAM,cAAA;AAAA,MAAc,cAAA;AAAA,IAAa;AAAA,EAC5C,CAAC;AACD,SAAO,IAAU,IAAa;AAChC;AAKA,SAAgB,EACd,GACA,IAAkB,GACe;AACjC,QAAM,IAAuC,CAAC;AAC9C,MAAI,IAAK,GAAG,IAAK;AACjB,aAAW,KAAO,EAChB,SAAQ,EAAI,MAAZ;AAAA,IACE,KAAK;AAAA,IACL,KAAK;AACH,MAAA,IAAK,EAAI,GAAG,IAAK,EAAI,GACrB,EAAI,KAAK;AAAA,QAAE,GAAG;AAAA,QAAI;AAAA,MAAM,CAAC;AACzB;AAAA,IACF,KAAK,KAAK;AACR,YAAM,IAAM,EAAI,MAAO,IAAM,EAAI;AACjC,eAAS,IAAI,GAAG,KAAK,GAAiB,KAAK;AACzC,cAAM,IAAI,IAAI,GAAiB,IAAK,IAAI;AACxC,QAAA,EAAI,KAAK;AAAA,UACP,GAAG,IAAK,IAAK,IAAK,IAAI,IAAK,IAAI,IAAM,IAAI,IAAI,EAAI;AAAA,UACjD,GAAG,IAAK,IAAK,IAAK,IAAI,IAAK,IAAI,IAAM,IAAI,IAAI,EAAI;AAAA,QACnD,CAAC;AAAA,MACH;AACA,MAAA,IAAK,EAAI,GAAG,IAAK,EAAI;AACrB;AAAA,IACF;AAAA,IACA,KAAK,KAAK;AACR,YAAM,IAAM,EAAI,MAAO,IAAM,EAAI,MAAO,IAAM,EAAI,MAAO,IAAM,EAAI;AACnE,eAAS,IAAI,GAAG,KAAK,GAAiB,KAAK;AACzC,cAAM,IAAI,IAAI,GAAiB,IAAK,IAAI;AACxC,QAAA,EAAI,KAAK;AAAA,UACP,GAAG,KAAM,IAAI,IAAK,IAAI,KAAM,IAAI,IAAI,IAAM,IAAI,IAAK,KAAK,IAAI,IAAM,KAAK,IAAI,EAAI;AAAA,UAC/E,GAAG,KAAM,IAAI,IAAK,IAAI,KAAM,IAAI,IAAI,IAAM,IAAI,IAAK,KAAK,IAAI,IAAM,KAAK,IAAI,EAAI;AAAA,QACjF,CAAC;AAAA,MACH;AACA,MAAA,IAAK,EAAI,GAAG,IAAK,EAAI;AACrB;AAAA,IACF;AAAA,EACF;AAEF,SAAO;AACT"}
@@ -1,24 +1,35 @@
1
1
  import { useFlowContext as u } from "../context/FlowContext.js";
2
2
  import { useFlowUI as i } from "../context/FlowUIContext.js";
3
- import { useEffect as a } from "react";
3
+ import { useEffect as d } from "react";
4
4
  function D(t) {
5
- const { selection: d, setSelection: f, currentCanvas: p } = u(), { editingNodeId: n, setToolMode: s, setPendingPlacement: y } = i();
6
- a(() => {
5
+ const { selection: a, setSelection: n, currentCanvas: p } = u(), { editingNodeId: f, setToolMode: s, setPendingPlacement: y } = i();
6
+ d(() => {
7
7
  const o = (e) => {
8
8
  const l = e.target;
9
- if (l.tagName === "INPUT" || l.tagName === "TEXTAREA" || l.isContentEditable || n) return;
9
+ if (l.tagName === "INPUT" || l.tagName === "TEXTAREA" || l.isContentEditable || f) return;
10
10
  const r = e.metaKey || e.ctrlKey;
11
- r && e.key === "z" && !e.shiftKey ? (e.preventDefault(), t.undo()) : r && (e.key === "Z" || e.key === "z" && e.shiftKey) ? (e.preventDefault(), t.redo()) : r && e.key === "c" ? (e.preventDefault(), t.copy()) : r && e.key === "x" ? (e.preventDefault(), t.cut()) : r && e.key === "v" ? (e.preventDefault(), t.paste()) : r && e.key === "a" ? (e.preventDefault(), t.selectAll()) : r && e.altKey && (e.key === "g" || e.key === "G") ? (e.preventDefault(), t.geoGroup?.()) : r && e.key === "g" && !e.shiftKey && !e.altKey ? (e.preventDefault(), t.group?.()) : r && (e.key === "G" || e.key === "g" && e.shiftKey) && !e.altKey ? (e.preventDefault(), t.ungroup?.()) : r && e.shiftKey && e.key === "ArrowUp" ? (e.preventDefault(), t.bringToFront?.()) : r && !e.shiftKey && e.key === "ArrowUp" ? (e.preventDefault(), t.bringForward?.()) : r && !e.shiftKey && e.key === "ArrowDown" ? (e.preventDefault(), t.sendBackward?.()) : r && e.shiftKey && e.key === "ArrowDown" ? (e.preventDefault(), t.sendToBack?.()) : e.key === "Delete" || e.key === "Backspace" ? (e.preventDefault(), t.deleteSelected()) : e.key === "Escape" && (f({
12
- nodeIds: /* @__PURE__ */ new Set(),
13
- edgeIds: /* @__PURE__ */ new Set(),
14
- lineIds: /* @__PURE__ */ new Set()
15
- }), s("select"), y(null));
11
+ if (r && e.key === "z" && !e.shiftKey)
12
+ e.preventDefault(), t.undo();
13
+ else if (r && (e.key === "Z" || e.key === "z" && e.shiftKey))
14
+ e.preventDefault(), t.redo();
15
+ else if (r && e.key === "c")
16
+ e.preventDefault(), t.copy();
17
+ else if (r && e.key === "x")
18
+ e.preventDefault(), t.cut();
19
+ else {
20
+ if (r && e.key === "v") return;
21
+ r && e.key === "a" ? (e.preventDefault(), t.selectAll()) : r && e.altKey && (e.key === "g" || e.key === "G") ? (e.preventDefault(), t.geoGroup?.()) : r && e.key === "g" && !e.shiftKey && !e.altKey ? (e.preventDefault(), t.group?.()) : r && (e.key === "G" || e.key === "g" && e.shiftKey) && !e.altKey ? (e.preventDefault(), t.ungroup?.()) : r && e.shiftKey && e.key === "ArrowUp" ? (e.preventDefault(), t.bringToFront?.()) : r && !e.shiftKey && e.key === "ArrowUp" ? (e.preventDefault(), t.bringForward?.()) : r && !e.shiftKey && e.key === "ArrowDown" ? (e.preventDefault(), t.sendBackward?.()) : r && e.shiftKey && e.key === "ArrowDown" ? (e.preventDefault(), t.sendToBack?.()) : e.key === "Delete" || e.key === "Backspace" ? (e.preventDefault(), t.deleteSelected()) : e.key === "Escape" && (n({
22
+ nodeIds: /* @__PURE__ */ new Set(),
23
+ edgeIds: /* @__PURE__ */ new Set(),
24
+ lineIds: /* @__PURE__ */ new Set()
25
+ }), s("select"), y(null));
26
+ }
16
27
  };
17
28
  return window.addEventListener("keydown", o), () => window.removeEventListener("keydown", o);
18
29
  }, [
19
30
  t,
20
- n,
21
31
  f,
32
+ n,
22
33
  s,
23
34
  y
24
35
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"useKeyboardShortcuts.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useKeyboardShortcuts.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowUI } from '../context/FlowUIContext';\n\ninterface KeyboardShortcutActions {\n undo: () => void;\n redo: () => void;\n copy: () => void;\n cut: () => void;\n paste: () => void;\n deleteSelected: () => void;\n selectAll: () => void;\n group?: () => void;\n geoGroup?: () => void;\n ungroup?: () => void;\n bringToFront?: () => void;\n bringForward?: () => void;\n sendBackward?: () => void;\n sendToBack?: () => void;\n}\n\n/**\n * Registers global keyboard shortcuts for the flow editor.\n */\nexport function useKeyboardShortcuts(actions: KeyboardShortcutActions) {\n const { selection, setSelection, currentCanvas } = useFlowContext();\n const { editingNodeId, setToolMode, setPendingPlacement } = useFlowUI();\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n // Don't intercept when editing text in inputs\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;\n if (editingNodeId) return;\n\n const meta = e.metaKey || e.ctrlKey;\n\n if (meta && e.key === 'z' && !e.shiftKey) {\n e.preventDefault();\n actions.undo();\n } else if (meta && (e.key === 'Z' || (e.key === 'z' && e.shiftKey))) {\n e.preventDefault();\n actions.redo();\n } else if (meta && e.key === 'c') {\n e.preventDefault();\n actions.copy();\n } else if (meta && e.key === 'x') {\n e.preventDefault();\n actions.cut();\n } else if (meta && e.key === 'v') {\n e.preventDefault();\n actions.paste();\n } else if (meta && e.key === 'a') {\n e.preventDefault();\n actions.selectAll();\n } else if (meta && e.altKey && (e.key === 'g' || e.key === 'G')) {\n e.preventDefault();\n actions.geoGroup?.();\n } else if (meta && e.key === 'g' && !e.shiftKey && !e.altKey) {\n e.preventDefault();\n actions.group?.();\n } else if (meta && (e.key === 'G' || (e.key === 'g' && e.shiftKey)) && !e.altKey) {\n e.preventDefault();\n actions.ungroup?.();\n } else if (meta && e.shiftKey && e.key === 'ArrowUp') {\n e.preventDefault();\n actions.bringToFront?.();\n } else if (meta && !e.shiftKey && e.key === 'ArrowUp') {\n e.preventDefault();\n actions.bringForward?.();\n } else if (meta && !e.shiftKey && e.key === 'ArrowDown') {\n e.preventDefault();\n actions.sendBackward?.();\n } else if (meta && e.shiftKey && e.key === 'ArrowDown') {\n e.preventDefault();\n actions.sendToBack?.();\n } else if (e.key === 'Delete' || e.key === 'Backspace') {\n e.preventDefault();\n actions.deleteSelected();\n } else if (e.key === 'Escape') {\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n setToolMode('select');\n setPendingPlacement(null);\n }\n };\n\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [actions, editingNodeId, setSelection, setToolMode, setPendingPlacement]);\n}\n"],"mappings":";;;AAwBA,SAAgB,EAAqB,GAAkC;AACrE,QAAM,EAAE,WAAA,GAAW,cAAA,GAAc,eAAA,EAAA,IAAkB,EAAe,GAC5D,EAAE,eAAA,GAAe,aAAA,GAAa,qBAAA,EAAA,IAAwB,EAAU;AAEtE,EAAA,EAAA,MAAgB;AACd,UAAM,IAAA,CAAW,MAAqB;AAEpC,YAAM,IAAS,EAAE;AAEjB,UADI,EAAO,YAAY,WAAW,EAAO,YAAY,cAAc,EAAO,qBACtE,EAAe;AAEnB,YAAM,IAAO,EAAE,WAAW,EAAE;AAE5B,MAAI,KAAQ,EAAE,QAAQ,OAAO,CAAC,EAAE,YAC9B,EAAE,eAAe,GACjB,EAAQ,KAAK,KACJ,MAAS,EAAE,QAAQ,OAAQ,EAAE,QAAQ,OAAO,EAAE,aACvD,EAAE,eAAe,GACjB,EAAQ,KAAK,KACJ,KAAQ,EAAE,QAAQ,OAC3B,EAAE,eAAe,GACjB,EAAQ,KAAK,KACJ,KAAQ,EAAE,QAAQ,OAC3B,EAAE,eAAe,GACjB,EAAQ,IAAI,KACH,KAAQ,EAAE,QAAQ,OAC3B,EAAE,eAAe,GACjB,EAAQ,MAAM,KACL,KAAQ,EAAE,QAAQ,OAC3B,EAAE,eAAe,GACjB,EAAQ,UAAU,KACT,KAAQ,EAAE,WAAW,EAAE,QAAQ,OAAO,EAAE,QAAQ,QACzD,EAAE,eAAe,GACjB,EAAQ,WAAW,KACV,KAAQ,EAAE,QAAQ,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,UACpD,EAAE,eAAe,GACjB,EAAQ,QAAQ,KACP,MAAS,EAAE,QAAQ,OAAQ,EAAE,QAAQ,OAAO,EAAE,aAAc,CAAC,EAAE,UACxE,EAAE,eAAe,GACjB,EAAQ,UAAU,KACT,KAAQ,EAAE,YAAY,EAAE,QAAQ,aACzC,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,CAAC,EAAE,YAAY,EAAE,QAAQ,aAC1C,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,CAAC,EAAE,YAAY,EAAE,QAAQ,eAC1C,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,EAAE,YAAY,EAAE,QAAQ,eACzC,EAAE,eAAe,GACjB,EAAQ,aAAa,KACZ,EAAE,QAAQ,YAAY,EAAE,QAAQ,eACzC,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,EAAE,QAAQ,aACnB,EAAa;AAAA,QAAE,SAAS,oBAAI,IAAI;AAAA,QAAG,SAAS,oBAAI,IAAI;AAAA,QAAG,SAAS,oBAAI,IAAI;AAAA,MAAE,CAAC,GAC3E,EAAY,QAAQ,GACpB,EAAoB,IAAI;AAAA,IAE5B;AAEA,kBAAO,iBAAiB,WAAW,CAAO,GAC1C,MAAa,OAAO,oBAAoB,WAAW,CAAO;AAAA,EAC5D,GAAG;AAAA,IAAC;AAAA,IAAS;AAAA,IAAe;AAAA,IAAc;AAAA,IAAa;AAAA,EAAmB,CAAC;AAC7E"}
1
+ {"version":3,"file":"useKeyboardShortcuts.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useKeyboardShortcuts.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowUI } from '../context/FlowUIContext';\n\ninterface KeyboardShortcutActions {\n undo: () => void;\n redo: () => void;\n copy: () => void;\n cut: () => void;\n paste: () => void;\n deleteSelected: () => void;\n selectAll: () => void;\n group?: () => void;\n geoGroup?: () => void;\n ungroup?: () => void;\n bringToFront?: () => void;\n bringForward?: () => void;\n sendBackward?: () => void;\n sendToBack?: () => void;\n}\n\n/**\n * Registers global keyboard shortcuts for the flow editor.\n */\nexport function useKeyboardShortcuts(actions: KeyboardShortcutActions) {\n const { selection, setSelection, currentCanvas } = useFlowContext();\n const { editingNodeId, setToolMode, setPendingPlacement } = useFlowUI();\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n // Don't intercept when editing text in inputs\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;\n if (editingNodeId) return;\n\n const meta = e.metaKey || e.ctrlKey;\n\n if (meta && e.key === 'z' && !e.shiftKey) {\n e.preventDefault();\n actions.undo();\n } else if (meta && (e.key === 'Z' || (e.key === 'z' && e.shiftKey))) {\n e.preventDefault();\n actions.redo();\n } else if (meta && e.key === 'c') {\n e.preventDefault();\n actions.copy();\n } else if (meta && e.key === 'x') {\n e.preventDefault();\n actions.cut();\n } else if (meta && e.key === 'v') {\n // Let the native paste event inspect image clipboard data. Structured\n // Flow clipboard fallback is handled there when no image is present.\n return;\n } else if (meta && e.key === 'a') {\n e.preventDefault();\n actions.selectAll();\n } else if (meta && e.altKey && (e.key === 'g' || e.key === 'G')) {\n e.preventDefault();\n actions.geoGroup?.();\n } else if (meta && e.key === 'g' && !e.shiftKey && !e.altKey) {\n e.preventDefault();\n actions.group?.();\n } else if (meta && (e.key === 'G' || (e.key === 'g' && e.shiftKey)) && !e.altKey) {\n e.preventDefault();\n actions.ungroup?.();\n } else if (meta && e.shiftKey && e.key === 'ArrowUp') {\n e.preventDefault();\n actions.bringToFront?.();\n } else if (meta && !e.shiftKey && e.key === 'ArrowUp') {\n e.preventDefault();\n actions.bringForward?.();\n } else if (meta && !e.shiftKey && e.key === 'ArrowDown') {\n e.preventDefault();\n actions.sendBackward?.();\n } else if (meta && e.shiftKey && e.key === 'ArrowDown') {\n e.preventDefault();\n actions.sendToBack?.();\n } else if (e.key === 'Delete' || e.key === 'Backspace') {\n e.preventDefault();\n actions.deleteSelected();\n } else if (e.key === 'Escape') {\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n setToolMode('select');\n setPendingPlacement(null);\n }\n };\n\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [actions, editingNodeId, setSelection, setToolMode, setPendingPlacement]);\n}\n"],"mappings":";;;AAwBA,SAAgB,EAAqB,GAAkC;AACrE,QAAM,EAAE,WAAA,GAAW,cAAA,GAAc,eAAA,EAAA,IAAkB,EAAe,GAC5D,EAAE,eAAA,GAAe,aAAA,GAAa,qBAAA,EAAA,IAAwB,EAAU;AAEtE,EAAA,EAAA,MAAgB;AACd,UAAM,IAAA,CAAW,MAAqB;AAEpC,YAAM,IAAS,EAAE;AAEjB,UADI,EAAO,YAAY,WAAW,EAAO,YAAY,cAAc,EAAO,qBACtE,EAAe;AAEnB,YAAM,IAAO,EAAE,WAAW,EAAE;AAE5B,UAAI,KAAQ,EAAE,QAAQ,OAAO,CAAC,EAAE;AAC9B,UAAE,eAAe,GACjB,EAAQ,KAAK;AAAA,eACJ,MAAS,EAAE,QAAQ,OAAQ,EAAE,QAAQ,OAAO,EAAE;AACvD,UAAE,eAAe,GACjB,EAAQ,KAAK;AAAA,eACJ,KAAQ,EAAE,QAAQ;AAC3B,UAAE,eAAe,GACjB,EAAQ,KAAK;AAAA,eACJ,KAAQ,EAAE,QAAQ;AAC3B,UAAE,eAAe,GACjB,EAAQ,IAAI;AAAA,WACP;AAAA,YAAI,KAAQ,EAAE,QAAQ,IAG3B;AACK,QAAI,KAAQ,EAAE,QAAQ,OAC3B,EAAE,eAAe,GACjB,EAAQ,UAAU,KACT,KAAQ,EAAE,WAAW,EAAE,QAAQ,OAAO,EAAE,QAAQ,QACzD,EAAE,eAAe,GACjB,EAAQ,WAAW,KACV,KAAQ,EAAE,QAAQ,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,UACpD,EAAE,eAAe,GACjB,EAAQ,QAAQ,KACP,MAAS,EAAE,QAAQ,OAAQ,EAAE,QAAQ,OAAO,EAAE,aAAc,CAAC,EAAE,UACxE,EAAE,eAAe,GACjB,EAAQ,UAAU,KACT,KAAQ,EAAE,YAAY,EAAE,QAAQ,aACzC,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,CAAC,EAAE,YAAY,EAAE,QAAQ,aAC1C,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,CAAC,EAAE,YAAY,EAAE,QAAQ,eAC1C,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,KAAQ,EAAE,YAAY,EAAE,QAAQ,eACzC,EAAE,eAAe,GACjB,EAAQ,aAAa,KACZ,EAAE,QAAQ,YAAY,EAAE,QAAQ,eACzC,EAAE,eAAe,GACjB,EAAQ,eAAe,KACd,EAAE,QAAQ,aACnB,EAAa;AAAA,UAAE,SAAS,oBAAI,IAAI;AAAA,UAAG,SAAS,oBAAI,IAAI;AAAA,UAAG,SAAS,oBAAI,IAAI;AAAA,QAAE,CAAC,GAC3E,EAAY,QAAQ,GACpB,EAAoB,IAAI;AAAA;AAAA,IAE5B;AAEA,kBAAO,iBAAiB,WAAW,CAAO,GAC1C,MAAa,OAAO,oBAAoB,WAAW,CAAO;AAAA,EAC5D,GAAG;AAAA,IAAC;AAAA,IAAS;AAAA,IAAe;AAAA,IAAc;AAAA,IAAa;AAAA,EAAmB,CAAC;AAC7E"}
@@ -1,154 +1,154 @@
1
- import { DEFAULT_EDGE_DATA as C, DEFAULT_NODE_DATA as T } from "../constants.js";
2
- import { useFlowContext as U } from "../context/FlowContext.js";
1
+ import { DEFAULT_EDGE_DATA as U, DEFAULT_NODE_DATA as _ } from "../constants.js";
2
+ import { useFlowContext as F } from "../context/FlowContext.js";
3
3
  import { useFlowUI as O } from "../context/FlowUIContext.js";
4
- import { generateId as P } from "../nodes/nodeUtils.js";
5
- import { useCallback as R, useEffect as _ } from "react";
6
- var L = 150, S = 52, W = 100, F = 26;
7
- function G(N, D, a) {
8
- const h = N.nodes.filter((d) => d.data.isMindMapNode), c = new Map(h.map((d) => [d.id, d])), w = /* @__PURE__ */ new Map();
9
- for (const d of h) {
10
- const t = d.data.mindMapParentId;
11
- if (!t || !c.has(t)) continue;
12
- const e = w.get(t) ?? [];
13
- e.push(d), w.set(t, e);
4
+ import { generateId as R } from "../nodes/nodeUtils.js";
5
+ import { useCallback as L, useEffect as C } from "react";
6
+ var S = 150, z = 52, W = 100, G = 26;
7
+ function H(D, P, g) {
8
+ const a = D.nodes.filter((i) => i.data.isMindMapNode), m = new Map(a.map((i) => [i.id, i])), c = /* @__PURE__ */ new Map();
9
+ for (const i of a) {
10
+ const p = i.data.mindMapParentId;
11
+ if (!p || !m.has(p)) continue;
12
+ const t = c.get(p) ?? [];
13
+ t.push(i), c.set(p, t);
14
14
  }
15
- const I = c.get(D);
16
- if (!I) return /* @__PURE__ */ new Map();
17
- const m = /* @__PURE__ */ new Map();
18
- let y = I.position.y;
19
- const k = (d, t) => {
20
- const e = w.get(d.id) ?? [];
21
- let o;
22
- if (e.length === 0)
23
- o = y, y += 78;
15
+ const u = m.get(P);
16
+ if (!u) return /* @__PURE__ */ new Map();
17
+ const I = /* @__PURE__ */ new Map();
18
+ let b = u.position.y;
19
+ const x = (i, p) => {
20
+ const t = c.get(i.id) ?? [];
21
+ let e;
22
+ if (t.length === 0)
23
+ e = b, b += 78;
24
24
  else {
25
- const i = e.map((n) => k(n, t + 1));
26
- o = (i[0] + i[i.length - 1]) / 2;
25
+ const n = t.map((d) => x(d, p + 1));
26
+ e = (n[0] + n[n.length - 1]) / 2;
27
27
  }
28
- return m.set(d.id, {
29
- x: I.position.x + t * 250,
30
- y: o
31
- }), o;
28
+ return I.set(i.id, {
29
+ x: u.position.x + p * 250,
30
+ y: e
31
+ }), e;
32
32
  };
33
- if (k(I, 0), a) {
34
- const d = m.get(a.id);
35
- if (d) {
36
- const t = a.position.x - d.x, e = a.position.y - d.y;
37
- for (const [o, i] of m) m.set(o, {
38
- x: i.x + t,
39
- y: i.y + e
33
+ if (x(u, 0), g) {
34
+ const i = I.get(g.id);
35
+ if (i) {
36
+ const p = g.position.x - i.x, t = g.position.y - i.y;
37
+ for (const [e, n] of I) I.set(e, {
38
+ x: n.x + p,
39
+ y: n.y + t
40
40
  });
41
41
  }
42
42
  }
43
- return m;
43
+ return I;
44
44
  }
45
- function j() {
46
- const { setEditingNodeId: N, focusOnRect: D } = O(), { currentCanvas: a, currentCanvasId: h, selection: c, setSelection: w, setDoc: I } = U(), m = R((t) => {
45
+ function q() {
46
+ const { setEditingNodeId: D, focusOnRect: P, autoFocus: g } = O(), { currentCanvas: a, currentCanvasId: m, selection: c, setSelection: u, setDoc: I } = F(), b = L((t) => {
47
47
  t && window.setTimeout(() => {
48
- D(t.position.x, t.position.y, t.width, t.height, {
48
+ P(t.position.x, t.position.y, t.width, t.height, {
49
49
  padding: 80,
50
50
  preserveZoom: !0,
51
51
  duration: 280
52
52
  });
53
53
  }, 0);
54
- }, [D]), y = R((t) => {
55
- const e = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null, o = e ? a.nodes.find((l) => l.id === e) : void 0;
56
- if (!o) return;
57
- const i = t === "child" ? o.id : o.data.mindMapParentId;
58
- if (t !== "child" && !i) return;
59
- const n = P("mind"), x = {
60
- id: n,
54
+ }, [P]), x = L((t) => {
55
+ const e = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null, n = e ? a.nodes.find((f) => f.id === e) : void 0;
56
+ if (!n) return;
57
+ const d = t === "child" ? n.id : n.data.mindMapParentId;
58
+ if (t !== "child" && !d) return;
59
+ const s = R("mind"), A = {
60
+ id: s,
61
61
  type: "shapeRoundRect",
62
62
  position: {
63
- x: o.position.x + L + W,
64
- y: o.position.y + S + F
63
+ x: n.position.x + S + W,
64
+ y: n.position.y + z + G
65
65
  },
66
- width: L,
67
- height: S,
68
- zIndex: Math.max(0, ...a.nodes.map((l) => l.zIndex ?? 0)) + 1,
66
+ width: S,
67
+ height: z,
68
+ zIndex: Math.max(0, ...a.nodes.map((f) => f.zIndex ?? 0)) + 1,
69
69
  data: {
70
- ...T,
70
+ ..._,
71
71
  label: t === "child" ? "子主题" : "主题",
72
72
  fill: "#ffffff",
73
73
  stroke: "#6366f1",
74
74
  strokeWidth: 2,
75
75
  isMindMapNode: !0,
76
- mindMapParentId: i
76
+ mindMapParentId: d
77
77
  }
78
78
  };
79
- I((l) => {
80
- const f = l.canvases[h];
81
- if (!f) return l;
82
- const g = (() => {
83
- let s = o;
84
- const E = new Map(f.nodes.map((z) => [z.id, z]));
85
- for (; s.data.mindMapParentId && E.has(s.data.mindMapParentId); ) s = E.get(s.data.mindMapParentId);
86
- return s.id;
87
- })(), b = f.nodes.map((s) => s.id === o.id && !s.data.isMindMapNode ? {
88
- ...s,
79
+ I((f) => {
80
+ const w = f.canvases[m];
81
+ if (!w) return f;
82
+ const y = (() => {
83
+ let o = n;
84
+ const N = new Map(w.nodes.map((T) => [T.id, T]));
85
+ for (; o.data.mindMapParentId && N.has(o.data.mindMapParentId); ) o = N.get(o.data.mindMapParentId);
86
+ return o.id;
87
+ })(), E = w.nodes.map((o) => o.id === n.id && !o.data.isMindMapNode ? {
88
+ ...o,
89
89
  data: {
90
- ...s.data,
90
+ ...o.data,
91
91
  isMindMapNode: !0
92
92
  }
93
- } : s), u = b.findIndex((s) => s.id === o.id), p = t === "sibling-before" ? u : u + 1;
94
- b.splice(Math.max(0, p), 0, x);
95
- const A = {
96
- ...f,
97
- nodes: b,
98
- edges: [...f.edges, {
99
- id: P("edge"),
100
- source: i,
101
- target: n,
93
+ } : o), h = E.findIndex((o) => o.id === n.id), l = t === "sibling-before" ? h : h + 1;
94
+ E.splice(Math.max(0, l), 0, A);
95
+ const k = {
96
+ ...w,
97
+ nodes: E,
98
+ edges: [...w.edges, {
99
+ id: R("edge"),
100
+ source: d,
101
+ target: s,
102
102
  type: "simplebezier",
103
103
  data: {
104
- ...C,
104
+ ...U,
105
105
  markerEnd: "none",
106
106
  strokeColor: "#94a3b8",
107
107
  strokeWidth: 1.5
108
108
  }
109
109
  }]
110
- }, r = t === "child" ? o : f.nodes.find((s) => s.id === i) ?? o, M = G(A, g, {
110
+ }, r = t === "child" ? n : w.nodes.find((o) => o.id === d) ?? n, M = H(k, y, {
111
111
  id: r.id,
112
112
  position: r.position
113
113
  });
114
- return A.nodes = A.nodes.map((s) => {
115
- const E = M.get(s.id);
116
- return E ? {
117
- ...s,
118
- position: E
119
- } : s;
114
+ return k.nodes = k.nodes.map((o) => {
115
+ const N = M.get(o.id);
116
+ return N ? {
117
+ ...o,
118
+ position: N
119
+ } : o;
120
120
  }), {
121
- ...l,
121
+ ...f,
122
122
  canvases: {
123
- ...l.canvases,
124
- [h]: A
123
+ ...f.canvases,
124
+ [m]: k
125
125
  }
126
126
  };
127
- }), w({
128
- nodeIds: /* @__PURE__ */ new Set([n]),
127
+ }), u({
128
+ nodeIds: /* @__PURE__ */ new Set([s]),
129
129
  edgeIds: /* @__PURE__ */ new Set(),
130
130
  lineIds: /* @__PURE__ */ new Set()
131
131
  });
132
132
  }, [
133
133
  c,
134
134
  a,
135
- h,
135
+ m,
136
136
  I,
137
- w
138
- ]), k = R(() => {
137
+ u
138
+ ]), i = L(() => {
139
139
  if (c.nodeIds.size !== 0) return !1;
140
- const t = P("mind"), e = Math.max(0, ...a.nodes.map((i) => i.zIndex ?? 0)), o = {
140
+ const t = R("mind"), e = Math.max(0, ...a.nodes.map((d) => d.zIndex ?? 0)), n = {
141
141
  id: t,
142
142
  type: "shapeRoundRect",
143
143
  position: {
144
144
  x: 120,
145
145
  y: 120
146
146
  },
147
- width: L,
148
- height: S,
147
+ width: S,
148
+ height: z,
149
149
  zIndex: e + 1,
150
150
  data: {
151
- ...T,
151
+ ..._,
152
152
  label: "中心主题",
153
153
  fill: "#eef2ff",
154
154
  stroke: "#4f46e5",
@@ -156,19 +156,19 @@ function j() {
156
156
  isMindMapNode: !0
157
157
  }
158
158
  };
159
- return I((i) => {
160
- const n = i.canvases[h];
161
- return n ? {
162
- ...i,
159
+ return I((d) => {
160
+ const s = d.canvases[m];
161
+ return s ? {
162
+ ...d,
163
163
  canvases: {
164
- ...i.canvases,
165
- [h]: {
166
- ...n,
167
- nodes: [...n.nodes, o]
164
+ ...d.canvases,
165
+ [m]: {
166
+ ...s,
167
+ nodes: [...s.nodes, n]
168
168
  }
169
169
  }
170
- } : i;
171
- }), w({
170
+ } : d;
171
+ }), u({
172
172
  nodeIds: /* @__PURE__ */ new Set([t]),
173
173
  edgeIds: /* @__PURE__ */ new Set(),
174
174
  lineIds: /* @__PURE__ */ new Set()
@@ -176,50 +176,54 @@ function j() {
176
176
  }, [
177
177
  c,
178
178
  a,
179
- h,
179
+ m,
180
180
  I,
181
- w
182
- ]), d = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null;
183
- _(() => {
184
- if (!d) return;
185
- const t = a.nodes.find((o) => o.id === d);
181
+ u
182
+ ]), p = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null;
183
+ C(() => {
184
+ if (!g || !p) return;
185
+ const t = a.nodes.find((n) => n.id === p);
186
186
  if (!t) return;
187
- const e = window.setTimeout(() => m(t), 20);
187
+ const e = window.setTimeout(() => b(t), 20);
188
188
  return () => window.clearTimeout(e);
189
- }, [d, m]), _(() => {
189
+ }, [
190
+ g,
191
+ p,
192
+ b
193
+ ]), C(() => {
190
194
  const t = (e) => {
191
- const o = e.target;
192
- if (o.matches("input, textarea, select, .flow-label-editor") || o.isContentEditable) return;
193
- const i = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null, n = i ? a.nodes.find((l) => l.id === i) : void 0, x = () => {
195
+ const n = e.target;
196
+ if (n.matches("input, textarea, select, .flow-label-editor") || n.isContentEditable) return;
197
+ const d = c.nodeIds.size === 1 ? [...c.nodeIds][0] : null, s = d ? a.nodes.find((f) => f.id === d) : void 0, A = () => {
194
198
  e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation();
195
199
  };
196
200
  if (e.key === "Tab")
197
- x(), n ? y("child") : k();
198
- else if (e.key === "Enter" && n)
199
- x(), y(e.shiftKey ? "sibling-before" : "sibling-after");
200
- else if ((e.key === " " || e.code === "Space") && n)
201
- x(), N(n.id);
202
- else if (n && [
201
+ A(), s ? x("child") : i();
202
+ else if (e.key === "Enter" && s)
203
+ A(), x(e.shiftKey ? "sibling-before" : "sibling-after");
204
+ else if ((e.key === " " || e.code === "Space") && s)
205
+ A(), D(s.id);
206
+ else if (s && [
203
207
  "ArrowUp",
204
208
  "ArrowDown",
205
209
  "ArrowLeft",
206
210
  "ArrowRight"
207
211
  ].includes(e.key)) {
208
- const l = new Map(a.nodes.map((p) => [p.id, p])), f = a.nodes.filter((p) => p.data.isMindMapNode && p.data.mindMapParentId === n.data.mindMapParentId), g = f.findIndex((p) => p.id === n.id), b = a.nodes.filter((p) => p.data.mindMapParentId === n.id);
209
- let u;
210
- if (e.key === "ArrowLeft" && n.data.mindMapParentId ? u = l.get(n.data.mindMapParentId) : e.key === "ArrowRight" ? u = b[0] : e.key === "ArrowUp" && g > 0 ? u = f[g - 1] : e.key === "ArrowDown" && g >= 0 && g < f.length - 1 && (u = f[g + 1]), !u) {
211
- const p = n.position.x + n.width / 2, A = n.position.y + n.height / 2;
212
- u = a.nodes.filter((r) => r.id !== n.id && r.type !== "animAnchor").map((r) => {
213
- const M = r.position.x + r.width / 2 - p, s = r.position.y + r.height / 2 - A;
212
+ const f = new Map(a.nodes.map((l) => [l.id, l])), w = a.nodes.filter((l) => l.data.isMindMapNode && l.data.mindMapParentId === s.data.mindMapParentId), y = w.findIndex((l) => l.id === s.id), E = a.nodes.filter((l) => l.data.mindMapParentId === s.id);
213
+ let h;
214
+ if (e.key === "ArrowLeft" && s.data.mindMapParentId ? h = f.get(s.data.mindMapParentId) : e.key === "ArrowRight" ? h = E[0] : e.key === "ArrowUp" && y > 0 ? h = w[y - 1] : e.key === "ArrowDown" && y >= 0 && y < w.length - 1 && (h = w[y + 1]), !h) {
215
+ const l = s.position.x + s.width / 2, k = s.position.y + s.height / 2;
216
+ h = a.nodes.filter((r) => r.id !== s.id && r.type !== "animAnchor").map((r) => {
217
+ const M = r.position.x + r.width / 2 - l, o = r.position.y + r.height / 2 - k;
214
218
  return {
215
219
  node: r,
216
- inDirection: e.key === "ArrowLeft" ? M < 0 : e.key === "ArrowRight" ? M > 0 : e.key === "ArrowUp" ? s < 0 : s > 0,
217
- score: (e.key === "ArrowLeft" || e.key === "ArrowRight" ? Math.abs(M) : Math.abs(s)) + (e.key === "ArrowLeft" || e.key === "ArrowRight" ? Math.abs(s) : Math.abs(M)) * 1.75
220
+ inDirection: e.key === "ArrowLeft" ? M < 0 : e.key === "ArrowRight" ? M > 0 : e.key === "ArrowUp" ? o < 0 : o > 0,
221
+ score: (e.key === "ArrowLeft" || e.key === "ArrowRight" ? Math.abs(M) : Math.abs(o)) + (e.key === "ArrowLeft" || e.key === "ArrowRight" ? Math.abs(o) : Math.abs(M)) * 1.75
218
222
  };
219
223
  }).filter((r) => r.inDirection).sort((r, M) => r.score - M.score)[0]?.node;
220
224
  }
221
- u && (x(), w({
222
- nodeIds: /* @__PURE__ */ new Set([u.id]),
225
+ h && (A(), u({
226
+ nodeIds: /* @__PURE__ */ new Set([h.id]),
223
227
  edgeIds: /* @__PURE__ */ new Set(),
224
228
  lineIds: /* @__PURE__ */ new Set()
225
229
  }));
@@ -229,14 +233,14 @@ function j() {
229
233
  }, [
230
234
  c,
231
235
  a,
232
- y,
233
- k,
234
- N,
235
- w
236
+ x,
237
+ i,
238
+ D,
239
+ u
236
240
  ]);
237
241
  }
238
242
  export {
239
- j as useMindMap
243
+ q as useMindMap
240
244
  };
241
245
 
242
246
  //# sourceMappingURL=useMindMap.js.map