dishui 0.0.64 → 0.0.65

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 (177) hide show
  1. package/dist/components/Badge/index.js +12 -9
  2. package/dist/components/Badge/index.js.map +1 -1
  3. package/dist/components/Button/index.js +43 -40
  4. package/dist/components/Button/index.js.map +1 -1
  5. package/dist/components/Card/index.d.ts +11 -0
  6. package/dist/components/Card/index.js +62 -37
  7. package/dist/components/Card/index.js.map +1 -1
  8. package/dist/components/Chart/Chart.js.map +1 -1
  9. package/dist/components/Checkbox/index.js +32 -30
  10. package/dist/components/Checkbox/index.js.map +1 -1
  11. package/dist/components/Demo/index.js.map +1 -1
  12. package/dist/components/EmptyState/index.d.ts +4 -1
  13. package/dist/components/EmptyState/index.js +3 -3
  14. package/dist/components/EmptyState/index.js.map +1 -1
  15. package/dist/components/FileUploader/DropZone.js.map +1 -1
  16. package/dist/components/FileUploader/FileItem.js.map +1 -1
  17. package/dist/components/FileUploader/FileUploader.js.map +1 -1
  18. package/dist/components/FileUploader/UploadQueue.js.map +1 -1
  19. package/dist/components/Input/index.js +30 -30
  20. package/dist/components/Input/index.js.map +1 -1
  21. package/dist/components/Label/index.js +41 -40
  22. package/dist/components/Label/index.js.map +1 -1
  23. package/dist/components/List/index.js +47 -32
  24. package/dist/components/List/index.js.map +1 -1
  25. package/dist/components/Markdown/Markdown.js +61 -57
  26. package/dist/components/Markdown/Markdown.js.map +1 -1
  27. package/dist/components/Markdown/markdownComponents.js +49 -49
  28. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  29. package/dist/components/Modal/index.d.ts +7 -3
  30. package/dist/components/Modal/index.js +77 -65
  31. package/dist/components/Modal/index.js.map +1 -1
  32. package/dist/components/Page/index.d.ts +58 -0
  33. package/dist/components/Page/index.js +74 -0
  34. package/dist/components/Page/index.js.map +1 -0
  35. package/dist/components/PageHeader/index.js.map +1 -1
  36. package/dist/components/Select/index.js +0 -3
  37. package/dist/components/Select/index.js.map +1 -1
  38. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  39. package/dist/components/StatCard/index.d.ts +3 -1
  40. package/dist/components/StatCard/index.js +39 -11
  41. package/dist/components/StatCard/index.js.map +1 -1
  42. package/dist/components/Table/index.js +103 -85
  43. package/dist/components/Table/index.js.map +1 -1
  44. package/dist/components/Tabs/index.d.ts +19 -5
  45. package/dist/components/Tabs/index.js +32 -13
  46. package/dist/components/Tabs/index.js.map +1 -1
  47. package/dist/components/Tree/Tree.js.map +1 -1
  48. package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
  49. package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
  50. package/dist/components/pro/CodeEditor/editors/CodeEditor.js +141 -134
  51. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  52. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js +81 -78
  53. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  54. package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
  55. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
  56. package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
  57. package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
  58. package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
  59. package/dist/components/pro/CodeEditor/themes.js +59 -59
  60. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  61. package/dist/components/pro/DataTable/DataTable.js +49 -48
  62. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  63. package/dist/components/pro/DataTable/Filters.js +42 -42
  64. package/dist/components/pro/DataTable/Filters.js.map +1 -1
  65. package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
  66. package/dist/components/pro/DataTable/PivotView.js +35 -32
  67. package/dist/components/pro/DataTable/PivotView.js.map +1 -1
  68. package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
  69. package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
  70. package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
  71. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  72. package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
  73. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  74. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  75. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  76. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  77. package/dist/components/pro/DataTable/tanstack-table.js +37 -37
  78. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  79. package/dist/components/pro/FileExplorer/Breadcrumb.js +53 -53
  80. package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
  81. package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
  82. package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
  83. package/dist/components/pro/FileExplorer/FileIcon.js +22 -22
  84. package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
  85. package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
  86. package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
  87. package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
  88. package/dist/components/pro/Flow/Flow.js +496 -494
  89. package/dist/components/pro/Flow/Flow.js.map +1 -1
  90. package/dist/components/pro/Flow/FlowCanvas.js +916 -917
  91. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  92. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  93. package/dist/components/pro/Flow/edges/EdgeRenderer.js +59 -59
  94. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  95. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  96. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
  97. package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
  98. package/dist/components/pro/Flow/hooks/useLayoutActions.js +9 -11
  99. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  100. package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
  101. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  102. package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
  103. package/dist/components/pro/Flow/lines/FreehandTool.js +9 -9
  104. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  105. package/dist/components/pro/Flow/lines/LineRenderer.js +5 -5
  106. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  107. package/dist/components/pro/Flow/nodes/DataNodeView.js +113 -93
  108. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  109. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  110. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  111. package/dist/components/pro/Flow/nodes/Model3DView.js +1 -1
  112. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  113. package/dist/components/pro/Flow/nodes/NodeRenderer.js +118 -118
  114. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  115. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
  116. package/dist/components/pro/Flow/nodes/shapes.js +1 -3
  117. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  118. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
  119. package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
  120. package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
  121. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
  122. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
  123. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  124. package/dist/components/pro/Flow/panels/FlowToolbar.js +97 -97
  125. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  126. package/dist/components/pro/Flow/panels/InspectorPanel.js +57 -57
  127. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  128. package/dist/components/pro/Flow/panels/OutlinePanel.js +26 -22
  129. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  130. package/dist/components/pro/Flow/panels/PresentationMode.js +18 -16
  131. package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
  132. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
  133. package/dist/components/pro/Flow/panels/ShapePalette.js +109 -104
  134. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  135. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  136. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  137. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  138. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  139. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  140. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  141. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  142. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  143. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  144. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  145. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  146. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  147. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  148. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  149. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  150. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  151. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  152. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  153. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  154. package/dist/contexts/AppContext.js.map +1 -1
  155. package/dist/dishui.css +1 -1
  156. package/dist/hooks/useTableColumns.js +7 -8
  157. package/dist/hooks/useTableColumns.js.map +1 -1
  158. package/dist/index.d.ts +2 -0
  159. package/dist/index.js +227 -221
  160. package/dist/layouts/MainLayout.js +22 -22
  161. package/dist/layouts/MainLayout.js.map +1 -1
  162. package/dist/layouts/Navbar.js.map +1 -1
  163. package/dist/layouts/Sidebar.js +94 -73
  164. package/dist/layouts/Sidebar.js.map +1 -1
  165. package/dist/layouts/headbar/Headbar.js.map +1 -1
  166. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  167. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  168. package/dist/layouts/headbar/HeadbarThemeSwitcher.js +11 -11
  169. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  170. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  171. package/dist/utils/i18n.js +10 -10
  172. package/dist/utils/i18n.js.map +1 -1
  173. package/dist/utils/menu.js.map +1 -1
  174. package/dist/utils/routerBuilder.js +17 -15
  175. package/dist/utils/routerBuilder.js.map +1 -1
  176. package/dist/utils/themes.js.map +1 -1
  177. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"FlowUIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */\n placementSnap: boolean;\n setPlacementSnap: (v: boolean) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [placementSnap, setPlacementSnap] = useState(true);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n placementSnap, setPlacementSnap,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, placementSnap, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FlowUIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */\n placementSnap: boolean;\n setPlacementSnap: (v: boolean) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [placementSnap, setPlacementSnap] = useState(true);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n placementSnap, setPlacementSnap,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, placementSnap, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- import { resolveThemeColor as E } from "../utils/themeColor.js";
2
- import { drawDashedPath as y } from "../utils/dashedLine.js";
3
- import { buildEdgePath as T, getPathCenter as B, resolveEdgeEndpoints as M } from "./edgePaths.js";
4
- import { angleBetween as k, drawMarker as _ } from "./edgeMarkers.js";
5
- import { Container as v, Graphics as x, Text as L, TextStyle as O } from "pixi.js";
6
- function P(e, l, a = 2) {
1
+ import { resolveThemeColor as _ } from "../utils/themeColor.js";
2
+ import { drawDashedPath as x } from "../utils/dashedLine.js";
3
+ import { buildEdgePath as v, getPathCenter as E, resolveEdgeEndpoints as T } from "./edgePaths.js";
4
+ import { angleBetween as C, drawMarker as w } from "./edgeMarkers.js";
5
+ import { Container as k, Graphics as u, Text as B, TextStyle as M } from "pixi.js";
6
+ function L(e, l, a = 2) {
7
7
  if (!(!e || e === "solid"))
8
8
  return e === "dynamic" ? [a * 4, a * 3] : [e === "dotted" ? a : a * 3, l === "dense" ? a : l === "sparse" ? a * 4 : a * 2];
9
9
  }
10
- var R = class {
10
+ var F = class {
11
11
  world;
12
12
  edgeLayer;
13
13
  edges = /* @__PURE__ */ new Map();
@@ -16,84 +16,84 @@ var R = class {
16
16
  this._dynamicOffset = (this._dynamicOffset + e * 0.06) % 1e3;
17
17
  }
18
18
  constructor(e) {
19
- this.world = e, this.edgeLayer = new v({ label: "edges" }), this.world.addChildAt(this.edgeLayer, 0);
19
+ this.world = e, this.edgeLayer = new k({ label: "edges" }), this.world.addChildAt(this.edgeLayer, 0);
20
20
  }
21
- sync(e, l, a, i, c) {
21
+ sync(e, l, a, i, h) {
22
22
  const g = /* @__PURE__ */ new Set();
23
- for (const r of e) {
24
- g.add(r.id);
25
- const t = M(r, l);
23
+ for (const o of e) {
24
+ g.add(o.id);
25
+ const t = T(o, l);
26
26
  if (!t) continue;
27
- let h = this.edges.get(r.id);
28
- h || (h = this._createEdge(r), this.edges.set(r.id, h)), this._updateEdge(h, r, t, a.has(r.id), i === r.id, c?.presentation ?? !1);
27
+ let f = this.edges.get(o.id);
28
+ f || (f = this._createEdge(o), this.edges.set(o.id, f)), this._updateEdge(f, o, t, a.has(o.id), i === o.id, h?.presentation ?? !1);
29
29
  }
30
- for (const [r, t] of this.edges) g.has(r) || (this.edgeLayer.removeChild(t.container), t.container.destroy({ children: !0 }), this.edges.delete(r));
30
+ for (const [o, t] of this.edges) g.has(o) || (this.edgeLayer.removeChild(t.container), t.container.destroy({ children: !0 }), this.edges.delete(o));
31
31
  }
32
32
  _createEdge(e) {
33
- const l = new v({ label: `edge-${e.id}` }), a = new x();
33
+ const l = new k({ label: `edge-${e.id}` }), a = new u();
34
34
  a.label = "edge-hitarea", a.eventMode = "static", a.cursor = "pointer", a.alpha = 0, l.addChild(a);
35
- const i = new x();
35
+ const i = new u();
36
36
  i.label = "edge-line", l.addChild(i);
37
- const c = new x();
38
- return c.label = "edge-animation", l.addChild(c), this.edgeLayer.addChild(l), {
37
+ const h = new u();
38
+ return h.label = "edge-animation", l.addChild(h), this.edgeLayer.addChild(l), {
39
39
  container: l,
40
40
  line: i,
41
- animation: c,
41
+ animation: h,
42
42
  hitArea: a,
43
43
  labelBg: null,
44
44
  label: null,
45
45
  edgeId: e.id
46
46
  };
47
47
  }
48
- _updateEdge(e, l, a, i, c, g) {
49
- const { line: r, animation: t, hitArea: h } = e, o = l.data, m = i ? "#3b82f6" : E(o.strokeColor, "#374151"), f = o.strokeWidth ?? 2, s = T(l.type, a, o.waypoints, o.bezierControls);
50
- if (r.clear(), this._drawPath(r, s, m, f, o.lineStyle, o.dashDensity), t.clear(), g && o.animated) {
51
- const n = [Math.max(18, f * 12), Math.max(90, f * 45)];
52
- y(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
48
+ _updateEdge(e, l, a, i, h, g) {
49
+ const { line: o, animation: t, hitArea: f } = e, r = l.data, y = i ? "#3b82f6" : _(r.strokeColor, "#374151"), m = r.strokeWidth ?? 2, s = v(l.type, a, r.waypoints, r.bezierControls);
50
+ if (o.clear(), this._drawPath(o, s, y, m, r.lineStyle, r.dashDensity), t.clear(), g && r.animated) {
51
+ const n = [Math.max(18, m * 12), Math.max(90, m * 45)];
52
+ x(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
53
53
  color: 6333946,
54
- width: f + 5,
54
+ width: m + 5,
55
55
  alpha: 0.18,
56
56
  cap: "round"
57
- }), y(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
57
+ }), x(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
58
58
  color: 3718648,
59
- width: f + 2,
59
+ width: m + 2,
60
60
  alpha: 0.55,
61
61
  cap: "round"
62
- }), y(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
62
+ }), x(t, s, n, -this._dynamicOffset * 2.2), t.stroke({
63
63
  color: 16777215,
64
- width: Math.max(1, f * 0.7),
64
+ width: Math.max(1, m * 0.7),
65
65
  alpha: 0.9,
66
66
  cap: "round"
67
67
  });
68
68
  }
69
- if (o.markerStart && o.markerStart !== "none" && s.length >= 2) {
70
- const n = s[0], d = s[1], b = k(d.type === "C" ? d.cp1x : d.x, d.type === "C" ? d.cp1y : d.y, n.x, n.y);
71
- _(r, o.markerStart, n.x, n.y, b, m);
69
+ if (r.markerStart && r.markerStart !== "none" && s.length >= 2) {
70
+ const n = s[0], c = s[1], b = c.type === "C" ? c.cp1x : c.x, d = c.type === "C" ? c.cp1y : c.y, p = C(b, d, n.x, n.y);
71
+ w(o, r.markerStart, n.x, n.y, p, y);
72
72
  }
73
- if (o.markerEnd && o.markerEnd !== "none" && s.length >= 2) {
74
- const n = s[s.length - 1], d = k(n.type === "C" ? n.cp2x : s[s.length - 2].x, n.type === "C" ? n.cp2y : s[s.length - 2].y, n.x, n.y);
75
- _(r, o.markerEnd, n.x, n.y, d, m);
73
+ if (r.markerEnd && r.markerEnd !== "none" && s.length >= 2) {
74
+ const n = s[s.length - 1], c = n.type === "C" ? n.cp2x : s[s.length - 2].x, b = n.type === "C" ? n.cp2y : s[s.length - 2].y, d = C(c, b, n.x, n.y);
75
+ w(o, r.markerEnd, n.x, n.y, d, y);
76
76
  }
77
- if (h.clear(), this._drawPath(h, s, "#000000", Math.max(f + 10, 14), "solid"), h.alpha = 1e-3, o.labelText) {
78
- const n = B(s);
77
+ if (f.clear(), this._drawPath(f, s, "#000000", Math.max(m + 10, 14), "solid"), f.alpha = 1e-3, r.labelText) {
78
+ const n = E(s);
79
79
  if (!e.label) {
80
- const p = new x();
81
- p.label = "edge-label-bg", e.container.addChild(p), e.labelBg = p;
82
- const u = new O({
83
- fontFamily: o.labelFontFamily ?? "system-ui, -apple-system, sans-serif",
84
- fontSize: o.labelFontSize ?? 12,
85
- fill: m
80
+ const d = new u();
81
+ d.label = "edge-label-bg", e.container.addChild(d), e.labelBg = d;
82
+ const p = new M({
83
+ fontFamily: r.labelFontFamily ?? "system-ui, -apple-system, sans-serif",
84
+ fontSize: r.labelFontSize ?? 12,
85
+ fill: y
86
86
  });
87
- e.label = new L({
88
- text: o.labelText,
89
- style: u
87
+ e.label = new B({
88
+ text: r.labelText,
89
+ style: p
90
90
  }), e.label.anchor.set(0.5, 0.5), e.container.addChild(e.label);
91
91
  }
92
- e.label.text = o.labelText;
93
- const d = n.x, b = n.y - 10;
94
- if (e.label.position.set(d, b), e.label.style.fill = m, e.labelBg) {
95
- const C = e.label.width + 10, w = e.label.height + 4;
96
- e.labelBg.clear(), e.labelBg.roundRect(d - C / 2, b - w / 2, C, w, 4).fill({
92
+ e.label.text = r.labelText;
93
+ const c = n.x, b = n.y - 10;
94
+ if (e.label.position.set(c, b), e.label.style.fill = y, e.labelBg) {
95
+ const d = e.label.width + 10, p = e.label.height + 4;
96
+ e.labelBg.clear(), e.labelBg.roundRect(c - d / 2, b - p / 2, d, p, 4).fill({
97
97
  color: 16777215,
98
98
  alpha: 0.92
99
99
  });
@@ -101,15 +101,16 @@ var R = class {
101
101
  } else
102
102
  e.label && (e.label.text = ""), e.labelBg && e.labelBg.clear();
103
103
  }
104
- _drawPath(e, l, a, i, c, g) {
105
- const r = P(c, g, i);
106
- if (r)
107
- y(e, l, r, c === "dynamic" ? this._dynamicOffset : 0), e.stroke({
104
+ _drawPath(e, l, a, i, h, g) {
105
+ const o = L(h, g, i);
106
+ if (o) {
107
+ const t = h === "dynamic" ? this._dynamicOffset : 0;
108
+ x(e, l, o, t), e.stroke({
108
109
  color: a,
109
110
  width: i,
110
111
  cap: "round"
111
112
  });
112
- else {
113
+ } else {
113
114
  for (const t of l) switch (t.type) {
114
115
  case "M":
115
116
  e.moveTo(t.x, t.y);
@@ -122,7 +123,6 @@ var R = class {
122
123
  break;
123
124
  case "Q":
124
125
  e.quadraticCurveTo(t.cp1x, t.cp1y, t.x, t.y);
125
- break;
126
126
  }
127
127
  e.stroke({
128
128
  color: a,
@@ -136,7 +136,7 @@ var R = class {
136
136
  }
137
137
  };
138
138
  export {
139
- R as EdgeRenderer
139
+ F as EdgeRenderer
140
140
  };
141
141
 
142
142
  //# sourceMappingURL=EdgeRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EdgeRenderer.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/EdgeRenderer.ts"],"sourcesContent":["import { Container, Graphics, Text, TextStyle } from 'pixi.js';\nimport type { FlowEdge, FlowNode } from '../types';\nimport { buildEdgePath, getPathCenter, resolveEdgeEndpoints, type PathSegment, type EdgeEndpoints } from './edgePaths';\nimport { drawMarker, angleBetween } from './edgeMarkers';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\ninterface EdgeDisplay {\n container: Container;\n line: Graphics;\n animation: Graphics;\n hitArea: Graphics;\n labelBg: Graphics | null;\n label: Text | null;\n edgeId: string;\n}\n\nfunction getDashPattern(style?: string, density?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n const base = style === 'dotted' ? width : width * 3;\n const gap = density === 'dense' ? width : density === 'sparse' ? width * 4 : width * 2;\n return [base, gap];\n}\n\n/**\n * Manages PixiJS display objects for all edges.\n */\nexport class EdgeRenderer {\n private world: Container;\n private edgeLayer: Container;\n private edges = new Map<string, EdgeDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.edgeLayer = new Container({ label: 'edges' });\n // Edges below nodes\n this.world.addChildAt(this.edgeLayer, 0);\n }\n\n sync(\n flowEdges: FlowEdge[],\n nodeMap: Map<string, FlowNode>,\n selectedIds: Set<string>,\n hoveredId: string | null,\n options?: { presentation?: boolean },\n ): void {\n const seen = new Set<string>();\n\n for (const edge of flowEdges) {\n seen.add(edge.id);\n const endpoints = resolveEdgeEndpoints(edge, nodeMap);\n if (!endpoints) continue;\n\n let display = this.edges.get(edge.id);\n if (!display) {\n display = this._createEdge(edge);\n this.edges.set(edge.id, display);\n }\n this._updateEdge(\n display,\n edge,\n endpoints,\n selectedIds.has(edge.id),\n hoveredId === edge.id,\n options?.presentation ?? false,\n );\n }\n\n for (const [id, display] of this.edges) {\n if (!seen.has(id)) {\n this.edgeLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.edges.delete(id);\n }\n }\n }\n\n private _createEdge(edge: FlowEdge): EdgeDisplay {\n const container = new Container({ label: `edge-${edge.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'edge-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0;\n container.addChild(hitArea);\n\n const line = new Graphics();\n line.label = 'edge-line';\n container.addChild(line);\n\n const animation = new Graphics();\n animation.label = 'edge-animation';\n container.addChild(animation);\n\n this.edgeLayer.addChild(container);\n return { container, line, animation, hitArea, labelBg: null, label: null, edgeId: edge.id };\n }\n\n private _updateEdge(\n display: EdgeDisplay,\n edge: FlowEdge,\n endpoints: EdgeEndpoints,\n selected: boolean,\n hovered: boolean,\n presentation: boolean,\n ): void {\n const { line, animation, hitArea } = display;\n const data = edge.data;\n const color = selected ? '#3b82f6' : resolveThemeColor(data.strokeColor, '#374151');\n const width = data.strokeWidth ?? 2;\n\n const segments = buildEdgePath(edge.type, endpoints, data.waypoints, data.bezierControls);\n\n // Draw visible line\n line.clear();\n this._drawPath(line, segments, color, width, data.lineStyle, data.dashDensity);\n\n // Presentation animation: a bright gradient-like pulse travels from source\n // to target. A short dashed segment plus soft outer stroke gives the pulse\n // a leading highlight and fading tail without requiring SVG filters.\n animation.clear();\n if (presentation && data.animated) {\n const pattern = [Math.max(18, width * 12), Math.max(90, width * 45)];\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x60a5fa, width: width + 5, alpha: 0.18, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x38bdf8, width: width + 2, alpha: 0.55, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0xffffff, width: Math.max(1, width * 0.7), alpha: 0.9, cap: 'round' as const });\n }\n\n // Draw markers — use curve tangent for accurate arrow direction\n if (data.markerStart && data.markerStart !== 'none' && segments.length >= 2) {\n const tip = segments[0];\n const next = segments[1];\n // For curves the tangent at t=0 is tip→cp1; for lines it's tip→next\n const fromX = next.type === 'C' ? next.cp1x! : next.x;\n const fromY = next.type === 'C' ? next.cp1y! : next.y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerStart, tip.x, tip.y, angle, color);\n }\n if (data.markerEnd && data.markerEnd !== 'none' && segments.length >= 2) {\n const tip = segments[segments.length - 1];\n // For curves the tangent at t=1 is cp2→endpoint\n const fromX = tip.type === 'C' ? tip.cp2x! : segments[segments.length - 2].x;\n const fromY = tip.type === 'C' ? tip.cp2y! : segments[segments.length - 2].y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerEnd, tip.x, tip.y, angle, color);\n }\n\n // Wider invisible hit area\n hitArea.clear();\n this._drawPath(hitArea, segments, '#000000', Math.max(width + 10, 14), 'solid');\n hitArea.alpha = 0.001;\n\n // Edge label\n if (data.labelText) {\n const center = getPathCenter(segments);\n if (!display.label) {\n // Background chip drawn first so it sits behind the text.\n const labelBg = new Graphics();\n labelBg.label = 'edge-label-bg';\n display.container.addChild(labelBg);\n display.labelBg = labelBg;\n\n const style = new TextStyle({\n fontFamily: data.labelFontFamily ?? 'system-ui, -apple-system, sans-serif',\n fontSize: data.labelFontSize ?? 12,\n fill: color,\n });\n display.label = new Text({ text: data.labelText, style });\n display.label.anchor.set(0.5, 0.5);\n display.container.addChild(display.label);\n }\n display.label.text = data.labelText;\n const lx = center.x;\n const ly = center.y - 10;\n display.label.position.set(lx, ly);\n (display.label.style as TextStyle).fill = color;\n\n // Draw a rounded background chip behind the label so the line / waypoints\n // don't show through the text.\n if (display.labelBg) {\n const padX = 5;\n const padY = 2;\n const tw = display.label.width + padX * 2;\n const th = display.label.height + padY * 2;\n display.labelBg.clear();\n display.labelBg\n .roundRect(lx - tw / 2, ly - th / 2, tw, th, 4)\n .fill({ color: 0xffffff, alpha: 0.92 });\n }\n } else {\n if (display.label) display.label.text = '';\n if (display.labelBg) display.labelBg.clear();\n }\n }\n\n private _drawPath(\n g: Graphics,\n segs: PathSegment[],\n color: string,\n width: number,\n lineStyle?: string,\n dashDensity?: string,\n ): void {\n const dash = getDashPattern(lineStyle, dashDensity, width);\n if (dash) {\n const offset = lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n drawDashedPath(g, segs as PathSeg[], dash, offset);\n g.stroke({ color, width, cap: 'round' as const });\n } else {\n for (const seg of segs) {\n switch (seg.type) {\n case 'M': g.moveTo(seg.x, seg.y); break;\n case 'L': g.lineTo(seg.x, seg.y); break;\n case 'C': g.bezierCurveTo(seg.cp1x!, seg.cp1y!, seg.cp2x!, seg.cp2y!, seg.x, seg.y); break;\n case 'Q': g.quadraticCurveTo(seg.cp1x!, seg.cp1y!, seg.x, seg.y); break;\n }\n }\n g.stroke({ color, width });\n }\n }\n\n destroy(): void {\n for (const [, display] of this.edges) {\n display.container.destroy({ children: true });\n }\n this.edges.clear();\n this.edgeLayer.destroy({ children: true });\n }\n}\n"],"mappings":";;;;;AAiBA,SAAS,EAAe,GAAgB,GAAkB,IAAQ,GAAyB;AACzF,MAAI,GAAC,KAAS,MAAU;AACxB,WAAI,MAAU,YAAkB,CAAC,IAAQ,GAAG,IAAQ,CAAC,IAG9C,CAFM,MAAU,WAAW,IAAQ,IAAQ,GACtC,MAAY,UAAU,IAAQ,MAAY,WAAW,IAAQ,IAAI,IAAQ,CACpE;AACnB;AAKA,IAAa,IAAb,MAA0B;AAAA,EACxB;AAAA,EACA;AAAA,EACA,QAAgB,oBAAI,IAAyB;AAAA,EAC7C,iBAAyB;AAAA,EAGzB,iBAAiB,GAAuB;AACtC,SAAK,kBAAkB,KAAK,iBAAiB,IAAU,QAAQ;AAAA,EACjE;AAAA,EAEA,YAAY,GAAkB;AAC5B,SAAK,QAAQ,GACb,KAAK,YAAY,IAAI,EAAU,EAAE,OAAO,QAAQ,CAAC,GAEjD,KAAK,MAAM,WAAW,KAAK,WAAW,CAAC;AAAA,EACzC;AAAA,EAEA,KACE,GACA,GACA,GACA,GACA,GACM;AACN,UAAM,IAAO,oBAAI,IAAY;AAE7B,eAAW,KAAQ,GAAW;AAC5B,MAAA,EAAK,IAAI,EAAK,EAAE;AAChB,YAAM,IAAY,EAAqB,GAAM,CAAO;AACpD,UAAI,CAAC,EAAW;AAEhB,UAAI,IAAU,KAAK,MAAM,IAAI,EAAK,EAAE;AACpC,MAAK,MACH,IAAU,KAAK,YAAY,CAAI,GAC/B,KAAK,MAAM,IAAI,EAAK,IAAI,CAAO,IAEjC,KAAK,YACH,GACA,GACA,GACA,EAAY,IAAI,EAAK,EAAE,GACvB,MAAc,EAAK,IACnB,GAAS,gBAAgB,EAC3B;AAAA,IACF;AAEA,eAAW,CAAC,GAAI,CAAA,KAAY,KAAK,MAC/B,CAAK,EAAK,IAAI,CAAE,MACd,KAAK,UAAU,YAAY,EAAQ,SAAS,GAC5C,EAAQ,UAAU,QAAQ,EAAE,UAAU,GAAK,CAAC,GAC5C,KAAK,MAAM,OAAO,CAAE;AAAA,EAG1B;AAAA,EAEA,YAAoB,GAA6B;AAC/C,UAAM,IAAY,IAAI,EAAU,EAAE,OAAO,QAAQ,EAAK,EAAA,GAAK,CAAC,GAEtD,IAAU,IAAI,EAAS;AAC7B,IAAA,EAAQ,QAAQ,gBAChB,EAAQ,YAAY,UACpB,EAAQ,SAAS,WACjB,EAAQ,QAAQ,GAChB,EAAU,SAAS,CAAO;AAE1B,UAAM,IAAO,IAAI,EAAS;AAC1B,IAAA,EAAK,QAAQ,aACb,EAAU,SAAS,CAAI;AAEvB,UAAM,IAAY,IAAI,EAAS;AAC/B,WAAA,EAAU,QAAQ,kBAClB,EAAU,SAAS,CAAS,GAE5B,KAAK,UAAU,SAAS,CAAS,GAC1B;AAAA,MAAE,WAAA;AAAA,MAAW,MAAA;AAAA,MAAM,WAAA;AAAA,MAAW,SAAA;AAAA,MAAS,SAAS;AAAA,MAAM,OAAO;AAAA,MAAM,QAAQ,EAAK;AAAA,IAAG;AAAA,EAC5F;AAAA,EAEA,YACE,GACA,GACA,GACA,GACA,GACA,GACM;AACN,UAAM,EAAE,MAAA,GAAM,WAAA,GAAW,SAAA,EAAA,IAAY,GAC/B,IAAO,EAAK,MACZ,IAAQ,IAAW,YAAY,EAAkB,EAAK,aAAa,SAAS,GAC5E,IAAQ,EAAK,eAAe,GAE5B,IAAW,EAAc,EAAK,MAAM,GAAW,EAAK,WAAW,EAAK,cAAc;AAUxF,QAPA,EAAK,MAAM,GACX,KAAK,UAAU,GAAM,GAAU,GAAO,GAAO,EAAK,WAAW,EAAK,WAAW,GAK7E,EAAU,MAAM,GACZ,KAAgB,EAAK,UAAU;AACjC,YAAM,IAAU,CAAC,KAAK,IAAI,IAAI,IAAQ,EAAE,GAAG,KAAK,IAAI,IAAI,IAAQ,EAAE,CAAC;AACnE,MAAA,EAAe,GAAW,GAAuB,GAAS,CAAC,KAAK,iBAAiB,GAAG,GACpF,EAAU,OAAO;AAAA,QAAE,OAAO;AAAA,QAAU,OAAO,IAAQ;AAAA,QAAG,OAAO;AAAA,QAAM,KAAK;AAAA,MAAiB,CAAC,GAC1F,EAAe,GAAW,GAAuB,GAAS,CAAC,KAAK,iBAAiB,GAAG,GACpF,EAAU,OAAO;AAAA,QAAE,OAAO;AAAA,QAAU,OAAO,IAAQ;AAAA,QAAG,OAAO;AAAA,QAAM,KAAK;AAAA,MAAiB,CAAC,GAC1F,EAAe,GAAW,GAAuB,GAAS,CAAC,KAAK,iBAAiB,GAAG,GACpF,EAAU,OAAO;AAAA,QAAE,OAAO;AAAA,QAAU,OAAO,KAAK,IAAI,GAAG,IAAQ,GAAG;AAAA,QAAG,OAAO;AAAA,QAAK,KAAK;AAAA,MAAiB,CAAC;AAAA,IAC1G;AAGA,QAAI,EAAK,eAAe,EAAK,gBAAgB,UAAU,EAAS,UAAU,GAAG;AAC3E,YAAM,IAAM,EAAS,CAAA,GACf,IAAO,EAAS,CAAA,GAIhB,IAAQ,EAFA,EAAK,SAAS,MAAM,EAAK,OAAQ,EAAK,GACtC,EAAK,SAAS,MAAM,EAAK,OAAQ,EAAK,GACX,EAAI,GAAG,EAAI,CAAC;AACrD,MAAA,EAAW,GAAM,EAAK,aAAa,EAAI,GAAG,EAAI,GAAG,GAAO,CAAK;AAAA,IAC/D;AACA,QAAI,EAAK,aAAa,EAAK,cAAc,UAAU,EAAS,UAAU,GAAG;AACvE,YAAM,IAAM,EAAS,EAAS,SAAS,CAAA,GAIjC,IAAQ,EAFA,EAAI,SAAS,MAAM,EAAI,OAAQ,EAAS,EAAS,SAAS,CAAA,EAAG,GAC7D,EAAI,SAAS,MAAM,EAAI,OAAQ,EAAS,EAAS,SAAS,CAAA,EAAG,GAClC,EAAI,GAAG,EAAI,CAAC;AACrD,MAAA,EAAW,GAAM,EAAK,WAAW,EAAI,GAAG,EAAI,GAAG,GAAO,CAAK;AAAA,IAC7D;AAQA,QALA,EAAQ,MAAM,GACd,KAAK,UAAU,GAAS,GAAU,WAAW,KAAK,IAAI,IAAQ,IAAI,EAAE,GAAG,OAAO,GAC9E,EAAQ,QAAQ,MAGZ,EAAK,WAAW;AAClB,YAAM,IAAS,EAAc,CAAQ;AACrC,UAAI,CAAC,EAAQ,OAAO;AAElB,cAAM,IAAU,IAAI,EAAS;AAC7B,QAAA,EAAQ,QAAQ,iBAChB,EAAQ,UAAU,SAAS,CAAO,GAClC,EAAQ,UAAU;AAElB,cAAM,IAAQ,IAAI,EAAU;AAAA,UAC1B,YAAY,EAAK,mBAAmB;AAAA,UACpC,UAAU,EAAK,iBAAiB;AAAA,UAChC,MAAM;AAAA,QACR,CAAC;AACD,QAAA,EAAQ,QAAQ,IAAI,EAAK;AAAA,UAAE,MAAM,EAAK;AAAA,UAAW,OAAA;AAAA,QAAM,CAAC,GACxD,EAAQ,MAAM,OAAO,IAAI,KAAK,GAAG,GACjC,EAAQ,UAAU,SAAS,EAAQ,KAAK;AAAA,MAC1C;AACA,MAAA,EAAQ,MAAM,OAAO,EAAK;AAC1B,YAAM,IAAK,EAAO,GACZ,IAAK,EAAO,IAAI;AAMtB,UALA,EAAQ,MAAM,SAAS,IAAI,GAAI,CAAE,GACjC,EAAS,MAAM,MAAoB,OAAO,GAItC,EAAQ,SAAS;AAGnB,cAAM,IAAK,EAAQ,MAAM,QAAQ,IAC3B,IAAK,EAAQ,MAAM,SAAS;AAClC,QAAA,EAAQ,QAAQ,MAAM,GACtB,EAAQ,QACL,UAAU,IAAK,IAAK,GAAG,IAAK,IAAK,GAAG,GAAI,GAAI,CAAC,EAC7C,KAAK;AAAA,UAAE,OAAO;AAAA,UAAU,OAAO;AAAA,QAAK,CAAC;AAAA,MAC1C;AAAA,IACF;AACE,MAAI,EAAQ,UAAO,EAAQ,MAAM,OAAO,KACpC,EAAQ,WAAS,EAAQ,QAAQ,MAAM;AAAA,EAE/C;AAAA,EAEA,UACE,GACA,GACA,GACA,GACA,GACA,GACM;AACN,UAAM,IAAO,EAAe,GAAW,GAAa,CAAK;AACzD,QAAI;AAEF,MAAA,EAAe,GAAG,GAAmB,GADtB,MAAc,YAAY,KAAK,iBAAiB,CACd,GACjD,EAAE,OAAO;AAAA,QAAE,OAAA;AAAA,QAAO,OAAA;AAAA,QAAO,KAAK;AAAA,MAAiB,CAAC;AAAA,SAC3C;AACL,iBAAW,KAAO,EAChB,SAAQ,EAAI,MAAZ;AAAA,QACE,KAAK;AAAK,UAAA,EAAE,OAAO,EAAI,GAAG,EAAI,CAAC;AAAG;AAAA,QAClC,KAAK;AAAK,UAAA,EAAE,OAAO,EAAI,GAAG,EAAI,CAAC;AAAG;AAAA,QAClC,KAAK;AAAK,UAAA,EAAE,cAAc,EAAI,MAAO,EAAI,MAAO,EAAI,MAAO,EAAI,MAAO,EAAI,GAAG,EAAI,CAAC;AAAG;AAAA,QACrF,KAAK;AAAK,UAAA,EAAE,iBAAiB,EAAI,MAAO,EAAI,MAAO,EAAI,GAAG,EAAI,CAAC;AAAG;AAAA,MACpE;AAEF,MAAA,EAAE,OAAO;AAAA,QAAE,OAAA;AAAA,QAAO,OAAA;AAAA,MAAM,CAAC;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,eAAW,CAAA,EAAG,CAAA,KAAY,KAAK,MAC7B,CAAA,EAAQ,UAAU,QAAQ,EAAE,UAAU,GAAK,CAAC;AAE9C,SAAK,MAAM,MAAM,GACjB,KAAK,UAAU,QAAQ,EAAE,UAAU,GAAK,CAAC;AAAA,EAC3C;AACF"}
1
+ {"version":3,"file":"EdgeRenderer.js","names":[],"sources":["../../../../../src/components/pro/Flow/edges/EdgeRenderer.ts"],"sourcesContent":["import { Container, Graphics, Text, TextStyle } from 'pixi.js';\nimport type { FlowEdge, FlowNode } from '../types';\nimport { buildEdgePath, getPathCenter, resolveEdgeEndpoints, type PathSegment, type EdgeEndpoints } from './edgePaths';\nimport { drawMarker, angleBetween } from './edgeMarkers';\nimport { drawDashedPath, type PathSeg } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\ninterface EdgeDisplay {\n container: Container;\n line: Graphics;\n animation: Graphics;\n hitArea: Graphics;\n labelBg: Graphics | null;\n label: Text | null;\n edgeId: string;\n}\n\nfunction getDashPattern(style?: string, density?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n const base = style === 'dotted' ? width : width * 3;\n const gap = density === 'dense' ? width : density === 'sparse' ? width * 4 : width * 2;\n return [base, gap];\n}\n\n/**\n * Manages PixiJS display objects for all edges.\n */\nexport class EdgeRenderer {\n private world: Container;\n private edgeLayer: Container;\n private edges = new Map<string, EdgeDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.edgeLayer = new Container({ label: 'edges' });\n // Edges below nodes\n this.world.addChildAt(this.edgeLayer, 0);\n }\n\n sync(\n flowEdges: FlowEdge[],\n nodeMap: Map<string, FlowNode>,\n selectedIds: Set<string>,\n hoveredId: string | null,\n options?: { presentation?: boolean },\n ): void {\n const seen = new Set<string>();\n\n for (const edge of flowEdges) {\n seen.add(edge.id);\n const endpoints = resolveEdgeEndpoints(edge, nodeMap);\n if (!endpoints) continue;\n\n let display = this.edges.get(edge.id);\n if (!display) {\n display = this._createEdge(edge);\n this.edges.set(edge.id, display);\n }\n this._updateEdge(\n display,\n edge,\n endpoints,\n selectedIds.has(edge.id),\n hoveredId === edge.id,\n options?.presentation ?? false,\n );\n }\n\n for (const [id, display] of this.edges) {\n if (!seen.has(id)) {\n this.edgeLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.edges.delete(id);\n }\n }\n }\n\n private _createEdge(edge: FlowEdge): EdgeDisplay {\n const container = new Container({ label: `edge-${edge.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'edge-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0;\n container.addChild(hitArea);\n\n const line = new Graphics();\n line.label = 'edge-line';\n container.addChild(line);\n\n const animation = new Graphics();\n animation.label = 'edge-animation';\n container.addChild(animation);\n\n this.edgeLayer.addChild(container);\n return { container, line, animation, hitArea, labelBg: null, label: null, edgeId: edge.id };\n }\n\n private _updateEdge(\n display: EdgeDisplay,\n edge: FlowEdge,\n endpoints: EdgeEndpoints,\n selected: boolean,\n hovered: boolean,\n presentation: boolean,\n ): void {\n const { line, animation, hitArea } = display;\n const data = edge.data;\n const color = selected ? '#3b82f6' : resolveThemeColor(data.strokeColor, '#374151');\n const width = data.strokeWidth ?? 2;\n\n const segments = buildEdgePath(edge.type, endpoints, data.waypoints, data.bezierControls);\n\n // Draw visible line\n line.clear();\n this._drawPath(line, segments, color, width, data.lineStyle, data.dashDensity);\n\n // Presentation animation: a bright gradient-like pulse travels from source\n // to target. A short dashed segment plus soft outer stroke gives the pulse\n // a leading highlight and fading tail without requiring SVG filters.\n animation.clear();\n if (presentation && data.animated) {\n const pattern = [Math.max(18, width * 12), Math.max(90, width * 45)];\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x60a5fa, width: width + 5, alpha: 0.18, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0x38bdf8, width: width + 2, alpha: 0.55, cap: 'round' as const });\n drawDashedPath(animation, segments as PathSeg[], pattern, -this._dynamicOffset * 2.2);\n animation.stroke({ color: 0xffffff, width: Math.max(1, width * 0.7), alpha: 0.9, cap: 'round' as const });\n }\n\n // Draw markers — use curve tangent for accurate arrow direction\n if (data.markerStart && data.markerStart !== 'none' && segments.length >= 2) {\n const tip = segments[0];\n const next = segments[1];\n // For curves the tangent at t=0 is tip→cp1; for lines it's tip→next\n const fromX = next.type === 'C' ? next.cp1x! : next.x;\n const fromY = next.type === 'C' ? next.cp1y! : next.y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerStart, tip.x, tip.y, angle, color);\n }\n if (data.markerEnd && data.markerEnd !== 'none' && segments.length >= 2) {\n const tip = segments[segments.length - 1];\n // For curves the tangent at t=1 is cp2→endpoint\n const fromX = tip.type === 'C' ? tip.cp2x! : segments[segments.length - 2].x;\n const fromY = tip.type === 'C' ? tip.cp2y! : segments[segments.length - 2].y;\n const angle = angleBetween(fromX, fromY, tip.x, tip.y);\n drawMarker(line, data.markerEnd, tip.x, tip.y, angle, color);\n }\n\n // Wider invisible hit area\n hitArea.clear();\n this._drawPath(hitArea, segments, '#000000', Math.max(width + 10, 14), 'solid');\n hitArea.alpha = 0.001;\n\n // Edge label\n if (data.labelText) {\n const center = getPathCenter(segments);\n if (!display.label) {\n // Background chip drawn first so it sits behind the text.\n const labelBg = new Graphics();\n labelBg.label = 'edge-label-bg';\n display.container.addChild(labelBg);\n display.labelBg = labelBg;\n\n const style = new TextStyle({\n fontFamily: data.labelFontFamily ?? 'system-ui, -apple-system, sans-serif',\n fontSize: data.labelFontSize ?? 12,\n fill: color,\n });\n display.label = new Text({ text: data.labelText, style });\n display.label.anchor.set(0.5, 0.5);\n display.container.addChild(display.label);\n }\n display.label.text = data.labelText;\n const lx = center.x;\n const ly = center.y - 10;\n display.label.position.set(lx, ly);\n (display.label.style as TextStyle).fill = color;\n\n // Draw a rounded background chip behind the label so the line / waypoints\n // don't show through the text.\n if (display.labelBg) {\n const padX = 5;\n const padY = 2;\n const tw = display.label.width + padX * 2;\n const th = display.label.height + padY * 2;\n display.labelBg.clear();\n display.labelBg\n .roundRect(lx - tw / 2, ly - th / 2, tw, th, 4)\n .fill({ color: 0xffffff, alpha: 0.92 });\n }\n } else {\n if (display.label) display.label.text = '';\n if (display.labelBg) display.labelBg.clear();\n }\n }\n\n private _drawPath(\n g: Graphics,\n segs: PathSegment[],\n color: string,\n width: number,\n lineStyle?: string,\n dashDensity?: string,\n ): void {\n const dash = getDashPattern(lineStyle, dashDensity, width);\n if (dash) {\n const offset = lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n drawDashedPath(g, segs as PathSeg[], dash, offset);\n g.stroke({ color, width, cap: 'round' as const });\n } else {\n for (const seg of segs) {\n switch (seg.type) {\n case 'M': g.moveTo(seg.x, seg.y); break;\n case 'L': g.lineTo(seg.x, seg.y); break;\n case 'C': g.bezierCurveTo(seg.cp1x!, seg.cp1y!, seg.cp2x!, seg.cp2y!, seg.x, seg.y); break;\n case 'Q': g.quadraticCurveTo(seg.cp1x!, seg.cp1y!, seg.x, seg.y); break;\n }\n }\n g.stroke({ color, width });\n }\n }\n\n destroy(): void {\n for (const [, display] of this.edges) {\n display.container.destroy({ children: true });\n }\n this.edges.clear();\n this.edgeLayer.destroy({ children: true });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useClipboard.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useClipboard.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { generateId } from '../nodes/nodeUtils';\nimport type { FlowNode, FlowEdge, FlowLine } from '../types';\n\ninterface ClipboardData {\n nodes: FlowNode[];\n edges: FlowEdge[];\n lines: FlowLine[];\n}\n\n/**\n * Copy/paste/cut for selected flow elements.\n * Uses internal clipboard (not system clipboard) for structured data.\n */\nexport function useClipboard() {\n const { currentCanvas, selection, setDoc, currentCanvasId, setSelection } = useFlowContext();\n const clipboardRef = useRef<ClipboardData | null>(null);\n\n const copy = useCallback(() => {\n const nodes = currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id));\n const edges = currentCanvas.edges.filter(e => selection.edgeIds.has(e.id));\n const lines = currentCanvas.lines.filter(l => selection.lineIds.has(l.id));\n\n // Also include edges that connect selected nodes\n const nodeIds = new Set(nodes.map(n => n.id));\n const connectedEdges = currentCanvas.edges.filter(\n e => nodeIds.has(e.source) && nodeIds.has(e.target) && !selection.edgeIds.has(e.id),\n );\n\n clipboardRef.current = {\n nodes: [...nodes],\n edges: [...edges, ...connectedEdges],\n lines: [...lines],\n };\n }, [currentCanvas, selection]);\n\n const cut = useCallback(() => {\n copy();\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.filter(n => !selection.nodeIds.has(n.id)),\n edges: canvas.edges.filter(e =>\n !selection.edgeIds.has(e.id) &&\n !selection.nodeIds.has(e.source) &&\n !selection.nodeIds.has(e.target),\n ),\n lines: canvas.lines.filter(l => !selection.lineIds.has(l.id)),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [copy, setDoc, currentCanvasId, selection, setSelection]);\n\n const paste = useCallback((offsetX = 20, offsetY = 20) => {\n const cb = clipboardRef.current;\n if (!cb) return;\n\n const idMap = new Map<string, string>();\n const newNodes: FlowNode[] = cb.nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return {\n ...n,\n id: newId,\n position: { x: n.position.x + offsetX, y: n.position.y + offsetY },\n data: { ...n.data },\n };\n });\n\n const newEdges: FlowEdge[] = cb.edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = cb.lines.map(l => ({\n ...l,\n id: generateId('line'),\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [setDoc, currentCanvasId, setSelection]);\n\n const hasClipboard = clipboardRef.current !== null;\n\n /**\n * Duplicate the current selection in place (Cmd/Ctrl+D). Unlike copy+paste\n * this does NOT touch the clipboard, so a prior copy stays intact. Clones the\n * selected nodes (plus edges wholly between them) and lines with a small\n * offset, then selects the clones.\n */\n const duplicate = useCallback((\n offsetX = 24,\n offsetY = 24,\n targets?: { nodeIds?: Set<string>; edgeIds?: Set<string>; lineIds?: Set<string> },\n ) => {\n const nodeSel = targets?.nodeIds ?? selection.nodeIds;\n const edgeSel = targets?.edgeIds ?? selection.edgeIds;\n const lineSel = targets?.lineIds ?? selection.lineIds;\n const nodes = currentCanvas.nodes.filter(n => nodeSel.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineSel.has(l.id));\n const nodeIdSet = new Set(nodes.map(n => n.id));\n const edges = currentCanvas.edges.filter(e =>\n edgeSel.has(e.id) ||\n (nodeIdSet.has(e.source) && nodeIdSet.has(e.target)),\n );\n if (nodes.length === 0 && lines.length === 0 && edges.length === 0) return;\n\n const idMap = new Map<string, string>();\n // Assign fresh ids to nodes first so intra-selection edges can be remapped.\n const newNodes: FlowNode[] = nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return { ...n, id: newId, position: { x: n.position.x + offsetX, y: n.position.y + offsetY }, data: { ...n.data } };\n });\n // Re-parent cloned children onto cloned groups when both were duplicated.\n for (const n of newNodes) {\n if (n.parentId && idMap.has(n.parentId)) n.parentId = idMap.get(n.parentId);\n }\n\n const newEdges: FlowEdge[] = edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = lines.map(l => ({\n ...l,\n id: generateId('line'),\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [currentCanvas, selection, setDoc, currentCanvasId, setSelection]);\n\n return { copy, cut, paste, duplicate, hasClipboard };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useClipboard.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useClipboard.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport { generateId } from '../nodes/nodeUtils';\nimport type { FlowNode, FlowEdge, FlowLine } from '../types';\n\ninterface ClipboardData {\n nodes: FlowNode[];\n edges: FlowEdge[];\n lines: FlowLine[];\n}\n\n/**\n * Copy/paste/cut for selected flow elements.\n * Uses internal clipboard (not system clipboard) for structured data.\n */\nexport function useClipboard() {\n const { currentCanvas, selection, setDoc, currentCanvasId, setSelection } = useFlowContext();\n const clipboardRef = useRef<ClipboardData | null>(null);\n\n const copy = useCallback(() => {\n const nodes = currentCanvas.nodes.filter(n => selection.nodeIds.has(n.id));\n const edges = currentCanvas.edges.filter(e => selection.edgeIds.has(e.id));\n const lines = currentCanvas.lines.filter(l => selection.lineIds.has(l.id));\n\n // Also include edges that connect selected nodes\n const nodeIds = new Set(nodes.map(n => n.id));\n const connectedEdges = currentCanvas.edges.filter(\n e => nodeIds.has(e.source) && nodeIds.has(e.target) && !selection.edgeIds.has(e.id),\n );\n\n clipboardRef.current = {\n nodes: [...nodes],\n edges: [...edges, ...connectedEdges],\n lines: [...lines],\n };\n }, [currentCanvas, selection]);\n\n const cut = useCallback(() => {\n copy();\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.filter(n => !selection.nodeIds.has(n.id)),\n edges: canvas.edges.filter(e =>\n !selection.edgeIds.has(e.id) &&\n !selection.nodeIds.has(e.source) &&\n !selection.nodeIds.has(e.target),\n ),\n lines: canvas.lines.filter(l => !selection.lineIds.has(l.id)),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [copy, setDoc, currentCanvasId, selection, setSelection]);\n\n const paste = useCallback((offsetX = 20, offsetY = 20) => {\n const cb = clipboardRef.current;\n if (!cb) return;\n\n const idMap = new Map<string, string>();\n const newNodes: FlowNode[] = cb.nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return {\n ...n,\n id: newId,\n position: { x: n.position.x + offsetX, y: n.position.y + offsetY },\n data: { ...n.data },\n };\n });\n\n const newEdges: FlowEdge[] = cb.edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = cb.lines.map(l => ({\n ...l,\n id: generateId('line'),\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [setDoc, currentCanvasId, setSelection]);\n\n const hasClipboard = clipboardRef.current !== null;\n\n /**\n * Duplicate the current selection in place (Cmd/Ctrl+D). Unlike copy+paste\n * this does NOT touch the clipboard, so a prior copy stays intact. Clones the\n * selected nodes (plus edges wholly between them) and lines with a small\n * offset, then selects the clones.\n */\n const duplicate = useCallback((\n offsetX = 24,\n offsetY = 24,\n targets?: { nodeIds?: Set<string>; edgeIds?: Set<string>; lineIds?: Set<string> },\n ) => {\n const nodeSel = targets?.nodeIds ?? selection.nodeIds;\n const edgeSel = targets?.edgeIds ?? selection.edgeIds;\n const lineSel = targets?.lineIds ?? selection.lineIds;\n const nodes = currentCanvas.nodes.filter(n => nodeSel.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineSel.has(l.id));\n const nodeIdSet = new Set(nodes.map(n => n.id));\n const edges = currentCanvas.edges.filter(e =>\n edgeSel.has(e.id) ||\n (nodeIdSet.has(e.source) && nodeIdSet.has(e.target)),\n );\n if (nodes.length === 0 && lines.length === 0 && edges.length === 0) return;\n\n const idMap = new Map<string, string>();\n // Assign fresh ids to nodes first so intra-selection edges can be remapped.\n const newNodes: FlowNode[] = nodes.map(n => {\n const newId = generateId('node');\n idMap.set(n.id, newId);\n return { ...n, id: newId, position: { x: n.position.x + offsetX, y: n.position.y + offsetY }, data: { ...n.data } };\n });\n // Re-parent cloned children onto cloned groups when both were duplicated.\n for (const n of newNodes) {\n if (n.parentId && idMap.has(n.parentId)) n.parentId = idMap.get(n.parentId);\n }\n\n const newEdges: FlowEdge[] = edges\n .filter(e => idMap.has(e.source) && idMap.has(e.target))\n .map(e => ({\n ...e,\n id: generateId('edge'),\n source: idMap.get(e.source)!,\n target: idMap.get(e.target)!,\n data: { ...e.data },\n }));\n\n const newLines: FlowLine[] = lines.map(l => ({\n ...l,\n id: generateId('line'),\n points: l.points.map(p => ({ x: p.x + offsetX, y: p.y + offsetY })),\n }));\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: [...canvas.nodes, ...newNodes],\n edges: [...canvas.edges, ...newEdges],\n lines: [...canvas.lines, ...newLines],\n },\n },\n };\n });\n\n setSelection({\n nodeIds: new Set(newNodes.map(n => n.id)),\n edgeIds: new Set(newEdges.map(e => e.id)),\n lineIds: new Set(newLines.map(l => l.id)),\n });\n }, [currentCanvas, selection, setDoc, currentCanvasId, setSelection]);\n\n return { copy, cut, paste, duplicate, hasClipboard };\n}\n"],"mappings":";;;AAeA,SAAgB,IAAe;AAC7B,QAAM,EAAE,eAAA,GAAe,WAAA,GAAW,QAAA,GAAQ,iBAAA,GAAiB,cAAA,EAAA,IAAiB,EAAe,GACrF,IAAe,EAA6B,IAAI,GAEhD,IAAO,EAAA,MAAkB;AAC7B,UAAM,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAU,QAAQ,IAAI,EAAE,EAAE,CAAC,GACnE,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAU,QAAQ,IAAI,EAAE,EAAE,CAAC,GACnE,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAU,QAAQ,IAAI,EAAE,EAAE,CAAC,GAGnE,IAAU,IAAI,IAAI,EAAM,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC,GACtC,IAAiB,EAAc,MAAM,OAAA,CACzC,MAAK,EAAQ,IAAI,EAAE,MAAM,KAAK,EAAQ,IAAI,EAAE,MAAM,KAAK,CAAC,EAAU,QAAQ,IAAI,EAAE,EAAE,CACpF;AAEA,IAAA,EAAa,UAAU;AAAA,MACrB,OAAO,CAAC,GAAG,CAAK;AAAA,MAChB,OAAO,CAAC,GAAG,GAAO,GAAG,CAAc;AAAA,MACnC,OAAO,CAAC,GAAG,CAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,GAAe,CAAS,CAAC,GAEvB,IAAM,EAAA,MAAkB;AAC5B,IAAA,EAAK,GACL,EAAA,CAAO,MAAQ;AACb,YAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,aAAK,IACE;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG,EAAK;AAAA,UACP,CAAA,CAAA,GAAkB;AAAA,YACjB,GAAG;AAAA,YACH,OAAO,EAAO,MAAM,OAAA,CAAO,MAAK,CAAC,EAAU,QAAQ,IAAI,EAAE,EAAE,CAAC;AAAA,YAC5D,OAAO,EAAO,MAAM,OAAA,CAAO,MACzB,CAAC,EAAU,QAAQ,IAAI,EAAE,EAAE,KAC3B,CAAC,EAAU,QAAQ,IAAI,EAAE,MAAM,KAC/B,CAAC,EAAU,QAAQ,IAAI,EAAE,MAAM,CACjC;AAAA,YACA,OAAO,EAAO,MAAM,OAAA,CAAO,MAAK,CAAC,EAAU,QAAQ,IAAI,EAAE,EAAE,CAAC;AAAA,UAC9D;AAAA,QACF;AAAA,MACF,IAhBoB;AAAA,IAiBtB,CAAC,GACD,EAAa;AAAA,MAAE,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,IAAE,CAAC;AAAA,EAC7E,GAAG;AAAA,IAAC;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAiB;AAAA,IAAW;AAAA,EAAY,CAAC,GAErD,IAAQ,EAAA,CAAa,IAAU,IAAI,IAAU,OAAO;AACxD,UAAM,IAAK,EAAa;AACxB,QAAI,CAAC,EAAI;AAET,UAAM,IAAQ,oBAAI,IAAoB,GAChC,IAAuB,EAAG,MAAM,IAAA,CAAI,MAAK;AAC7C,YAAM,IAAQ,EAAW,MAAM;AAC/B,aAAA,EAAM,IAAI,EAAE,IAAI,CAAK,GACd;AAAA,QACL,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,UAAU;AAAA,UAAE,GAAG,EAAE,SAAS,IAAI;AAAA,UAAS,GAAG,EAAE,SAAS,IAAI;AAAA,QAAQ;AAAA,QACjE,MAAM,EAAE,GAAG,EAAE,KAAK;AAAA,MACpB;AAAA,IACF,CAAC,GAEK,IAAuB,EAAG,MAC7B,OAAA,CAAO,MAAK,EAAM,IAAI,EAAE,MAAM,KAAK,EAAM,IAAI,EAAE,MAAM,CAAC,EACtD,IAAA,CAAI,OAAM;AAAA,MACT,GAAG;AAAA,MACH,IAAI,EAAW,MAAM;AAAA,MACrB,QAAQ,EAAM,IAAI,EAAE,MAAM;AAAA,MAC1B,QAAQ,EAAM,IAAI,EAAE,MAAM;AAAA,MAC1B,MAAM,EAAE,GAAG,EAAE,KAAK;AAAA,IACpB,EAAE,GAEE,IAAuB,EAAG,MAAM,IAAA,CAAI,OAAM;AAAA,MAC9C,GAAG;AAAA,MACH,IAAI,EAAW,MAAM;AAAA,MACrB,QAAQ,EAAE,OAAO,IAAA,CAAI,OAAM;AAAA,QAAE,GAAG,EAAE,IAAI;AAAA,QAAS,GAAG,EAAE,IAAI;AAAA,MAAQ,EAAE;AAAA,IACpE,EAAE;AAEF,IAAA,EAAA,CAAO,MAAQ;AACb,YAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,aAAK,IACE;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG,EAAK;AAAA,UACP,CAAA,CAAA,GAAkB;AAAA,YACjB,GAAG;AAAA,YACH,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,YACpC,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,YACpC,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,UACtC;AAAA,QACF;AAAA,MACF,IAZoB;AAAA,IAatB,CAAC,GAED,EAAa;AAAA,MACX,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,MACxC,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,MACxC,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,IAC1C,CAAC;AAAA,EACH,GAAG;AAAA,IAAC;AAAA,IAAQ;AAAA,IAAiB;AAAA,EAAY,CAAC,GAEpC,IAAe,EAAa,YAAY;AA6E9C,SAAO;AAAA,IAAE,MAAA;AAAA,IAAM,KAAA;AAAA,IAAK,OAAA;AAAA,IAAO,WArET,EAAA,CAChB,IAAU,IACV,IAAU,IACV,MACG;AACH,YAAM,IAAU,GAAS,WAAW,EAAU,SACxC,IAAU,GAAS,WAAW,EAAU,SACxC,IAAU,GAAS,WAAW,EAAU,SACxC,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAQ,IAAI,EAAE,EAAE,CAAC,GACzD,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAQ,IAAI,EAAE,EAAE,CAAC,GACzD,IAAY,IAAI,IAAI,EAAM,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC,GACxC,IAAQ,EAAc,MAAM,OAAA,CAAO,MACvC,EAAQ,IAAI,EAAE,EAAE,KACf,EAAU,IAAI,EAAE,MAAM,KAAK,EAAU,IAAI,EAAE,MAAM,CACpD;AACA,UAAI,EAAM,WAAW,KAAK,EAAM,WAAW,KAAK,EAAM,WAAW,EAAG;AAEpE,YAAM,IAAQ,oBAAI,IAAoB,GAEhC,IAAuB,EAAM,IAAA,CAAI,MAAK;AAC1C,cAAM,IAAQ,EAAW,MAAM;AAC/B,eAAA,EAAM,IAAI,EAAE,IAAI,CAAK,GACd;AAAA,UAAE,GAAG;AAAA,UAAG,IAAI;AAAA,UAAO,UAAU;AAAA,YAAE,GAAG,EAAE,SAAS,IAAI;AAAA,YAAS,GAAG,EAAE,SAAS,IAAI;AAAA,UAAQ;AAAA,UAAG,MAAM,EAAE,GAAG,EAAE,KAAK;AAAA,QAAE;AAAA,MACpH,CAAC;AAED,iBAAW,KAAK,EACd,CAAI,EAAE,YAAY,EAAM,IAAI,EAAE,QAAQ,MAAG,EAAE,WAAW,EAAM,IAAI,EAAE,QAAQ;AAG5E,YAAM,IAAuB,EAC1B,OAAA,CAAO,MAAK,EAAM,IAAI,EAAE,MAAM,KAAK,EAAM,IAAI,EAAE,MAAM,CAAC,EACtD,IAAA,CAAI,OAAM;AAAA,QACT,GAAG;AAAA,QACH,IAAI,EAAW,MAAM;AAAA,QACrB,QAAQ,EAAM,IAAI,EAAE,MAAM;AAAA,QAC1B,QAAQ,EAAM,IAAI,EAAE,MAAM;AAAA,QAC1B,MAAM,EAAE,GAAG,EAAE,KAAK;AAAA,MACpB,EAAE,GAEE,IAAuB,EAAM,IAAA,CAAI,OAAM;AAAA,QAC3C,GAAG;AAAA,QACH,IAAI,EAAW,MAAM;AAAA,QACrB,QAAQ,EAAE,OAAO,IAAA,CAAI,OAAM;AAAA,UAAE,GAAG,EAAE,IAAI;AAAA,UAAS,GAAG,EAAE,IAAI;AAAA,QAAQ,EAAE;AAAA,MACpE,EAAE;AAEF,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,cACpC,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,cACpC,OAAO,CAAC,GAAG,EAAO,OAAO,GAAG,CAAQ;AAAA,YACtC;AAAA,UACF;AAAA,QACF,IAZoB;AAAA,MAatB,CAAC,GAED,EAAa;AAAA,QACX,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,QACxC,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,QACxC,SAAS,IAAI,IAAI,EAAS,IAAA,CAAI,MAAK,EAAE,EAAE,CAAC;AAAA,MAC1C,CAAC;AAAA,IACH,GAAG;AAAA,MAAC;AAAA,MAAe;AAAA,MAAW;AAAA,MAAQ;AAAA,MAAiB;AAAA,IAAY,CAExC;AAAA,IAAW,cAAA;AAAA,EAAa;AACrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useDeleteSelection.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useDeleteSelection.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\n\n/**\n * Delete everything selected on the current canvas (nodes, edges, lines).\n *\n * Shared by the Delete/Backspace keyboard shortcut and the on-canvas delete\n * button, so touch devices (no keyboard) get exactly the same behavior,\n * including the multi-node confirmation prompt.\n */\nexport function useDeleteSelection() {\n const { selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n\n return useCallback(() => {\n const { nodeIds, edgeIds, lineIds } = selection;\n if (nodeIds.size === 0 && edgeIds.size === 0 && lineIds.size === 0) return;\n if (nodeIds.size > 1 && !window.confirm(`确定要删除选中的 ${nodeIds.size} 个节点吗?`)) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !nodeIds.has(n.id))\n .map(n => n.parentId && nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !edgeIds.has(e.id) && !nodeIds.has(e.source) && !nodeIds.has(e.target),\n ),\n lines: canvas.lines\n .filter(l => !lineIds.has(l.id))\n .map(l => l.parentId && nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, setDoc, currentCanvasId, setSelection]);\n}\n"],"mappings":";;AAUA,SAAgB,IAAqB;AACnC,QAAM,EAAE,WAAA,GAAW,cAAA,GAAc,QAAA,GAAQ,iBAAA,EAAA,IAAoB,EAAe;AAE5E,SAAO,EAAA,MAAkB;AACvB,UAAM,EAAE,SAAA,GAAS,SAAA,GAAS,SAAA,EAAA,IAAY;AACtC,IAAI,EAAQ,SAAS,KAAK,EAAQ,SAAS,KAAK,EAAQ,SAAS,KAC7D,EAAQ,OAAO,KAAK,CAAC,OAAO,QAAQ,YAAY,EAAQ,IAAA,QAAY,MACxE,EAAA,CAAO,MAAQ;AACb,YAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,aAAK,IACE;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG,EAAK;AAAA,WACP,CAAA,GAAkB;AAAA,YACjB,GAAG;AAAA,YACH,OAAO,EAAO,MACX,OAAA,CAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,EAC9B,IAAA,CAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;AAAA,cAAE,GAAG;AAAA,cAAG,UAAU;AAAA,YAAU,IAAI,CAAC;AAAA,YACrF,OAAO,EAAO,MAAM,OAAA,CAAO,MACzB,CAAC,EAAQ,IAAI,EAAE,EAAE,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,CACvE;AAAA,YACA,OAAO,EAAO,MACX,OAAA,CAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,EAC9B,IAAA,CAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;AAAA,cAAE,GAAG;AAAA,cAAG,UAAU;AAAA,YAAU,IAAI,CAAC;AAAA,UACvF;AAAA,QACF;AAAA,MACF,IAlBoB;AAAA,IAmBtB,CAAC,GACD,EAAa;AAAA,MAAE,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,IAAE,CAAC;AAAA,EAC7E,GAAG;AAAA,IAAC;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAiB;AAAA,EAAY,CAAC;AACvD"}
1
+ {"version":3,"file":"useDeleteSelection.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useDeleteSelection.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\n\n/**\n * Delete everything selected on the current canvas (nodes, edges, lines).\n *\n * Shared by the Delete/Backspace keyboard shortcut and the on-canvas delete\n * button, so touch devices (no keyboard) get exactly the same behavior,\n * including the multi-node confirmation prompt.\n */\nexport function useDeleteSelection() {\n const { selection, setSelection, setDoc, currentCanvasId } = useFlowContext();\n\n return useCallback(() => {\n const { nodeIds, edgeIds, lineIds } = selection;\n if (nodeIds.size === 0 && edgeIds.size === 0 && lineIds.size === 0) return;\n if (nodeIds.size > 1 && !window.confirm(`确定要删除选中的 ${nodeIds.size} 个节点吗?`)) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !nodeIds.has(n.id))\n .map(n => n.parentId && nodeIds.has(n.parentId) ? { ...n, parentId: undefined } : n),\n edges: canvas.edges.filter(e =>\n !edgeIds.has(e.id) && !nodeIds.has(e.source) && !nodeIds.has(e.target),\n ),\n lines: canvas.lines\n .filter(l => !lineIds.has(l.id))\n .map(l => l.parentId && nodeIds.has(l.parentId) ? { ...l, parentId: undefined } : l),\n },\n },\n };\n });\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, setDoc, currentCanvasId, setSelection]);\n}\n"],"mappings":";;AAUA,SAAgB,IAAqB;AACnC,QAAM,EAAE,WAAA,GAAW,cAAA,GAAc,QAAA,GAAQ,iBAAA,EAAA,IAAoB,EAAe;AAE5E,SAAO,EAAA,MAAkB;AACvB,UAAM,EAAE,SAAA,GAAS,SAAA,GAAS,SAAA,EAAA,IAAY;AACtC,IAAI,EAAQ,SAAS,KAAK,EAAQ,SAAS,KAAK,EAAQ,SAAS,KAC7D,EAAQ,OAAO,KAAK,CAAC,OAAO,QAAQ,YAAY,EAAQ,IAAA,QAAY,MACxE,EAAA,CAAO,MAAQ;AACb,YAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,aAAK,IACE;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG,EAAK;AAAA,UACP,CAAA,CAAA,GAAkB;AAAA,YACjB,GAAG;AAAA,YACH,OAAO,EAAO,MACX,OAAA,CAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,EAC9B,IAAA,CAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;AAAA,cAAE,GAAG;AAAA,cAAG,UAAU;AAAA,YAAU,IAAI,CAAC;AAAA,YACrF,OAAO,EAAO,MAAM,OAAA,CAAO,MACzB,CAAC,EAAQ,IAAI,EAAE,EAAE,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,KAAK,CAAC,EAAQ,IAAI,EAAE,MAAM,CACvE;AAAA,YACA,OAAO,EAAO,MACX,OAAA,CAAO,MAAK,CAAC,EAAQ,IAAI,EAAE,EAAE,CAAC,EAC9B,IAAA,CAAI,MAAK,EAAE,YAAY,EAAQ,IAAI,EAAE,QAAQ,IAAI;AAAA,cAAE,GAAG;AAAA,cAAG,UAAU;AAAA,YAAU,IAAI,CAAC;AAAA,UACvF;AAAA,QACF;AAAA,MACF,IAlBoB;AAAA,IAmBtB,CAAC,GACD,EAAa;AAAA,MAAE,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,MAAG,SAAS,oBAAI,IAAI;AAAA,IAAE,CAAC;AAAA,EAC7E,GAAG;AAAA,IAAC;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAiB;AAAA,EAAY,CAAC;AACvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useEdgeMutations.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useEdgeMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowEdge, FlowEdgeData, FlowEdgeTypeName, FlowBezierControl } from '../types';\nimport { DEFAULT_EDGE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport function useEdgeMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addEdge = useCallback(\n (\n source: string,\n target: string,\n type: FlowEdgeTypeName = 'smoothstep',\n data?: Partial<FlowEdgeData>,\n sourceHandle?: string,\n targetHandle?: string,\n ): string => {\n const id = generateId('edge');\n const edge: FlowEdge = {\n id,\n source,\n target,\n sourceHandle,\n targetHandle,\n type,\n data: { ...DEFAULT_EDGE_DATA, ...data },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n // Prevent duplicates\n const exists = canvas.edges.some(e => e.source === source && e.target === target);\n if (exists) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, edges: [...canvas.edges, edge] },\n },\n };\n });\n return id;\n },\n [setDoc, currentCanvasId],\n );\n\n const updateEdge = useCallback(\n (id: string, updates: Partial<Pick<FlowEdge, 'type'>> & { data?: Partial<FlowEdgeData> }) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== id) return e;\n return {\n ...e,\n ...(updates.type !== undefined ? { type: updates.type } : {}),\n data: updates.data ? { ...e.data, ...updates.data } : e.data,\n };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateWaypoint = useCallback(\n (edgeId: string, waypointIndex: number, x: number, y: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId || !e.data.waypoints) return e;\n const wps = [...e.data.waypoints];\n wps[waypointIndex] = { x, y };\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const addWaypoint = useCallback(\n (edgeId: string, x: number, y: number, insertIndex?: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const wps = [...(e.data.waypoints ?? [])];\n const idx = insertIndex ?? wps.length;\n wps.splice(idx, 0, { x, y });\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateBezierControl = useCallback(\n (edgeId: string, segIndex: number, control: FlowBezierControl) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const ctrls = [...(e.data.bezierControls ?? [])];\n while (ctrls.length <= segIndex) ctrls.push(null);\n ctrls[segIndex] = control;\n return { ...e, data: { ...e.data, bezierControls: ctrls } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteEdges = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.filter(e => !ids.has(e.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addEdge, updateEdge, updateWaypoint, addWaypoint, updateBezierControl, deleteEdges };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useEdgeMutations.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useEdgeMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowEdge, FlowEdgeData, FlowEdgeTypeName, FlowBezierControl } from '../types';\nimport { DEFAULT_EDGE_DATA } from '../constants';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport function useEdgeMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addEdge = useCallback(\n (\n source: string,\n target: string,\n type: FlowEdgeTypeName = 'smoothstep',\n data?: Partial<FlowEdgeData>,\n sourceHandle?: string,\n targetHandle?: string,\n ): string => {\n const id = generateId('edge');\n const edge: FlowEdge = {\n id,\n source,\n target,\n sourceHandle,\n targetHandle,\n type,\n data: { ...DEFAULT_EDGE_DATA, ...data },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n // Prevent duplicates\n const exists = canvas.edges.some(e => e.source === source && e.target === target);\n if (exists) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, edges: [...canvas.edges, edge] },\n },\n };\n });\n return id;\n },\n [setDoc, currentCanvasId],\n );\n\n const updateEdge = useCallback(\n (id: string, updates: Partial<Pick<FlowEdge, 'type'>> & { data?: Partial<FlowEdgeData> }) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== id) return e;\n return {\n ...e,\n ...(updates.type !== undefined ? { type: updates.type } : {}),\n data: updates.data ? { ...e.data, ...updates.data } : e.data,\n };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateWaypoint = useCallback(\n (edgeId: string, waypointIndex: number, x: number, y: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId || !e.data.waypoints) return e;\n const wps = [...e.data.waypoints];\n wps[waypointIndex] = { x, y };\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const addWaypoint = useCallback(\n (edgeId: string, x: number, y: number, insertIndex?: number) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const wps = [...(e.data.waypoints ?? [])];\n const idx = insertIndex ?? wps.length;\n wps.splice(idx, 0, { x, y });\n return { ...e, data: { ...e.data, waypoints: wps } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateBezierControl = useCallback(\n (edgeId: string, segIndex: number, control: FlowBezierControl) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.map(e => {\n if (e.id !== edgeId) return e;\n const ctrls = [...(e.data.bezierControls ?? [])];\n while (ctrls.length <= segIndex) ctrls.push(null);\n ctrls[segIndex] = control;\n return { ...e, data: { ...e.data, bezierControls: ctrls } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteEdges = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n edges: canvas.edges.filter(e => !ids.has(e.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addEdge, updateEdge, updateWaypoint, addWaypoint, updateBezierControl, deleteEdges };\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { useFlowContext as M } from "../context/FlowContext.js";
2
- import { useCallback as b } from "react";
3
- function I() {
4
- const { setDoc: u, currentCanvasId: h, selection: g, currentCanvas: m } = M();
1
+ import { useFlowContext as b } from "../context/FlowContext.js";
2
+ import { useCallback as w } from "react";
3
+ function k() {
4
+ const { setDoc: u, currentCanvasId: h, selection: g, currentCanvas: m } = b();
5
5
  return {
6
- align: b((l) => {
6
+ align: w((l) => {
7
7
  const p = g.nodeIds;
8
8
  if (p.size < 2) return;
9
9
  const a = m.nodes.filter((t) => p.has(t.id));
@@ -27,7 +27,6 @@ function I() {
27
27
  break;
28
28
  case "center-v":
29
29
  e = a.reduce((t, i) => t + i.position.y + i.height / 2, 0) / a.length;
30
- break;
31
30
  }
32
31
  u((t) => {
33
32
  const i = t.canvases[h];
@@ -58,7 +57,6 @@ function I() {
58
57
  break;
59
58
  case "center-v":
60
59
  c = e - o.height / 2;
61
- break;
62
60
  }
63
61
  return {
64
62
  ...o,
@@ -78,7 +76,7 @@ function I() {
78
76
  g,
79
77
  m
80
78
  ]),
81
- distribute: b((l) => {
79
+ distribute: w((l) => {
82
80
  const p = g.nodeIds;
83
81
  if (p.size < 3) return;
84
82
  const a = m.nodes.filter((o) => p.has(o.id));
@@ -147,12 +145,12 @@ function I() {
147
145
  g,
148
146
  m
149
147
  ]),
150
- changeZIndex: b((l) => {
148
+ changeZIndex: w((l) => {
151
149
  const p = g.nodeIds, a = g.lineIds;
152
150
  p.size === 0 && a.size === 0 || u((e) => {
153
151
  const t = e.canvases[h];
154
152
  if (!t) return e;
155
- const i = t.nodes.map((n) => n.zIndex ?? 0), o = i.length > 0 ? Math.max(...i) : 0, d = i.length > 0 ? Math.min(...i) : 0, c = t.lines.map((n) => n.zIndex ?? 0), f = c.length > 0 ? Math.max(...c) : 0, s = c.length > 0 ? Math.min(...c) : 0, r = (n, x, w) => l === "front" ? x + 1 : l === "back" ? w - 1 : l === "up" ? n + 1 : n - 1;
153
+ const i = t.nodes.map((n) => n.zIndex ?? 0), o = i.length > 0 ? Math.max(...i) : 0, d = i.length > 0 ? Math.min(...i) : 0, c = t.lines.map((n) => n.zIndex ?? 0), f = c.length > 0 ? Math.max(...c) : 0, s = c.length > 0 ? Math.min(...c) : 0, r = (n, x, M) => l === "front" ? x + 1 : l === "back" ? M - 1 : l === "up" ? n + 1 : n - 1;
156
154
  return {
157
155
  ...e,
158
156
  canvases: {
@@ -179,7 +177,7 @@ function I() {
179
177
  };
180
178
  }
181
179
  export {
182
- I as useLayoutActions
180
+ k as useLayoutActions
183
181
  };
184
182
 
185
183
  //# sourceMappingURL=useLayoutActions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLayoutActions.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLayoutActions.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowNode } from '../types';\n\ntype Align = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom';\ntype Distribute = 'horizontal' | 'vertical';\ntype LayerMode = 'front' | 'back' | 'up' | 'down';\n\nexport function useLayoutActions() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n\n const align = useCallback(\n (direction: Align) => {\n const ids = selection.nodeIds;\n if (ids.size < 2) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 2) return;\n\n let target: number;\n switch (direction) {\n case 'left':\n target = Math.min(...nodes.map(n => n.position.x));\n break;\n case 'right':\n target = Math.max(...nodes.map(n => n.position.x + n.width));\n break;\n case 'center-h':\n target = nodes.reduce((s, n) => s + n.position.x + n.width / 2, 0) / nodes.length;\n break;\n case 'top':\n target = Math.min(...nodes.map(n => n.position.y));\n break;\n case 'bottom':\n target = Math.max(...nodes.map(n => n.position.y + n.height));\n break;\n case 'center-v':\n target = nodes.reduce((s, n) => s + n.position.y + n.height / 2, 0) / nodes.length;\n break;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n let newX = n.position.x;\n let newY = n.position.y;\n switch (direction) {\n case 'left': newX = target; break;\n case 'right': newX = target - n.width; break;\n case 'center-h': newX = target - n.width / 2; break;\n case 'top': newY = target; break;\n case 'bottom': newY = target - n.height; break;\n case 'center-v': newY = target - n.height / 2; break;\n }\n return { ...n, position: { x: newX, y: newY } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const distribute = useCallback(\n (direction: Distribute) => {\n const ids = selection.nodeIds;\n if (ids.size < 3) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 3) return;\n\n const sorted = [...nodes].sort((a, b) =>\n direction === 'horizontal'\n ? a.position.x - b.position.x\n : a.position.y - b.position.y,\n );\n\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n\n if (direction === 'horizontal') {\n const totalWidth = sorted.reduce((s, n) => s + n.width, 0);\n const totalSpace = (last.position.x + last.width) - first.position.x - totalWidth;\n const gap = totalSpace / (sorted.length - 1);\n let x = first.position.x;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, x);\n x += n.width + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newX = posMap.get(n.id);\n return newX !== undefined ? { ...n, position: { ...n.position, x: newX } } : n;\n }),\n },\n },\n };\n });\n } else {\n const totalHeight = sorted.reduce((s, n) => s + n.height, 0);\n const totalSpace = (last.position.y + last.height) - first.position.y - totalHeight;\n const gap = totalSpace / (sorted.length - 1);\n let y = first.position.y;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, y);\n y += n.height + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newY = posMap.get(n.id);\n return newY !== undefined ? { ...n, position: { ...n.position, y: newY } } : n;\n }),\n },\n },\n };\n });\n }\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const changeZIndex = useCallback(\n (mode: LayerMode) => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n if (nodeIds.size === 0 && lineIds.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const nodeAllZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const nodeMaxZ = nodeAllZ.length > 0 ? Math.max(...nodeAllZ) : 0;\n const nodeMinZ = nodeAllZ.length > 0 ? Math.min(...nodeAllZ) : 0;\n const lineAllZ = canvas.lines.map(l => l.zIndex ?? 0);\n const lineMaxZ = lineAllZ.length > 0 ? Math.max(...lineAllZ) : 0;\n const lineMinZ = lineAllZ.length > 0 ? Math.min(...lineAllZ) : 0;\n const applyZ = (z: number, maxZ: number, minZ: number) => {\n if (mode === 'front') return maxZ + 1;\n if (mode === 'back') return minZ - 1;\n if (mode === 'up') return z + 1;\n return z - 1;\n };\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, zIndex: applyZ(n.zIndex ?? 0, nodeMaxZ, nodeMinZ) } : n),\n lines: canvas.lines.map(l => lineIds.has(l.id) ? { ...l, zIndex: applyZ(l.zIndex ?? 0, lineMaxZ, lineMinZ) } : l),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection],\n );\n\n return { align, distribute, changeZIndex };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useLayoutActions.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLayoutActions.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowNode } from '../types';\n\ntype Align = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom';\ntype Distribute = 'horizontal' | 'vertical';\ntype LayerMode = 'front' | 'back' | 'up' | 'down';\n\nexport function useLayoutActions() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n\n const align = useCallback(\n (direction: Align) => {\n const ids = selection.nodeIds;\n if (ids.size < 2) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 2) return;\n\n let target: number;\n switch (direction) {\n case 'left':\n target = Math.min(...nodes.map(n => n.position.x));\n break;\n case 'right':\n target = Math.max(...nodes.map(n => n.position.x + n.width));\n break;\n case 'center-h':\n target = nodes.reduce((s, n) => s + n.position.x + n.width / 2, 0) / nodes.length;\n break;\n case 'top':\n target = Math.min(...nodes.map(n => n.position.y));\n break;\n case 'bottom':\n target = Math.max(...nodes.map(n => n.position.y + n.height));\n break;\n case 'center-v':\n target = nodes.reduce((s, n) => s + n.position.y + n.height / 2, 0) / nodes.length;\n break;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n let newX = n.position.x;\n let newY = n.position.y;\n switch (direction) {\n case 'left': newX = target; break;\n case 'right': newX = target - n.width; break;\n case 'center-h': newX = target - n.width / 2; break;\n case 'top': newY = target; break;\n case 'bottom': newY = target - n.height; break;\n case 'center-v': newY = target - n.height / 2; break;\n }\n return { ...n, position: { x: newX, y: newY } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const distribute = useCallback(\n (direction: Distribute) => {\n const ids = selection.nodeIds;\n if (ids.size < 3) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 3) return;\n\n const sorted = [...nodes].sort((a, b) =>\n direction === 'horizontal'\n ? a.position.x - b.position.x\n : a.position.y - b.position.y,\n );\n\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n\n if (direction === 'horizontal') {\n const totalWidth = sorted.reduce((s, n) => s + n.width, 0);\n const totalSpace = (last.position.x + last.width) - first.position.x - totalWidth;\n const gap = totalSpace / (sorted.length - 1);\n let x = first.position.x;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, x);\n x += n.width + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newX = posMap.get(n.id);\n return newX !== undefined ? { ...n, position: { ...n.position, x: newX } } : n;\n }),\n },\n },\n };\n });\n } else {\n const totalHeight = sorted.reduce((s, n) => s + n.height, 0);\n const totalSpace = (last.position.y + last.height) - first.position.y - totalHeight;\n const gap = totalSpace / (sorted.length - 1);\n let y = first.position.y;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, y);\n y += n.height + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newY = posMap.get(n.id);\n return newY !== undefined ? { ...n, position: { ...n.position, y: newY } } : n;\n }),\n },\n },\n };\n });\n }\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const changeZIndex = useCallback(\n (mode: LayerMode) => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n if (nodeIds.size === 0 && lineIds.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const nodeAllZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const nodeMaxZ = nodeAllZ.length > 0 ? Math.max(...nodeAllZ) : 0;\n const nodeMinZ = nodeAllZ.length > 0 ? Math.min(...nodeAllZ) : 0;\n const lineAllZ = canvas.lines.map(l => l.zIndex ?? 0);\n const lineMaxZ = lineAllZ.length > 0 ? Math.max(...lineAllZ) : 0;\n const lineMinZ = lineAllZ.length > 0 ? Math.min(...lineAllZ) : 0;\n const applyZ = (z: number, maxZ: number, minZ: number) => {\n if (mode === 'front') return maxZ + 1;\n if (mode === 'back') return minZ - 1;\n if (mode === 'up') return z + 1;\n return z - 1;\n };\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, zIndex: applyZ(n.zIndex ?? 0, nodeMaxZ, nodeMinZ) } : n),\n lines: canvas.lines.map(l => lineIds.has(l.id) ? { ...l, zIndex: applyZ(l.zIndex ?? 0, lineMaxZ, lineMinZ) } : l),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection],\n );\n\n return { align, distribute, changeZIndex };\n}\n"],"mappings":";;AAQA,SAAgB,IAAmB;AACjC,QAAM,EAAE,QAAA,GAAQ,iBAAA,GAAiB,WAAA,GAAW,eAAA,EAAA,IAAkB,EAAe;AAiL7E,SAAO;AAAA,IAAE,OA/KK,EAAA,CACX,MAAqB;AACpB,YAAM,IAAM,EAAU;AACtB,UAAI,EAAI,OAAO,EAAG;AAClB,YAAM,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAI,IAAI,EAAE,EAAE,CAAC;AAC3D,UAAI,EAAM,SAAS,EAAG;AAEtB,UAAI;AACJ,cAAQ,GAAR;AAAA,QACE,KAAK;AACH,UAAA,IAAS,KAAK,IAAI,GAAG,EAAM,IAAA,CAAI,MAAK,EAAE,SAAS,CAAC,CAAC;AACjD;AAAA,QACF,KAAK;AACH,UAAA,IAAS,KAAK,IAAI,GAAG,EAAM,IAAA,CAAI,MAAK,EAAE,SAAS,IAAI,EAAE,KAAK,CAAC;AAC3D;AAAA,QACF,KAAK;AACH,UAAA,IAAS,EAAM,OAAA,CAAQ,GAAG,MAAM,IAAI,EAAE,SAAS,IAAI,EAAE,QAAQ,GAAG,CAAC,IAAI,EAAM;AAC3E;AAAA,QACF,KAAK;AACH,UAAA,IAAS,KAAK,IAAI,GAAG,EAAM,IAAA,CAAI,MAAK,EAAE,SAAS,CAAC,CAAC;AACjD;AAAA,QACF,KAAK;AACH,UAAA,IAAS,KAAK,IAAI,GAAG,EAAM,IAAA,CAAI,MAAK,EAAE,SAAS,IAAI,EAAE,MAAM,CAAC;AAC5D;AAAA,QACF,KAAK;AACH,UAAA,IAAS,EAAM,OAAA,CAAQ,GAAG,MAAM,IAAI,EAAE,SAAS,IAAI,EAAE,SAAS,GAAG,CAAC,IAAI,EAAM;AAAA,MAEhF;AAEA,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAK;AAC3B,oBAAI,CAAC,EAAI,IAAI,EAAE,EAAE,EAAG,QAAO;AAC3B,oBAAI,IAAO,EAAE,SAAS,GAClB,IAAO,EAAE,SAAS;AACtB,wBAAQ,GAAR;AAAA,kBACE,KAAK;AAAQ,oBAAA,IAAO;AAAQ;AAAA,kBAC5B,KAAK;AAAS,oBAAA,IAAO,IAAS,EAAE;AAAO;AAAA,kBACvC,KAAK;AAAY,oBAAA,IAAO,IAAS,EAAE,QAAQ;AAAG;AAAA,kBAC9C,KAAK;AAAO,oBAAA,IAAO;AAAQ;AAAA,kBAC3B,KAAK;AAAU,oBAAA,IAAO,IAAS,EAAE;AAAQ;AAAA,kBACzC,KAAK;AAAY,oBAAA,IAAO,IAAS,EAAE,SAAS;AAAA,gBAC9C;AACA,uBAAO;AAAA,kBAAE,GAAG;AAAA,kBAAG,UAAU;AAAA,oBAAE,GAAG;AAAA,oBAAM,GAAG;AAAA,kBAAK;AAAA,gBAAE;AAAA,cAChD,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,IAvBoB;AAAA,MAwBtB,CAAC;AAAA,IACH,GACA;AAAA,MAAC;AAAA,MAAQ;AAAA,MAAiB;AAAA,MAAW;AAAA,IAAa,CAsH3C;AAAA,IAAO,YAnHG,EAAA,CAChB,MAA0B;AACzB,YAAM,IAAM,EAAU;AACtB,UAAI,EAAI,OAAO,EAAG;AAClB,YAAM,IAAQ,EAAc,MAAM,OAAA,CAAO,MAAK,EAAI,IAAI,EAAE,EAAE,CAAC;AAC3D,UAAI,EAAM,SAAS,EAAG;AAEtB,YAAM,IAAS,CAAC,GAAG,CAAK,EAAE,KAAA,CAAM,GAAG,MACjC,MAAc,eACV,EAAE,SAAS,IAAI,EAAE,SAAS,IAC1B,EAAE,SAAS,IAAI,EAAE,SAAS,CAChC,GAEM,IAAQ,EAAO,CAAA,GACf,IAAO,EAAO,EAAO,SAAS,CAAA;AAEpC,UAAI,MAAc,cAAc;AAC9B,cAAM,IAAa,EAAO,OAAA,CAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,GAEnD,KADc,EAAK,SAAS,IAAI,EAAK,QAAS,EAAM,SAAS,IAAI,MAC7C,EAAO,SAAS;AAC1C,YAAI,IAAI,EAAM,SAAS;AAEvB,cAAM,IAAS,oBAAI,IAAoB;AACvC,mBAAW,KAAK;AACd,UAAA,EAAO,IAAI,EAAE,IAAI,CAAC,GAClB,KAAK,EAAE,QAAQ;AAGjB,QAAA,EAAA,CAAO,MAAQ;AACb,gBAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,iBAAK,IACE;AAAA,YACL,GAAG;AAAA,YACH,UAAU;AAAA,cACR,GAAG,EAAK;AAAA,cACP,CAAA,CAAA,GAAkB;AAAA,gBACjB,GAAG;AAAA,gBACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAK;AAC3B,wBAAM,IAAO,EAAO,IAAI,EAAE,EAAE;AAC5B,yBAAO,MAAS,SAAY;AAAA,oBAAE,GAAG;AAAA,oBAAG,UAAU;AAAA,sBAAE,GAAG,EAAE;AAAA,sBAAU;AAAA,oBAAQ;AAAA,kBAAE,IAAI;AAAA,gBAC/E,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,IAboB;AAAA,QActB,CAAC;AAAA,MACH,OAAO;AACL,cAAM,IAAc,EAAO,OAAA,CAAQ,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC,GAErD,KADc,EAAK,SAAS,IAAI,EAAK,SAAU,EAAM,SAAS,IAAI,MAC9C,EAAO,SAAS;AAC1C,YAAI,IAAI,EAAM,SAAS;AAEvB,cAAM,IAAS,oBAAI,IAAoB;AACvC,mBAAW,KAAK;AACd,UAAA,EAAO,IAAI,EAAE,IAAI,CAAC,GAClB,KAAK,EAAE,SAAS;AAGlB,QAAA,EAAA,CAAO,MAAQ;AACb,gBAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,iBAAK,IACE;AAAA,YACL,GAAG;AAAA,YACH,UAAU;AAAA,cACR,GAAG,EAAK;AAAA,cACP,CAAA,CAAA,GAAkB;AAAA,gBACjB,GAAG;AAAA,gBACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAK;AAC3B,wBAAM,IAAO,EAAO,IAAI,EAAE,EAAE;AAC5B,yBAAO,MAAS,SAAY;AAAA,oBAAE,GAAG;AAAA,oBAAG,UAAU;AAAA,sBAAE,GAAG,EAAE;AAAA,sBAAU,GAAG;AAAA,oBAAK;AAAA,kBAAE,IAAI;AAAA,gBAC/E,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,IAboB;AAAA,QActB,CAAC;AAAA,MACH;AAAA,IACF,GACA;AAAA,MAAC;AAAA,MAAQ;AAAA,MAAiB;AAAA,MAAW;AAAA,IAAa,CAuCpC;AAAA,IAAY,cApCP,EAAA,CAClB,MAAoB;AACnB,YAAM,IAAU,EAAU,SACpB,IAAU,EAAU;AAC1B,MAAI,EAAQ,SAAS,KAAK,EAAQ,SAAS,KAC3C,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,YAAI,CAAC,EAAQ,QAAO;AACpB,cAAM,IAAW,EAAO,MAAM,IAAA,CAAI,MAAK,EAAE,UAAU,CAAC,GAC9C,IAAW,EAAS,SAAS,IAAI,KAAK,IAAI,GAAG,CAAQ,IAAI,GACzD,IAAW,EAAS,SAAS,IAAI,KAAK,IAAI,GAAG,CAAQ,IAAI,GACzD,IAAW,EAAO,MAAM,IAAA,CAAI,MAAK,EAAE,UAAU,CAAC,GAC9C,IAAW,EAAS,SAAS,IAAI,KAAK,IAAI,GAAG,CAAQ,IAAI,GACzD,IAAW,EAAS,SAAS,IAAI,KAAK,IAAI,GAAG,CAAQ,IAAI,GACzD,IAAA,CAAU,GAAW,GAAc,MACnC,MAAS,UAAgB,IAAO,IAChC,MAAS,SAAe,IAAO,IAC/B,MAAS,OAAa,IAAI,IACvB,IAAI;AAEb,eAAO;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAK,EAAQ,IAAI,EAAE,EAAE,IAAI;AAAA,gBAAE,GAAG;AAAA,gBAAG,QAAQ,EAAO,EAAE,UAAU,GAAG,GAAU,CAAQ;AAAA,cAAE,IAAI,CAAC;AAAA,cAChH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAK,EAAQ,IAAI,EAAE,EAAE,IAAI;AAAA,gBAAE,GAAG;AAAA,gBAAG,QAAQ,EAAO,EAAE,UAAU,GAAG,GAAU,CAAQ;AAAA,cAAE,IAAI,CAAC;AAAA,YAClH;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,GACA;AAAA,MAAC;AAAA,MAAQ;AAAA,MAAiB;AAAA,IAAS,CAGT;AAAA,EAAa;AAC3C"}
@@ -1 +1 @@
1
- {"version":3,"file":"useLineMutations.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLineMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowLine } from '../types';\n\nexport function useLineMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addLine = useCallback(\n (line: FlowLine) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, lines: [...canvas.lines, line] },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateLine = useCallback(\n (id: string, updates: Partial<Omit<FlowLine, 'id'>>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.map(l => (l.id === id ? { ...l, ...updates } : l)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteLines = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.filter(l => !ids.has(l.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addLine, updateLine, deleteLines };\n}\n"],"mappings":";;AAIA,SAAgB,IAAmB;AACjC,QAAM,EAAE,QAAA,GAAQ,iBAAA,EAAA,IAAoB,EAAe;AA2DnD,SAAO;AAAA,IAAE,SAzDO,EAAA,CACb,MAAmB;AAClB,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,aACP,CAAA,GAAkB;AAAA,cAAE,GAAG;AAAA,cAAQ,OAAO,CAAC,GAAG,EAAO,OAAO,CAAI;AAAA,YAAE;AAAA,UACjE;AAAA,QACF,IAPoB;AAAA,MAQtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CA2CjB;AAAA,IAAS,YAxCC,EAAA,CAChB,GAAY,MAA2C;AACtD,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,aACP,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAM,EAAE,OAAO,IAAK;AAAA,gBAAE,GAAG;AAAA,gBAAG,GAAG;AAAA,cAAQ,IAAI,CAAE;AAAA,YACvE;AAAA,UACF;AAAA,QACF,IAVoB;AAAA,MAWtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CAuBR;AAAA,IAAY,aApBV,EAAA,CACjB,MAAqB;AACpB,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,aACP,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,OAAA,CAAO,MAAK,CAAC,EAAI,IAAI,EAAE,EAAE,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,QACF,IAVoB;AAAA,MAWtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CAGI;AAAA,EAAY;AAC5C"}
1
+ {"version":3,"file":"useLineMutations.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLineMutations.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowLine } from '../types';\n\nexport function useLineMutations() {\n const { setDoc, currentCanvasId } = useFlowContext();\n\n const addLine = useCallback(\n (line: FlowLine) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: { ...canvas, lines: [...canvas.lines, line] },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const updateLine = useCallback(\n (id: string, updates: Partial<Omit<FlowLine, 'id'>>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.map(l => (l.id === id ? { ...l, ...updates } : l)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n const deleteLines = useCallback(\n (ids: Set<string>) => {\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n lines: canvas.lines.filter(l => !ids.has(l.id)),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId],\n );\n\n return { addLine, updateLine, deleteLines };\n}\n"],"mappings":";;AAIA,SAAgB,IAAmB;AACjC,QAAM,EAAE,QAAA,GAAQ,iBAAA,EAAA,IAAoB,EAAe;AA2DnD,SAAO;AAAA,IAAE,SAzDO,EAAA,CACb,MAAmB;AAClB,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cAAE,GAAG;AAAA,cAAQ,OAAO,CAAC,GAAG,EAAO,OAAO,CAAI;AAAA,YAAE;AAAA,UACjE;AAAA,QACF,IAPoB;AAAA,MAQtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CA2CjB;AAAA,IAAS,YAxCC,EAAA,CAChB,GAAY,MAA2C;AACtD,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,IAAA,CAAI,MAAM,EAAE,OAAO,IAAK;AAAA,gBAAE,GAAG;AAAA,gBAAG,GAAG;AAAA,cAAQ,IAAI,CAAE;AAAA,YACvE;AAAA,UACF;AAAA,QACF,IAVoB;AAAA,MAWtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CAuBR;AAAA,IAAY,aApBV,EAAA,CACjB,MAAqB;AACpB,MAAA,EAAA,CAAO,MAAQ;AACb,cAAM,IAAS,EAAK,SAAS,CAAA;AAC7B,eAAK,IACE;AAAA,UACL,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,EAAK;AAAA,YACP,CAAA,CAAA,GAAkB;AAAA,cACjB,GAAG;AAAA,cACH,OAAO,EAAO,MAAM,OAAA,CAAO,MAAK,CAAC,EAAI,IAAI,EAAE,EAAE,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,QACF,IAVoB;AAAA,MAWtB,CAAC;AAAA,IACH,GACA,CAAC,GAAQ,CAAe,CAGI;AAAA,EAAY;AAC5C"}