dishui 0.0.49 → 0.0.50

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 (52) hide show
  1. package/dist/components/pro/Flow/Flow.js +419 -407
  2. package/dist/components/pro/Flow/Flow.js.map +1 -1
  3. package/dist/components/pro/Flow/archify/build.d.ts +74 -0
  4. package/dist/components/pro/Flow/archify/build.js +103 -0
  5. package/dist/components/pro/Flow/archify/build.js.map +1 -0
  6. package/dist/components/pro/Flow/archify/convert.d.ts +14 -0
  7. package/dist/components/pro/Flow/archify/convert.js +534 -0
  8. package/dist/components/pro/Flow/archify/convert.js.map +1 -0
  9. package/dist/components/pro/Flow/archify/index.d.ts +12 -0
  10. package/dist/components/pro/Flow/archify/palette.d.ts +64 -0
  11. package/dist/components/pro/Flow/archify/palette.js +112 -0
  12. package/dist/components/pro/Flow/archify/palette.js.map +1 -0
  13. package/dist/components/pro/Flow/archify/presets.d.ts +26 -0
  14. package/dist/components/pro/Flow/archify/presets.js +43 -0
  15. package/dist/components/pro/Flow/archify/presets.js.map +1 -0
  16. package/dist/components/pro/Flow/archify/spec.d.ts +283 -0
  17. package/dist/components/pro/Flow/archify/spec.js +10 -0
  18. package/dist/components/pro/Flow/archify/spec.js.map +1 -0
  19. package/dist/components/pro/Flow/constants.js +14 -0
  20. package/dist/components/pro/Flow/constants.js.map +1 -1
  21. package/dist/components/pro/Flow/hooks/useClipboard.d.ts +5 -0
  22. package/dist/components/pro/Flow/hooks/useClipboard.js +129 -73
  23. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  24. package/dist/components/pro/Flow/hooks/useFlowImportExport.d.ts +1 -0
  25. package/dist/components/pro/Flow/hooks/useFlowImportExport.js +108 -93
  26. package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
  27. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.d.ts +1 -0
  28. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js +7 -7
  29. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  30. package/dist/components/pro/Flow/index.d.ts +2 -0
  31. package/dist/components/pro/Flow/nodes/DataNodeView.d.ts +4 -1
  32. package/dist/components/pro/Flow/nodes/DataNodeView.js +127 -115
  33. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  34. package/dist/components/pro/Flow/nodes/MediaContent.js +72 -67
  35. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  36. package/dist/components/pro/Flow/nodes/NodeRenderer.d.ts +5 -0
  37. package/dist/components/pro/Flow/nodes/NodeRenderer.js +216 -115
  38. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  39. package/dist/components/pro/Flow/panels/FlowToolbar.js +208 -169
  40. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  41. package/dist/components/pro/Flow/panels/InspectorPanel.js +602 -369
  42. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  43. package/dist/components/pro/Flow/panels/ShapePalette.js +50 -39
  44. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  45. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +1 -0
  46. package/dist/components/pro/Flow/panels/toolbarIcons.js +36 -8
  47. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  48. package/dist/components/pro/Flow/types.d.ts +30 -0
  49. package/dist/components/pro/Flow/types.js.map +1 -1
  50. package/dist/dishui.css +1 -1
  51. package/dist/flow.js +73 -56
  52. package/package.json +18 -17
@@ -1 +1 @@
1
- {"version":3,"file":"Flow.js","names":[],"sources":["../../../../src/components/pro/Flow/Flow.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';\nimport { FlowProvider, useFlowContext } from './context/FlowContext';\nimport { FlowUIProvider, useFlowUI } from './context/FlowUIContext';\nimport { FlowAIProvider } from './context/FlowAIContext';\nimport FlowCanvas from './FlowCanvas';\nimport FlowToolbar, { FlowZoomControls } from './panels/FlowToolbar';\nimport { ShapePaletteContent, SvgStampContent, MediaStampContent } from './panels/ShapePalette';\nimport { InspectorPanelContent } from './panels/InspectorPanel';\nimport { OutlinePanelContent } from './panels/OutlinePanel';\nimport { AIPanelContent } from './panels/AIPanel';\nimport { PresentationMode } from './panels/PresentationMode';\nimport { MediaOverlay } from './nodes/MediaOverlay';\nimport FlowPanelGroup, { type PanelTab } from './panels/FlowPanelGroup';\nimport Breadcrumb from './panels/Breadcrumb';\nimport ContextMenu from './panels/ContextMenu';\nimport type { ContextMenuItem } from './panels/ContextMenu';\nimport { MiniMapRenderer } from './canvas/MiniMapRenderer';\nimport { CodeEditor, type CodeEditorHandle } from '../CodeEditor';\nimport { EditorView } from '@codemirror/view';\nimport { useUndoRedo } from './hooks/useUndoRedo';\nimport { useClipboard } from './hooks/useClipboard';\nimport { downloadDataURL, safeFileBaseName } from './hooks/useFlowImportExport';\nimport { usePdfExport } from './hooks/usePdfExport';\nimport { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';\nimport { useMindMap } from './hooks/useMindMap';\nimport { createEmptyDocument, ROOT_CANVAS_ID, DEFAULT_NODE_DATA } from './constants';\nimport { normalizeEdgeHandles } from './edges/edgePaths';\nimport { generateId } from './nodes/nodeUtils';\nimport type { FlowProps, FlowDocument, FlowNode, SelectionState, FlowCanvasData } from './types';\nimport type { PixiApp } from './canvas/PixiApp';\nimport './styles.css';\n\nfunction normalizeDocument(doc: FlowDocument): FlowDocument {\n let changed = false;\n const canvases = { ...doc.canvases };\n for (const [id, canvas] of Object.entries(canvases)) {\n const nodes = canvas.nodes.map(node => {\n if (node.type !== 'shapeSvg') return node;\n const legacyPlacement = node.data.labelPlacement as string | undefined;\n const labelPlacement = legacyPlacement === 'above'\n ? 'top'\n : legacyPlacement === 'center'\n ? 'middle'\n : legacyPlacement === 'below'\n ? 'bottom'\n : node.data.labelPlacement;\n if (labelPlacement === node.data.labelPlacement) return node;\n changed = true;\n return { ...node, data: { ...node.data, labelPlacement } };\n });\n const nodeMap = new Map<string, FlowNode>();\n for (const node of nodes) nodeMap.set(node.id, node);\n const edges = normalizeEdgeHandles(canvas.edges, nodeMap);\n if (nodes !== canvas.nodes || edges !== canvas.edges) {\n canvases[id] = { ...canvas, nodes, edges };\n if (edges !== canvas.edges) changed = true;\n }\n }\n return changed ? { ...doc, canvases } : doc;\n}\n\nconst EMPTY_SELECTION: SelectionState = {\n nodeIds: new Set(),\n edgeIds: new Set(),\n lineIds: new Set(),\n};\n\nfunction FlowKeyboardShortcutsWire({ onUndo, onRedo, groupRef, geoGroupRef, ungroupRef }: {\n onUndo: () => void;\n onRedo: () => void;\n groupRef: React.MutableRefObject<(() => void) | null>;\n geoGroupRef: React.MutableRefObject<(() => void) | null>;\n ungroupRef: React.MutableRefObject<(() => void) | null>;\n}) {\n const { selection, setSelection, currentCanvas, setDoc, currentCanvasId } = useFlowContext();\n const { viewport } = useFlowUI();\n const { copy, cut, paste } = useClipboard();\n\n const deleteSelected = 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(EMPTY_SELECTION);\n }, [selection, setDoc, currentCanvasId, setSelection]);\n\n const selectAll = useCallback(() => {\n setSelection({\n nodeIds: new Set(currentCanvas.nodes.map(n => n.id)),\n edgeIds: new Set(currentCanvas.edges.map(e => e.id)),\n lineIds: new Set(currentCanvas.lines.map(l => l.id)),\n });\n }, [currentCanvas, setSelection]);\n\n const createGroup = useCallback((type: 'flowGroup' | 'geometryGroup') => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n const totalCount = nodeIds.size + lineIds.size;\n if (totalCount < 2) return;\n const nodes = currentCanvas.nodes.filter(n => nodeIds.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineIds.has(l.id));\n const PAD = 20;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of nodes) {\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + n.width);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n for (const l of lines) {\n for (const p of l.points) {\n minX = Math.min(minX, p.x); minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y);\n }\n }\n const isGeo = type === 'geometryGroup';\n const groupId = generateId('group');\n const groupNode: FlowNode = {\n id: groupId,\n type,\n position: { x: minX - PAD, y: minY - PAD },\n width: maxX - minX + PAD * 2,\n height: maxY - minY + PAD * 2,\n data: {\n ...DEFAULT_NODE_DATA,\n label: isGeo ? 'Geo Group' : 'Group',\n fill: isGeo ? '#fefce8' : '#f0f9ff',\n stroke: '#9ca3af', strokeWidth: 1.5,\n borderStyle: isGeo ? 'dashed' : 'dotted',\n isGroup: true,\n },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: isGeo\n ? [groupNode, ...canvas.nodes]\n : [groupNode, ...canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, parentId: groupId } : n)],\n lines: isGeo\n ? canvas.lines\n : canvas.lines.map(l => lineIds.has(l.id) ? { ...l, parentId: groupId } : l),\n }},\n };\n });\n setSelection({ nodeIds: new Set([groupId]), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, currentCanvas, setDoc, currentCanvasId, setSelection]);\n\n const groupSelected = useCallback(() => createGroup('flowGroup'), [createGroup]);\n const geoGroupSelected = useCallback(() => createGroup('geometryGroup'), [createGroup]);\n\n const ungroupSelected = useCallback(() => {\n const ids = selection.nodeIds;\n if (ids.size === 0) return;\n const groupNodeIds = new Set<string>();\n const childNodeIds = new Set<string>();\n const childLineIds = new Set<string>();\n for (const node of currentCanvas.nodes) {\n if (ids.has(node.id) && (node.type === 'flowGroup' || node.type === 'geometryGroup' || node.data.isGroup)) {\n groupNodeIds.add(node.id);\n }\n }\n if (groupNodeIds.size === 0) return;\n for (const node of currentCanvas.nodes) {\n if (node.parentId && groupNodeIds.has(node.parentId)) {\n childNodeIds.add(node.id);\n }\n }\n for (const line of currentCanvas.lines) {\n if (line.parentId && groupNodeIds.has(line.parentId)) {\n childLineIds.add(line.id);\n }\n }\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !groupNodeIds.has(n.id))\n .map(n => childNodeIds.has(n.id) ? { ...n, parentId: undefined } : n),\n lines: canvas.lines\n .map(l => childLineIds.has(l.id) ? { ...l, parentId: undefined } : l),\n }},\n };\n });\n setSelection({ nodeIds: childNodeIds, edgeIds: new Set(), lineIds: childLineIds });\n }, [selection, currentCanvas, setDoc, currentCanvasId, setSelection]);\n\n groupRef.current = groupSelected;\n geoGroupRef.current = geoGroupSelected;\n ungroupRef.current = ungroupSelected;\n\n const changeZIndex = useCallback((mode: 'front' | 'back' | 'up' | 'down') => {\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: { ...prev.canvases, [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 }, [selection, setDoc, currentCanvasId]);\n\n useEffect(() => {\n const handlePaste = (event: ClipboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (target?.tagName === 'INPUT' || target?.tagName === 'TEXTAREA' || target?.isContentEditable) return;\n\n const imageItem = Array.from(event.clipboardData?.items ?? []).find(item => item.type.startsWith('image/'));\n if (!imageItem) {\n event.preventDefault();\n paste();\n return;\n }\n\n const file = imageItem.getAsFile();\n if (!file) return;\n event.preventDefault();\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result !== 'string') return;\n const selectedImage = selection.nodeIds.size === 1\n ? currentCanvas.nodes.find(node => selection.nodeIds.has(node.id) && node.type === 'mediaNode' && node.data.mediaKind === 'image')\n : undefined;\n\n if (selectedImage) {\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(node => node.id === selectedImage.id\n ? { ...node, data: { ...node.data, mediaContent: reader.result as string } }\n : node),\n },\n },\n };\n });\n return;\n }\n\n const id = generateId('node');\n const width = 320;\n const height = 220;\n const screenWidth = window.innerWidth;\n const screenHeight = window.innerHeight;\n const centerX = (screenWidth / 2 - viewport.x) / viewport.zoom;\n const centerY = (screenHeight / 2 - viewport.y) / viewport.zoom;\n const highestZ = Math.max(0, ...currentCanvas.nodes.map(node => node.zIndex ?? 0));\n const imageNode: FlowNode = {\n id,\n type: 'mediaNode',\n position: { x: centerX - width / 2, y: centerY - height / 2 },\n width,\n height,\n zIndex: highestZ + 1,\n data: {\n ...DEFAULT_NODE_DATA,\n label: file.name || 'Image',\n fill: 'theme:base-100',\n stroke: 'theme:base-content',\n strokeWidth: 1.5,\n color: 'theme:base-content',\n fontSize: 13,\n borderStyle: 'solid',\n mediaKind: 'image',\n mediaContent: reader.result,\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]: { ...canvas, nodes: [...canvas.nodes, imageNode] },\n },\n };\n });\n setSelection({ nodeIds: new Set([id]), edgeIds: new Set(), lineIds: new Set() });\n };\n reader.readAsDataURL(file);\n };\n\n window.addEventListener('paste', handlePaste);\n return () => window.removeEventListener('paste', handlePaste);\n }, [currentCanvas, currentCanvasId, paste, selection, setDoc, setSelection, viewport]);\n\n const actions = useMemo(() => ({\n undo: onUndo, redo: onRedo, copy, cut, paste, deleteSelected, selectAll,\n group: groupSelected, geoGroup: geoGroupSelected, ungroup: ungroupSelected,\n bringToFront: () => changeZIndex('front'),\n bringForward: () => changeZIndex('up'),\n sendBackward: () => changeZIndex('down'),\n sendToBack: () => changeZIndex('back'),\n }), [onUndo, onRedo, copy, cut, paste, deleteSelected, selectAll, groupSelected, geoGroupSelected, ungroupSelected, changeZIndex]);\n\n useKeyboardShortcuts(actions);\n useMindMap();\n return null;\n}\n\n/**\n * Bridges the anchor→PDF export (which needs canvas/viewport context) out to the\n * toolbar in the outer Flow component via a ref. Renders nothing.\n */\nfunction PdfExportWire({\n pixiRef,\n exportPdfRef,\n}: {\n pixiRef: React.RefObject<PixiApp | null>;\n exportPdfRef: React.MutableRefObject<(() => Promise<boolean>) | null>;\n}) {\n const exportPdf = usePdfExport(pixiRef);\n exportPdfRef.current = exportPdf;\n return null;\n}\n\n/** Imperative handle exposed via a ref on the `<Flow>` component. */\nexport interface FlowHandle {\n /** Export the current diagram to a PNG data URL (null if unavailable). */\n exportPNG: (backgroundColor?: number) => Promise<string | null>;\n /** Get the current document. */\n getDocument: () => FlowDocument;\n}\n\nconst Flow = forwardRef<FlowHandle, FlowProps>(function Flow({\n initialDocument,\n onChange,\n width,\n height,\n readOnly = false,\n onBack,\n onExportPNG,\n onPublish,\n showMiniMap = true,\n showGrid = true,\n gridSize = 20,\n className,\n showAI = true,\n showAIConfig = true,\n aiConfig,\n}: FlowProps, ref) {\n const [doc, setDoc] = useState<FlowDocument>(() => normalizeDocument(initialDocument ?? createEmptyDocument()));\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION);\n const pixiRef = useRef<PixiApp | null>(null);\n const miniMapCanvasRef = useRef<HTMLCanvasElement>(null);\n const miniMapRef = useRef<MiniMapRenderer | null>(null);\n\n const { wrappedSetDoc, undo, redo, canUndo, canRedo } = useUndoRedo(doc, setDoc);\n const groupRef = useRef<(() => void) | null>(null);\n const geoGroupRef = useRef<(() => void) | null>(null);\n const ungroupRef = useRef<(() => void) | null>(null);\n const exportPdfRef = useRef<(() => Promise<boolean>) | null>(null);\n\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n // Keep the latest doc in a ref for the imperative handle.\n const docRef = useRef(doc);\n docRef.current = doc;\n\n useImperativeHandle(ref, () => ({\n exportPNG: async (backgroundColor?: number) => {\n const pixi = pixiRef.current;\n if (!pixi || pixi.destroyed) return null;\n return pixi.exportPNG(backgroundColor);\n },\n getDocument: () => docRef.current,\n }), []);\n\n const outerSetDoc: React.Dispatch<React.SetStateAction<FlowDocument>> = useCallback(\n (action) => {\n wrappedSetDoc(prev => {\n const next = typeof action === 'function' ? action(prev) : action;\n queueMicrotask(() => onChangeRef.current?.(next));\n return next;\n });\n },\n [wrappedSetDoc],\n );\n\n const handlePixiReady = useCallback((pixi: PixiApp) => {\n pixiRef.current = pixi;\n if (miniMapCanvasRef.current && !miniMapRef.current) {\n miniMapRef.current = new MiniMapRenderer(miniMapCanvasRef.current);\n }\n }, []);\n\n // Built-in PNG export: if the host supplies `onExportPNG` we defer to it,\n // otherwise snapshot the Pixi scene and download it directly so the toolbar\n // button always works out of the box.\n const handleExportPNG = useCallback(async () => {\n if (onExportPNG) return void onExportPNG();\n const pixi = pixiRef.current;\n if (!pixi || pixi.destroyed) return;\n const url = await pixi.exportPNG(0xffffff);\n if (url) downloadDataURL(url, `${safeFileBaseName(docRef.current.title)}.png`);\n }, [onExportPNG]);\n\n // Built-in PDF export: capture each anchor's presentation framing into a\n // multi-page PDF (implemented by PdfExportWire inside the providers).\n const handleExportPDF = useCallback(async () => {\n await exportPdfRef.current?.();\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n let subscribed: PixiApp | null = null;\n\n const tickerFn = () => {\n const pixi = pixiRef.current;\n const mm = miniMapRef.current;\n if (!pixi || pixi.destroyed || !mm) return;\n const vp = { x: pixi.world.position.x, y: pixi.world.position.y, zoom: pixi.world.scale.x };\n const currentId = doc.stack[doc.stack.length - 1] ?? ROOT_CANVAS_ID;\n const canvas = doc.canvases[currentId];\n if (canvas) mm.update(canvas.nodes, vp, pixi.app.screen.width, pixi.app.screen.height);\n };\n\n // Pixi initializes asynchronously; the minimap renderer is created in\n // handlePixiReady. Poll until both exist, then attach the ticker. This\n // avoids a race where the effect runs before pixi is ready and the minimap\n // stays blank until the next document edit.\n const attach = () => {\n if (cancelled) return;\n const pixi = pixiRef.current;\n if (pixi && !pixi.destroyed && miniMapRef.current) {\n pixi.app.ticker.add(tickerFn);\n subscribed = pixi;\n } else {\n requestAnimationFrame(attach);\n }\n };\n attach();\n\n return () => {\n cancelled = true;\n if (subscribed && !subscribed.destroyed) subscribed.app.ticker.remove(tickerFn);\n };\n }, [doc]);\n\n const style: React.CSSProperties = { width: width ?? '100%', height: height ?? '100%' };\n\n return (\n <div className={`flow-container ${className ?? ''}`} style={style}>\n <FlowProvider doc={doc} setDoc={outerSetDoc} selection={selection} setSelection={setSelection}>\n <FlowUIProvider showMiniMap={showMiniMap} showGrid={showGrid} gridSize={gridSize} showAI={showAI}>\n <FlowAIProvider initialConfig={aiConfig} showAIConfig={showAIConfig}>\n <FlowKeyboardShortcutsWire onUndo={undo} onRedo={redo} groupRef={groupRef} geoGroupRef={geoGroupRef} ungroupRef={ungroupRef} />\n <PdfExportWire pixiRef={pixiRef} exportPdfRef={exportPdfRef} />\n <UnifiedPanelGroup\n toolbar={!readOnly ? (\n <FlowToolbar\n onBack={onBack}\n onUndo={undo} onRedo={redo} canUndo={canUndo} canRedo={canRedo}\n onGroup={() => groupRef.current?.()} onGeoGroup={() => geoGroupRef.current?.()} onUngroup={() => ungroupRef.current?.()}\n onExportPNG={handleExportPNG}\n onExportPDF={handleExportPDF}\n onPublish={onPublish}\n />\n ) : null}\n >\n <FlowCanvas onPixiReady={handlePixiReady} />\n {/* Media content (markdown/mermaid/data/…) must stay visible in\n presentation & read-only preview — PixiJS only draws the node\n frame, so hiding this layer would blank every media node. */}\n <MediaOverlay />\n <PresentationGate>\n {!readOnly && <FlowZoomControls />}\n <Breadcrumb />\n </PresentationGate>\n <FlowContextMenuWire />\n <MiniMapWrapper canvasRef={miniMapCanvasRef} pixiRef={pixiRef} miniMapRef={miniMapRef} />\n <PresentationMode />\n </UnifiedPanelGroup>\n </FlowAIProvider>\n </FlowUIProvider>\n </FlowProvider>\n </div>\n );\n});\n\nexport default Flow;\n\ninterface TabDef {\n id: string;\n label: string;\n icon: string;\n side: 'left' | 'right';\n showKey?: 'showPalette' | 'showInspector' | 'showOutline' | 'showJson' | 'showAI';\n}\n\n/**\n * Hides all editable overlay UI (toolbar, panels, breadcrumb) while in\n * presentation mode, keeping only the canvas visible for the slideshow.\n */\nfunction PresentationGate({ children }: { children: React.ReactNode }) {\n const { presentation } = useFlowUI();\n return (\n <div className=\"flow-overlay\" style={{ display: presentation ? 'none' : undefined }}>\n {children}\n </div>\n );\n}\n\nconst ALL_TAB_DEFS: TabDef[] = [\n { id: 'shapes', label: 'Shapes', icon: '▢', side: 'left', showKey: 'showPalette' },\n { id: 'icons', label: 'Icons', icon: '★', side: 'left', showKey: 'showPalette' },\n { id: 'media', label: 'Media', icon: '▶', side: 'left', showKey: 'showPalette' },\n { id: 'inspector', label: 'Inspector', icon: '⚙', side: 'right', showKey: 'showInspector' },\n { id: 'outline', label: 'Outline', icon: '☰', side: 'right', showKey: 'showOutline' },\n { id: 'json', label: 'JSON', icon: '{ }', side: 'right', showKey: 'showJson' },\n { id: 'ai', label: 'AI', icon: '✨', side: 'right', showKey: 'showAI' },\n];\n\nfunction tabContent(id: string): React.ReactNode {\n switch (id) {\n case 'shapes': return <ShapePaletteContent />;\n case 'icons': return <SvgStampContent />;\n case 'media': return <MediaStampContent />;\n case 'inspector': return <InspectorPanelContent />;\n case 'outline': return <OutlinePanelContent />;\n case 'json': return <JsonEditorPanel />;\n case 'ai': return <AIPanelContent />;\n default: return null;\n }\n}\n\nfunction UnifiedPanelGroup({ children, toolbar }: { children: React.ReactNode; toolbar?: React.ReactNode }) {\n const ui = useFlowUI();\n const { detachedTabs, toggleDetach, presentation } = ui;\n\n const visibleTabs = ALL_TAB_DEFS.filter(def =>\n !def.showKey || (ui as any)[def.showKey],\n );\n\n const toPanelTab = (def: TabDef): PanelTab => ({\n id: def.id, label: def.label, icon: def.icon, content: tabContent(def.id),\n });\n\n const leftTabs: PanelTab[] = visibleTabs\n .filter(def => def.side === 'left' && !detachedTabs.has(def.id))\n .map(toPanelTab);\n const rightTabs: PanelTab[] = visibleTabs\n .filter(def => def.side === 'right' && !detachedTabs.has(def.id))\n .map(toPanelTab);\n\n const detachedList = visibleTabs.filter(def => detachedTabs.has(def.id));\n\n const handleDetach = useCallback((tabId: string) => toggleDetach(tabId), [toggleDetach]);\n const handleAttach = useCallback((tabId: string) => toggleDetach(tabId), [toggleDetach]);\n\n return (\n <div className=\"flow-workspace\">\n {/* Slim full-width toolbar strip above panels + canvas. */}\n {!presentation && toolbar}\n <div className=\"flow-workspace-main\">\n {!presentation && leftTabs.length > 0 && (\n <FlowPanelGroup\n tabs={leftTabs}\n defaultTab={leftTabs[0]?.id}\n resizeEdge=\"right\"\n defaultWidth={132}\n onDetach={handleDetach}\n />\n )}\n <div className=\"flow-stage\">\n {children}\n </div>\n {!presentation && rightTabs.length > 0 && (\n <FlowPanelGroup\n tabs={rightTabs}\n defaultTab={rightTabs[0]?.id}\n resizeEdge=\"left\"\n defaultWidth={220}\n onDetach={handleDetach}\n />\n )}\n {/* Detached panels float above every docked panel. Rendered as a direct\n child of the (position:relative) workspace-main so they are not\n clipped by the stage's `overflow: hidden` and can overlap the side\n panels. */}\n {!presentation && detachedList.map((def, i) => (\n <FlowPanelGroup\n key={def.id}\n tabs={[toPanelTab(def)]}\n resizeEdge=\"right\"\n defaultWidth={220}\n style={{ top: 48 + i * 40, left: 24 + i * 30 }}\n isDetached\n onAttach={handleAttach}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MiniMapWrapper({\n canvasRef,\n pixiRef,\n miniMapRef,\n}: {\n canvasRef: React.RefObject<HTMLCanvasElement | null>;\n pixiRef: React.RefObject<PixiApp | null>;\n miniMapRef: React.RefObject<MiniMapRenderer | null>;\n}) {\n const { showMiniMap, setViewport, presentation } = useFlowUI();\n const draggingRef = useRef(false);\n\n // Move the main canvas so that the world point under the minimap click is\n // centered in the viewport. Routed through setViewport so the change syncs\n // with the ViewportManager (setting world.position directly would be\n // overwritten on the next viewport apply).\n const navigateTo = useCallback((clientX: number, clientY: number) => {\n const canvas = canvasRef.current;\n const pixi = pixiRef.current;\n const mm = miniMapRef.current;\n if (!canvas || !pixi || pixi.destroyed || !mm) return;\n\n const rect = canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return;\n // CSS pixels -> canvas backing pixels.\n const { width: cw, height: ch } = mm.size;\n const px = ((clientX - rect.left) / rect.width) * cw;\n const py = ((clientY - rect.top) / rect.height) * ch;\n\n const world = mm.minimapToWorld(px, py);\n if (!world) return;\n\n const zoom = pixi.world.scale.x || 1;\n const screenW = pixi.app.screen.width;\n const screenH = pixi.app.screen.height;\n setViewport({\n x: screenW / 2 - world.x * zoom,\n y: screenH / 2 - world.y * zoom,\n zoom,\n });\n }, [canvasRef, pixiRef, miniMapRef, setViewport]);\n\n const onPointerDown = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);\n draggingRef.current = true;\n navigateTo(e.clientX, e.clientY);\n }, [navigateTo]);\n\n const onPointerMove = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n navigateTo(e.clientX, e.clientY);\n }, [navigateTo]);\n\n const onPointerUp = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n draggingRef.current = false;\n try { (e.currentTarget as HTMLElement).releasePointerCapture(e.pointerId); } catch { /* noop */ }\n }, []);\n\n return (\n <div\n className=\"flow-minimap\"\n style={{ display: showMiniMap && !presentation ? undefined : 'none', cursor: 'pointer' }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n title=\"点击或拖动以移动画布\"\n >\n <canvas ref={canvasRef} width={180} height={120} style={{ width: '100%', height: '100%', pointerEvents: 'none' }} />\n </div>\n );\n}\n\n/**\n * Find the line range (1-based) of a JSON object with the given id.\n */\nfunction findElementLineRange(jsonStr: string, elementId: string): { startLine: number; endLine: number } | null {\n const idPattern = `\"id\": \"${elementId}\"`;\n const idx = jsonStr.indexOf(idPattern);\n if (idx === -1) return null;\n\n let braceDepth = 0;\n let startIdx = -1;\n for (let i = idx; i >= 0; i--) {\n if (jsonStr[i] === '}') braceDepth++;\n if (jsonStr[i] === '{') {\n if (braceDepth === 0) { startIdx = i; break; }\n braceDepth--;\n }\n }\n if (startIdx === -1) return null;\n\n braceDepth = 0;\n let endIdx = -1;\n for (let i = startIdx; i < jsonStr.length; i++) {\n if (jsonStr[i] === '{') braceDepth++;\n if (jsonStr[i] === '}') {\n braceDepth--;\n if (braceDepth === 0) { endIdx = i; break; }\n }\n }\n if (endIdx === -1) return null;\n\n const startLine = jsonStr.slice(0, startIdx).split('\\n').length;\n const endLine = jsonStr.slice(0, endIdx + 1).split('\\n').length;\n return { startLine, endLine };\n}\n\nfunction clearLineHighlights(container: HTMLElement) {\n container.querySelectorAll('.cm-line.flow-json-hl').forEach(el => el.classList.remove('flow-json-hl'));\n}\n\nfunction applyLineHighlightsViaView(handle: CodeEditorHandle, startLine: number, endLine: number) {\n const view = handle.getView();\n if (!view) return;\n for (let ln = startLine; ln <= endLine; ln++) {\n try {\n const lineInfo = view.state.doc.line(ln);\n const dom = view.domAtPos(lineInfo.from);\n const lineEl = dom.node instanceof HTMLElement\n ? dom.node.closest('.cm-line')\n : dom.node.parentElement?.closest('.cm-line');\n if (lineEl) lineEl.classList.add('flow-json-hl');\n } catch { /* line not in viewport */ }\n }\n}\n\nfunction JsonEditorPanel() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n const [jsonStr, setJsonStr] = useState('');\n const [error, setError] = useState<string | null>(null);\n const skipNextSync = useRef(false);\n const editorRef = useRef<CodeEditorHandle>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n\n const singleId = useMemo(() => {\n const total = selection.nodeIds.size + selection.edgeIds.size + selection.lineIds.size;\n if (total !== 1) return null;\n if (selection.nodeIds.size === 1) return [...selection.nodeIds][0];\n if (selection.edgeIds.size === 1) return [...selection.edgeIds][0];\n if (selection.lineIds.size === 1) return [...selection.lineIds][0];\n return null;\n }, [selection]);\n\n useEffect(() => {\n if (skipNextSync.current) { skipNextSync.current = false; return; }\n setJsonStr(JSON.stringify(currentCanvas, null, 2));\n setError(null);\n }, [currentCanvas]);\n\n useEffect(() => {\n const wrap = wrapRef.current;\n if (wrap) clearLineHighlights(wrap);\n if (!singleId) return;\n\n const timer = setTimeout(() => {\n const range = findElementLineRange(jsonStr, singleId);\n if (!range || !wrapRef.current) return;\n\n const view = editorRef.current?.getView();\n if (!view) return;\n\n const w = wrapRef.current;\n const scroller = view.scrollDOM;\n\n scroller.style.scrollBehavior = 'smooth';\n\n const lineInfo = view.state.doc.line(range.startLine);\n view.dispatch({\n effects: EditorView.scrollIntoView(lineInfo.from, { y: 'start', yMargin: 0 }),\n });\n\n const onScrollEnd = () => {\n scroller.style.scrollBehavior = '';\n clearLineHighlights(w);\n applyLineHighlightsViaView(editorRef.current!, range.startLine, range.endLine);\n };\n\n let scrollTimer: ReturnType<typeof setTimeout>;\n const onScroll = () => {\n clearTimeout(scrollTimer);\n scrollTimer = setTimeout(onScrollEnd, 100);\n };\n scroller.addEventListener('scroll', onScroll);\n scrollTimer = setTimeout(() => {\n scroller.removeEventListener('scroll', onScroll);\n onScrollEnd();\n }, 800);\n }, 120);\n return () => clearTimeout(timer);\n }, [singleId, jsonStr]);\n\n const handleChange = useCallback((value: string) => {\n setJsonStr(value);\n try {\n const parsed = JSON.parse(value);\n if (parsed && Array.isArray(parsed.nodes) && Array.isArray(parsed.edges) && Array.isArray(parsed.lines)) {\n setError(null);\n skipNextSync.current = true;\n setDoc(prev => ({\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: parsed },\n }));\n } else {\n setError('JSON must have nodes, edges, lines arrays');\n }\n } catch (e: any) {\n setError(e.message?.slice(0, 60) ?? 'Invalid JSON');\n }\n }, [setDoc, currentCanvasId]);\n\n const label = singleId\n ? (selection.nodeIds.has(singleId) ? 'Node' : selection.edgeIds.has(singleId) ? 'Edge' : 'Line')\n : null;\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}>\n <div className=\"flow-json-header\">\n <span className=\"flow-json-scope\">\n {label ? `${label}: ${singleId!.slice(0, 8)}` : `Canvas`}\n </span>\n </div>\n {error && (\n <div style={{ fontSize: 11, color: 'oklch(var(--er))', padding: '4px 0', flexShrink: 0 }}>\n {error}\n </div>\n )}\n <div ref={wrapRef} style={{ flex: 1, minHeight: 0 }}>\n <CodeEditor\n ref={editorRef}\n value={jsonStr}\n onChange={handleChange}\n language=\"json\"\n lineNumbers={false}\n height=\"100%\"\n highlightActiveLine={false}\n />\n </div>\n </div>\n );\n}\n\nfunction FlowContextMenuWire() {\n const { contextMenu, setContextMenu } = useFlowUI();\n const { doc, setDoc, currentCanvasId, pushCanvas, setSelection } = useFlowContext();\n\n if (!contextMenu) return null;\n\n const canvas = doc.canvases[currentCanvasId];\n if (!canvas) { setContextMenu(null); return null; }\n\n const node = contextMenu.nodeId ? canvas.nodes.find(n => n.id === contextMenu.nodeId) : null;\n const items: ContextMenuItem[] = [];\n\n if (node) {\n const hasChild = !!node.data.childCanvasId;\n\n if (hasChild) {\n items.push({\n label: 'Enter Sub-canvas',\n icon: '↓',\n action: () => {\n pushCanvas(node.data.childCanvasId!);\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n },\n });\n items.push({ label: '---', action: () => {} });\n items.push({\n label: 'Delete Sub-canvas',\n icon: '🗑',\n danger: true,\n action: () => {\n const childId = node.data.childCanvasId!;\n setDoc(prev => {\n const canvases = { ...prev.canvases };\n collectAndRemoveCanvases(canvases, childId);\n const c = canvases[currentCanvasId];\n if (!c) return prev;\n canvases[currentCanvasId] = {\n ...c,\n nodes: c.nodes.map(n =>\n n.id === node.id\n ? { ...n, data: { ...n.data, childCanvasId: undefined } }\n : n,\n ),\n };\n const stack = prev.stack.filter(id => canvases[id]);\n if (stack.length === 0) stack.push(ROOT_CANVAS_ID);\n return { ...prev, canvases, stack };\n });\n },\n });\n } else {\n items.push({\n label: 'Create Sub-canvas',\n icon: '⊞',\n action: () => {\n const childCanvasId = generateId('canvas');\n setDoc(prev => {\n const c = prev.canvases[currentCanvasId];\n if (!c) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...c,\n nodes: c.nodes.map(n =>\n n.id === node.id\n ? { ...n, data: { ...n.data, childCanvasId } }\n : n,\n ),\n },\n [childCanvasId]: { nodes: [], edges: [], lines: [] },\n },\n };\n });\n pushCanvas(childCanvasId);\n },\n });\n }\n }\n\n if (items.length === 0) return null;\n\n return (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n items={items}\n onClose={() => setContextMenu(null)}\n />\n );\n}\n\nfunction collectAndRemoveCanvases(\n canvases: Record<string, FlowCanvasData>,\n canvasId: string,\n): void {\n const canvas = canvases[canvasId];\n if (!canvas) return;\n for (const node of canvas.nodes) {\n if (node.data.childCanvasId) {\n collectAndRemoveCanvases(canvases, node.data.childCanvasId);\n }\n }\n delete canvases[canvasId];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Flow.js","names":[],"sources":["../../../../src/components/pro/Flow/Flow.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';\nimport { FlowProvider, useFlowContext } from './context/FlowContext';\nimport { FlowUIProvider, useFlowUI } from './context/FlowUIContext';\nimport { FlowAIProvider } from './context/FlowAIContext';\nimport FlowCanvas from './FlowCanvas';\nimport FlowToolbar, { FlowZoomControls } from './panels/FlowToolbar';\nimport { ShapePaletteContent, SvgStampContent, MediaStampContent } from './panels/ShapePalette';\nimport { InspectorPanelContent } from './panels/InspectorPanel';\nimport { OutlinePanelContent } from './panels/OutlinePanel';\nimport { AIPanelContent } from './panels/AIPanel';\nimport { PresentationMode } from './panels/PresentationMode';\nimport { MediaOverlay } from './nodes/MediaOverlay';\nimport FlowPanelGroup, { type PanelTab } from './panels/FlowPanelGroup';\nimport Breadcrumb from './panels/Breadcrumb';\nimport ContextMenu from './panels/ContextMenu';\nimport type { ContextMenuItem } from './panels/ContextMenu';\nimport { MiniMapRenderer } from './canvas/MiniMapRenderer';\nimport { CodeEditor, type CodeEditorHandle } from '../CodeEditor';\nimport { EditorView } from '@codemirror/view';\nimport { useUndoRedo } from './hooks/useUndoRedo';\nimport { useClipboard } from './hooks/useClipboard';\nimport { downloadDataURL, safeFileBaseName } from './hooks/useFlowImportExport';\nimport { usePdfExport } from './hooks/usePdfExport';\nimport { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';\nimport { useMindMap } from './hooks/useMindMap';\nimport { createEmptyDocument, ROOT_CANVAS_ID, DEFAULT_NODE_DATA } from './constants';\nimport { normalizeEdgeHandles } from './edges/edgePaths';\nimport { generateId } from './nodes/nodeUtils';\nimport type { FlowProps, FlowDocument, FlowNode, SelectionState, FlowCanvasData } from './types';\nimport type { PixiApp } from './canvas/PixiApp';\nimport './styles.css';\n\nfunction normalizeDocument(doc: FlowDocument): FlowDocument {\n let changed = false;\n const canvases = { ...doc.canvases };\n for (const [id, canvas] of Object.entries(canvases)) {\n const nodes = canvas.nodes.map(node => {\n if (node.type !== 'shapeSvg') return node;\n const legacyPlacement = node.data.labelPlacement as string | undefined;\n const labelPlacement = legacyPlacement === 'above'\n ? 'top'\n : legacyPlacement === 'center'\n ? 'middle'\n : legacyPlacement === 'below'\n ? 'bottom'\n : node.data.labelPlacement;\n if (labelPlacement === node.data.labelPlacement) return node;\n changed = true;\n return { ...node, data: { ...node.data, labelPlacement } };\n });\n const nodeMap = new Map<string, FlowNode>();\n for (const node of nodes) nodeMap.set(node.id, node);\n const edges = normalizeEdgeHandles(canvas.edges, nodeMap);\n if (nodes !== canvas.nodes || edges !== canvas.edges) {\n canvases[id] = { ...canvas, nodes, edges };\n if (edges !== canvas.edges) changed = true;\n }\n }\n return changed ? { ...doc, canvases } : doc;\n}\n\nconst EMPTY_SELECTION: SelectionState = {\n nodeIds: new Set(),\n edgeIds: new Set(),\n lineIds: new Set(),\n};\n\nfunction FlowKeyboardShortcutsWire({ onUndo, onRedo, groupRef, geoGroupRef, ungroupRef }: {\n onUndo: () => void;\n onRedo: () => void;\n groupRef: React.MutableRefObject<(() => void) | null>;\n geoGroupRef: React.MutableRefObject<(() => void) | null>;\n ungroupRef: React.MutableRefObject<(() => void) | null>;\n}) {\n const { selection, setSelection, currentCanvas, setDoc, currentCanvasId } = useFlowContext();\n const { viewport } = useFlowUI();\n const { copy, cut, paste, duplicate } = useClipboard();\n\n const deleteSelected = 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(EMPTY_SELECTION);\n }, [selection, setDoc, currentCanvasId, setSelection]);\n\n const selectAll = useCallback(() => {\n setSelection({\n nodeIds: new Set(currentCanvas.nodes.map(n => n.id)),\n edgeIds: new Set(currentCanvas.edges.map(e => e.id)),\n lineIds: new Set(currentCanvas.lines.map(l => l.id)),\n });\n }, [currentCanvas, setSelection]);\n\n const createGroup = useCallback((type: 'flowGroup' | 'geometryGroup') => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n const totalCount = nodeIds.size + lineIds.size;\n if (totalCount < 2) return;\n const nodes = currentCanvas.nodes.filter(n => nodeIds.has(n.id));\n const lines = currentCanvas.lines.filter(l => lineIds.has(l.id));\n const PAD = 20;\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of nodes) {\n minX = Math.min(minX, n.position.x);\n minY = Math.min(minY, n.position.y);\n maxX = Math.max(maxX, n.position.x + n.width);\n maxY = Math.max(maxY, n.position.y + n.height);\n }\n for (const l of lines) {\n for (const p of l.points) {\n minX = Math.min(minX, p.x); minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y);\n }\n }\n const isGeo = type === 'geometryGroup';\n const groupId = generateId('group');\n const groupNode: FlowNode = {\n id: groupId,\n type,\n position: { x: minX - PAD, y: minY - PAD },\n width: maxX - minX + PAD * 2,\n height: maxY - minY + PAD * 2,\n data: {\n ...DEFAULT_NODE_DATA,\n label: isGeo ? 'Geo Group' : 'Group',\n fill: isGeo ? '#fefce8' : '#f0f9ff',\n stroke: '#9ca3af', strokeWidth: 1.5,\n borderStyle: isGeo ? 'dashed' : 'dotted',\n isGroup: true,\n },\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: isGeo\n ? [groupNode, ...canvas.nodes]\n : [groupNode, ...canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, parentId: groupId } : n)],\n lines: isGeo\n ? canvas.lines\n : canvas.lines.map(l => lineIds.has(l.id) ? { ...l, parentId: groupId } : l),\n }},\n };\n });\n setSelection({ nodeIds: new Set([groupId]), edgeIds: new Set(), lineIds: new Set() });\n }, [selection, currentCanvas, setDoc, currentCanvasId, setSelection]);\n\n const groupSelected = useCallback(() => createGroup('flowGroup'), [createGroup]);\n const geoGroupSelected = useCallback(() => createGroup('geometryGroup'), [createGroup]);\n\n const ungroupSelected = useCallback(() => {\n const ids = selection.nodeIds;\n if (ids.size === 0) return;\n const groupNodeIds = new Set<string>();\n const childNodeIds = new Set<string>();\n const childLineIds = new Set<string>();\n for (const node of currentCanvas.nodes) {\n if (ids.has(node.id) && (node.type === 'flowGroup' || node.type === 'geometryGroup' || node.data.isGroup)) {\n groupNodeIds.add(node.id);\n }\n }\n if (groupNodeIds.size === 0) return;\n for (const node of currentCanvas.nodes) {\n if (node.parentId && groupNodeIds.has(node.parentId)) {\n childNodeIds.add(node.id);\n }\n }\n for (const line of currentCanvas.lines) {\n if (line.parentId && groupNodeIds.has(line.parentId)) {\n childLineIds.add(line.id);\n }\n }\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes\n .filter(n => !groupNodeIds.has(n.id))\n .map(n => childNodeIds.has(n.id) ? { ...n, parentId: undefined } : n),\n lines: canvas.lines\n .map(l => childLineIds.has(l.id) ? { ...l, parentId: undefined } : l),\n }},\n };\n });\n setSelection({ nodeIds: childNodeIds, edgeIds: new Set(), lineIds: childLineIds });\n }, [selection, currentCanvas, setDoc, currentCanvasId, setSelection]);\n\n groupRef.current = groupSelected;\n geoGroupRef.current = geoGroupSelected;\n ungroupRef.current = ungroupSelected;\n\n const changeZIndex = useCallback((mode: 'front' | 'back' | 'up' | 'down') => {\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: { ...prev.canvases, [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 }, [selection, setDoc, currentCanvasId]);\n\n useEffect(() => {\n const handlePaste = (event: ClipboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (target?.tagName === 'INPUT' || target?.tagName === 'TEXTAREA' || target?.isContentEditable) return;\n\n const imageItem = Array.from(event.clipboardData?.items ?? []).find(item => item.type.startsWith('image/'));\n if (!imageItem) {\n event.preventDefault();\n paste();\n return;\n }\n\n const file = imageItem.getAsFile();\n if (!file) return;\n event.preventDefault();\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result !== 'string') return;\n const selectedImage = selection.nodeIds.size === 1\n ? currentCanvas.nodes.find(node => selection.nodeIds.has(node.id) && node.type === 'mediaNode' && node.data.mediaKind === 'image')\n : undefined;\n\n if (selectedImage) {\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(node => node.id === selectedImage.id\n ? { ...node, data: { ...node.data, mediaContent: reader.result as string } }\n : node),\n },\n },\n };\n });\n return;\n }\n\n const id = generateId('node');\n const width = 320;\n const height = 220;\n const screenWidth = window.innerWidth;\n const screenHeight = window.innerHeight;\n const centerX = (screenWidth / 2 - viewport.x) / viewport.zoom;\n const centerY = (screenHeight / 2 - viewport.y) / viewport.zoom;\n const highestZ = Math.max(0, ...currentCanvas.nodes.map(node => node.zIndex ?? 0));\n const imageNode: FlowNode = {\n id,\n type: 'mediaNode',\n position: { x: centerX - width / 2, y: centerY - height / 2 },\n width,\n height,\n zIndex: highestZ + 1,\n data: {\n ...DEFAULT_NODE_DATA,\n label: file.name || 'Image',\n fill: 'theme:base-100',\n stroke: 'theme:base-content',\n strokeWidth: 1.5,\n color: 'theme:base-content',\n fontSize: 13,\n borderStyle: 'solid',\n mediaKind: 'image',\n mediaContent: reader.result,\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]: { ...canvas, nodes: [...canvas.nodes, imageNode] },\n },\n };\n });\n setSelection({ nodeIds: new Set([id]), edgeIds: new Set(), lineIds: new Set() });\n };\n reader.readAsDataURL(file);\n };\n\n window.addEventListener('paste', handlePaste);\n return () => window.removeEventListener('paste', handlePaste);\n }, [currentCanvas, currentCanvasId, paste, selection, setDoc, setSelection, viewport]);\n\n const actions = useMemo(() => ({\n undo: onUndo, redo: onRedo, copy, cut, paste, duplicate, deleteSelected, selectAll,\n group: groupSelected, geoGroup: geoGroupSelected, ungroup: ungroupSelected,\n bringToFront: () => changeZIndex('front'),\n bringForward: () => changeZIndex('up'),\n sendBackward: () => changeZIndex('down'),\n sendToBack: () => changeZIndex('back'),\n }), [onUndo, onRedo, copy, cut, paste, duplicate, deleteSelected, selectAll, groupSelected, geoGroupSelected, ungroupSelected, changeZIndex]);\n\n useKeyboardShortcuts(actions);\n useMindMap();\n return null;\n}\n\n/**\n * Bridges the anchor→PDF export (which needs canvas/viewport context) out to the\n * toolbar in the outer Flow component via a ref. Renders nothing.\n */\nfunction PdfExportWire({\n pixiRef,\n exportPdfRef,\n}: {\n pixiRef: React.RefObject<PixiApp | null>;\n exportPdfRef: React.MutableRefObject<(() => Promise<boolean>) | null>;\n}) {\n const exportPdf = usePdfExport(pixiRef);\n exportPdfRef.current = exportPdf;\n return null;\n}\n\n/** Imperative handle exposed via a ref on the `<Flow>` component. */\nexport interface FlowHandle {\n /** Export the current diagram to a PNG data URL (null if unavailable). */\n exportPNG: (backgroundColor?: number) => Promise<string | null>;\n /** Get the current document. */\n getDocument: () => FlowDocument;\n}\n\nconst Flow = forwardRef<FlowHandle, FlowProps>(function Flow({\n initialDocument,\n onChange,\n width,\n height,\n readOnly = false,\n onBack,\n onExportPNG,\n onPublish,\n showMiniMap = true,\n showGrid = true,\n gridSize = 20,\n className,\n showAI = true,\n showAIConfig = true,\n aiConfig,\n}: FlowProps, ref) {\n const [doc, setDoc] = useState<FlowDocument>(() => normalizeDocument(initialDocument ?? createEmptyDocument()));\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION);\n const pixiRef = useRef<PixiApp | null>(null);\n const miniMapCanvasRef = useRef<HTMLCanvasElement>(null);\n const miniMapRef = useRef<MiniMapRenderer | null>(null);\n\n const { wrappedSetDoc, undo, redo, canUndo, canRedo } = useUndoRedo(doc, setDoc);\n const groupRef = useRef<(() => void) | null>(null);\n const geoGroupRef = useRef<(() => void) | null>(null);\n const ungroupRef = useRef<(() => void) | null>(null);\n const exportPdfRef = useRef<(() => Promise<boolean>) | null>(null);\n\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n // Keep the latest doc in a ref for the imperative handle.\n const docRef = useRef(doc);\n docRef.current = doc;\n\n useImperativeHandle(ref, () => ({\n exportPNG: async (backgroundColor?: number) => {\n const pixi = pixiRef.current;\n if (!pixi || pixi.destroyed) return null;\n return pixi.exportPNG(backgroundColor);\n },\n getDocument: () => docRef.current,\n }), []);\n\n const outerSetDoc: React.Dispatch<React.SetStateAction<FlowDocument>> = useCallback(\n (action) => {\n wrappedSetDoc(prev => {\n const next = typeof action === 'function' ? action(prev) : action;\n queueMicrotask(() => onChangeRef.current?.(next));\n return next;\n });\n },\n [wrappedSetDoc],\n );\n\n const handlePixiReady = useCallback((pixi: PixiApp) => {\n pixiRef.current = pixi;\n if (miniMapCanvasRef.current && !miniMapRef.current) {\n miniMapRef.current = new MiniMapRenderer(miniMapCanvasRef.current);\n }\n }, []);\n\n // Built-in PNG export: if the host supplies `onExportPNG` we defer to it,\n // otherwise snapshot the Pixi scene and download it directly so the toolbar\n // button always works out of the box.\n const handleExportPNG = useCallback(async () => {\n if (onExportPNG) return void onExportPNG();\n const pixi = pixiRef.current;\n if (!pixi || pixi.destroyed) return;\n const url = await pixi.exportPNG(0xffffff);\n if (url) downloadDataURL(url, `${safeFileBaseName(docRef.current.title)}.png`);\n }, [onExportPNG]);\n\n // Built-in PDF export: capture each anchor's presentation framing into a\n // multi-page PDF (implemented by PdfExportWire inside the providers).\n const handleExportPDF = useCallback(async () => {\n await exportPdfRef.current?.();\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n let subscribed: PixiApp | null = null;\n\n const tickerFn = () => {\n const pixi = pixiRef.current;\n const mm = miniMapRef.current;\n if (!pixi || pixi.destroyed || !mm) return;\n const vp = { x: pixi.world.position.x, y: pixi.world.position.y, zoom: pixi.world.scale.x };\n const currentId = doc.stack[doc.stack.length - 1] ?? ROOT_CANVAS_ID;\n const canvas = doc.canvases[currentId];\n if (canvas) mm.update(canvas.nodes, vp, pixi.app.screen.width, pixi.app.screen.height);\n };\n\n // Pixi initializes asynchronously; the minimap renderer is created in\n // handlePixiReady. Poll until both exist, then attach the ticker. This\n // avoids a race where the effect runs before pixi is ready and the minimap\n // stays blank until the next document edit.\n const attach = () => {\n if (cancelled) return;\n const pixi = pixiRef.current;\n if (pixi && !pixi.destroyed && miniMapRef.current) {\n pixi.app.ticker.add(tickerFn);\n subscribed = pixi;\n } else {\n requestAnimationFrame(attach);\n }\n };\n attach();\n\n return () => {\n cancelled = true;\n if (subscribed && !subscribed.destroyed) subscribed.app.ticker.remove(tickerFn);\n };\n }, [doc]);\n\n const style: React.CSSProperties = { width: width ?? '100%', height: height ?? '100%' };\n\n return (\n <div className={`flow-container ${className ?? ''}`} style={style}>\n <FlowProvider doc={doc} setDoc={outerSetDoc} selection={selection} setSelection={setSelection}>\n <FlowUIProvider showMiniMap={showMiniMap} showGrid={showGrid} gridSize={gridSize} showAI={showAI}>\n <FlowAIProvider initialConfig={aiConfig} showAIConfig={showAIConfig}>\n <FlowKeyboardShortcutsWire onUndo={undo} onRedo={redo} groupRef={groupRef} geoGroupRef={geoGroupRef} ungroupRef={ungroupRef} />\n <PdfExportWire pixiRef={pixiRef} exportPdfRef={exportPdfRef} />\n <UnifiedPanelGroup\n toolbar={!readOnly ? (\n <FlowToolbar\n onBack={onBack}\n onUndo={undo} onRedo={redo} canUndo={canUndo} canRedo={canRedo}\n onGroup={() => groupRef.current?.()} onGeoGroup={() => geoGroupRef.current?.()} onUngroup={() => ungroupRef.current?.()}\n onExportPNG={handleExportPNG}\n onExportPDF={handleExportPDF}\n onPublish={onPublish}\n />\n ) : null}\n >\n <FlowCanvas onPixiReady={handlePixiReady} />\n {/* Media content (markdown/mermaid/data/…) must stay visible in\n presentation & read-only preview — PixiJS only draws the node\n frame, so hiding this layer would blank every media node. */}\n <MediaOverlay />\n <PresentationGate>\n {!readOnly && <FlowZoomControls />}\n <Breadcrumb />\n </PresentationGate>\n <FlowContextMenuWire />\n <MiniMapWrapper canvasRef={miniMapCanvasRef} pixiRef={pixiRef} miniMapRef={miniMapRef} />\n <PresentationMode />\n </UnifiedPanelGroup>\n </FlowAIProvider>\n </FlowUIProvider>\n </FlowProvider>\n </div>\n );\n});\n\nexport default Flow;\n\ninterface TabDef {\n id: string;\n label: string;\n icon: string;\n side: 'left' | 'right';\n showKey?: 'showPalette' | 'showInspector' | 'showOutline' | 'showJson' | 'showAI';\n}\n\n/**\n * Hides all editable overlay UI (toolbar, panels, breadcrumb) while in\n * presentation mode, keeping only the canvas visible for the slideshow.\n */\nfunction PresentationGate({ children }: { children: React.ReactNode }) {\n const { presentation } = useFlowUI();\n return (\n <div className=\"flow-overlay\" style={{ display: presentation ? 'none' : undefined }}>\n {children}\n </div>\n );\n}\n\nconst ALL_TAB_DEFS: TabDef[] = [\n { id: 'shapes', label: 'Shapes', icon: '▢', side: 'left', showKey: 'showPalette' },\n { id: 'icons', label: 'Icons', icon: '★', side: 'left', showKey: 'showPalette' },\n { id: 'media', label: 'Media', icon: '▶', side: 'left', showKey: 'showPalette' },\n { id: 'inspector', label: 'Inspector', icon: '⚙', side: 'right', showKey: 'showInspector' },\n { id: 'outline', label: 'Outline', icon: '☰', side: 'right', showKey: 'showOutline' },\n { id: 'json', label: 'JSON', icon: '{ }', side: 'right', showKey: 'showJson' },\n { id: 'ai', label: 'AI', icon: '✨', side: 'right', showKey: 'showAI' },\n];\n\nfunction tabContent(id: string): React.ReactNode {\n switch (id) {\n case 'shapes': return <ShapePaletteContent />;\n case 'icons': return <SvgStampContent />;\n case 'media': return <MediaStampContent />;\n case 'inspector': return <InspectorPanelContent />;\n case 'outline': return <OutlinePanelContent />;\n case 'json': return <JsonEditorPanel />;\n case 'ai': return <AIPanelContent />;\n default: return null;\n }\n}\n\nfunction UnifiedPanelGroup({ children, toolbar }: { children: React.ReactNode; toolbar?: React.ReactNode }) {\n const ui = useFlowUI();\n const { detachedTabs, toggleDetach, presentation } = ui;\n\n const visibleTabs = ALL_TAB_DEFS.filter(def =>\n !def.showKey || (ui as any)[def.showKey],\n );\n\n const toPanelTab = (def: TabDef): PanelTab => ({\n id: def.id, label: def.label, icon: def.icon, content: tabContent(def.id),\n });\n\n const leftTabs: PanelTab[] = visibleTabs\n .filter(def => def.side === 'left' && !detachedTabs.has(def.id))\n .map(toPanelTab);\n const rightTabs: PanelTab[] = visibleTabs\n .filter(def => def.side === 'right' && !detachedTabs.has(def.id))\n .map(toPanelTab);\n\n const detachedList = visibleTabs.filter(def => detachedTabs.has(def.id));\n\n const handleDetach = useCallback((tabId: string) => toggleDetach(tabId), [toggleDetach]);\n const handleAttach = useCallback((tabId: string) => toggleDetach(tabId), [toggleDetach]);\n\n return (\n <div className=\"flow-workspace\">\n {/* Slim full-width toolbar strip above panels + canvas. */}\n {!presentation && toolbar}\n <div className=\"flow-workspace-main\">\n {!presentation && leftTabs.length > 0 && (\n <FlowPanelGroup\n tabs={leftTabs}\n defaultTab={leftTabs[0]?.id}\n resizeEdge=\"right\"\n defaultWidth={132}\n onDetach={handleDetach}\n />\n )}\n <div className=\"flow-stage\">\n {children}\n </div>\n {!presentation && rightTabs.length > 0 && (\n <FlowPanelGroup\n tabs={rightTabs}\n defaultTab={rightTabs[0]?.id}\n resizeEdge=\"left\"\n defaultWidth={220}\n onDetach={handleDetach}\n />\n )}\n {/* Detached panels float above every docked panel. Rendered as a direct\n child of the (position:relative) workspace-main so they are not\n clipped by the stage's `overflow: hidden` and can overlap the side\n panels. */}\n {!presentation && detachedList.map((def, i) => (\n <FlowPanelGroup\n key={def.id}\n tabs={[toPanelTab(def)]}\n resizeEdge=\"right\"\n defaultWidth={220}\n style={{ top: 48 + i * 40, left: 24 + i * 30 }}\n isDetached\n onAttach={handleAttach}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MiniMapWrapper({\n canvasRef,\n pixiRef,\n miniMapRef,\n}: {\n canvasRef: React.RefObject<HTMLCanvasElement | null>;\n pixiRef: React.RefObject<PixiApp | null>;\n miniMapRef: React.RefObject<MiniMapRenderer | null>;\n}) {\n const { showMiniMap, setViewport, presentation } = useFlowUI();\n const draggingRef = useRef(false);\n\n // Move the main canvas so that the world point under the minimap click is\n // centered in the viewport. Routed through setViewport so the change syncs\n // with the ViewportManager (setting world.position directly would be\n // overwritten on the next viewport apply).\n const navigateTo = useCallback((clientX: number, clientY: number) => {\n const canvas = canvasRef.current;\n const pixi = pixiRef.current;\n const mm = miniMapRef.current;\n if (!canvas || !pixi || pixi.destroyed || !mm) return;\n\n const rect = canvas.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return;\n // CSS pixels -> canvas backing pixels.\n const { width: cw, height: ch } = mm.size;\n const px = ((clientX - rect.left) / rect.width) * cw;\n const py = ((clientY - rect.top) / rect.height) * ch;\n\n const world = mm.minimapToWorld(px, py);\n if (!world) return;\n\n const zoom = pixi.world.scale.x || 1;\n const screenW = pixi.app.screen.width;\n const screenH = pixi.app.screen.height;\n setViewport({\n x: screenW / 2 - world.x * zoom,\n y: screenH / 2 - world.y * zoom,\n zoom,\n });\n }, [canvasRef, pixiRef, miniMapRef, setViewport]);\n\n const onPointerDown = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);\n draggingRef.current = true;\n navigateTo(e.clientX, e.clientY);\n }, [navigateTo]);\n\n const onPointerMove = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n navigateTo(e.clientX, e.clientY);\n }, [navigateTo]);\n\n const onPointerUp = useCallback((e: React.PointerEvent<HTMLDivElement>) => {\n draggingRef.current = false;\n try { (e.currentTarget as HTMLElement).releasePointerCapture(e.pointerId); } catch { /* noop */ }\n }, []);\n\n return (\n <div\n className=\"flow-minimap\"\n style={{ display: showMiniMap && !presentation ? undefined : 'none', cursor: 'pointer' }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n title=\"点击或拖动以移动画布\"\n >\n <canvas ref={canvasRef} width={180} height={120} style={{ width: '100%', height: '100%', pointerEvents: 'none' }} />\n </div>\n );\n}\n\n/**\n * Find the line range (1-based) of a JSON object with the given id.\n */\nfunction findElementLineRange(jsonStr: string, elementId: string): { startLine: number; endLine: number } | null {\n const idPattern = `\"id\": \"${elementId}\"`;\n const idx = jsonStr.indexOf(idPattern);\n if (idx === -1) return null;\n\n let braceDepth = 0;\n let startIdx = -1;\n for (let i = idx; i >= 0; i--) {\n if (jsonStr[i] === '}') braceDepth++;\n if (jsonStr[i] === '{') {\n if (braceDepth === 0) { startIdx = i; break; }\n braceDepth--;\n }\n }\n if (startIdx === -1) return null;\n\n braceDepth = 0;\n let endIdx = -1;\n for (let i = startIdx; i < jsonStr.length; i++) {\n if (jsonStr[i] === '{') braceDepth++;\n if (jsonStr[i] === '}') {\n braceDepth--;\n if (braceDepth === 0) { endIdx = i; break; }\n }\n }\n if (endIdx === -1) return null;\n\n const startLine = jsonStr.slice(0, startIdx).split('\\n').length;\n const endLine = jsonStr.slice(0, endIdx + 1).split('\\n').length;\n return { startLine, endLine };\n}\n\nfunction clearLineHighlights(container: HTMLElement) {\n container.querySelectorAll('.cm-line.flow-json-hl').forEach(el => el.classList.remove('flow-json-hl'));\n}\n\nfunction applyLineHighlightsViaView(handle: CodeEditorHandle, startLine: number, endLine: number) {\n const view = handle.getView();\n if (!view) return;\n for (let ln = startLine; ln <= endLine; ln++) {\n try {\n const lineInfo = view.state.doc.line(ln);\n const dom = view.domAtPos(lineInfo.from);\n const lineEl = dom.node instanceof HTMLElement\n ? dom.node.closest('.cm-line')\n : dom.node.parentElement?.closest('.cm-line');\n if (lineEl) lineEl.classList.add('flow-json-hl');\n } catch { /* line not in viewport */ }\n }\n}\n\nfunction JsonEditorPanel() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n const [jsonStr, setJsonStr] = useState('');\n const [error, setError] = useState<string | null>(null);\n const skipNextSync = useRef(false);\n const editorRef = useRef<CodeEditorHandle>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n\n const singleId = useMemo(() => {\n const total = selection.nodeIds.size + selection.edgeIds.size + selection.lineIds.size;\n if (total !== 1) return null;\n if (selection.nodeIds.size === 1) return [...selection.nodeIds][0];\n if (selection.edgeIds.size === 1) return [...selection.edgeIds][0];\n if (selection.lineIds.size === 1) return [...selection.lineIds][0];\n return null;\n }, [selection]);\n\n useEffect(() => {\n if (skipNextSync.current) { skipNextSync.current = false; return; }\n setJsonStr(JSON.stringify(currentCanvas, null, 2));\n setError(null);\n }, [currentCanvas]);\n\n useEffect(() => {\n const wrap = wrapRef.current;\n if (wrap) clearLineHighlights(wrap);\n if (!singleId) return;\n\n const timer = setTimeout(() => {\n const range = findElementLineRange(jsonStr, singleId);\n if (!range || !wrapRef.current) return;\n\n const view = editorRef.current?.getView();\n if (!view) return;\n\n const w = wrapRef.current;\n const scroller = view.scrollDOM;\n\n scroller.style.scrollBehavior = 'smooth';\n\n const lineInfo = view.state.doc.line(range.startLine);\n view.dispatch({\n effects: EditorView.scrollIntoView(lineInfo.from, { y: 'start', yMargin: 0 }),\n });\n\n const onScrollEnd = () => {\n scroller.style.scrollBehavior = '';\n clearLineHighlights(w);\n applyLineHighlightsViaView(editorRef.current!, range.startLine, range.endLine);\n };\n\n let scrollTimer: ReturnType<typeof setTimeout>;\n const onScroll = () => {\n clearTimeout(scrollTimer);\n scrollTimer = setTimeout(onScrollEnd, 100);\n };\n scroller.addEventListener('scroll', onScroll);\n scrollTimer = setTimeout(() => {\n scroller.removeEventListener('scroll', onScroll);\n onScrollEnd();\n }, 800);\n }, 120);\n return () => clearTimeout(timer);\n }, [singleId, jsonStr]);\n\n const handleChange = useCallback((value: string) => {\n setJsonStr(value);\n try {\n const parsed = JSON.parse(value);\n if (parsed && Array.isArray(parsed.nodes) && Array.isArray(parsed.edges) && Array.isArray(parsed.lines)) {\n setError(null);\n skipNextSync.current = true;\n setDoc(prev => ({\n ...prev,\n canvases: { ...prev.canvases, [currentCanvasId]: parsed },\n }));\n } else {\n setError('JSON must have nodes, edges, lines arrays');\n }\n } catch (e: any) {\n setError(e.message?.slice(0, 60) ?? 'Invalid JSON');\n }\n }, [setDoc, currentCanvasId]);\n\n const label = singleId\n ? (selection.nodeIds.has(singleId) ? 'Node' : selection.edgeIds.has(singleId) ? 'Edge' : 'Line')\n : null;\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}>\n <div className=\"flow-json-header\">\n <span className=\"flow-json-scope\">\n {label ? `${label}: ${singleId!.slice(0, 8)}` : `Canvas`}\n </span>\n </div>\n {error && (\n <div style={{ fontSize: 11, color: 'oklch(var(--er))', padding: '4px 0', flexShrink: 0 }}>\n {error}\n </div>\n )}\n <div ref={wrapRef} style={{ flex: 1, minHeight: 0 }}>\n <CodeEditor\n ref={editorRef}\n value={jsonStr}\n onChange={handleChange}\n language=\"json\"\n lineNumbers={false}\n height=\"100%\"\n highlightActiveLine={false}\n />\n </div>\n </div>\n );\n}\n\nfunction FlowContextMenuWire() {\n const { contextMenu, setContextMenu } = useFlowUI();\n const { doc, setDoc, currentCanvasId, pushCanvas, setSelection } = useFlowContext();\n const { duplicate } = useClipboard();\n\n if (!contextMenu) return null;\n\n const canvas = doc.canvases[currentCanvasId];\n if (!canvas) { setContextMenu(null); return null; }\n\n const node = contextMenu.nodeId ? canvas.nodes.find(n => n.id === contextMenu.nodeId) : null;\n const items: ContextMenuItem[] = [];\n\n if (node) {\n // Duplicate the node (Cmd/Ctrl+D equivalent). Ensure it is selected first so\n // the clone covers the intended target even on a right-click without a prior\n // left-click selection.\n items.push({\n label: 'Duplicate',\n icon: '⧉',\n action: () => {\n duplicate(24, 24, { nodeIds: new Set([node.id]) });\n },\n });\n items.push({ label: '---', action: () => {} });\n\n const hasChild = !!node.data.childCanvasId;\n\n if (hasChild) {\n items.push({\n label: 'Enter Sub-canvas',\n icon: '↓',\n action: () => {\n pushCanvas(node.data.childCanvasId!);\n setSelection({ nodeIds: new Set(), edgeIds: new Set(), lineIds: new Set() });\n },\n });\n items.push({ label: '---', action: () => {} });\n items.push({\n label: 'Delete Sub-canvas',\n icon: '🗑',\n danger: true,\n action: () => {\n const childId = node.data.childCanvasId!;\n setDoc(prev => {\n const canvases = { ...prev.canvases };\n collectAndRemoveCanvases(canvases, childId);\n const c = canvases[currentCanvasId];\n if (!c) return prev;\n canvases[currentCanvasId] = {\n ...c,\n nodes: c.nodes.map(n =>\n n.id === node.id\n ? { ...n, data: { ...n.data, childCanvasId: undefined } }\n : n,\n ),\n };\n const stack = prev.stack.filter(id => canvases[id]);\n if (stack.length === 0) stack.push(ROOT_CANVAS_ID);\n return { ...prev, canvases, stack };\n });\n },\n });\n } else {\n items.push({\n label: 'Create Sub-canvas',\n icon: '⊞',\n action: () => {\n const childCanvasId = generateId('canvas');\n setDoc(prev => {\n const c = prev.canvases[currentCanvasId];\n if (!c) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...c,\n nodes: c.nodes.map(n =>\n n.id === node.id\n ? { ...n, data: { ...n.data, childCanvasId } }\n : n,\n ),\n },\n [childCanvasId]: { nodes: [], edges: [], lines: [] },\n },\n };\n });\n pushCanvas(childCanvasId);\n },\n });\n }\n }\n\n if (items.length === 0) return null;\n\n return (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n items={items}\n onClose={() => setContextMenu(null)}\n />\n );\n}\n\nfunction collectAndRemoveCanvases(\n canvases: Record<string, FlowCanvasData>,\n canvasId: string,\n): void {\n const canvas = canvases[canvasId];\n if (!canvas) return;\n for (const node of canvas.nodes) {\n if (node.data.childCanvasId) {\n collectAndRemoveCanvases(canvases, node.data.childCanvasId);\n }\n }\n delete canvases[canvasId];\n}\n"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Shared helpers for building a Flow `FlowDocument` from an Archify spec.
3
+ *
4
+ * The converters reproduce Archify's fixed grid/lane geometry (coordinates
5
+ * copied from the reference renderers) so an imported diagram matches the
6
+ * artifact screenshots. Everything is emitted as native Flow nodes/edges/lines
7
+ * with literal Archify colors, so the result is fully editable afterwards.
8
+ */
9
+ import type { FlowNode, FlowEdge, FlowNodeData, FlowEdgeData, FlowEdgeLineStyle } from '../types';
10
+ import type { ArchifySide } from './spec';
11
+ declare function uid(prefix: string): string;
12
+ export interface BuildNodeOptions {
13
+ id: string;
14
+ x: number;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ label: string;
19
+ sublabel?: string;
20
+ tag?: string;
21
+ fill: string;
22
+ stroke: string;
23
+ text: string;
24
+ sub?: string;
25
+ fontSize?: number;
26
+ borderStyle?: FlowNodeData['borderStyle'];
27
+ strokeWidth?: number;
28
+ zIndex?: number;
29
+ }
30
+ /** Build a rounded-rect card node in the Archify style. */
31
+ export declare function card(opts: BuildNodeOptions): FlowNode;
32
+ export interface BuildGroupOptions {
33
+ id: string;
34
+ x: number;
35
+ y: number;
36
+ width: number;
37
+ height: number;
38
+ label: string;
39
+ stroke?: string;
40
+ fill?: string;
41
+ borderStyle?: FlowNodeData['borderStyle'];
42
+ labelColor?: string;
43
+ zIndex?: number;
44
+ }
45
+ /**
46
+ * Build a boundary / lane / phase frame as a group rectangle. Rendered behind
47
+ * the cards (low zIndex) with a dashed outline and a top-left label.
48
+ */
49
+ export declare function frame(opts: BuildGroupOptions): FlowNode;
50
+ export interface BuildEdgeOptions {
51
+ id?: string;
52
+ source: string;
53
+ target: string;
54
+ sourceHandle?: string;
55
+ targetHandle?: string;
56
+ label?: string;
57
+ color: string;
58
+ width?: number;
59
+ lineStyle?: FlowEdgeLineStyle;
60
+ animated?: boolean;
61
+ waypoints?: Array<{
62
+ x: number;
63
+ y: number;
64
+ }>;
65
+ markerEnd?: FlowEdgeData['markerEnd'];
66
+ }
67
+ /** Build a smoothstep edge in the Archify style (optionally trace-animated). */
68
+ export declare function edge(opts: BuildEdgeOptions): FlowEdge;
69
+ /**
70
+ * Map an Archify side to the nearest Flow handle id (center of that side).
71
+ * Flow handles are `t_/b_/l_/r_` with offsets 1/6..5/6; the center is 3/6.
72
+ */
73
+ export declare function sideHandle(side?: ArchifySide): string | undefined;
74
+ export { uid };
@@ -0,0 +1,103 @@
1
+ import "./palette.js";
2
+ var r = 0;
3
+ function l(e) {
4
+ return r += 1, `${e}_${r.toString(36)}_${Math.floor(Math.random() * 1e6).toString(36)}`;
5
+ }
6
+ function n(e) {
7
+ return {
8
+ id: e.id,
9
+ type: "shapeRoundRect",
10
+ position: {
11
+ x: e.x,
12
+ y: e.y
13
+ },
14
+ width: e.width,
15
+ height: e.height,
16
+ zIndex: e.zIndex ?? 2,
17
+ data: {
18
+ label: e.label,
19
+ sublabel: e.sublabel,
20
+ sublabelColor: e.sub ?? "#94a3b8",
21
+ tag: e.tag,
22
+ fill: e.fill,
23
+ stroke: e.stroke,
24
+ strokeWidth: e.strokeWidth ?? 1.75,
25
+ color: e.text,
26
+ labelColor: e.text,
27
+ fontSize: e.fontSize ?? 13,
28
+ borderStyle: e.borderStyle ?? "solid",
29
+ attributes: []
30
+ }
31
+ };
32
+ }
33
+ function d(e) {
34
+ return {
35
+ id: e.id,
36
+ type: "geometryGroup",
37
+ position: {
38
+ x: e.x,
39
+ y: e.y
40
+ },
41
+ width: e.width,
42
+ height: e.height,
43
+ zIndex: e.zIndex ?? 0,
44
+ data: {
45
+ label: e.label,
46
+ fill: e.fill ?? "transparent",
47
+ stroke: e.stroke ?? "#334155",
48
+ strokeWidth: 1.25,
49
+ color: e.labelColor ?? "#94a3b8",
50
+ labelColor: e.labelColor ?? "#94a3b8",
51
+ fontSize: 12,
52
+ isGroup: !0,
53
+ borderStyle: e.borderStyle ?? "dashed",
54
+ groupLabelPlacement: "top",
55
+ groupLabelAlign: "start",
56
+ groupLabelBgMode: "text",
57
+ attributes: []
58
+ }
59
+ };
60
+ }
61
+ function o(e) {
62
+ return {
63
+ id: e.id ?? l("edge"),
64
+ source: e.source,
65
+ target: e.target,
66
+ sourceHandle: e.sourceHandle,
67
+ targetHandle: e.targetHandle,
68
+ type: "smoothstep",
69
+ data: {
70
+ strokeColor: e.color,
71
+ strokeWidth: e.width ?? 1.75,
72
+ lineStyle: e.lineStyle ?? "solid",
73
+ markerEnd: e.markerEnd ?? "arrowclosed",
74
+ labelText: e.label,
75
+ labelFontSize: 11,
76
+ animated: e.animated ?? !1,
77
+ waypoints: e.waypoints
78
+ }
79
+ };
80
+ }
81
+ function u(e) {
82
+ switch (e) {
83
+ case "top":
84
+ return `t_${3 / 6}`;
85
+ case "bottom":
86
+ return `b_${3 / 6}`;
87
+ case "left":
88
+ return `l_${3 / 6}`;
89
+ case "right":
90
+ return `r_${3 / 6}`;
91
+ default:
92
+ return;
93
+ }
94
+ }
95
+ export {
96
+ n as card,
97
+ o as edge,
98
+ d as frame,
99
+ u as sideHandle,
100
+ l as uid
101
+ };
102
+
103
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","names":[],"sources":["../../../../../src/components/pro/Flow/archify/build.ts"],"sourcesContent":["/**\n * Shared helpers for building a Flow `FlowDocument` from an Archify spec.\n *\n * The converters reproduce Archify's fixed grid/lane geometry (coordinates\n * copied from the reference renderers) so an imported diagram matches the\n * artifact screenshots. Everything is emitted as native Flow nodes/edges/lines\n * with literal Archify colors, so the result is fully editable afterwards.\n */\n\nimport type {\n FlowNode,\n FlowEdge,\n FlowNodeData,\n FlowEdgeData,\n FlowEdgeLineStyle,\n} from '../types';\nimport type { ArchifySide } from './spec';\nimport { ARCHIFY_LANE_STROKE, ARCHIFY_TEXT_MUTED } from './palette';\n\nlet _seq = 0;\nfunction uid(prefix: string): string {\n _seq += 1;\n return `${prefix}_${_seq.toString(36)}_${Math.floor(Math.random() * 1e6).toString(36)}`;\n}\n\nexport interface BuildNodeOptions {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n label: string;\n sublabel?: string;\n tag?: string;\n fill: string;\n stroke: string;\n text: string;\n sub?: string;\n fontSize?: number;\n borderStyle?: FlowNodeData['borderStyle'];\n strokeWidth?: number;\n zIndex?: number;\n}\n\n/** Build a rounded-rect card node in the Archify style. */\nexport function card(opts: BuildNodeOptions): FlowNode {\n return {\n id: opts.id,\n type: 'shapeRoundRect',\n position: { x: opts.x, y: opts.y },\n width: opts.width,\n height: opts.height,\n zIndex: opts.zIndex ?? 2,\n data: {\n label: opts.label,\n sublabel: opts.sublabel,\n sublabelColor: opts.sub ?? ARCHIFY_TEXT_MUTED,\n tag: opts.tag,\n fill: opts.fill,\n stroke: opts.stroke,\n strokeWidth: opts.strokeWidth ?? 1.75,\n color: opts.text,\n labelColor: opts.text,\n fontSize: opts.fontSize ?? 13,\n borderStyle: opts.borderStyle ?? 'solid',\n attributes: [],\n },\n };\n}\n\nexport interface BuildGroupOptions {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n label: string;\n stroke?: string;\n fill?: string;\n borderStyle?: FlowNodeData['borderStyle'];\n labelColor?: string;\n zIndex?: number;\n}\n\n/**\n * Build a boundary / lane / phase frame as a group rectangle. Rendered behind\n * the cards (low zIndex) with a dashed outline and a top-left label.\n */\nexport function frame(opts: BuildGroupOptions): FlowNode {\n return {\n id: opts.id,\n type: 'geometryGroup',\n position: { x: opts.x, y: opts.y },\n width: opts.width,\n height: opts.height,\n zIndex: opts.zIndex ?? 0,\n data: {\n label: opts.label,\n fill: opts.fill ?? 'transparent',\n stroke: opts.stroke ?? ARCHIFY_LANE_STROKE,\n strokeWidth: 1.25,\n color: opts.labelColor ?? ARCHIFY_TEXT_MUTED,\n labelColor: opts.labelColor ?? ARCHIFY_TEXT_MUTED,\n fontSize: 12,\n isGroup: true,\n borderStyle: opts.borderStyle ?? 'dashed',\n groupLabelPlacement: 'top',\n groupLabelAlign: 'start',\n groupLabelBgMode: 'text',\n attributes: [],\n },\n };\n}\n\nexport interface BuildEdgeOptions {\n id?: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n color: string;\n width?: number;\n lineStyle?: FlowEdgeLineStyle;\n animated?: boolean;\n waypoints?: Array<{ x: number; y: number }>;\n markerEnd?: FlowEdgeData['markerEnd'];\n}\n\n/** Build a smoothstep edge in the Archify style (optionally trace-animated). */\nexport function edge(opts: BuildEdgeOptions): FlowEdge {\n return {\n id: opts.id ?? uid('edge'),\n source: opts.source,\n target: opts.target,\n sourceHandle: opts.sourceHandle,\n targetHandle: opts.targetHandle,\n type: 'smoothstep',\n data: {\n strokeColor: opts.color,\n strokeWidth: opts.width ?? 1.75,\n lineStyle: opts.lineStyle ?? 'solid',\n markerEnd: opts.markerEnd ?? 'arrowclosed',\n labelText: opts.label,\n labelFontSize: 11,\n animated: opts.animated ?? false,\n waypoints: opts.waypoints,\n },\n };\n}\n\n/**\n * Map an Archify side to the nearest Flow handle id (center of that side).\n * Flow handles are `t_/b_/l_/r_` with offsets 1/6..5/6; the center is 3/6.\n */\nexport function sideHandle(side?: ArchifySide): string | undefined {\n switch (side) {\n case 'top':\n return `t_${3 / 6}`;\n case 'bottom':\n return `b_${3 / 6}`;\n case 'left':\n return `l_${3 / 6}`;\n case 'right':\n return `r_${3 / 6}`;\n default:\n return undefined;\n }\n}\n\nexport { uid };\n"],"mappings":";AAmBA,IAAI,IAAO;AACX,SAAS,EAAI,GAAwB;AACnC,SAAA,KAAQ,GACD,GAAG,CAAA,IAAU,EAAK,SAAS,EAAE,CAAA,IAAK,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,EAAE,SAAS,EAAE,CAAA;AACtF;AAsBA,SAAgB,EAAK,GAAkC;AACrD,SAAO;AAAA,IACL,IAAI,EAAK;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,MAAE,GAAG,EAAK;AAAA,MAAG,GAAG,EAAK;AAAA,IAAE;AAAA,IACjC,OAAO,EAAK;AAAA,IACZ,QAAQ,EAAK;AAAA,IACb,QAAQ,EAAK,UAAU;AAAA,IACvB,MAAM;AAAA,MACJ,OAAO,EAAK;AAAA,MACZ,UAAU,EAAK;AAAA,MACf,eAAe,EAAK,OAAA;AAAA,MACpB,KAAK,EAAK;AAAA,MACV,MAAM,EAAK;AAAA,MACX,QAAQ,EAAK;AAAA,MACb,aAAa,EAAK,eAAe;AAAA,MACjC,OAAO,EAAK;AAAA,MACZ,YAAY,EAAK;AAAA,MACjB,UAAU,EAAK,YAAY;AAAA,MAC3B,aAAa,EAAK,eAAe;AAAA,MACjC,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;AAoBA,SAAgB,EAAM,GAAmC;AACvD,SAAO;AAAA,IACL,IAAI,EAAK;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,MAAE,GAAG,EAAK;AAAA,MAAG,GAAG,EAAK;AAAA,IAAE;AAAA,IACjC,OAAO,EAAK;AAAA,IACZ,QAAQ,EAAK;AAAA,IACb,QAAQ,EAAK,UAAU;AAAA,IACvB,MAAM;AAAA,MACJ,OAAO,EAAK;AAAA,MACZ,MAAM,EAAK,QAAQ;AAAA,MACnB,QAAQ,EAAK,UAAA;AAAA,MACb,aAAa;AAAA,MACb,OAAO,EAAK,cAAA;AAAA,MACZ,YAAY,EAAK,cAAA;AAAA,MACjB,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa,EAAK,eAAe;AAAA,MACjC,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AACF;AAkBA,SAAgB,EAAK,GAAkC;AACrD,SAAO;AAAA,IACL,IAAI,EAAK,MAAM,EAAI,MAAM;AAAA,IACzB,QAAQ,EAAK;AAAA,IACb,QAAQ,EAAK;AAAA,IACb,cAAc,EAAK;AAAA,IACnB,cAAc,EAAK;AAAA,IACnB,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,aAAa,EAAK;AAAA,MAClB,aAAa,EAAK,SAAS;AAAA,MAC3B,WAAW,EAAK,aAAa;AAAA,MAC7B,WAAW,EAAK,aAAa;AAAA,MAC7B,WAAW,EAAK;AAAA,MAChB,eAAe;AAAA,MACf,UAAU,EAAK,YAAY;AAAA,MAC3B,WAAW,EAAK;AAAA,IAClB;AAAA,EACF;AACF;AAMA,SAAgB,EAAW,GAAwC;AACjE,UAAQ,GAAR;AAAA,IACE,KAAK;AACH,aAAO,KAAK,IAAI,CAAA;AAAA,IAClB,KAAK;AACH,aAAO,KAAK,IAAI,CAAA;AAAA,IAClB,KAAK;AACH,aAAO,KAAK,IAAI,CAAA;AAAA,IAClB,KAAK;AACH,aAAO,KAAK,IAAI,CAAA;AAAA,IAClB;AACE;AAAA,EACJ;AACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Convert an Archify spec into a native Flow `FlowDocument`.
3
+ *
4
+ * One converter per diagram type reproduces Archify's fixed layout geometry
5
+ * (constants copied from the reference renderers) so the imported diagram
6
+ * matches the reference artifact, then emits editable Flow nodes/edges/lines.
7
+ *
8
+ * When `meta.animation === "trace"`, edges are marked `animated` so the Flow
9
+ * presentation / preview mode plays the traveling gradient pulse.
10
+ */
11
+ import type { FlowDocument } from '../types';
12
+ import type { ArchifySpec } from './spec';
13
+ /** Convert any supported Archify spec into a Flow document. */
14
+ export declare function archifyToFlowDocument(spec: ArchifySpec): FlowDocument;