@utisha/graph-editor 1.0.3 → 1.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"utisha-graph-editor.mjs","sources":["../../../projects/graph-editor/src/lib/services/graph-history.service.ts","../../../projects/graph-editor/src/lib/graph-editor.component.ts","../../../projects/graph-editor/src/lib/graph-editor.component.html","../../../projects/graph-editor/src/lib/icons/workflow-icons.ts","../../../projects/graph-editor/src/public-api.ts","../../../projects/graph-editor/src/utisha-graph-editor.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { Graph } from '../graph.model';\n\n/**\n * Service for managing undo/redo history of graph state.\n * \n * Uses a simple snapshot-based approach where each history entry\n * is a deep copy of the entire graph state.\n */\n@Injectable()\nexport class GraphHistoryService {\n private history: Graph[] = [];\n private historyIndex = -1;\n private maxHistorySize = 100;\n \n /** Signal to track if an undo/redo operation is in progress */\n readonly isUndoRedo = signal(false);\n\n /**\n * Initialize history with the given graph state.\n * Clears any existing history.\n */\n init(graph: Graph): void {\n this.history = [structuredClone(graph)];\n this.historyIndex = 0;\n }\n\n /**\n * Push a new state to the history stack.\n * If we're not at the end of history, truncates future states.\n * Prevents duplicate consecutive states.\n * \n * @returns true if state was pushed, false if it was a duplicate\n */\n push(graph: Graph): boolean {\n const currentState = structuredClone(graph);\n \n // Don't push if state hasn't changed\n if (this.historyIndex >= 0 && this.historyIndex < this.history.length) {\n const lastState = this.history[this.historyIndex];\n if (JSON.stringify(lastState) === JSON.stringify(currentState)) {\n return false;\n }\n }\n \n // If we're not at the end of history, truncate future states\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n \n // Add new state\n this.history.push(currentState);\n this.historyIndex = this.history.length - 1;\n \n // Enforce max history size\n if (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n \n return true;\n }\n\n /**\n * Undo the last action.\n * @returns The previous graph state, or null if nothing to undo\n */\n undo(): Graph | null {\n if (this.historyIndex <= 0) {\n return null;\n }\n \n this.historyIndex--;\n this.isUndoRedo.set(true);\n const state = structuredClone(this.history[this.historyIndex]);\n // Note: caller should set isUndoRedo back to false after applying state\n return state;\n }\n\n /**\n * Redo the last undone action.\n * @returns The next graph state, or null if nothing to redo\n */\n redo(): Graph | null {\n if (this.historyIndex >= this.history.length - 1) {\n return null;\n }\n \n this.historyIndex++;\n this.isUndoRedo.set(true);\n const state = structuredClone(this.history[this.historyIndex]);\n // Note: caller should set isUndoRedo back to false after applying state\n return state;\n }\n\n /**\n * Complete an undo/redo operation.\n * Call this after applying the state returned by undo() or redo().\n */\n completeUndoRedo(): void {\n this.isUndoRedo.set(false);\n }\n\n /** Check if undo is available */\n canUndo(): boolean {\n return this.historyIndex > 0;\n }\n\n /** Check if redo is available */\n canRedo(): boolean {\n return this.historyIndex < this.history.length - 1;\n }\n\n /** Clear history and reset to given state */\n clear(graph: Graph): void {\n this.init(graph);\n }\n\n /** Get current history size */\n get size(): number {\n return this.history.length;\n }\n\n /** Get current position in history (0-indexed) */\n get position(): number {\n return this.historyIndex;\n }\n\n /** Set maximum history size */\n setMaxSize(size: number): void {\n this.maxHistorySize = size;\n // Trim history if necessary\n while (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnInit,\n Output,\n signal,\n SimpleChanges,\n viewChild\n} from '@angular/core';\n// dagre is loaded dynamically in applyLayout() to avoid compile-time resolution issues\nimport {Graph, GraphEdge, GraphNode, Position} from './graph.model';\nimport {ContextMenuEvent, GraphEditorConfig, NodeTypeDefinition, SelectionState, ValidationResult} from './graph-editor.config';\nimport {GraphHistoryService} from './services/graph-history.service';\nimport {SvgIconDefinition} from './icons/workflow-icons';\n\n/**\n * Main graph editor component.\n *\n * @example\n * <graph-editor\n * [config]=\"editorConfig\"\n * [graph]=\"currentGraph()\"\n * (graphChange)=\"onGraphChange($event)\"\n * />\n */\n@Component({\n selector: 'graph-editor',\n standalone: true,\n imports: [],\n providers: [GraphHistoryService],\n host: {\n 'tabindex': '0',\n 'style': 'outline: none;',\n '(keydown)': 'onKeyDown($event)'\n },\n templateUrl: './graph-editor.component.html',\n styleUrl: './graph-editor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class GraphEditorComponent implements OnInit, OnChanges {\n // Inputs\n @Input({ required: true }) config!: GraphEditorConfig;\n @Input() graph: Graph = { nodes: [], edges: [] };\n @Input() readonly = false;\n @Input() visualizationMode = false;\n @Input() overlayData?: Map<string, any>;\n\n // Outputs\n @Output() graphChange = new EventEmitter<Graph>();\n @Output() nodeAdded = new EventEmitter<GraphNode>();\n @Output() nodeUpdated = new EventEmitter<GraphNode>();\n @Output() nodeRemoved = new EventEmitter<GraphNode>();\n @Output() edgeAdded = new EventEmitter<GraphEdge>();\n @Output() edgeUpdated = new EventEmitter<GraphEdge>();\n @Output() edgeRemoved = new EventEmitter<GraphEdge>();\n @Output() selectionChange = new EventEmitter<SelectionState>();\n @Output() validationChange = new EventEmitter<ValidationResult>();\n @Output() nodeClick = new EventEmitter<GraphNode>();\n @Output() nodeDoubleClick = new EventEmitter<GraphNode>();\n @Output() edgeClick = new EventEmitter<GraphEdge>();\n @Output() edgeDoubleClick = new EventEmitter<GraphEdge>();\n @Output() canvasClick = new EventEmitter<Position>();\n @Output() contextMenu = new EventEmitter<ContextMenuEvent>();\n\n private readonly canvasSvgRef = viewChild<ElementRef>('canvasSvg');\n private readonly historyService = inject(GraphHistoryService);\n\n // Internal state\n internalGraph = signal<Graph>({ nodes: [], edges: [] });\n selection = signal<SelectionState>({ nodes: [], edges: [] });\n validationResult = signal<ValidationResult | null>(null);\n\n // Pan & Zoom state\n panX = signal(0);\n panY = signal(0);\n scale = signal(1);\n\n // Dragging state\n private draggedNode: GraphNode | null = null;\n private dragOffset: Position = { x: 0, y: 0 };\n private draggedNodeOffsets: Map<string, Position> = new Map(); // For multi-node drag\n private didDrag = false; // Track if actual dragging occurred (to suppress click after drag)\n private isPanning = false;\n private lastMousePos: Position = { x: 0, y: 0 };\n private draggedEdge: { edge: GraphEdge; endpoint: 'source' | 'target' } | null = null;\n private hoveredNodeId: string | null = null;\n hoveredPort: { nodeId: string; port: 'top' | 'bottom' | 'left' | 'right' } | null = null;\n\n // Attachment points visibility\n showAttachmentPoints = signal<string | null>(null); // nodeId to show ports for\n\n // Active tool\n activeTool = signal<'hand' | 'line'>('hand');\n\n // Line tool state\n private pendingEdge: { sourceId: string; sourcePort: 'top' | 'bottom' | 'left' | 'right' } | null = null;\n\n // Preview line for line tool (rubber-band from source to cursor)\n previewLine = signal<{ source: Position; target: Position } | null>(null);\n\n // Box selection state (Shift+drag)\n private isBoxSelecting = false;\n private boxSelectStart: Position = { x: 0, y: 0 };\n selectionBox = signal<{ x: number; y: number; width: number; height: number } | null>(null);\n\n // Computed\n transform = computed(() =>\n `translate(${this.panX()}, ${this.panY()}) scale(${this.scale()})`\n );\n\n gridBounds = computed(() => {\n const gridSize = this.config.canvas?.grid?.size || 20;\n const viewportWidth = 10000; // Large enough to cover any reasonable viewport\n const viewportHeight = 10000;\n\n // Calculate grid offset to align with pan\n const x = Math.floor(-this.panX() / this.scale() / gridSize) * gridSize - viewportWidth / 2;\n const y = Math.floor(-this.panY() / this.scale() / gridSize) * gridSize - viewportHeight / 2;\n\n return {\n x,\n y,\n width: viewportWidth * 2,\n height: viewportHeight * 2\n };\n });\n\n // Shadow configuration (defaults to true)\n shadowsEnabled = computed(() => this.config.theme?.shadows !== false);\n\n // Selected edge info for direction selector positioning\n selectedEdgeMidpoint = computed(() => {\n const sel = this.selection();\n if (sel.edges.length !== 1) return null;\n const edge = this.internalGraph().edges.find(e => e.id === sel.edges[0]);\n if (!edge) return null;\n\n const sourcePoint = this.getEdgeSourcePoint(edge);\n const targetPoint = this.getEdgeTargetPoint(edge);\n const midX = (sourcePoint.x + targetPoint.x) / 2;\n const midY = (sourcePoint.y + targetPoint.y) / 2;\n\n return {\n edge,\n x: midX * this.scale() + this.panX(),\n y: midY * this.scale() + this.panY()\n };\n });\n\n constructor() {}\n\n ngOnChanges(changes: SimpleChanges) {\n // Sync graph input to internal signal\n if (changes['graph'] && changes['graph'].currentValue) {\n this.internalGraph.set(structuredClone(changes['graph'].currentValue));\n }\n }\n\n ngOnInit() {\n // Initialize with current graph value\n if (this.graph) {\n this.internalGraph.set(structuredClone(this.graph));\n }\n this.validate();\n // Initialize history with starting state\n this.historyService.init(this.internalGraph());\n }\n\n // Node operations\n addNode(type: string, position?: Position): GraphNode {\n const nodeConfig = this.config.nodes.types.find(t => t.type === type);\n if (!nodeConfig) {\n throw new Error(`Unknown node type: ${type}`);\n }\n\n const newNode: GraphNode = {\n id: this.generateId(),\n type,\n data: structuredClone(nodeConfig.defaultData),\n position: position || { x: 100, y: 100 }\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n nodes: [...graph.nodes, newNode]\n });\n\n this.emitGraphChange();\n this.nodeAdded.emit(newNode);\n this.switchTool('hand');\n return newNode;\n }\n\n removeNode(nodeId: string, removeAttachedEdges = false): void {\n const graph = this.internalGraph();\n const removedNode = graph.nodes.find(n => n.id === nodeId);\n this.internalGraph.set({\n ...graph,\n nodes: graph.nodes.filter(n => n.id !== nodeId),\n edges: removeAttachedEdges\n ? graph.edges.filter(e => e.source !== nodeId && e.target !== nodeId)\n : graph.edges\n });\n this.selection.set({ nodes: [], edges: [] });\n this.emitGraphChange();\n if (removedNode) this.nodeRemoved.emit(removedNode);\n }\n\n removeEdge(edgeId: string): void {\n const graph = this.internalGraph();\n const removedEdge = graph.edges.find(e => e.id === edgeId);\n this.internalGraph.set({\n ...graph,\n edges: graph.edges.filter(e => e.id !== edgeId)\n });\n this.selection.set({ nodes: [], edges: [] });\n this.emitGraphChange();\n if (removedEdge) this.edgeRemoved.emit(removedEdge);\n }\n\n updateNode(nodeId: string, updates: Partial<GraphNode>): void {\n const graph = this.internalGraph();\n const nodeIndex = graph.nodes.findIndex(n => n.id === nodeId);\n if (nodeIndex === -1) return;\n\n const updatedNodes = [...graph.nodes];\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], ...updates };\n\n this.internalGraph.set({\n ...graph,\n nodes: updatedNodes\n });\n this.emitGraphChange();\n }\n\n // Selection\n selectNode(nodeId: string | null): void {\n if (nodeId === null) {\n this.selection.set({ nodes: [], edges: [] });\n } else {\n this.selection.set({ nodes: [nodeId], edges: [] });\n }\n this.selectionChange.emit(this.selection());\n }\n\n selectEdge(edgeId: string | null): void {\n if (edgeId === null) {\n this.selection.set({ nodes: [], edges: [] });\n } else {\n this.selection.set({ nodes: [], edges: [edgeId] });\n }\n this.selectionChange.emit(this.selection());\n }\n\n /** Toggle a node in/out of the current selection (for Ctrl+Click) */\n toggleNodeSelection(nodeId: string): void {\n const sel = this.selection();\n const isSelected = sel.nodes.includes(nodeId);\n if (isSelected) {\n // Remove from selection\n this.selection.set({\n nodes: sel.nodes.filter(id => id !== nodeId),\n edges: sel.edges\n });\n } else {\n // Add to selection\n this.selection.set({\n nodes: [...sel.nodes, nodeId],\n edges: sel.edges\n });\n }\n this.selectionChange.emit(this.selection());\n }\n\n /** Toggle an edge in/out of the current selection (for Ctrl+Click) */\n toggleEdgeSelection(edgeId: string): void {\n const sel = this.selection();\n const isSelected = sel.edges.includes(edgeId);\n if (isSelected) {\n // Remove from selection\n this.selection.set({\n nodes: sel.nodes,\n edges: sel.edges.filter(id => id !== edgeId)\n });\n } else {\n // Add to selection\n this.selection.set({\n nodes: sel.nodes,\n edges: [...sel.edges, edgeId]\n });\n }\n this.selectionChange.emit(this.selection());\n }\n\n onKeyDown(event: KeyboardEvent): void {\n if (this.readonly || this.config.interaction?.readonly) return;\n\n // Escape: cancel line drawing, clear selection\n if (event.key === 'Escape') {\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n this.showAttachmentPoints.set(null);\n event.preventDefault();\n return;\n }\n\n // Undo: Ctrl+Z (or Cmd+Z on Mac)\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n if (this.undo()) {\n event.preventDefault();\n }\n return;\n }\n\n // Redo: Ctrl+Y or Ctrl+Shift+Z (or Cmd+Y / Cmd+Shift+Z on Mac)\n if ((event.ctrlKey || event.metaKey) && (event.key === 'y' || (event.key === 'z' && event.shiftKey))) {\n if (this.redo()) {\n event.preventDefault();\n }\n return;\n }\n\n if (event.key === 'Delete' || event.key === 'Backspace') {\n const sel = this.selection();\n if (sel.nodes.length === 0 && sel.edges.length === 0) return;\n\n // Batch delete: remove all selected items atomically (single history entry)\n const graph = this.internalGraph();\n const nodeIdsToRemove = new Set(sel.nodes);\n const edgeIdsToRemove = new Set(sel.edges);\n\n // Collect removed items for events\n const removedNodes = graph.nodes.filter(n => nodeIdsToRemove.has(n.id));\n const removedEdges = graph.edges.filter(e => edgeIdsToRemove.has(e.id));\n\n // Filter out selected nodes\n const remainingNodes = graph.nodes.filter(n => !nodeIdsToRemove.has(n.id));\n\n // Filter out selected edges AND edges connected to deleted nodes\n const remainingEdges = graph.edges.filter(e =>\n !edgeIdsToRemove.has(e.id) &&\n !nodeIdsToRemove.has(e.source) &&\n !nodeIdsToRemove.has(e.target)\n );\n\n // Find edges that were removed because they connected to deleted nodes\n const additionalRemovedEdges = graph.edges.filter(e =>\n !edgeIdsToRemove.has(e.id) &&\n (nodeIdsToRemove.has(e.source) || nodeIdsToRemove.has(e.target))\n );\n\n // Update graph atomically (single history push)\n this.internalGraph.set({ ...graph, nodes: remainingNodes, edges: remainingEdges });\n this.emitGraphChange();\n\n // Emit removal events\n for (const edge of removedEdges) {\n this.edgeRemoved.emit(edge);\n }\n for (const edge of additionalRemovedEdges) {\n this.edgeRemoved.emit(edge);\n }\n for (const node of removedNodes) {\n this.nodeRemoved.emit(node);\n }\n\n // Clear selection\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n\n event.preventDefault();\n return;\n }\n\n // Arrow keys: nudge selected node(s) — 1px default, 10px with Shift\n if (event.key.startsWith('Arrow')) {\n const sel = this.selection();\n if (sel.nodes.length === 0) return;\n\n const step = event.shiftKey ? 10 : 1;\n let dx = 0;\n let dy = 0;\n switch (event.key) {\n case 'ArrowUp': dy = -step; break;\n case 'ArrowDown': dy = step; break;\n case 'ArrowLeft': dx = -step; break;\n case 'ArrowRight': dx = step; break;\n }\n\n event.preventDefault();\n\n const graph = this.internalGraph();\n const updatedNodes = [...graph.nodes];\n for (const nodeId of sel.nodes) {\n const idx = updatedNodes.findIndex(n => n.id === nodeId);\n if (idx === -1) continue;\n const pos = updatedNodes[idx].position;\n updatedNodes[idx] = { ...updatedNodes[idx], position: { x: pos.x + dx, y: pos.y + dy } };\n }\n\n // Recalculate edge ports for moved nodes (atomic update)\n const movedIds = new Set(sel.nodes);\n const updatedEdges = graph.edges.map(edge => {\n if (!movedIds.has(edge.source) && !movedIds.has(edge.target)) return edge;\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n }\n }\n\n switchTool(tool: 'hand' | 'line'): void {\n const previousTool = this.activeTool();\n\n // Cancel any in-progress line drawing\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n\n // Preserve node selection when switching hand → line\n if (!(previousTool === 'hand' && tool === 'line')) {\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n }\n\n this.activeTool.set(tool);\n\n // Hand → line with a node selected: start edge from that node\n if (previousTool === 'hand' && tool === 'line') {\n const sel = this.selection();\n if (sel.nodes.length === 1) {\n this.pendingEdge = { sourceId: sel.nodes[0], sourcePort: 'bottom' };\n }\n }\n }\n\n /** @deprecated Use switchTool('line') instead */\n switchToLineTool(): void {\n this.switchTool('line');\n }\n\n onEdgeClick(event: MouseEvent, edge: GraphEdge): void {\n if (this.activeTool() !== 'hand') return;\n event.stopPropagation();\n if (event.ctrlKey || event.metaKey) {\n // Ctrl/Cmd+Click: toggle edge in selection\n this.toggleEdgeSelection(edge.id);\n } else {\n // Normal click: replace selection with this edge\n this.selectEdge(edge.id);\n }\n this.edgeClick.emit(edge);\n }\n\n onEdgeDoubleClick(event: MouseEvent, edge: GraphEdge): void {\n if (this.activeTool() !== 'hand') return;\n event.stopPropagation();\n this.selectEdge(edge.id);\n this.edgeDoubleClick.emit(edge);\n }\n\n clearSelection(): void {\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n }\n\n // Validation\n validate(): ValidationResult {\n if (!this.config.validation) {\n const result = { valid: true, errors: [] };\n this.validationResult.set(result);\n return result;\n }\n\n const errors = this.config.validation!.validators.flatMap(rule =>\n rule.validator(this.internalGraph(), this.config)\n );\n\n const result = {\n valid: errors.filter(e => e.severity !== 'warning').length === 0,\n errors\n };\n\n this.validationResult.set(result);\n this.validationChange.emit(result);\n return result;\n }\n\n // Layout\n async applyLayout(direction: 'TB' | 'LR' = 'TB'): Promise<void> {\n const graph = this.internalGraph();\n if (graph.nodes.length === 0) return;\n\n // Dynamic import to avoid compile-time module resolution issues\n const dagreModule = await import('dagre');\n const dagre = dagreModule.default ?? dagreModule;\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: direction,\n nodesep: 60,\n ranksep: 80,\n marginx: 40,\n marginy: 40,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const node of graph.nodes) {\n const size = this.getNodeSize(node);\n g.setNode(node.id, { width: size.width, height: size.height });\n }\n\n for (const edge of graph.edges) {\n g.setEdge(edge.source, edge.target);\n }\n\n dagre.layout(g);\n\n const updatedNodes = graph.nodes.map(node => {\n const dagreNode = g.node(node.id);\n if (!dagreNode) return node;\n const size = this.getNodeSize(node);\n return {\n ...node,\n position: {\n x: dagreNode.x - size.width / 2,\n y: dagreNode.y - size.height / 2,\n },\n };\n });\n\n // Recalculate edge ports based on new node positions\n const updatedEdges = graph.edges.map(edge => {\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n\n setTimeout(() => this.fitToScreen());\n }\n\n fitToScreen(padding = 40): void {\n const nodes = this.internalGraph().nodes;\n if (nodes.length === 0) return;\n\n // Get SVG element dimensions\n const ref = this.canvasSvgRef();\n const svgEl: SVGSVGElement | null = ref?.nativeElement ?? ref ?? null;\n if (!svgEl || typeof svgEl.getBoundingClientRect !== 'function') return;\n\n const rect = svgEl.getBoundingClientRect();\n const viewW = rect.width;\n const viewH = rect.height;\n if (viewW === 0 || viewH === 0) return;\n\n // Calculate bounding box of all nodes\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const node of nodes) {\n const size = this.getNodeSize(node);\n minX = Math.min(minX, node.position.x);\n minY = Math.min(minY, node.position.y);\n maxX = Math.max(maxX, node.position.x + size.width);\n maxY = Math.max(maxY, node.position.y + size.height);\n }\n\n const contentW = maxX - minX;\n const contentH = maxY - minY;\n\n // Handle single node or all nodes stacked\n if (contentW <= 0 && contentH <= 0) {\n this.scale.set(1);\n this.panX.set(viewW / 2 - (minX + 110) * 1);\n this.panY.set(viewH / 2 - (minY + 50) * 1);\n return;\n }\n\n // Calculate scale to fit content with padding (cap at 1 to avoid zooming in too much)\n const zoomConfig = this.config.canvas?.zoom;\n const minScale = zoomConfig?.min ?? 0.25;\n const scaleX = contentW > 0 ? (viewW - padding * 2) / contentW : 1;\n const scaleY = contentH > 0 ? (viewH - padding * 2) / contentH : 1;\n const newScale = Math.max(minScale, Math.min(1, Math.min(scaleX, scaleY)));\n\n // Center the content in the viewport\n const centerX = (minX + maxX) / 2;\n const centerY = (minY + maxY) / 2;\n const newPanX = viewW / 2 - centerX * newScale;\n const newPanY = viewH / 2 - centerY * newScale;\n\n this.scale.set(newScale);\n this.panX.set(newPanX);\n this.panY.set(newPanY);\n }\n\n zoomTo(level: number): void {\n const zoomConfig = this.config.canvas?.zoom;\n const min = zoomConfig?.min ?? 0.25;\n const max = zoomConfig?.max ?? 2.0;\n this.scale.set(Math.max(min, Math.min(max, level)));\n }\n\n getSelection(): SelectionState {\n return this.selection();\n }\n\n // Event handlers\n onCanvasMouseDown(event: MouseEvent): void {\n if (this.readonly) return;\n\n // Cancel pending edge on empty space click\n if (this.pendingEdge) {\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n\n const target = event.target as SVGElement;\n const isNode = !!target.closest('.graph-node');\n const isEdgeEndpoint = target.classList.contains('edge-endpoint');\n const isAttachmentPoint = target.classList.contains('attachment-point');\n const isHitArea = target.classList.contains('edge-hit-area');\n const isInteractive = isNode || isEdgeEndpoint || isAttachmentPoint || isHitArea;\n\n if (!isInteractive) {\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n if (event.shiftKey && this.activeTool() === 'hand') {\n // Shift+drag = box selection (only with hand tool)\n this.isBoxSelecting = true;\n this.boxSelectStart = { x: mouseX, y: mouseY };\n this.selectionBox.set({ x: mouseX, y: mouseY, width: 0, height: 0 });\n } else {\n // Normal drag = pan\n this.isPanning = true;\n }\n this.lastMousePos = { x: event.clientX, y: event.clientY };\n this.clearSelection();\n event.preventDefault();\n }\n }\n\n onCanvasMouseMove(event: MouseEvent): void {\n if (this.isBoxSelecting) {\n // Update selection box\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n const x = Math.min(this.boxSelectStart.x, mouseX);\n const y = Math.min(this.boxSelectStart.y, mouseY);\n const width = Math.abs(mouseX - this.boxSelectStart.x);\n const height = Math.abs(mouseY - this.boxSelectStart.y);\n\n this.selectionBox.set({ x, y, width, height });\n } else if (this.isPanning) {\n const dx = event.clientX - this.lastMousePos.x;\n const dy = event.clientY - this.lastMousePos.y;\n this.panX.set(this.panX() + dx);\n this.panY.set(this.panY() + dy);\n this.lastMousePos = { x: event.clientX, y: event.clientY };\n } else if (this.draggedNode) {\n this.didDrag = true; // Mark that dragging occurred\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n const graph = this.internalGraph();\n const updatedNodes = [...graph.nodes];\n const movedNodeIds = new Set<string>();\n\n // Check if we're dragging multiple selected nodes\n if (this.draggedNodeOffsets.size > 1) {\n // Multi-node drag: move all selected nodes\n for (const [nodeId, offset] of this.draggedNodeOffsets) {\n const nodeIndex = updatedNodes.findIndex(n => n.id === nodeId);\n if (nodeIndex === -1) continue;\n\n let x = mouseX - offset.x;\n let y = mouseY - offset.y;\n\n // Smart snap to grid\n if (this.config.canvas?.grid?.snap) {\n const gridSize = this.config.canvas.grid.size || 20;\n const snapThreshold = gridSize / 4;\n const snapX = Math.round(x / gridSize) * gridSize;\n const snapY = Math.round(y / gridSize) * gridSize;\n if (Math.abs(x - snapX) < snapThreshold) x = snapX;\n if (Math.abs(y - snapY) < snapThreshold) y = snapY;\n }\n\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], position: { x, y } };\n movedNodeIds.add(nodeId);\n }\n } else {\n // Single node drag\n let x = mouseX - this.dragOffset.x;\n let y = mouseY - this.dragOffset.y;\n\n // Smart snap to grid\n if (this.config.canvas?.grid?.snap) {\n const gridSize = this.config.canvas.grid.size || 20;\n const snapThreshold = gridSize / 4;\n const snapX = Math.round(x / gridSize) * gridSize;\n const snapY = Math.round(y / gridSize) * gridSize;\n if (Math.abs(x - snapX) < snapThreshold) x = snapX;\n if (Math.abs(y - snapY) < snapThreshold) y = snapY;\n }\n\n const nodeIndex = updatedNodes.findIndex(n => n.id === this.draggedNode!.id);\n if (nodeIndex !== -1) {\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], position: { x, y } };\n movedNodeIds.add(this.draggedNode!.id);\n }\n }\n\n // Recalculate ports for all edges connected to moved nodes\n const updatedEdges = graph.edges.map(edge => {\n if (!movedNodeIds.has(edge.source) && !movedNodeIds.has(edge.target)) return edge;\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n } else if (this.draggedEdge) {\n // Edge reconnection - find hovered node and closest port\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n // Find node under cursor\n const nodeId = this.findNodeAtPosition({ x: mouseX, y: mouseY });\n\n if (nodeId) {\n // Show attachment points for this node\n this.showAttachmentPoints.set(nodeId);\n\n // Find closest port\n const closestPort = this.findClosestPort(nodeId, { x: mouseX, y: mouseY });\n\n // Highlight port if within snap distance (40px)\n if (closestPort && closestPort.distance < 40) {\n this.hoveredPort = { nodeId, port: closestPort.port };\n this.hoveredNodeId = nodeId;\n } else {\n this.hoveredPort = null;\n this.hoveredNodeId = null;\n }\n } else {\n // No node nearby - hide attachment points\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.hoveredNodeId = null;\n }\n } else if (this.pendingEdge && this.activeTool() === 'line') {\n // Line tool pending state - show rubber-band preview + attachment points on hovered node\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n // Get source port position\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePoint = this.getPortWorldPosition(sourceNode, this.pendingEdge.sourcePort);\n\n // Check if cursor is near a node - snap to its closest port\n const hoveredNodeId = this.findNodeAtPosition({ x: mouseX, y: mouseY });\n let targetPoint: Position = { x: mouseX, y: mouseY };\n\n if (hoveredNodeId && hoveredNodeId !== this.pendingEdge.sourceId) {\n // Show attachment points on hovered node\n this.showAttachmentPoints.set(hoveredNodeId);\n\n // Find and highlight closest port\n const closestPort = this.findClosestPort(hoveredNodeId, { x: mouseX, y: mouseY });\n if (closestPort && closestPort.distance < 40) {\n this.hoveredPort = { nodeId: hoveredNodeId, port: closestPort.port };\n // Snap preview line to port\n const hoveredNode = this.internalGraph().nodes.find(n => n.id === hoveredNodeId);\n if (hoveredNode) {\n targetPoint = this.getPortWorldPosition(hoveredNode, closestPort.port);\n }\n } else {\n this.hoveredPort = null;\n }\n } else {\n // Not over a valid target node - hide attachment points\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n }\n\n this.previewLine.set({ source: sourcePoint, target: targetPoint });\n }\n }\n }\n\n onCanvasMouseUp(_event: MouseEvent): void {\n // Handle box selection completion\n if (this.isBoxSelecting) {\n const box = this.selectionBox();\n if (box && (box.width > 5 || box.height > 5)) {\n // Find all nodes within the selection box\n const selectedNodes: string[] = [];\n for (const node of this.internalGraph().nodes) {\n const size = this.getNodeSize(node);\n const nodeRight = node.position.x + size.width;\n const nodeBottom = node.position.y + size.height;\n const boxRight = box.x + box.width;\n const boxBottom = box.y + box.height;\n\n // Check if node intersects with selection box\n if (node.position.x < boxRight &&\n nodeRight > box.x &&\n node.position.y < boxBottom &&\n nodeBottom > box.y) {\n selectedNodes.push(node.id);\n }\n }\n\n if (selectedNodes.length > 0) {\n // Also select edges where both source and target are selected\n const selectedEdges: string[] = [];\n for (const edge of this.internalGraph().edges) {\n if (selectedNodes.includes(edge.source) && selectedNodes.includes(edge.target)) {\n selectedEdges.push(edge.id);\n }\n }\n this.selection.set({ nodes: selectedNodes, edges: selectedEdges });\n this.selectionChange.emit(this.selection());\n }\n }\n this.isBoxSelecting = false;\n this.selectionBox.set(null);\n }\n\n // Handle edge reconnection with port snapping\n if (this.draggedEdge && this.hoveredNodeId && this.hoveredPort) {\n const graph = this.internalGraph();\n const edgeIndex = graph.edges.findIndex(e => e.id === this.draggedEdge!.edge.id);\n\n if (edgeIndex !== -1) {\n const updatedEdges = [...graph.edges];\n const updatedEdge = { ...updatedEdges[edgeIndex] };\n\n // Update node connection and store port information (non-null: guarded by if condition)\n if (this.draggedEdge.endpoint === 'source') {\n updatedEdge.source = this.hoveredNodeId!;\n updatedEdge.sourcePort = this.hoveredPort!.port;\n } else {\n updatedEdge.target = this.hoveredNodeId!;\n updatedEdge.targetPort = this.hoveredPort!.port;\n }\n\n updatedEdges[edgeIndex] = updatedEdge;\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n this.emitGraphChange();\n this.edgeUpdated.emit(updatedEdge);\n }\n }\n\n this.isPanning = false;\n this.draggedNode = null;\n this.draggedNodeOffsets.clear();\n this.draggedEdge = null;\n this.hoveredNodeId = null;\n this.hoveredPort = null;\n this.showAttachmentPoints.set(null);\n }\n\n onNodeMouseDown(event: MouseEvent, node: GraphNode): void {\n if (this.readonly) return;\n event.stopPropagation(); // Always prevent canvas from seeing node mousedowns\n if (this.activeTool() !== 'hand') return;\n\n this.draggedNode = node;\n this.didDrag = false; // Reset - will be set true if actual movement occurs\n // Calculate offset between mouse position and node origin to prevent jump\n const svg = (event.target as SVGElement).closest('svg')!;\n const rect = svg.getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n this.dragOffset = {\n x: mouseX - node.position.x,\n y: mouseY - node.position.y\n };\n\n // If this node is part of a multi-selection, calculate offsets for all selected nodes\n const sel = this.selection();\n this.draggedNodeOffsets.clear();\n if (sel.nodes.includes(node.id) && sel.nodes.length > 1) {\n const graph = this.internalGraph();\n for (const nodeId of sel.nodes) {\n const n = graph.nodes.find(nd => nd.id === nodeId);\n if (n) {\n this.draggedNodeOffsets.set(nodeId, {\n x: mouseX - n.position.x,\n y: mouseY - n.position.y\n });\n }\n }\n }\n }\n\n onNodeClick(event: MouseEvent, node: GraphNode): void {\n if (this.activeTool() === 'line') {\n event.stopPropagation();\n\n if (!this.pendingEdge) {\n // First click - start edge from this node\n // Pick initial port based on geometry (will be recalculated on second click)\n this.pendingEdge = { sourceId: node.id, sourcePort: 'bottom' };\n this.selectNode(node.id);\n } else if (this.pendingEdge.sourceId !== node.id) {\n // Second click on different node - complete the edge\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePort = this.findClosestPortForEdge(sourceNode, node, 'source');\n const targetPort = this.findClosestPortForEdge(node, sourceNode, 'target');\n\n const newEdge: GraphEdge = {\n id: `edge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n source: this.pendingEdge.sourceId,\n target: node.id,\n sourcePort,\n targetPort\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n edges: [...graph.edges, newEdge]\n });\n this.emitGraphChange();\n this.edgeAdded.emit(newEdge);\n }\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n } else {\n // Clicked same node - cancel\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n } else {\n // Hand tool - select or toggle selection\n // Skip selection change if we just finished dragging\n if (this.didDrag) {\n this.didDrag = false;\n return;\n }\n if (event.ctrlKey || event.metaKey) {\n // Ctrl/Cmd+Click: toggle node in selection\n this.toggleNodeSelection(node.id);\n } else {\n // Normal click: replace selection with this node\n this.selectNode(node.id);\n }\n }\n }\n\n onAttachmentPointClick(event: MouseEvent, node: GraphNode, port: 'top' | 'bottom' | 'left' | 'right'): void {\n event.stopPropagation();\n if (this.readonly) return;\n\n if (this.activeTool() === 'line') {\n if (!this.pendingEdge) {\n // First click on attachment point - start edge from this specific port\n this.pendingEdge = { sourceId: node.id, sourcePort: port };\n this.selectNode(node.id);\n } else if (this.pendingEdge.sourceId !== node.id) {\n // Second click - complete edge to this specific port\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePort = this.findClosestPortForEdge(sourceNode, node, 'source');\n\n const newEdge: GraphEdge = {\n id: `edge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n source: this.pendingEdge.sourceId,\n target: node.id,\n sourcePort,\n targetPort: port\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n edges: [...graph.edges, newEdge]\n });\n this.emitGraphChange();\n this.edgeAdded.emit(newEdge);\n }\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n } else {\n // Clicked same node - cancel\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n }\n }\n\n onEdgeEndpointMouseDown(event: MouseEvent, edge: GraphEdge, endpoint: 'source' | 'target'): void {\n if (this.readonly) return;\n event.stopPropagation();\n this.draggedEdge = { edge, endpoint };\n }\n\n onWheel(event: WheelEvent): void {\n const zoomConfig = this.config.canvas?.zoom;\n if (!zoomConfig?.wheelEnabled) return;\n\n event.preventDefault();\n const delta = -event.deltaY;\n const step = zoomConfig.step ?? 0.1;\n const newScale = Math.max(\n zoomConfig.min ?? 0.25,\n Math.min(\n zoomConfig.max ?? 2.0,\n this.scale() + (delta > 0 ? step : -step)\n )\n );\n\n this.scale.set(newScale);\n }\n\n onContextMenu(event: MouseEvent): void {\n event.preventDefault();\n\n const svgRect = this.canvasSvgRef()?.nativeElement.getBoundingClientRect();\n if (!svgRect) return;\n\n // Calculate position in graph coordinates\n const x = (event.clientX - svgRect.left - this.panX()) / this.scale();\n const y = (event.clientY - svgRect.top - this.panY()) / this.scale();\n\n // Check if clicking on a node\n const nodeId = this.findNodeAtPosition({ x, y });\n if (nodeId) {\n this.contextMenu.emit({\n type: 'node',\n position: { x: event.clientX, y: event.clientY },\n nodeId\n });\n return;\n }\n\n // Check if clicking on an edge (use hit area logic)\n const edgeId = this.findEdgeAtPosition({ x, y });\n if (edgeId) {\n this.contextMenu.emit({\n type: 'edge',\n position: { x: event.clientX, y: event.clientY },\n edgeId\n });\n return;\n }\n\n // Canvas click\n this.contextMenu.emit({\n type: 'canvas',\n position: { x: event.clientX, y: event.clientY }\n });\n }\n\n // Helper methods\n private emitGraphChange(): void {\n // Push to history (unless this is an undo/redo operation)\n if (!this.historyService.isUndoRedo()) {\n this.historyService.push(this.internalGraph());\n }\n this.graphChange.emit(this.internalGraph());\n if (this.config.validation?.validateOnChange) {\n this.validate();\n }\n }\n\n /** Undo the last action (Ctrl+Z) */\n undo(): boolean {\n const state = this.historyService.undo();\n if (!state) {\n return false;\n }\n \n this.internalGraph.set(state);\n this.graphChange.emit(this.internalGraph());\n this.historyService.completeUndoRedo();\n \n // Clear selection after undo\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n \n return true;\n }\n\n /** Redo the last undone action (Ctrl+Y / Ctrl+Shift+Z) */\n redo(): boolean {\n const state = this.historyService.redo();\n if (!state) {\n return false;\n }\n \n this.internalGraph.set(state);\n this.graphChange.emit(this.internalGraph());\n this.historyService.completeUndoRedo();\n \n // Clear selection after redo\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n \n return true;\n }\n\n /** Check if undo is available */\n canUndo(): boolean {\n return this.historyService.canUndo();\n }\n\n /** Check if redo is available */\n canRedo(): boolean {\n return this.historyService.canRedo();\n }\n\n /** Clear history and reset to current state */\n clearHistory(): void {\n this.historyService.clear(this.internalGraph());\n }\n\n private generateId(): string {\n return `node_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private recalculateEdgePorts(nodeId: string): void {\n const graph = this.internalGraph();\n let changed = false;\n const updatedEdges = graph.edges.map(edge => {\n if (edge.source !== nodeId && edge.target !== nodeId) return edge;\n\n const sourceNode = graph.nodes.find(n => n.id === edge.source);\n const targetNode = graph.nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n\n changed = true;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n if (changed) {\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n }\n }\n\n getNodeSize(node: GraphNode): { width: number; height: number } {\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n return nodeConfig?.size || this.config.nodes.defaultSize || { width: 220, height: 100 };\n }\n\n getEdgePath(edge: GraphEdge): string {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n\n if (!sourceNode || !targetNode) return '';\n\n // Get port positions from edge or calculate closest\n const sourcePort = (edge.sourcePort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const targetPort = (edge.targetPort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n\n const sourcePoint = this.getPortWorldPosition(sourceNode, sourcePort);\n const targetPoint = this.getPortWorldPosition(targetNode, targetPort);\n\n // Simple straight line\n return `M ${sourcePoint.x},${sourcePoint.y} L ${targetPoint.x},${targetPoint.y}`;\n }\n\n getEdgeColor(edge: GraphEdge): string {\n return edge.metadata?.style?.stroke || this.config.edges.style?.stroke || '#94a3b8';\n }\n\n getEdgeMarkerEnd(edge: GraphEdge): string | null {\n const dir = edge.direction || 'forward';\n const selected = this.selection().edges.includes(edge.id);\n if (dir === 'forward' || dir === 'bidirectional') {\n return selected ? 'url(#arrow-end-selected)' : 'url(#arrow-end)';\n }\n return null;\n }\n\n getEdgeMarkerStart(edge: GraphEdge): string | null {\n const dir = edge.direction || 'forward';\n const selected = this.selection().edges.includes(edge.id);\n if (dir === 'backward' || dir === 'bidirectional') {\n return selected ? 'url(#arrow-start-selected)' : 'url(#arrow-start)';\n }\n return null;\n }\n\n setEdgeDirection(direction: 'forward' | 'backward' | 'bidirectional'): void {\n const sel = this.selection();\n if (sel.edges.length !== 1) return;\n\n const graph = this.internalGraph();\n const edgeIndex = graph.edges.findIndex(e => e.id === sel.edges[0]);\n if (edgeIndex === -1) return;\n\n const updatedEdges = [...graph.edges];\n updatedEdges[edgeIndex] = { ...updatedEdges[edgeIndex], direction };\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n this.emitGraphChange();\n this.edgeUpdated.emit(updatedEdges[edgeIndex]);\n }\n\n getEdgeSourcePoint(edge: GraphEdge): Position {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return { x: 0, y: 0 };\n\n const sourcePort = (edge.sourcePort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n return this.getPortWorldPosition(sourceNode, sourcePort);\n }\n\n getEdgeTargetPoint(edge: GraphEdge): Position {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return { x: 0, y: 0 };\n\n const targetPort = (edge.targetPort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n return this.getPortWorldPosition(targetNode, targetPort);\n }\n\n getNodeTypeIcon(node: GraphNode): string {\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n return nodeConfig?.icon || '●';\n }\n\n /**\n * Get image URL for a node icon.\n * Priority: node.data['imageUrl'] > nodeType.iconSvg (converted to data URL) > nodeType.defaultData['imageUrl']\n * Returns null if no image is configured (will render text icon instead).\n */\n getNodeImage(node: GraphNode): string | null {\n // Check instance-level image first\n if (node.data['imageUrl']) {\n return node.data['imageUrl'] as string;\n }\n\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n\n // Check for iconSvg definition (convert to data URL)\n if (nodeConfig?.iconSvg) {\n return this.svgIconToDataUrl(nodeConfig.iconSvg);\n }\n\n // Fall back to node type default imageUrl\n if (nodeConfig?.defaultData['imageUrl']) {\n return nodeConfig.defaultData['imageUrl'] as string;\n }\n\n return null;\n }\n\n /**\n * Convert an SvgIconDefinition to a data URL for use in <image> elements.\n * Caches results to avoid repeated conversion.\n */\n private svgIconCache = new Map<SvgIconDefinition, string>();\n\n private svgIconToDataUrl(icon: SvgIconDefinition): string {\n // Check cache first\n const cached = this.svgIconCache.get(icon);\n if (cached) return cached;\n\n const viewBox = icon.viewBox || '0 0 24 24';\n const fill = icon.fill || 'none';\n const stroke = icon.stroke || '#1D6A96';\n const strokeWidth = icon.strokeWidth || 2;\n\n // Build SVG markup with proper path handling\n const paths = icon.path\n .split(/\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0)\n .map(p => `<path d=\"${p}\"/>`)\n .join('');\n\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"${viewBox}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\n\n // Encode as data URL\n const dataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;\n this.svgIconCache.set(icon, dataUrl);\n return dataUrl;\n }\n\n /**\n * Get the SVG icon definition for a node type (for palette rendering).\n * Returns null if no iconSvg is configured.\n */\n getNodeTypeSvgIcon(nodeType: NodeTypeDefinition): SvgIconDefinition | null {\n return nodeType.iconSvg || null;\n }\n\n /**\n * Split SVG path data by newlines for template iteration.\n * Used to render multiple path elements from a single path string.\n */\n splitIconPaths(pathData: string): string[] {\n return pathData\n .split(/\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0);\n }\n\n /**\n * Get the position for the node image (top-left corner of image).\n * Uses same positioning logic as icon but accounts for image dimensions.\n */\n getImagePosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const imageSize = this.getImageSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = 8;\n\n const positions: Record<string, Position> = {\n 'top-left': { x: padding, y: padding },\n 'top': { x: (size.width - imageSize) / 2, y: padding },\n 'top-right': { x: size.width - imageSize - padding, y: padding },\n 'right': { x: size.width - imageSize - padding, y: (size.height - imageSize) / 2 },\n 'bottom-right': { x: size.width - imageSize - padding, y: size.height - imageSize - padding },\n 'bottom': { x: (size.width - imageSize) / 2, y: size.height - imageSize - padding },\n 'bottom-left': { x: padding, y: size.height - imageSize - padding },\n 'left': { x: padding, y: (size.height - imageSize) / 2 }\n };\n\n return positions[pos] || positions['top-left'];\n }\n\n /**\n * Get the size (width/height) for node images.\n * Images are rendered as squares, sized proportionally to node height.\n */\n getImageSize(node: GraphNode): number {\n const size = this.getNodeSize(node);\n // Image takes up ~40% of node height, with min 24px and max 64px\n return Math.min(64, Math.max(24, size.height * 0.4));\n }\n\n getIconPosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = size.height * 0.25;\n const iconSize = size.height * 0.28;\n\n const positions: Record<string, Position> = {\n 'top-left': { x: padding, y: padding },\n 'top': { x: size.width / 2, y: padding },\n 'top-right': { x: size.width - padding, y: padding },\n 'right': { x: size.width - padding, y: size.height / 2 },\n 'bottom-right': { x: size.width - padding, y: size.height - padding },\n 'bottom': { x: size.width / 2, y: size.height - padding },\n 'bottom-left': { x: padding, y: size.height - padding },\n 'left': { x: padding, y: size.height / 2 }\n };\n\n return positions[pos] || positions['left'];\n }\n\n getLabelPosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = size.height * 0.25;\n\n // Label position adjusts based on icon position\n const labelPositions: Record<string, Position> = {\n 'top-left': { x: size.width / 2 + padding / 2, y: size.height / 2 + 4 },\n 'top': { x: size.width / 2, y: size.height / 2 + padding / 2 },\n 'top-right': { x: size.width / 2 - padding / 2, y: size.height / 2 + 4 },\n 'right': { x: size.width / 2 - padding / 2, y: size.height / 2 },\n 'bottom-right': { x: size.width / 2 - padding / 2, y: size.height / 2 - 4 },\n 'bottom': { x: size.width / 2, y: size.height / 2 - padding / 2 },\n 'bottom-left': { x: size.width / 2 + padding / 2, y: size.height / 2 - 4 },\n 'left': { x: size.width / 2 + padding / 2, y: size.height / 2 }\n };\n\n return labelPositions[pos] || labelPositions['top-left'];\n }\n\n private findNodeAtPosition(pos: Position): string | null {\n for (const node of this.internalGraph().nodes) {\n const size = this.getNodeSize(node);\n if (\n pos.x >= node.position.x &&\n pos.x <= node.position.x + size.width &&\n pos.y >= node.position.y &&\n pos.y <= node.position.y + size.height\n ) {\n return node.id;\n }\n }\n return null;\n }\n\n private findEdgeAtPosition(pos: Position): string | null {\n const hitDistance = 10; // pixels tolerance\n for (const edge of this.internalGraph().edges) {\n const sourcePoint = this.getEdgeSourcePoint(edge);\n const targetPoint = this.getEdgeTargetPoint(edge);\n\n // Calculate distance from point to line segment\n const dist = this.pointToSegmentDistance(pos, sourcePoint, targetPoint);\n if (dist < hitDistance) {\n return edge.id;\n }\n }\n return null;\n }\n\n private pointToSegmentDistance(point: Position, lineStart: Position, lineEnd: Position): number {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n const lengthSquared = dx * dx + dy * dy;\n\n if (lengthSquared === 0) {\n // Line segment is a point\n return Math.sqrt((point.x - lineStart.x) ** 2 + (point.y - lineStart.y) ** 2);\n }\n\n // Project point onto line segment\n let t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / lengthSquared;\n t = Math.max(0, Math.min(1, t));\n\n const projX = lineStart.x + t * dx;\n const projY = lineStart.y + t * dy;\n\n return Math.sqrt((point.x - projX) ** 2 + (point.y - projY) ** 2);\n }\n\n getNodePorts(node: GraphNode): Array<{ position: 'top' | 'bottom' | 'left' | 'right'; x: number; y: number }> {\n const size = this.getNodeSize(node);\n return [\n { position: 'top', x: size.width / 2, y: 0 },\n { position: 'bottom', x: size.width / 2, y: size.height },\n { position: 'left', x: 0, y: size.height / 2 },\n { position: 'right', x: size.width, y: size.height / 2 }\n ];\n }\n\n private findClosestPort(nodeId: string, worldPos: Position): { port: 'top' | 'bottom' | 'left' | 'right'; distance: number } | null {\n const node = this.internalGraph().nodes.find(n => n.id === nodeId);\n if (!node) return null;\n\n const ports = this.getNodePorts(node);\n let closestPort: typeof ports[0] | null = null;\n let minDistance = Infinity;\n\n for (const port of ports) {\n const portWorldX = node.position.x + port.x;\n const portWorldY = node.position.y + port.y;\n const dx = worldPos.x - portWorldX;\n const dy = worldPos.y - portWorldY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < minDistance) {\n minDistance = distance;\n closestPort = port;\n }\n }\n\n return closestPort ? { port: closestPort.position, distance: minDistance } : null;\n }\n\n private getPortWorldPosition(node: GraphNode, port: 'top' | 'bottom' | 'left' | 'right'): Position {\n const size = this.getNodeSize(node);\n const portOffsets = {\n top: { x: size.width / 2, y: 0 },\n bottom: { x: size.width / 2, y: size.height },\n left: { x: 0, y: size.height / 2 },\n right: { x: size.width, y: size.height / 2 }\n };\n\n const offset = portOffsets[port];\n return {\n x: node.position.x + offset.x,\n y: node.position.y + offset.y\n };\n }\n\n private findClosestPortForEdge(\n node: GraphNode,\n otherNode: GraphNode,\n endpoint: 'source' | 'target'\n ): 'top' | 'bottom' | 'left' | 'right' {\n const size = this.getNodeSize(node);\n const nodeCenter = {\n x: node.position.x + size.width / 2,\n y: node.position.y + size.height / 2\n };\n const otherSize = this.getNodeSize(otherNode);\n const otherCenter = {\n x: otherNode.position.x + otherSize.width / 2,\n y: otherNode.position.y + otherSize.height / 2\n };\n\n const dx = otherCenter.x - nodeCenter.x;\n const dy = otherCenter.y - nodeCenter.y;\n\n // Determine which port is closest based on relative position\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n\n if (absDx > absDy) {\n // Horizontal connection\n return dx > 0 ? 'right' : 'left';\n } else {\n // Vertical connection\n return dy > 0 ? 'bottom' : 'top';\n }\n }\n}\n","<div class=\"graph-editor-container\">\n <!-- Canvas with overlaid palette -->\n <div class=\"graph-canvas-wrapper\">\n <!-- Top-left horizontal palette overlay -->\n @if (config.palette?.enabled !== false) {\n <div class=\"graph-palette-overlay\">\n <!-- Tools -->\n <button\n class=\"palette-item tool-item\"\n [class.active]=\"activeTool() === 'hand'\"\n title=\"Hand tool (move nodes)\"\n (click)=\"switchTool('hand')\"\n >\n <span class=\"icon\">✋</span>\n </button>\n <button\n class=\"palette-item tool-item\"\n [class.active]=\"activeTool() === 'line'\"\n title=\"Line tool (draw connections)\"\n (click)=\"switchTool('line')\"\n >\n <span class=\"icon\">∕</span>\n </button>\n\n <!-- Divider -->\n <div class=\"palette-divider\"></div>\n\n <!-- Node types -->\n @for (nodeType of config.nodes.types; track nodeType.type) {\n <button\n class=\"palette-item\"\n [attr.data-node-type]=\"nodeType.type\"\n [attr.title]=\"nodeType.label || nodeType.type\"\n (click)=\"addNode(nodeType.type)\"\n >\n @if (nodeType.iconSvg) {\n <svg\n class=\"palette-icon-svg\"\n [attr.viewBox]=\"nodeType.iconSvg.viewBox || '0 0 24 24'\"\n [attr.fill]=\"nodeType.iconSvg.fill || 'none'\"\n [attr.stroke]=\"nodeType.iconSvg.stroke || '#1D6A96'\"\n [attr.stroke-width]=\"nodeType.iconSvg.strokeWidth || 2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n @for (pathData of splitIconPaths(nodeType.iconSvg.path); track $index) {\n <path [attr.d]=\"pathData\"/>\n }\n </svg>\n } @else if (nodeType.defaultData['imageUrl']) {\n <img\n class=\"palette-icon-img\"\n [src]=\"nodeType.defaultData['imageUrl']\"\n [alt]=\"nodeType.label || nodeType.type\"\n />\n } @else {\n <span class=\"icon\">{{ nodeType.icon || '●' }}</span>\n }\n </button>\n }\n </div>\n }\n\n <svg\n #canvasSvg\n [class.tool-line]=\"activeTool() === 'line'\"\n [attr.width]=\"'100%'\"\n [attr.height]=\"'100%'\"\n (mousedown)=\"onCanvasMouseDown($event)\"\n (mousemove)=\"onCanvasMouseMove($event)\"\n (mouseup)=\"onCanvasMouseUp($event)\"\n (wheel)=\"onWheel($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n >\n <!-- Arrow marker definitions -->\n <defs>\n <marker id=\"arrow-end\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 1 L 8 5 L 0 9 z\" fill=\"#94a3b8\"/>\n </marker>\n <marker id=\"arrow-end-selected\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 1 L 8 5 L 0 9 z\" fill=\"#3b82f6\"/>\n </marker>\n <marker id=\"arrow-start\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 10 1 L 2 5 L 10 9 z\" fill=\"#94a3b8\"/>\n </marker>\n <marker id=\"arrow-start-selected\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 10 1 L 2 5 L 10 9 z\" fill=\"#3b82f6\"/>\n </marker>\n </defs>\n\n <!-- Main transform group (pan + zoom) -->\n <g [attr.transform]=\"transform()\">\n <!-- Grid (if enabled) -->\n <!-- Grid (if enabled) - extended to cover viewport during pan -->\n @if (config.canvas?.grid?.enabled) {\n <defs>\n <pattern\n id=\"grid\"\n [attr.width]=\"config.canvas!.grid!.size\"\n [attr.height]=\"config.canvas!.grid!.size\"\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n [attr.d]=\"'M ' + config.canvas!.grid!.size + ' 0 L 0 0 0 ' + config.canvas!.grid!.size\"\n fill=\"none\"\n [attr.stroke]=\"config.canvas!.grid!.color || '#e0e0e0'\"\n stroke-width=\"1\"\n />\n </pattern>\n </defs>\n <!-- Extended grid background covering viewport + pan offset -->\n <rect\n [attr.x]=\"gridBounds().x\"\n [attr.y]=\"gridBounds().y\"\n [attr.width]=\"gridBounds().width\"\n [attr.height]=\"gridBounds().height\"\n fill=\"url(#grid)\"\n />\n }\n\n <!-- Layer 0.5: Preview line for line tool (rubber-band) -->\n @if (previewLine()) {\n <line\n class=\"preview-line\"\n [attr.x1]=\"previewLine()!.source.x\"\n [attr.y1]=\"previewLine()!.source.y\"\n [attr.x2]=\"previewLine()!.target.x\"\n [attr.y2]=\"previewLine()!.target.y\"\n stroke=\"#3b82f6\"\n stroke-width=\"2.5\"\n stroke-dasharray=\"8,6\"\n stroke-linecap=\"round\"\n opacity=\"0.7\"\n />\n }\n\n <!-- Layer 1: Edge paths (behind everything) -->\n @for (edge of internalGraph().edges; track edge.id) {\n <!-- Edge shadow for depth (optional) -->\n @if (shadowsEnabled()) {\n <path\n class=\"edge-shadow\"\n [attr.d]=\"getEdgePath(edge)\"\n stroke=\"rgba(0,0,0,0.06)\"\n stroke-width=\"6\"\n fill=\"none\"\n stroke-linecap=\"round\"\n [attr.transform]=\"'translate(1, 2)'\"\n />\n }\n <!-- Invisible wide hit-area for easier clicking (hand tool only) -->\n <path\n [attr.d]=\"getEdgePath(edge)\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"20\"\n fill=\"none\"\n class=\"edge-hit-area\"\n [attr.pointer-events]=\"activeTool() === 'hand' ? 'stroke' : 'none'\"\n (click)=\"onEdgeClick($event, edge)\"\n (dblclick)=\"onEdgeDoubleClick($event, edge)\"\n />\n <!-- Visible edge line -->\n <path\n class=\"edge-line\"\n [attr.d]=\"getEdgePath(edge)\"\n [attr.stroke]=\"selection().edges.includes(edge.id) ? '#3b82f6' : '#94a3b8'\"\n [attr.stroke-width]=\"selection().edges.includes(edge.id) ? 2.5 : 2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n [class.selected]=\"selection().edges.includes(edge.id)\"\n [attr.marker-end]=\"getEdgeMarkerEnd(edge)\"\n [attr.marker-start]=\"getEdgeMarkerStart(edge)\"\n pointer-events=\"none\"\n />\n }\n\n <!-- Layer 2: Nodes -->\n @for (node of internalGraph().nodes; track node.id) {\n <g\n [attr.transform]=\"'translate(' + node.position.x + ',' + node.position.y + ')'\"\n class=\"graph-node\"\n [class.selected]=\"selection().nodes.includes(node.id)\"\n [attr.data-node-id]=\"node.id\"\n (mousedown)=\"onNodeMouseDown($event, node)\"\n (click)=\"onNodeClick($event, node)\"\n (dblclick)=\"nodeDoubleClick.emit(node)\"\n >\n <!-- Node shadow (optional) -->\n @if (shadowsEnabled()) {\n <rect\n class=\"node-shadow\"\n [attr.width]=\"getNodeSize(node).width\"\n [attr.height]=\"getNodeSize(node).height\"\n fill=\"rgba(0,0,0,0.08)\"\n rx=\"12\"\n transform=\"translate(2, 3)\"\n style=\"filter: blur(4px);\"\n />\n }\n <!-- Node background -->\n <rect\n class=\"node-bg\"\n [attr.width]=\"getNodeSize(node).width\"\n [attr.height]=\"getNodeSize(node).height\"\n fill=\"white\"\n [attr.stroke]=\"selection().nodes.includes(node.id) ? '#3b82f6' : '#e2e8f0'\"\n [attr.stroke-width]=\"selection().nodes.includes(node.id) ? 2.5 : 1.5\"\n rx=\"12\"\n />\n\n <!-- Node type icon (text/emoji) or custom image -->\n @if (getNodeImage(node)) {\n <image\n class=\"node-image\"\n [attr.href]=\"getNodeImage(node)\"\n [attr.xlink:href]=\"getNodeImage(node)\"\n [attr.x]=\"getImagePosition(node).x\"\n [attr.y]=\"getImagePosition(node).y\"\n [attr.width]=\"getImageSize(node)\"\n [attr.height]=\"getImageSize(node)\"\n preserveAspectRatio=\"xMidYMid meet\"\n />\n } @else {\n <text\n class=\"node-icon\"\n [attr.x]=\"getIconPosition(node).x\"\n [attr.y]=\"getIconPosition(node).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.font-size]=\"getNodeSize(node).height * 0.28\"\n >\n {{ getNodeTypeIcon(node) }}\n </text>\n }\n\n <!-- Node label -->\n <text\n class=\"node-label\"\n [attr.x]=\"getLabelPosition(node).x\"\n [attr.y]=\"getLabelPosition(node).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n font-size=\"14\"\n font-weight=\"500\"\n fill=\"#1e293b\"\n >\n {{ node.data['name'] || node.type }}\n </text>\n </g>\n }\n\n <!-- Layer 3: Attachment points (on top of nodes) -->\n @for (node of internalGraph().nodes; track node.id) {\n @if (showAttachmentPoints() === node.id) {\n <g [attr.transform]=\"'translate(' + node.position.x + ',' + node.position.y + ')'\">\n @for (port of getNodePorts(node); track port.position) {\n <circle\n [attr.cx]=\"port.x\"\n [attr.cy]=\"port.y\"\n [attr.r]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position ? 8 : 6\"\n [attr.fill]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position ? '#2563eb' : '#94a3b8'\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"attachment-point\"\n [class.hovered]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"onAttachmentPointClick($event, node, port.position)\"\n />\n }\n </g>\n }\n }\n\n <!-- Layer 4: Edge endpoints (only visible when edge is selected) -->\n @for (edge of internalGraph().edges; track edge.id) {\n @if (selection().edges.includes(edge.id)) {\n <g>\n <!-- Source endpoint -->\n <circle\n [attr.cx]=\"getEdgeSourcePoint(edge).x\"\n [attr.cy]=\"getEdgeSourcePoint(edge).y\"\n r=\"6\"\n fill=\"#3b82f6\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"edge-endpoint selected\"\n (mousedown)=\"onEdgeEndpointMouseDown($event, edge, 'source')\"\n />\n\n <!-- Target endpoint -->\n <circle\n [attr.cx]=\"getEdgeTargetPoint(edge).x\"\n [attr.cy]=\"getEdgeTargetPoint(edge).y\"\n r=\"6\"\n fill=\"#3b82f6\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"edge-endpoint selected\"\n (mousedown)=\"onEdgeEndpointMouseDown($event, edge, 'target')\"\n />\n </g>\n }\n }\n\n <!-- Layer 5: Selection box (Shift+drag) -->\n @if (selectionBox()) {\n <rect\n class=\"selection-box\"\n [attr.x]=\"selectionBox()!.x\"\n [attr.y]=\"selectionBox()!.y\"\n [attr.width]=\"selectionBox()!.width\"\n [attr.height]=\"selectionBox()!.height\"\n fill=\"rgba(59, 130, 246, 0.1)\"\n stroke=\"#3b82f6\"\n stroke-width=\"1\"\n stroke-dasharray=\"4,2\"\n />\n }\n </g>\n </svg>\n </div>\n\n <!-- Edge direction selector overlay -->\n @if (selectedEdgeMidpoint()) {\n <div\n class=\"edge-direction-selector\"\n [style.left.px]=\"selectedEdgeMidpoint()!.x\"\n [style.top.px]=\"selectedEdgeMidpoint()!.y\"\n >\n <button\n class=\"direction-btn\"\n [class.active]=\"selectedEdgeMidpoint()!.edge.direction === 'backward'\"\n title=\"Backward\"\n (click)=\"setEdgeDirection('backward')\"\n >←</button>\n <button\n class=\"direction-btn\"\n [class.active]=\"selectedEdgeMidpoint()!.edge.direction === 'bidirectional'\"\n title=\"Bidirectional\"\n (click)=\"setEdgeDirection('bidirectional')\"\n >↔</button>\n <button\n class=\"direction-btn\"\n [class.active]=\"!selectedEdgeMidpoint()!.edge.direction || selectedEdgeMidpoint()!.edge.direction === 'forward'\"\n title=\"Forward\"\n (click)=\"setEdgeDirection('forward')\"\n >→</button>\n </div>\n }\n</div>\n","/**\n * SVG icon definition interface for custom node icons.\n * Use this to define your own icons that match your design system.\n *\n * Example usage:\n * const myIcons = {\n * process: {\n * viewBox: '0 0 24 24',\n * fill: 'none',\n * stroke: '#1D6A96',\n * strokeWidth: 1.75,\n * path: 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z...'\n * }\n * };\n */\nexport interface SvgIconDefinition {\n /** SVG path data (d attribute) or full SVG markup */\n path: string;\n /** ViewBox dimensions (default: '0 0 24 24') */\n viewBox?: string;\n /** Fill color (default: 'none' for stroke-based icons) */\n fill?: string;\n /** Stroke color (default: currentColor) */\n stroke?: string;\n /** Stroke width (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Generate inline SVG markup for an icon (for use in palette/toolbar)\n */\nexport function renderIconSvg(icon: SvgIconDefinition, size: number = 24): string {\n const viewBox = icon.viewBox || '0 0 24 24';\n const fill = icon.fill || 'none';\n const stroke = icon.stroke || 'currentColor';\n const strokeWidth = icon.strokeWidth || 2;\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"${viewBox}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${icon.path.split('\\n').map(p => `<path d=\"${p.trim()}\"/>`).join('')}</svg>`;\n}\n\n/**\n * Generate data URL for an icon (for use as image source)\n */\nexport function iconToDataUrl(icon: SvgIconDefinition, size: number = 48): string {\n const svg = renderIconSvg(icon, size);\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\n","// Main component\nexport { GraphEditorComponent } from './lib/graph-editor.component';\n\n// Data model - use 'export type' for re-exports when isolatedModules is enabled\nexport type {\n Graph,\n GraphNode,\n GraphEdge,\n Position,\n NodeMetadata,\n EdgeMetadata,\n EdgeStyle,\n GraphMetadata\n} from './lib/graph.model';\n\n// Configuration - use 'export type' for re-exports\nexport type {\n GraphEditorConfig,\n NodesConfig,\n EdgesConfig,\n CanvasConfig,\n ValidationConfig,\n LayoutConfig,\n InteractionConfig,\n ThemeConfig,\n PaletteConfig,\n NodeTypeDefinition,\n PortConfig,\n PortDefinition,\n NodeConstraints,\n GridConfig,\n ZoomConfig,\n PanConfig,\n ValidationRule,\n ValidationError,\n LayoutOptions,\n ContextMenuConfig,\n ContextMenuItem,\n ContextMenuContext,\n SelectionState,\n ValidationResult,\n ContextMenuEvent\n} from './lib/graph-editor.config';\n\n// SVG icon utilities\nexport type { SvgIconDefinition } from './lib/icons/workflow-icons';\nexport { renderIconSvg, iconToDataUrl } from './lib/icons/workflow-icons';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utisha-graph-editor.mjs","sources":["../../../projects/graph-editor/src/lib/services/graph-history.service.ts","../../../projects/graph-editor/src/lib/graph-editor.component.ts","../../../projects/graph-editor/src/lib/graph-editor.component.html","../../../projects/graph-editor/src/lib/icons/workflow-icons.ts","../../../projects/graph-editor/src/public-api.ts","../../../projects/graph-editor/src/utisha-graph-editor.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { Graph } from '../graph.model';\n\n/**\n * Service for managing undo/redo history of graph state.\n * \n * Uses a simple snapshot-based approach where each history entry\n * is a deep copy of the entire graph state.\n */\n@Injectable()\nexport class GraphHistoryService {\n private history: Graph[] = [];\n private historyIndex = -1;\n private maxHistorySize = 100;\n \n /** Signal to track if an undo/redo operation is in progress */\n readonly isUndoRedo = signal(false);\n\n /**\n * Initialize history with the given graph state.\n * Clears any existing history.\n */\n init(graph: Graph): void {\n this.history = [structuredClone(graph)];\n this.historyIndex = 0;\n }\n\n /**\n * Push a new state to the history stack.\n * If we're not at the end of history, truncates future states.\n * Prevents duplicate consecutive states.\n * \n * @returns true if state was pushed, false if it was a duplicate\n */\n push(graph: Graph): boolean {\n const currentState = structuredClone(graph);\n \n // Don't push if state hasn't changed\n if (this.historyIndex >= 0 && this.historyIndex < this.history.length) {\n const lastState = this.history[this.historyIndex];\n if (JSON.stringify(lastState) === JSON.stringify(currentState)) {\n return false;\n }\n }\n \n // If we're not at the end of history, truncate future states\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n \n // Add new state\n this.history.push(currentState);\n this.historyIndex = this.history.length - 1;\n \n // Enforce max history size\n if (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n \n return true;\n }\n\n /**\n * Undo the last action.\n * @returns The previous graph state, or null if nothing to undo\n */\n undo(): Graph | null {\n if (this.historyIndex <= 0) {\n return null;\n }\n \n this.historyIndex--;\n this.isUndoRedo.set(true);\n const state = structuredClone(this.history[this.historyIndex]);\n // Note: caller should set isUndoRedo back to false after applying state\n return state;\n }\n\n /**\n * Redo the last undone action.\n * @returns The next graph state, or null if nothing to redo\n */\n redo(): Graph | null {\n if (this.historyIndex >= this.history.length - 1) {\n return null;\n }\n \n this.historyIndex++;\n this.isUndoRedo.set(true);\n const state = structuredClone(this.history[this.historyIndex]);\n // Note: caller should set isUndoRedo back to false after applying state\n return state;\n }\n\n /**\n * Complete an undo/redo operation.\n * Call this after applying the state returned by undo() or redo().\n */\n completeUndoRedo(): void {\n this.isUndoRedo.set(false);\n }\n\n /** Check if undo is available */\n canUndo(): boolean {\n return this.historyIndex > 0;\n }\n\n /** Check if redo is available */\n canRedo(): boolean {\n return this.historyIndex < this.history.length - 1;\n }\n\n /** Clear history and reset to given state */\n clear(graph: Graph): void {\n this.init(graph);\n }\n\n /** Get current history size */\n get size(): number {\n return this.history.length;\n }\n\n /** Get current position in history (0-indexed) */\n get position(): number {\n return this.historyIndex;\n }\n\n /** Set maximum history size */\n setMaxSize(size: number): void {\n this.maxHistorySize = size;\n // Trim history if necessary\n while (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnInit,\n Output,\n signal,\n SimpleChanges,\n viewChild\n} from '@angular/core';\n// dagre is loaded dynamically in applyLayout() to avoid compile-time resolution issues\nimport {Graph, GraphEdge, GraphNode, Position} from './graph.model';\nimport {ContextMenuEvent, GraphEditorConfig, NodeTypeDefinition, SelectionState, ValidationResult} from './graph-editor.config';\nimport {GraphHistoryService} from './services/graph-history.service';\nimport {SvgIconDefinition} from './icons/workflow-icons';\n\n/**\n * Main graph editor component.\n *\n * @example\n * <graph-editor\n * [config]=\"editorConfig\"\n * [graph]=\"currentGraph()\"\n * (graphChange)=\"onGraphChange($event)\"\n * />\n */\n@Component({\n selector: 'graph-editor',\n standalone: true,\n imports: [],\n providers: [GraphHistoryService],\n host: {\n 'tabindex': '0',\n 'style': 'outline: none;',\n '(keydown)': 'onKeyDown($event)'\n },\n templateUrl: './graph-editor.component.html',\n styleUrl: './graph-editor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class GraphEditorComponent implements OnInit, OnChanges {\n // Inputs\n @Input({ required: true }) config!: GraphEditorConfig;\n @Input() graph: Graph = { nodes: [], edges: [] };\n @Input() readonly = false;\n @Input() visualizationMode = false;\n @Input() overlayData?: Map<string, any>;\n\n // Outputs\n @Output() graphChange = new EventEmitter<Graph>();\n @Output() nodeAdded = new EventEmitter<GraphNode>();\n @Output() nodeUpdated = new EventEmitter<GraphNode>();\n @Output() nodeRemoved = new EventEmitter<GraphNode>();\n @Output() edgeAdded = new EventEmitter<GraphEdge>();\n @Output() edgeUpdated = new EventEmitter<GraphEdge>();\n @Output() edgeRemoved = new EventEmitter<GraphEdge>();\n @Output() selectionChange = new EventEmitter<SelectionState>();\n @Output() validationChange = new EventEmitter<ValidationResult>();\n @Output() nodeClick = new EventEmitter<GraphNode>();\n @Output() nodeDoubleClick = new EventEmitter<GraphNode>();\n @Output() edgeClick = new EventEmitter<GraphEdge>();\n @Output() edgeDoubleClick = new EventEmitter<GraphEdge>();\n @Output() canvasClick = new EventEmitter<Position>();\n @Output() contextMenu = new EventEmitter<ContextMenuEvent>();\n\n private readonly canvasSvgRef = viewChild<ElementRef>('canvasSvg');\n private readonly historyService = inject(GraphHistoryService);\n\n // Internal state\n internalGraph = signal<Graph>({ nodes: [], edges: [] });\n selection = signal<SelectionState>({ nodes: [], edges: [] });\n validationResult = signal<ValidationResult | null>(null);\n\n // Pan & Zoom state\n panX = signal(0);\n panY = signal(0);\n scale = signal(1);\n\n // Dragging state\n private draggedNode: GraphNode | null = null;\n private dragOffset: Position = { x: 0, y: 0 };\n private draggedNodeOffsets: Map<string, Position> = new Map(); // For multi-node drag\n private didDrag = false; // Track if actual dragging occurred (to suppress click after drag)\n private isPanning = false;\n private lastMousePos: Position = { x: 0, y: 0 };\n private draggedEdge: { edge: GraphEdge; endpoint: 'source' | 'target' } | null = null;\n private hoveredNodeId: string | null = null;\n hoveredPort: { nodeId: string; port: 'top' | 'bottom' | 'left' | 'right' } | null = null;\n\n // Attachment points visibility\n showAttachmentPoints = signal<string | null>(null); // nodeId to show ports for\n\n // Active tool\n activeTool = signal<'hand' | 'line'>('hand');\n\n // Line tool state\n private pendingEdge: { sourceId: string; sourcePort: 'top' | 'bottom' | 'left' | 'right' } | null = null;\n\n // Preview line for line tool (rubber-band from source to cursor)\n previewLine = signal<{ source: Position; target: Position } | null>(null);\n\n // Box selection state (Shift+drag)\n private isBoxSelecting = false;\n private boxSelectStart: Position = { x: 0, y: 0 };\n selectionBox = signal<{ x: number; y: number; width: number; height: number } | null>(null);\n\n // Resize state (hand tool)\n private resizingNode: GraphNode | null = null;\n private resizeStartSize: { width: number; height: number } = { width: 0, height: 0 };\n private resizeStartMousePos: Position = { x: 0, y: 0 };\n private resizeMinSize: { width: number; height: number } = { width: 0, height: 0 };\n\n // Computed\n transform = computed(() =>\n `translate(${this.panX()}, ${this.panY()}) scale(${this.scale()})`\n );\n\n gridBounds = computed(() => {\n const gridSize = this.config.canvas?.grid?.size || 20;\n const viewportWidth = 10000; // Large enough to cover any reasonable viewport\n const viewportHeight = 10000;\n\n // Calculate grid offset to align with pan\n const x = Math.floor(-this.panX() / this.scale() / gridSize) * gridSize - viewportWidth / 2;\n const y = Math.floor(-this.panY() / this.scale() / gridSize) * gridSize - viewportHeight / 2;\n\n return {\n x,\n y,\n width: viewportWidth * 2,\n height: viewportHeight * 2\n };\n });\n\n // Shadow configuration (defaults to true)\n shadowsEnabled = computed(() => this.config.theme?.shadows !== false);\n\n // Selected edge info for direction selector positioning\n selectedEdgeMidpoint = computed(() => {\n const sel = this.selection();\n if (sel.edges.length !== 1) return null;\n const edge = this.internalGraph().edges.find(e => e.id === sel.edges[0]);\n if (!edge) return null;\n\n const sourcePoint = this.getEdgeSourcePoint(edge);\n const targetPoint = this.getEdgeTargetPoint(edge);\n const midX = (sourcePoint.x + targetPoint.x) / 2;\n const midY = (sourcePoint.y + targetPoint.y) / 2;\n\n return {\n edge,\n x: midX * this.scale() + this.panX(),\n y: midY * this.scale() + this.panY()\n };\n });\n\n constructor() {}\n\n ngOnChanges(changes: SimpleChanges) {\n // Sync graph input to internal signal\n if (changes['graph'] && changes['graph'].currentValue) {\n this.internalGraph.set(structuredClone(changes['graph'].currentValue));\n }\n }\n\n ngOnInit() {\n // Initialize with current graph value\n if (this.graph) {\n this.internalGraph.set(structuredClone(this.graph));\n }\n this.validate();\n // Initialize history with starting state\n this.historyService.init(this.internalGraph());\n }\n\n // Node operations\n addNode(type: string, position?: Position): GraphNode {\n const nodeConfig = this.config.nodes.types.find(t => t.type === type);\n if (!nodeConfig) {\n throw new Error(`Unknown node type: ${type}`);\n }\n\n const newNode: GraphNode = {\n id: this.generateId(),\n type,\n data: structuredClone(nodeConfig.defaultData),\n position: position || { x: 100, y: 100 }\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n nodes: [...graph.nodes, newNode]\n });\n\n this.emitGraphChange();\n this.nodeAdded.emit(newNode);\n this.switchTool('hand');\n return newNode;\n }\n\n removeNode(nodeId: string, removeAttachedEdges = false): void {\n const graph = this.internalGraph();\n const removedNode = graph.nodes.find(n => n.id === nodeId);\n this.internalGraph.set({\n ...graph,\n nodes: graph.nodes.filter(n => n.id !== nodeId),\n edges: removeAttachedEdges\n ? graph.edges.filter(e => e.source !== nodeId && e.target !== nodeId)\n : graph.edges\n });\n this.selection.set({ nodes: [], edges: [] });\n this.emitGraphChange();\n if (removedNode) this.nodeRemoved.emit(removedNode);\n }\n\n removeEdge(edgeId: string): void {\n const graph = this.internalGraph();\n const removedEdge = graph.edges.find(e => e.id === edgeId);\n this.internalGraph.set({\n ...graph,\n edges: graph.edges.filter(e => e.id !== edgeId)\n });\n this.selection.set({ nodes: [], edges: [] });\n this.emitGraphChange();\n if (removedEdge) this.edgeRemoved.emit(removedEdge);\n }\n\n updateNode(nodeId: string, updates: Partial<GraphNode>): void {\n const graph = this.internalGraph();\n const nodeIndex = graph.nodes.findIndex(n => n.id === nodeId);\n if (nodeIndex === -1) return;\n\n const updatedNodes = [...graph.nodes];\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], ...updates };\n\n this.internalGraph.set({\n ...graph,\n nodes: updatedNodes\n });\n this.emitGraphChange();\n }\n\n // Selection\n selectNode(nodeId: string | null): void {\n if (nodeId === null) {\n this.selection.set({ nodes: [], edges: [] });\n } else {\n this.selection.set({ nodes: [nodeId], edges: [] });\n }\n this.selectionChange.emit(this.selection());\n }\n\n selectEdge(edgeId: string | null): void {\n if (edgeId === null) {\n this.selection.set({ nodes: [], edges: [] });\n } else {\n this.selection.set({ nodes: [], edges: [edgeId] });\n }\n this.selectionChange.emit(this.selection());\n }\n\n /** Toggle a node in/out of the current selection (for Ctrl+Click) */\n toggleNodeSelection(nodeId: string): void {\n const sel = this.selection();\n const isSelected = sel.nodes.includes(nodeId);\n if (isSelected) {\n // Remove from selection\n this.selection.set({\n nodes: sel.nodes.filter(id => id !== nodeId),\n edges: sel.edges\n });\n } else {\n // Add to selection\n this.selection.set({\n nodes: [...sel.nodes, nodeId],\n edges: sel.edges\n });\n }\n this.selectionChange.emit(this.selection());\n }\n\n /** Toggle an edge in/out of the current selection (for Ctrl+Click) */\n toggleEdgeSelection(edgeId: string): void {\n const sel = this.selection();\n const isSelected = sel.edges.includes(edgeId);\n if (isSelected) {\n // Remove from selection\n this.selection.set({\n nodes: sel.nodes,\n edges: sel.edges.filter(id => id !== edgeId)\n });\n } else {\n // Add to selection\n this.selection.set({\n nodes: sel.nodes,\n edges: [...sel.edges, edgeId]\n });\n }\n this.selectionChange.emit(this.selection());\n }\n\n onKeyDown(event: KeyboardEvent): void {\n if (this.readonly || this.config.interaction?.readonly) return;\n\n // Escape: cancel line drawing, clear selection\n if (event.key === 'Escape') {\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n this.showAttachmentPoints.set(null);\n event.preventDefault();\n return;\n }\n\n // Undo: Ctrl+Z (or Cmd+Z on Mac)\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n if (this.undo()) {\n event.preventDefault();\n }\n return;\n }\n\n // Redo: Ctrl+Y or Ctrl+Shift+Z (or Cmd+Y / Cmd+Shift+Z on Mac)\n if ((event.ctrlKey || event.metaKey) && (event.key === 'y' || (event.key === 'z' && event.shiftKey))) {\n if (this.redo()) {\n event.preventDefault();\n }\n return;\n }\n\n if (event.key === 'Delete' || event.key === 'Backspace') {\n const sel = this.selection();\n if (sel.nodes.length === 0 && sel.edges.length === 0) return;\n\n // Batch delete: remove all selected items atomically (single history entry)\n const graph = this.internalGraph();\n const nodeIdsToRemove = new Set(sel.nodes);\n const edgeIdsToRemove = new Set(sel.edges);\n\n // Collect removed items for events\n const removedNodes = graph.nodes.filter(n => nodeIdsToRemove.has(n.id));\n const removedEdges = graph.edges.filter(e => edgeIdsToRemove.has(e.id));\n\n // Filter out selected nodes\n const remainingNodes = graph.nodes.filter(n => !nodeIdsToRemove.has(n.id));\n\n // Filter out selected edges AND edges connected to deleted nodes\n const remainingEdges = graph.edges.filter(e =>\n !edgeIdsToRemove.has(e.id) &&\n !nodeIdsToRemove.has(e.source) &&\n !nodeIdsToRemove.has(e.target)\n );\n\n // Find edges that were removed because they connected to deleted nodes\n const additionalRemovedEdges = graph.edges.filter(e =>\n !edgeIdsToRemove.has(e.id) &&\n (nodeIdsToRemove.has(e.source) || nodeIdsToRemove.has(e.target))\n );\n\n // Update graph atomically (single history push)\n this.internalGraph.set({ ...graph, nodes: remainingNodes, edges: remainingEdges });\n this.emitGraphChange();\n\n // Emit removal events\n for (const edge of removedEdges) {\n this.edgeRemoved.emit(edge);\n }\n for (const edge of additionalRemovedEdges) {\n this.edgeRemoved.emit(edge);\n }\n for (const node of removedNodes) {\n this.nodeRemoved.emit(node);\n }\n\n // Clear selection\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n\n event.preventDefault();\n return;\n }\n\n // Arrow keys: nudge selected node(s) — 1px default, 10px with Shift\n if (event.key.startsWith('Arrow')) {\n const sel = this.selection();\n if (sel.nodes.length === 0) return;\n\n const step = event.shiftKey ? 10 : 1;\n let dx = 0;\n let dy = 0;\n switch (event.key) {\n case 'ArrowUp': dy = -step; break;\n case 'ArrowDown': dy = step; break;\n case 'ArrowLeft': dx = -step; break;\n case 'ArrowRight': dx = step; break;\n }\n\n event.preventDefault();\n\n const graph = this.internalGraph();\n const updatedNodes = [...graph.nodes];\n for (const nodeId of sel.nodes) {\n const idx = updatedNodes.findIndex(n => n.id === nodeId);\n if (idx === -1) continue;\n const pos = updatedNodes[idx].position;\n updatedNodes[idx] = { ...updatedNodes[idx], position: { x: pos.x + dx, y: pos.y + dy } };\n }\n\n // Recalculate edge ports for moved nodes (atomic update)\n const movedIds = new Set(sel.nodes);\n const updatedEdges = graph.edges.map(edge => {\n if (!movedIds.has(edge.source) && !movedIds.has(edge.target)) return edge;\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n }\n }\n\n switchTool(tool: 'hand' | 'line'): void {\n const previousTool = this.activeTool();\n\n // Cancel any in-progress line drawing\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n\n // Preserve node selection when switching hand → line\n if (!(previousTool === 'hand' && tool === 'line')) {\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n }\n\n this.activeTool.set(tool);\n\n // Hand → line with a node selected: start edge from that node\n if (previousTool === 'hand' && tool === 'line') {\n const sel = this.selection();\n if (sel.nodes.length === 1) {\n this.pendingEdge = { sourceId: sel.nodes[0], sourcePort: 'bottom' };\n }\n }\n }\n\n /** @deprecated Use switchTool('line') instead */\n switchToLineTool(): void {\n this.switchTool('line');\n }\n\n onEdgeClick(event: MouseEvent, edge: GraphEdge): void {\n if (this.activeTool() !== 'hand') return;\n event.stopPropagation();\n if (event.ctrlKey || event.metaKey) {\n // Ctrl/Cmd+Click: toggle edge in selection\n this.toggleEdgeSelection(edge.id);\n } else {\n // Normal click: replace selection with this edge\n this.selectEdge(edge.id);\n }\n this.edgeClick.emit(edge);\n }\n\n onEdgeDoubleClick(event: MouseEvent, edge: GraphEdge): void {\n if (this.activeTool() !== 'hand') return;\n event.stopPropagation();\n this.selectEdge(edge.id);\n this.edgeDoubleClick.emit(edge);\n }\n\n clearSelection(): void {\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n }\n\n // Validation\n validate(): ValidationResult {\n if (!this.config.validation) {\n const result = { valid: true, errors: [] };\n this.validationResult.set(result);\n return result;\n }\n\n const errors = this.config.validation!.validators.flatMap(rule =>\n rule.validator(this.internalGraph(), this.config)\n );\n\n const result = {\n valid: errors.filter(e => e.severity !== 'warning').length === 0,\n errors\n };\n\n this.validationResult.set(result);\n this.validationChange.emit(result);\n return result;\n }\n\n // Layout\n async applyLayout(direction: 'TB' | 'LR' = 'TB'): Promise<void> {\n const graph = this.internalGraph();\n if (graph.nodes.length === 0) return;\n\n // Dynamic import to avoid compile-time module resolution issues\n const dagreModule = await import('dagre');\n const dagre = dagreModule.default ?? dagreModule;\n\n const g = new dagre.graphlib.Graph();\n g.setGraph({\n rankdir: direction,\n nodesep: 60,\n ranksep: 80,\n marginx: 40,\n marginy: 40,\n });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const node of graph.nodes) {\n const size = this.getNodeSize(node);\n g.setNode(node.id, { width: size.width, height: size.height });\n }\n\n for (const edge of graph.edges) {\n g.setEdge(edge.source, edge.target);\n }\n\n dagre.layout(g);\n\n const updatedNodes = graph.nodes.map(node => {\n const dagreNode = g.node(node.id);\n if (!dagreNode) return node;\n const size = this.getNodeSize(node);\n return {\n ...node,\n position: {\n x: dagreNode.x - size.width / 2,\n y: dagreNode.y - size.height / 2,\n },\n };\n });\n\n // Recalculate edge ports based on new node positions\n const updatedEdges = graph.edges.map(edge => {\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n\n setTimeout(() => this.fitToScreen());\n }\n\n fitToScreen(padding = 40): void {\n const nodes = this.internalGraph().nodes;\n if (nodes.length === 0) return;\n\n // Get SVG element dimensions\n const ref = this.canvasSvgRef();\n const svgEl: SVGSVGElement | null = ref?.nativeElement ?? ref ?? null;\n if (!svgEl || typeof svgEl.getBoundingClientRect !== 'function') return;\n\n const rect = svgEl.getBoundingClientRect();\n const viewW = rect.width;\n const viewH = rect.height;\n if (viewW === 0 || viewH === 0) return;\n\n // Calculate bounding box of all nodes\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const node of nodes) {\n const size = this.getNodeSize(node);\n minX = Math.min(minX, node.position.x);\n minY = Math.min(minY, node.position.y);\n maxX = Math.max(maxX, node.position.x + size.width);\n maxY = Math.max(maxY, node.position.y + size.height);\n }\n\n const contentW = maxX - minX;\n const contentH = maxY - minY;\n\n // Handle single node or all nodes stacked\n if (contentW <= 0 && contentH <= 0) {\n this.scale.set(1);\n this.panX.set(viewW / 2 - (minX + 110) * 1);\n this.panY.set(viewH / 2 - (minY + 50) * 1);\n return;\n }\n\n // Calculate scale to fit content with padding (cap at 1 to avoid zooming in too much)\n const zoomConfig = this.config.canvas?.zoom;\n const minScale = zoomConfig?.min ?? 0.25;\n const scaleX = contentW > 0 ? (viewW - padding * 2) / contentW : 1;\n const scaleY = contentH > 0 ? (viewH - padding * 2) / contentH : 1;\n const newScale = Math.max(minScale, Math.min(1, Math.min(scaleX, scaleY)));\n\n // Center the content in the viewport\n const centerX = (minX + maxX) / 2;\n const centerY = (minY + maxY) / 2;\n const newPanX = viewW / 2 - centerX * newScale;\n const newPanY = viewH / 2 - centerY * newScale;\n\n this.scale.set(newScale);\n this.panX.set(newPanX);\n this.panY.set(newPanY);\n }\n\n zoomTo(level: number): void {\n const zoomConfig = this.config.canvas?.zoom;\n const min = zoomConfig?.min ?? 0.25;\n const max = zoomConfig?.max ?? 2.0;\n this.scale.set(Math.max(min, Math.min(max, level)));\n }\n\n getSelection(): SelectionState {\n return this.selection();\n }\n\n // Event handlers\n onCanvasMouseDown(event: MouseEvent): void {\n if (this.readonly) return;\n\n // Cancel pending edge on empty space click\n if (this.pendingEdge) {\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n\n const target = event.target as SVGElement;\n const isNode = !!target.closest('.graph-node');\n const isEdgeEndpoint = target.classList.contains('edge-endpoint');\n const isAttachmentPoint = target.classList.contains('attachment-point');\n const isHitArea = target.classList.contains('edge-hit-area');\n const isInteractive = isNode || isEdgeEndpoint || isAttachmentPoint || isHitArea;\n\n if (!isInteractive) {\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n if (event.shiftKey && this.activeTool() === 'hand') {\n // Shift+drag = box selection (only with hand tool)\n this.isBoxSelecting = true;\n this.boxSelectStart = { x: mouseX, y: mouseY };\n this.selectionBox.set({ x: mouseX, y: mouseY, width: 0, height: 0 });\n } else {\n // Normal drag = pan\n this.isPanning = true;\n }\n this.lastMousePos = { x: event.clientX, y: event.clientY };\n this.clearSelection();\n event.preventDefault();\n }\n }\n\n onCanvasMouseMove(event: MouseEvent): void {\n if (this.isBoxSelecting) {\n // Update selection box\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n const x = Math.min(this.boxSelectStart.x, mouseX);\n const y = Math.min(this.boxSelectStart.y, mouseY);\n const width = Math.abs(mouseX - this.boxSelectStart.x);\n const height = Math.abs(mouseY - this.boxSelectStart.y);\n\n this.selectionBox.set({ x, y, width, height });\n } else if (this.resizingNode) {\n // Node resize - calculate new size based on mouse delta\n const dx = (event.clientX - this.resizeStartMousePos.x) / this.scale();\n const dy = (event.clientY - this.resizeStartMousePos.y) / this.scale();\n \n // Calculate new size, enforcing minimum\n const newWidth = Math.max(this.resizeMinSize.width, this.resizeStartSize.width + dx);\n const newHeight = Math.max(this.resizeMinSize.height, this.resizeStartSize.height + dy);\n \n // Update node size\n const graph = this.internalGraph();\n const nodeIndex = graph.nodes.findIndex(n => n.id === this.resizingNode!.id);\n if (nodeIndex !== -1) {\n const updatedNodes = [...graph.nodes];\n updatedNodes[nodeIndex] = { \n ...updatedNodes[nodeIndex], \n size: { width: newWidth, height: newHeight } \n };\n \n // Recalculate edge ports for edges connected to this node\n const updatedEdges = graph.edges.map(edge => {\n if (edge.source !== this.resizingNode!.id && edge.target !== this.resizingNode!.id) return edge;\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n \n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n }\n } else if (this.isPanning) {\n const dx = event.clientX - this.lastMousePos.x;\n const dy = event.clientY - this.lastMousePos.y;\n this.panX.set(this.panX() + dx);\n this.panY.set(this.panY() + dy);\n this.lastMousePos = { x: event.clientX, y: event.clientY };\n } else if (this.draggedNode) {\n this.didDrag = true; // Mark that dragging occurred\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n const graph = this.internalGraph();\n const updatedNodes = [...graph.nodes];\n const movedNodeIds = new Set<string>();\n\n // Check if we're dragging multiple selected nodes\n if (this.draggedNodeOffsets.size > 1) {\n // Multi-node drag: move all selected nodes\n for (const [nodeId, offset] of this.draggedNodeOffsets) {\n const nodeIndex = updatedNodes.findIndex(n => n.id === nodeId);\n if (nodeIndex === -1) continue;\n\n let x = mouseX - offset.x;\n let y = mouseY - offset.y;\n\n // Smart snap to grid\n if (this.config.canvas?.grid?.snap) {\n const gridSize = this.config.canvas.grid.size || 20;\n const snapThreshold = gridSize / 4;\n const snapX = Math.round(x / gridSize) * gridSize;\n const snapY = Math.round(y / gridSize) * gridSize;\n if (Math.abs(x - snapX) < snapThreshold) x = snapX;\n if (Math.abs(y - snapY) < snapThreshold) y = snapY;\n }\n\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], position: { x, y } };\n movedNodeIds.add(nodeId);\n }\n } else {\n // Single node drag\n let x = mouseX - this.dragOffset.x;\n let y = mouseY - this.dragOffset.y;\n\n // Smart snap to grid\n if (this.config.canvas?.grid?.snap) {\n const gridSize = this.config.canvas.grid.size || 20;\n const snapThreshold = gridSize / 4;\n const snapX = Math.round(x / gridSize) * gridSize;\n const snapY = Math.round(y / gridSize) * gridSize;\n if (Math.abs(x - snapX) < snapThreshold) x = snapX;\n if (Math.abs(y - snapY) < snapThreshold) y = snapY;\n }\n\n const nodeIndex = updatedNodes.findIndex(n => n.id === this.draggedNode!.id);\n if (nodeIndex !== -1) {\n updatedNodes[nodeIndex] = { ...updatedNodes[nodeIndex], position: { x, y } };\n movedNodeIds.add(this.draggedNode!.id);\n }\n }\n\n // Recalculate ports for all edges connected to moved nodes\n const updatedEdges = graph.edges.map(edge => {\n if (!movedNodeIds.has(edge.source) && !movedNodeIds.has(edge.target)) return edge;\n const sourceNode = updatedNodes.find(n => n.id === edge.source);\n const targetNode = updatedNodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n this.internalGraph.set({ ...graph, nodes: updatedNodes, edges: updatedEdges });\n this.emitGraphChange();\n } else if (this.draggedEdge) {\n // Edge reconnection - find hovered node and closest port\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n // Find node under cursor\n const nodeId = this.findNodeAtPosition({ x: mouseX, y: mouseY });\n\n if (nodeId) {\n // Show attachment points for this node\n this.showAttachmentPoints.set(nodeId);\n\n // Find closest port\n const closestPort = this.findClosestPort(nodeId, { x: mouseX, y: mouseY });\n\n // Highlight port if within snap distance (40px)\n if (closestPort && closestPort.distance < 40) {\n this.hoveredPort = { nodeId, port: closestPort.port };\n this.hoveredNodeId = nodeId;\n } else {\n this.hoveredPort = null;\n this.hoveredNodeId = null;\n }\n } else {\n // No node nearby - hide attachment points\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.hoveredNodeId = null;\n }\n } else if (this.pendingEdge && this.activeTool() === 'line') {\n // Line tool pending state - show rubber-band preview + attachment points on hovered node\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n\n // Get source port position\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePoint = this.getPortWorldPosition(sourceNode, this.pendingEdge.sourcePort);\n\n // Check if cursor is near a node - snap to its closest port\n const hoveredNodeId = this.findNodeAtPosition({ x: mouseX, y: mouseY });\n let targetPoint: Position = { x: mouseX, y: mouseY };\n\n if (hoveredNodeId && hoveredNodeId !== this.pendingEdge.sourceId) {\n // Show attachment points on hovered node\n this.showAttachmentPoints.set(hoveredNodeId);\n\n // Find and highlight closest port\n const closestPort = this.findClosestPort(hoveredNodeId, { x: mouseX, y: mouseY });\n if (closestPort && closestPort.distance < 40) {\n this.hoveredPort = { nodeId: hoveredNodeId, port: closestPort.port };\n // Snap preview line to port\n const hoveredNode = this.internalGraph().nodes.find(n => n.id === hoveredNodeId);\n if (hoveredNode) {\n targetPoint = this.getPortWorldPosition(hoveredNode, closestPort.port);\n }\n } else {\n this.hoveredPort = null;\n }\n } else {\n // Not over a valid target node - hide attachment points\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n }\n\n this.previewLine.set({ source: sourcePoint, target: targetPoint });\n }\n }\n }\n\n onCanvasMouseUp(_event: MouseEvent): void {\n // Handle box selection completion\n if (this.isBoxSelecting) {\n const box = this.selectionBox();\n if (box && (box.width > 5 || box.height > 5)) {\n // Find all nodes within the selection box\n const selectedNodes: string[] = [];\n for (const node of this.internalGraph().nodes) {\n const size = this.getNodeSize(node);\n const nodeRight = node.position.x + size.width;\n const nodeBottom = node.position.y + size.height;\n const boxRight = box.x + box.width;\n const boxBottom = box.y + box.height;\n\n // Check if node intersects with selection box\n if (node.position.x < boxRight &&\n nodeRight > box.x &&\n node.position.y < boxBottom &&\n nodeBottom > box.y) {\n selectedNodes.push(node.id);\n }\n }\n\n if (selectedNodes.length > 0) {\n // Also select edges where both source and target are selected\n const selectedEdges: string[] = [];\n for (const edge of this.internalGraph().edges) {\n if (selectedNodes.includes(edge.source) && selectedNodes.includes(edge.target)) {\n selectedEdges.push(edge.id);\n }\n }\n this.selection.set({ nodes: selectedNodes, edges: selectedEdges });\n this.selectionChange.emit(this.selection());\n }\n }\n this.isBoxSelecting = false;\n this.selectionBox.set(null);\n }\n\n // Handle edge reconnection with port snapping\n if (this.draggedEdge && this.hoveredNodeId && this.hoveredPort) {\n const graph = this.internalGraph();\n const edgeIndex = graph.edges.findIndex(e => e.id === this.draggedEdge!.edge.id);\n\n if (edgeIndex !== -1) {\n const updatedEdges = [...graph.edges];\n const updatedEdge = { ...updatedEdges[edgeIndex] };\n\n // Update node connection and store port information (non-null: guarded by if condition)\n if (this.draggedEdge.endpoint === 'source') {\n updatedEdge.source = this.hoveredNodeId!;\n updatedEdge.sourcePort = this.hoveredPort!.port;\n } else {\n updatedEdge.target = this.hoveredNodeId!;\n updatedEdge.targetPort = this.hoveredPort!.port;\n }\n\n updatedEdges[edgeIndex] = updatedEdge;\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n this.emitGraphChange();\n this.edgeUpdated.emit(updatedEdge);\n }\n }\n\n this.isPanning = false;\n this.draggedNode = null;\n this.draggedNodeOffsets.clear();\n this.draggedEdge = null;\n this.hoveredNodeId = null;\n this.hoveredPort = null;\n this.showAttachmentPoints.set(null);\n this.resizingNode = null;\n }\n\n onNodeMouseDown(event: MouseEvent, node: GraphNode): void {\n if (this.readonly) return;\n event.stopPropagation(); // Always prevent canvas from seeing node mousedowns\n if (this.activeTool() !== 'hand') return;\n\n this.draggedNode = node;\n this.didDrag = false; // Reset - will be set true if actual movement occurs\n // Calculate offset between mouse position and node origin to prevent jump\n const svg = (event.target as SVGElement).closest('svg')!;\n const rect = svg.getBoundingClientRect();\n const mouseX = (event.clientX - rect.left - this.panX()) / this.scale();\n const mouseY = (event.clientY - rect.top - this.panY()) / this.scale();\n this.dragOffset = {\n x: mouseX - node.position.x,\n y: mouseY - node.position.y\n };\n\n // If this node is part of a multi-selection, calculate offsets for all selected nodes\n const sel = this.selection();\n this.draggedNodeOffsets.clear();\n if (sel.nodes.includes(node.id) && sel.nodes.length > 1) {\n const graph = this.internalGraph();\n for (const nodeId of sel.nodes) {\n const n = graph.nodes.find(nd => nd.id === nodeId);\n if (n) {\n this.draggedNodeOffsets.set(nodeId, {\n x: mouseX - n.position.x,\n y: mouseY - n.position.y\n });\n }\n }\n }\n }\n\n onNodeClick(event: MouseEvent, node: GraphNode): void {\n if (this.activeTool() === 'line') {\n event.stopPropagation();\n\n if (!this.pendingEdge) {\n // First click - start edge from this node\n // Pick initial port based on geometry (will be recalculated on second click)\n this.pendingEdge = { sourceId: node.id, sourcePort: 'bottom' };\n this.selectNode(node.id);\n } else if (this.pendingEdge.sourceId !== node.id) {\n // Second click on different node - complete the edge\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePort = this.findClosestPortForEdge(sourceNode, node, 'source');\n const targetPort = this.findClosestPortForEdge(node, sourceNode, 'target');\n\n const newEdge: GraphEdge = {\n id: `edge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n source: this.pendingEdge.sourceId,\n target: node.id,\n sourcePort,\n targetPort\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n edges: [...graph.edges, newEdge]\n });\n this.emitGraphChange();\n this.edgeAdded.emit(newEdge);\n }\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n } else {\n // Clicked same node - cancel\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n } else {\n // Hand tool - select or toggle selection\n // Skip selection change if we just finished dragging\n if (this.didDrag) {\n this.didDrag = false;\n return;\n }\n if (event.ctrlKey || event.metaKey) {\n // Ctrl/Cmd+Click: toggle node in selection\n this.toggleNodeSelection(node.id);\n } else {\n // Normal click: replace selection with this node\n this.selectNode(node.id);\n }\n }\n }\n\n onAttachmentPointClick(event: MouseEvent, node: GraphNode, port: 'top' | 'bottom' | 'left' | 'right'): void {\n event.stopPropagation();\n if (this.readonly) return;\n\n if (this.activeTool() === 'line') {\n if (!this.pendingEdge) {\n // First click on attachment point - start edge from this specific port\n this.pendingEdge = { sourceId: node.id, sourcePort: port };\n this.selectNode(node.id);\n } else if (this.pendingEdge.sourceId !== node.id) {\n // Second click - complete edge to this specific port\n const sourceNode = this.internalGraph().nodes.find(n => n.id === this.pendingEdge!.sourceId);\n if (sourceNode) {\n const sourcePort = this.findClosestPortForEdge(sourceNode, node, 'source');\n\n const newEdge: GraphEdge = {\n id: `edge_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n source: this.pendingEdge.sourceId,\n target: node.id,\n sourcePort,\n targetPort: port\n };\n\n const graph = this.internalGraph();\n this.internalGraph.set({\n ...graph,\n edges: [...graph.edges, newEdge]\n });\n this.emitGraphChange();\n this.edgeAdded.emit(newEdge);\n }\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n } else {\n // Clicked same node - cancel\n this.pendingEdge = null;\n this.previewLine.set(null);\n this.showAttachmentPoints.set(null);\n this.hoveredPort = null;\n this.clearSelection();\n }\n }\n }\n\n onEdgeEndpointMouseDown(event: MouseEvent, edge: GraphEdge, endpoint: 'source' | 'target'): void {\n if (this.readonly) return;\n event.stopPropagation();\n this.draggedEdge = { edge, endpoint };\n }\n\n onResizeHandleMouseDown(event: MouseEvent, node: GraphNode): void {\n if (this.readonly) return;\n event.stopPropagation();\n \n this.resizingNode = node;\n const currentSize = this.getNodeSize(node);\n this.resizeStartSize = { ...currentSize };\n this.resizeStartMousePos = { x: event.clientX, y: event.clientY };\n \n // Use current size as minimum (from config or existing node.size)\n this.resizeMinSize = { ...currentSize };\n }\n\n onWheel(event: WheelEvent): void {\n const zoomConfig = this.config.canvas?.zoom;\n if (!zoomConfig?.wheelEnabled) return;\n\n event.preventDefault();\n const delta = -event.deltaY;\n const step = zoomConfig.step ?? 0.1;\n const newScale = Math.max(\n zoomConfig.min ?? 0.25,\n Math.min(\n zoomConfig.max ?? 2.0,\n this.scale() + (delta > 0 ? step : -step)\n )\n );\n\n this.scale.set(newScale);\n }\n\n onContextMenu(event: MouseEvent): void {\n event.preventDefault();\n\n const svgRect = this.canvasSvgRef()?.nativeElement.getBoundingClientRect();\n if (!svgRect) return;\n\n // Calculate position in graph coordinates\n const x = (event.clientX - svgRect.left - this.panX()) / this.scale();\n const y = (event.clientY - svgRect.top - this.panY()) / this.scale();\n\n // Check if clicking on a node\n const nodeId = this.findNodeAtPosition({ x, y });\n if (nodeId) {\n this.contextMenu.emit({\n type: 'node',\n position: { x: event.clientX, y: event.clientY },\n nodeId\n });\n return;\n }\n\n // Check if clicking on an edge (use hit area logic)\n const edgeId = this.findEdgeAtPosition({ x, y });\n if (edgeId) {\n this.contextMenu.emit({\n type: 'edge',\n position: { x: event.clientX, y: event.clientY },\n edgeId\n });\n return;\n }\n\n // Canvas click\n this.contextMenu.emit({\n type: 'canvas',\n position: { x: event.clientX, y: event.clientY }\n });\n }\n\n // Helper methods\n private emitGraphChange(): void {\n // Push to history (unless this is an undo/redo operation)\n if (!this.historyService.isUndoRedo()) {\n this.historyService.push(this.internalGraph());\n }\n this.graphChange.emit(this.internalGraph());\n if (this.config.validation?.validateOnChange) {\n this.validate();\n }\n }\n\n /** Undo the last action (Ctrl+Z) */\n undo(): boolean {\n const state = this.historyService.undo();\n if (!state) {\n return false;\n }\n \n this.internalGraph.set(state);\n this.graphChange.emit(this.internalGraph());\n this.historyService.completeUndoRedo();\n \n // Clear selection after undo\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n \n return true;\n }\n\n /** Redo the last undone action (Ctrl+Y / Ctrl+Shift+Z) */\n redo(): boolean {\n const state = this.historyService.redo();\n if (!state) {\n return false;\n }\n \n this.internalGraph.set(state);\n this.graphChange.emit(this.internalGraph());\n this.historyService.completeUndoRedo();\n \n // Clear selection after redo\n this.selection.set({ nodes: [], edges: [] });\n this.selectionChange.emit(this.selection());\n \n return true;\n }\n\n /** Check if undo is available */\n canUndo(): boolean {\n return this.historyService.canUndo();\n }\n\n /** Check if redo is available */\n canRedo(): boolean {\n return this.historyService.canRedo();\n }\n\n /** Clear history and reset to current state */\n clearHistory(): void {\n this.historyService.clear(this.internalGraph());\n }\n\n private generateId(): string {\n return `node_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private recalculateEdgePorts(nodeId: string): void {\n const graph = this.internalGraph();\n let changed = false;\n const updatedEdges = graph.edges.map(edge => {\n if (edge.source !== nodeId && edge.target !== nodeId) return edge;\n\n const sourceNode = graph.nodes.find(n => n.id === edge.source);\n const targetNode = graph.nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return edge;\n\n const newSourcePort = this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const newTargetPort = this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n\n if (edge.sourcePort === newSourcePort && edge.targetPort === newTargetPort) return edge;\n\n changed = true;\n return { ...edge, sourcePort: newSourcePort, targetPort: newTargetPort };\n });\n\n if (changed) {\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n }\n }\n\n getNodeSize(node: GraphNode): { width: number; height: number } {\n // Check instance-level size override first (from resize)\n if (node.size) return node.size;\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n return nodeConfig?.size || this.config.nodes.defaultSize || { width: 220, height: 100 };\n }\n\n getEdgePath(edge: GraphEdge): string {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n\n if (!sourceNode || !targetNode) return '';\n\n // Get port positions from edge or calculate closest\n const sourcePort = (edge.sourcePort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n const targetPort = (edge.targetPort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n\n const sourcePoint = this.getPortWorldPosition(sourceNode, sourcePort);\n const targetPoint = this.getPortWorldPosition(targetNode, targetPort);\n\n // Simple straight line\n return `M ${sourcePoint.x},${sourcePoint.y} L ${targetPoint.x},${targetPoint.y}`;\n }\n\n getEdgeColor(edge: GraphEdge): string {\n return edge.metadata?.style?.stroke || this.config.edges.style?.stroke || '#94a3b8';\n }\n\n getEdgeMarkerEnd(edge: GraphEdge): string | null {\n const dir = edge.direction || 'forward';\n const selected = this.selection().edges.includes(edge.id);\n if (dir === 'forward' || dir === 'bidirectional') {\n return selected ? 'url(#arrow-end-selected)' : 'url(#arrow-end)';\n }\n return null;\n }\n\n getEdgeMarkerStart(edge: GraphEdge): string | null {\n const dir = edge.direction || 'forward';\n const selected = this.selection().edges.includes(edge.id);\n if (dir === 'backward' || dir === 'bidirectional') {\n return selected ? 'url(#arrow-start-selected)' : 'url(#arrow-start)';\n }\n return null;\n }\n\n setEdgeDirection(direction: 'forward' | 'backward' | 'bidirectional'): void {\n const sel = this.selection();\n if (sel.edges.length !== 1) return;\n\n const graph = this.internalGraph();\n const edgeIndex = graph.edges.findIndex(e => e.id === sel.edges[0]);\n if (edgeIndex === -1) return;\n\n const updatedEdges = [...graph.edges];\n updatedEdges[edgeIndex] = { ...updatedEdges[edgeIndex], direction };\n this.internalGraph.set({ ...graph, edges: updatedEdges });\n this.emitGraphChange();\n this.edgeUpdated.emit(updatedEdges[edgeIndex]);\n }\n\n getEdgeSourcePoint(edge: GraphEdge): Position {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return { x: 0, y: 0 };\n\n const sourcePort = (edge.sourcePort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(sourceNode, targetNode, 'source');\n return this.getPortWorldPosition(sourceNode, sourcePort);\n }\n\n getEdgeTargetPoint(edge: GraphEdge): Position {\n const sourceNode = this.internalGraph().nodes.find(n => n.id === edge.source);\n const targetNode = this.internalGraph().nodes.find(n => n.id === edge.target);\n if (!sourceNode || !targetNode) return { x: 0, y: 0 };\n\n const targetPort = (edge.targetPort as 'top' | 'bottom' | 'left' | 'right') || this.findClosestPortForEdge(targetNode, sourceNode, 'target');\n return this.getPortWorldPosition(targetNode, targetPort);\n }\n\n getNodeTypeIcon(node: GraphNode): string {\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n return nodeConfig?.icon || '●';\n }\n\n /**\n * Get image URL for a node icon.\n * Priority: node.data['imageUrl'] > nodeType.iconSvg (converted to data URL) > nodeType.defaultData['imageUrl']\n * Returns null if no image is configured (will render text icon instead).\n */\n getNodeImage(node: GraphNode): string | null {\n // Check instance-level image first\n if (node.data['imageUrl']) {\n return node.data['imageUrl'] as string;\n }\n\n const nodeConfig = this.config.nodes.types.find(t => t.type === node.type);\n\n // Check for iconSvg definition (convert to data URL)\n if (nodeConfig?.iconSvg) {\n return this.svgIconToDataUrl(nodeConfig.iconSvg);\n }\n\n // Fall back to node type default imageUrl\n if (nodeConfig?.defaultData['imageUrl']) {\n return nodeConfig.defaultData['imageUrl'] as string;\n }\n\n return null;\n }\n\n /**\n * Convert an SvgIconDefinition to a data URL for use in <image> elements.\n * Caches results to avoid repeated conversion.\n */\n private svgIconCache = new Map<SvgIconDefinition, string>();\n\n private svgIconToDataUrl(icon: SvgIconDefinition): string {\n // Check cache first\n const cached = this.svgIconCache.get(icon);\n if (cached) return cached;\n\n const viewBox = icon.viewBox || '0 0 24 24';\n const fill = icon.fill || 'none';\n const stroke = icon.stroke || '#1D6A96';\n const strokeWidth = icon.strokeWidth || 2;\n\n // Build SVG markup with proper path handling\n const paths = icon.path\n .split(/\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0)\n .map(p => `<path d=\"${p}\"/>`)\n .join('');\n\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"${viewBox}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${paths}</svg>`;\n\n // Encode as data URL\n const dataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;\n this.svgIconCache.set(icon, dataUrl);\n return dataUrl;\n }\n\n /**\n * Get the SVG icon definition for a node type (for palette rendering).\n * Returns null if no iconSvg is configured.\n */\n getNodeTypeSvgIcon(nodeType: NodeTypeDefinition): SvgIconDefinition | null {\n return nodeType.iconSvg || null;\n }\n\n /**\n * Split SVG path data by newlines for template iteration.\n * Used to render multiple path elements from a single path string.\n */\n splitIconPaths(pathData: string): string[] {\n return pathData\n .split(/\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0);\n }\n\n /**\n * Get the position for the node image (top-left corner of image).\n * Uses same positioning logic as icon but accounts for image dimensions.\n */\n getImagePosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const imageSize = this.getImageSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = 8;\n\n const positions: Record<string, Position> = {\n 'top-left': { x: padding, y: padding },\n 'top': { x: (size.width - imageSize) / 2, y: padding },\n 'top-right': { x: size.width - imageSize - padding, y: padding },\n 'right': { x: size.width - imageSize - padding, y: (size.height - imageSize) / 2 },\n 'bottom-right': { x: size.width - imageSize - padding, y: size.height - imageSize - padding },\n 'bottom': { x: (size.width - imageSize) / 2, y: size.height - imageSize - padding },\n 'bottom-left': { x: padding, y: size.height - imageSize - padding },\n 'left': { x: padding, y: (size.height - imageSize) / 2 }\n };\n\n return positions[pos] || positions['top-left'];\n }\n\n /**\n * Get the size (width/height) for node images.\n * Images are rendered as squares, sized proportionally to node height.\n */\n getImageSize(node: GraphNode): number {\n const size = this.getNodeSize(node);\n // Image takes up ~40% of node height, with min 24px and max 64px\n return Math.min(64, Math.max(24, size.height * 0.4));\n }\n\n getIconPosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = size.height * 0.25;\n const iconSize = size.height * 0.28;\n\n const positions: Record<string, Position> = {\n 'top-left': { x: padding, y: padding },\n 'top': { x: size.width / 2, y: padding },\n 'top-right': { x: size.width - padding, y: padding },\n 'right': { x: size.width - padding, y: size.height / 2 },\n 'bottom-right': { x: size.width - padding, y: size.height - padding },\n 'bottom': { x: size.width / 2, y: size.height - padding },\n 'bottom-left': { x: padding, y: size.height - padding },\n 'left': { x: padding, y: size.height / 2 }\n };\n\n return positions[pos] || positions['left'];\n }\n\n getLabelPosition(node: GraphNode): Position {\n const size = this.getNodeSize(node);\n const pos = this.config.nodes.iconPosition || 'top-left';\n const padding = size.height * 0.25;\n\n // Label position adjusts based on icon position\n const labelPositions: Record<string, Position> = {\n 'top-left': { x: size.width / 2 + padding / 2, y: size.height / 2 + 4 },\n 'top': { x: size.width / 2, y: size.height / 2 + padding / 2 },\n 'top-right': { x: size.width / 2 - padding / 2, y: size.height / 2 + 4 },\n 'right': { x: size.width / 2 - padding / 2, y: size.height / 2 },\n 'bottom-right': { x: size.width / 2 - padding / 2, y: size.height / 2 - 4 },\n 'bottom': { x: size.width / 2, y: size.height / 2 - padding / 2 },\n 'bottom-left': { x: size.width / 2 + padding / 2, y: size.height / 2 - 4 },\n 'left': { x: size.width / 2 + padding / 2, y: size.height / 2 }\n };\n\n return labelPositions[pos] || labelPositions['top-left'];\n }\n\n /**\n * Get the bounding box for label text within a node.\n * This box avoids the icon area and has proper padding.\n */\n getLabelBounds(node: GraphNode): { x: number; y: number; width: number; height: number } {\n const size = this.getNodeSize(node);\n const iconPos = this.config.nodes.iconPosition || 'top-left';\n const padding = 12; // Padding from node edges\n const iconAreaSize = Math.max(this.getImageSize(node), size.height * 0.35) + 8; // Icon + gap\n \n // Default: full node minus padding\n let x = padding;\n let y = padding;\n let width = size.width - padding * 2;\n let height = size.height - padding * 2;\n \n // Adjust based on icon position\n switch (iconPos) {\n case 'top-left':\n case 'left':\n case 'bottom-left':\n // Icon on left - text area starts after icon\n x = iconAreaSize + padding / 2;\n width = size.width - iconAreaSize - padding - padding / 2;\n break;\n case 'top-right':\n case 'right':\n case 'bottom-right':\n // Icon on right - text area ends before icon\n width = size.width - iconAreaSize - padding - padding / 2;\n break;\n case 'top':\n // Icon on top - text area below icon\n y = iconAreaSize + padding / 2;\n height = size.height - iconAreaSize - padding - padding / 2;\n break;\n case 'bottom':\n // Icon on bottom - text area above icon\n height = size.height - iconAreaSize - padding - padding / 2;\n break;\n }\n \n return { x, y, width: Math.max(width, 20), height: Math.max(height, 20) };\n }\n\n /**\n * Get wrapped text lines and font size for a node label.\n * Uses text wrapping first, then font downsizing if needed.\n */\n getWrappedLabel(node: GraphNode): { lines: string[]; fontSize: number; lineHeight: number } {\n const text = (node.data['name'] || node.type) as string;\n const bounds = this.getLabelBounds(node);\n const baseFontSize = 14;\n const minFontSize = 9;\n const lineHeightRatio = 1.3;\n \n // Try wrapping at current font size, then reduce if needed\n for (let fontSize = baseFontSize; fontSize >= minFontSize; fontSize -= 1) {\n const charWidth = fontSize * 0.6; // Approximate character width\n const lineHeight = fontSize * lineHeightRatio;\n const maxCharsPerLine = Math.floor(bounds.width / charWidth);\n const maxLines = Math.floor(bounds.height / lineHeight);\n \n if (maxCharsPerLine < 3 || maxLines < 1) continue;\n \n const lines = this.wrapText(text, maxCharsPerLine);\n \n // Check if text fits\n if (lines.length <= maxLines) {\n return { lines, fontSize, lineHeight };\n }\n \n // If at minimum font size, truncate\n if (fontSize === minFontSize) {\n const truncatedLines = lines.slice(0, maxLines);\n if (lines.length > maxLines && truncatedLines.length > 0) {\n // Add ellipsis to last line\n const lastLine = truncatedLines[truncatedLines.length - 1];\n if (lastLine.length > 3) {\n truncatedLines[truncatedLines.length - 1] = lastLine.slice(0, -3) + '...';\n }\n }\n return { lines: truncatedLines, fontSize, lineHeight };\n }\n }\n \n // Fallback\n return { lines: [text], fontSize: minFontSize, lineHeight: minFontSize * lineHeightRatio };\n }\n\n /**\n * Wrap text into lines respecting max characters per line.\n * Tries to break at word boundaries.\n */\n private wrapText(text: string, maxCharsPerLine: number): string[] {\n if (text.length <= maxCharsPerLine) {\n return [text];\n }\n \n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let currentLine = '';\n \n for (const word of words) {\n if (currentLine.length === 0) {\n // First word on line\n if (word.length > maxCharsPerLine) {\n // Word too long, break it\n let remaining = word;\n while (remaining.length > maxCharsPerLine) {\n lines.push(remaining.slice(0, maxCharsPerLine - 1) + '-');\n remaining = remaining.slice(maxCharsPerLine - 1);\n }\n currentLine = remaining;\n } else {\n currentLine = word;\n }\n } else if (currentLine.length + 1 + word.length <= maxCharsPerLine) {\n // Word fits on current line\n currentLine += ' ' + word;\n } else {\n // Start new line\n lines.push(currentLine);\n if (word.length > maxCharsPerLine) {\n // Word too long, break it\n let remaining = word;\n while (remaining.length > maxCharsPerLine) {\n lines.push(remaining.slice(0, maxCharsPerLine - 1) + '-');\n remaining = remaining.slice(maxCharsPerLine - 1);\n }\n currentLine = remaining;\n } else {\n currentLine = word;\n }\n }\n }\n \n if (currentLine.length > 0) {\n lines.push(currentLine);\n }\n \n return lines;\n }\n\n /**\n * Get the Y position for each line of wrapped text (centered vertically).\n */\n getLabelLineY(node: GraphNode, lineIndex: number, totalLines: number, lineHeight: number): number {\n const bounds = this.getLabelBounds(node);\n const totalTextHeight = totalLines * lineHeight;\n const startY = bounds.y + (bounds.height - totalTextHeight) / 2 + lineHeight / 2;\n return startY + lineIndex * lineHeight;\n }\n\n /**\n * Get the X position for label text (centered in bounds).\n */\n getLabelLineX(node: GraphNode): number {\n const bounds = this.getLabelBounds(node);\n return bounds.x + bounds.width / 2;\n }\n\n private findNodeAtPosition(pos: Position): string | null {\n for (const node of this.internalGraph().nodes) {\n const size = this.getNodeSize(node);\n if (\n pos.x >= node.position.x &&\n pos.x <= node.position.x + size.width &&\n pos.y >= node.position.y &&\n pos.y <= node.position.y + size.height\n ) {\n return node.id;\n }\n }\n return null;\n }\n\n private findEdgeAtPosition(pos: Position): string | null {\n const hitDistance = 10; // pixels tolerance\n for (const edge of this.internalGraph().edges) {\n const sourcePoint = this.getEdgeSourcePoint(edge);\n const targetPoint = this.getEdgeTargetPoint(edge);\n\n // Calculate distance from point to line segment\n const dist = this.pointToSegmentDistance(pos, sourcePoint, targetPoint);\n if (dist < hitDistance) {\n return edge.id;\n }\n }\n return null;\n }\n\n private pointToSegmentDistance(point: Position, lineStart: Position, lineEnd: Position): number {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n const lengthSquared = dx * dx + dy * dy;\n\n if (lengthSquared === 0) {\n // Line segment is a point\n return Math.sqrt((point.x - lineStart.x) ** 2 + (point.y - lineStart.y) ** 2);\n }\n\n // Project point onto line segment\n let t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / lengthSquared;\n t = Math.max(0, Math.min(1, t));\n\n const projX = lineStart.x + t * dx;\n const projY = lineStart.y + t * dy;\n\n return Math.sqrt((point.x - projX) ** 2 + (point.y - projY) ** 2);\n }\n\n getNodePorts(node: GraphNode): Array<{ position: 'top' | 'bottom' | 'left' | 'right'; x: number; y: number }> {\n const size = this.getNodeSize(node);\n return [\n { position: 'top', x: size.width / 2, y: 0 },\n { position: 'bottom', x: size.width / 2, y: size.height },\n { position: 'left', x: 0, y: size.height / 2 },\n { position: 'right', x: size.width, y: size.height / 2 }\n ];\n }\n\n private findClosestPort(nodeId: string, worldPos: Position): { port: 'top' | 'bottom' | 'left' | 'right'; distance: number } | null {\n const node = this.internalGraph().nodes.find(n => n.id === nodeId);\n if (!node) return null;\n\n const ports = this.getNodePorts(node);\n let closestPort: typeof ports[0] | null = null;\n let minDistance = Infinity;\n\n for (const port of ports) {\n const portWorldX = node.position.x + port.x;\n const portWorldY = node.position.y + port.y;\n const dx = worldPos.x - portWorldX;\n const dy = worldPos.y - portWorldY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance < minDistance) {\n minDistance = distance;\n closestPort = port;\n }\n }\n\n return closestPort ? { port: closestPort.position, distance: minDistance } : null;\n }\n\n private getPortWorldPosition(node: GraphNode, port: 'top' | 'bottom' | 'left' | 'right'): Position {\n const size = this.getNodeSize(node);\n const portOffsets = {\n top: { x: size.width / 2, y: 0 },\n bottom: { x: size.width / 2, y: size.height },\n left: { x: 0, y: size.height / 2 },\n right: { x: size.width, y: size.height / 2 }\n };\n\n const offset = portOffsets[port];\n return {\n x: node.position.x + offset.x,\n y: node.position.y + offset.y\n };\n }\n\n private findClosestPortForEdge(\n node: GraphNode,\n otherNode: GraphNode,\n endpoint: 'source' | 'target'\n ): 'top' | 'bottom' | 'left' | 'right' {\n const size = this.getNodeSize(node);\n const nodeCenter = {\n x: node.position.x + size.width / 2,\n y: node.position.y + size.height / 2\n };\n const otherSize = this.getNodeSize(otherNode);\n const otherCenter = {\n x: otherNode.position.x + otherSize.width / 2,\n y: otherNode.position.y + otherSize.height / 2\n };\n\n const dx = otherCenter.x - nodeCenter.x;\n const dy = otherCenter.y - nodeCenter.y;\n\n // Determine which port is closest based on relative position\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n\n if (absDx > absDy) {\n // Horizontal connection\n return dx > 0 ? 'right' : 'left';\n } else {\n // Vertical connection\n return dy > 0 ? 'bottom' : 'top';\n }\n }\n}\n","<div class=\"graph-editor-container\">\n <!-- Canvas with overlaid palette -->\n <div class=\"graph-canvas-wrapper\">\n <!-- Top-left horizontal palette overlay -->\n @if (config.palette?.enabled !== false) {\n <div class=\"graph-palette-overlay\">\n <!-- Tools -->\n <button\n class=\"palette-item tool-item\"\n [class.active]=\"activeTool() === 'hand'\"\n title=\"Hand tool (move nodes)\"\n (click)=\"switchTool('hand')\"\n >\n <span class=\"icon\">✋</span>\n </button>\n <button\n class=\"palette-item tool-item\"\n [class.active]=\"activeTool() === 'line'\"\n title=\"Line tool (draw connections)\"\n (click)=\"switchTool('line')\"\n >\n <span class=\"icon\">∕</span>\n </button>\n\n <!-- Divider -->\n <div class=\"palette-divider\"></div>\n\n <!-- Node types -->\n @for (nodeType of config.nodes.types; track nodeType.type) {\n <button\n class=\"palette-item\"\n [attr.data-node-type]=\"nodeType.type\"\n [attr.title]=\"nodeType.label || nodeType.type\"\n (click)=\"addNode(nodeType.type)\"\n >\n @if (nodeType.iconSvg) {\n <svg\n class=\"palette-icon-svg\"\n [attr.viewBox]=\"nodeType.iconSvg.viewBox || '0 0 24 24'\"\n [attr.fill]=\"nodeType.iconSvg.fill || 'none'\"\n [attr.stroke]=\"nodeType.iconSvg.stroke || '#1D6A96'\"\n [attr.stroke-width]=\"nodeType.iconSvg.strokeWidth || 2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n @for (pathData of splitIconPaths(nodeType.iconSvg.path); track $index) {\n <path [attr.d]=\"pathData\"/>\n }\n </svg>\n } @else if (nodeType.defaultData['imageUrl']) {\n <img\n class=\"palette-icon-img\"\n [src]=\"nodeType.defaultData['imageUrl']\"\n [alt]=\"nodeType.label || nodeType.type\"\n />\n } @else {\n <span class=\"icon\">{{ nodeType.icon || '●' }}</span>\n }\n </button>\n }\n </div>\n }\n\n <svg\n #canvasSvg\n [class.tool-line]=\"activeTool() === 'line'\"\n [attr.width]=\"'100%'\"\n [attr.height]=\"'100%'\"\n (mousedown)=\"onCanvasMouseDown($event)\"\n (mousemove)=\"onCanvasMouseMove($event)\"\n (mouseup)=\"onCanvasMouseUp($event)\"\n (wheel)=\"onWheel($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n >\n <!-- Arrow marker definitions -->\n <defs>\n <marker id=\"arrow-end\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 1 L 8 5 L 0 9 z\" fill=\"#94a3b8\"/>\n </marker>\n <marker id=\"arrow-end-selected\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 1 L 8 5 L 0 9 z\" fill=\"#3b82f6\"/>\n </marker>\n <marker id=\"arrow-start\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 10 1 L 2 5 L 10 9 z\" fill=\"#94a3b8\"/>\n </marker>\n <marker id=\"arrow-start-selected\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 10 1 L 2 5 L 10 9 z\" fill=\"#3b82f6\"/>\n </marker>\n </defs>\n\n <!-- Main transform group (pan + zoom) -->\n <g [attr.transform]=\"transform()\">\n <!-- Grid (if enabled) -->\n <!-- Grid (if enabled) - extended to cover viewport during pan -->\n @if (config.canvas?.grid?.enabled) {\n <defs>\n <pattern\n id=\"grid\"\n [attr.width]=\"config.canvas!.grid!.size\"\n [attr.height]=\"config.canvas!.grid!.size\"\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n [attr.d]=\"'M ' + config.canvas!.grid!.size + ' 0 L 0 0 0 ' + config.canvas!.grid!.size\"\n fill=\"none\"\n [attr.stroke]=\"config.canvas!.grid!.color || '#e0e0e0'\"\n stroke-width=\"1\"\n />\n </pattern>\n </defs>\n <!-- Extended grid background covering viewport + pan offset -->\n <rect\n [attr.x]=\"gridBounds().x\"\n [attr.y]=\"gridBounds().y\"\n [attr.width]=\"gridBounds().width\"\n [attr.height]=\"gridBounds().height\"\n fill=\"url(#grid)\"\n />\n }\n\n <!-- Layer 0.5: Preview line for line tool (rubber-band) -->\n @if (previewLine()) {\n <line\n class=\"preview-line\"\n [attr.x1]=\"previewLine()!.source.x\"\n [attr.y1]=\"previewLine()!.source.y\"\n [attr.x2]=\"previewLine()!.target.x\"\n [attr.y2]=\"previewLine()!.target.y\"\n stroke=\"#3b82f6\"\n stroke-width=\"2.5\"\n stroke-dasharray=\"8,6\"\n stroke-linecap=\"round\"\n opacity=\"0.7\"\n />\n }\n\n <!-- Layer 1: Edge paths (behind everything) -->\n @for (edge of internalGraph().edges; track edge.id) {\n <!-- Edge shadow for depth (optional) -->\n @if (shadowsEnabled()) {\n <path\n class=\"edge-shadow\"\n [attr.d]=\"getEdgePath(edge)\"\n stroke=\"rgba(0,0,0,0.06)\"\n stroke-width=\"6\"\n fill=\"none\"\n stroke-linecap=\"round\"\n [attr.transform]=\"'translate(1, 2)'\"\n />\n }\n <!-- Invisible wide hit-area for easier clicking (hand tool only) -->\n <path\n [attr.d]=\"getEdgePath(edge)\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"20\"\n fill=\"none\"\n class=\"edge-hit-area\"\n [attr.pointer-events]=\"activeTool() === 'hand' ? 'stroke' : 'none'\"\n (click)=\"onEdgeClick($event, edge)\"\n (dblclick)=\"onEdgeDoubleClick($event, edge)\"\n />\n <!-- Visible edge line -->\n <path\n class=\"edge-line\"\n [attr.d]=\"getEdgePath(edge)\"\n [attr.stroke]=\"selection().edges.includes(edge.id) ? '#3b82f6' : '#94a3b8'\"\n [attr.stroke-width]=\"selection().edges.includes(edge.id) ? 2.5 : 2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n [class.selected]=\"selection().edges.includes(edge.id)\"\n [attr.marker-end]=\"getEdgeMarkerEnd(edge)\"\n [attr.marker-start]=\"getEdgeMarkerStart(edge)\"\n pointer-events=\"none\"\n />\n }\n\n <!-- Layer 2: Nodes -->\n @for (node of internalGraph().nodes; track node.id) {\n <g\n [attr.transform]=\"'translate(' + node.position.x + ',' + node.position.y + ')'\"\n class=\"graph-node\"\n [class.selected]=\"selection().nodes.includes(node.id)\"\n [attr.data-node-id]=\"node.id\"\n (mousedown)=\"onNodeMouseDown($event, node)\"\n (click)=\"onNodeClick($event, node)\"\n (dblclick)=\"nodeDoubleClick.emit(node)\"\n >\n <!-- Node shadow (optional) -->\n @if (shadowsEnabled()) {\n <rect\n class=\"node-shadow\"\n [attr.width]=\"getNodeSize(node).width\"\n [attr.height]=\"getNodeSize(node).height\"\n fill=\"rgba(0,0,0,0.08)\"\n rx=\"12\"\n transform=\"translate(2, 3)\"\n style=\"filter: blur(4px);\"\n />\n }\n <!-- Node background -->\n <rect\n class=\"node-bg\"\n [attr.width]=\"getNodeSize(node).width\"\n [attr.height]=\"getNodeSize(node).height\"\n fill=\"white\"\n [attr.stroke]=\"selection().nodes.includes(node.id) ? '#3b82f6' : '#e2e8f0'\"\n [attr.stroke-width]=\"selection().nodes.includes(node.id) ? 2.5 : 1.5\"\n rx=\"12\"\n />\n\n <!-- Node type icon (text/emoji) or custom image -->\n @if (getNodeImage(node)) {\n <image\n class=\"node-image\"\n [attr.href]=\"getNodeImage(node)\"\n [attr.xlink:href]=\"getNodeImage(node)\"\n [attr.x]=\"getImagePosition(node).x\"\n [attr.y]=\"getImagePosition(node).y\"\n [attr.width]=\"getImageSize(node)\"\n [attr.height]=\"getImageSize(node)\"\n preserveAspectRatio=\"xMidYMid meet\"\n />\n } @else {\n <text\n class=\"node-icon\"\n [attr.x]=\"getIconPosition(node).x\"\n [attr.y]=\"getIconPosition(node).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.font-size]=\"getNodeSize(node).height * 0.28\"\n >\n {{ getNodeTypeIcon(node) }}\n </text>\n }\n\n <!-- Node label (wrapped and auto-sized) -->\n <text\n class=\"node-label\"\n [attr.x]=\"getLabelLineX(node)\"\n text-anchor=\"middle\"\n [attr.font-size]=\"getWrappedLabel(node).fontSize\"\n font-weight=\"500\"\n fill=\"#1e293b\"\n >\n @for (line of getWrappedLabel(node).lines; track $index) {\n <tspan\n [attr.x]=\"getLabelLineX(node)\"\n [attr.y]=\"getLabelLineY(node, $index, getWrappedLabel(node).lines.length, getWrappedLabel(node).lineHeight)\"\n >{{ line }}</tspan>\n }\n </text>\n\n <!-- Resize handle (SE corner, visible when selected + hand tool) -->\n @if (selection().nodes.includes(node.id) && activeTool() === 'hand' && selection().nodes.length === 1) {\n <rect\n class=\"resize-handle resize-handle-se\"\n [attr.x]=\"getNodeSize(node).width - 8\"\n [attr.y]=\"getNodeSize(node).height - 8\"\n width=\"10\"\n height=\"10\"\n fill=\"#3b82f6\"\n rx=\"2\"\n cursor=\"se-resize\"\n (mousedown)=\"onResizeHandleMouseDown($event, node)\"\n />\n }\n </g>\n }\n\n <!-- Layer 3: Attachment points (on top of nodes) -->\n @for (node of internalGraph().nodes; track node.id) {\n @if (showAttachmentPoints() === node.id) {\n <g [attr.transform]=\"'translate(' + node.position.x + ',' + node.position.y + ')'\">\n @for (port of getNodePorts(node); track port.position) {\n <circle\n [attr.cx]=\"port.x\"\n [attr.cy]=\"port.y\"\n [attr.r]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position ? 8 : 6\"\n [attr.fill]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position ? '#2563eb' : '#94a3b8'\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"attachment-point\"\n [class.hovered]=\"hoveredPort?.nodeId === node.id && hoveredPort?.port === port.position\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"onAttachmentPointClick($event, node, port.position)\"\n />\n }\n </g>\n }\n }\n\n <!-- Layer 4: Edge endpoints (only visible when edge is selected) -->\n @for (edge of internalGraph().edges; track edge.id) {\n @if (selection().edges.includes(edge.id)) {\n <g>\n <!-- Source endpoint -->\n <circle\n [attr.cx]=\"getEdgeSourcePoint(edge).x\"\n [attr.cy]=\"getEdgeSourcePoint(edge).y\"\n r=\"6\"\n fill=\"#3b82f6\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"edge-endpoint selected\"\n (mousedown)=\"onEdgeEndpointMouseDown($event, edge, 'source')\"\n />\n\n <!-- Target endpoint -->\n <circle\n [attr.cx]=\"getEdgeTargetPoint(edge).x\"\n [attr.cy]=\"getEdgeTargetPoint(edge).y\"\n r=\"6\"\n fill=\"#3b82f6\"\n stroke=\"white\"\n stroke-width=\"2\"\n class=\"edge-endpoint selected\"\n (mousedown)=\"onEdgeEndpointMouseDown($event, edge, 'target')\"\n />\n </g>\n }\n }\n\n <!-- Layer 5: Selection box (Shift+drag) -->\n @if (selectionBox()) {\n <rect\n class=\"selection-box\"\n [attr.x]=\"selectionBox()!.x\"\n [attr.y]=\"selectionBox()!.y\"\n [attr.width]=\"selectionBox()!.width\"\n [attr.height]=\"selectionBox()!.height\"\n fill=\"rgba(59, 130, 246, 0.1)\"\n stroke=\"#3b82f6\"\n stroke-width=\"1\"\n stroke-dasharray=\"4,2\"\n />\n }\n </g>\n </svg>\n </div>\n\n <!-- Edge direction selector overlay -->\n @if (selectedEdgeMidpoint()) {\n <div\n class=\"edge-direction-selector\"\n [style.left.px]=\"selectedEdgeMidpoint()!.x\"\n [style.top.px]=\"selectedEdgeMidpoint()!.y\"\n >\n <button\n class=\"direction-btn\"\n [class.active]=\"selectedEdgeMidpoint()!.edge.direction === 'backward'\"\n title=\"Backward\"\n (click)=\"setEdgeDirection('backward')\"\n >←</button>\n <button\n class=\"direction-btn\"\n [class.active]=\"selectedEdgeMidpoint()!.edge.direction === 'bidirectional'\"\n title=\"Bidirectional\"\n (click)=\"setEdgeDirection('bidirectional')\"\n >↔</button>\n <button\n class=\"direction-btn\"\n [class.active]=\"!selectedEdgeMidpoint()!.edge.direction || selectedEdgeMidpoint()!.edge.direction === 'forward'\"\n title=\"Forward\"\n (click)=\"setEdgeDirection('forward')\"\n >→</button>\n </div>\n }\n</div>\n","/**\n * SVG icon definition interface for custom node icons.\n * Use this to define your own icons that match your design system.\n *\n * Example usage:\n * const myIcons = {\n * process: {\n * viewBox: '0 0 24 24',\n * fill: 'none',\n * stroke: '#1D6A96',\n * strokeWidth: 1.75,\n * path: 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z...'\n * }\n * };\n */\nexport interface SvgIconDefinition {\n /** SVG path data (d attribute) or full SVG markup */\n path: string;\n /** ViewBox dimensions (default: '0 0 24 24') */\n viewBox?: string;\n /** Fill color (default: 'none' for stroke-based icons) */\n fill?: string;\n /** Stroke color (default: currentColor) */\n stroke?: string;\n /** Stroke width (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Generate inline SVG markup for an icon (for use in palette/toolbar)\n */\nexport function renderIconSvg(icon: SvgIconDefinition, size: number = 24): string {\n const viewBox = icon.viewBox || '0 0 24 24';\n const fill = icon.fill || 'none';\n const stroke = icon.stroke || 'currentColor';\n const strokeWidth = icon.strokeWidth || 2;\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"${viewBox}\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${icon.path.split('\\n').map(p => `<path d=\"${p.trim()}\"/>`).join('')}</svg>`;\n}\n\n/**\n * Generate data URL for an icon (for use as image source)\n */\nexport function iconToDataUrl(icon: SvgIconDefinition, size: number = 48): string {\n const svg = renderIconSvg(icon, size);\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\n","// Main component\nexport { GraphEditorComponent } from './lib/graph-editor.component';\n\n// Data model - use 'export type' for re-exports when isolatedModules is enabled\nexport type {\n Graph,\n GraphNode,\n GraphEdge,\n Position,\n NodeMetadata,\n EdgeMetadata,\n EdgeStyle,\n GraphMetadata\n} from './lib/graph.model';\n\n// Configuration - use 'export type' for re-exports\nexport type {\n GraphEditorConfig,\n NodesConfig,\n EdgesConfig,\n CanvasConfig,\n ValidationConfig,\n LayoutConfig,\n InteractionConfig,\n ThemeConfig,\n PaletteConfig,\n NodeTypeDefinition,\n PortConfig,\n PortDefinition,\n NodeConstraints,\n GridConfig,\n ZoomConfig,\n PanConfig,\n ValidationRule,\n ValidationError,\n LayoutOptions,\n ContextMenuConfig,\n ContextMenuItem,\n ContextMenuContext,\n SelectionState,\n ValidationResult,\n ContextMenuEvent\n} from './lib/graph-editor.config';\n\n// SVG icon utilities\nexport type { SvgIconDefinition } from './lib/icons/workflow-icons';\nexport { renderIconSvg, iconToDataUrl } from './lib/icons/workflow-icons';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}