bpmn-elk-layout 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/bpmn-elk-layout.js +6698 -0
- package/dist/bin/bpmn-elk-layout.js.map +1 -0
- package/dist/index.d.mts +693 -0
- package/dist/index.d.ts +693 -0
- package/dist/index.js +6122 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6072 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.node.d.mts +82 -0
- package/dist/index.node.d.ts +82 -0
- package/dist/index.node.js +6631 -0
- package/dist/index.node.js.map +1 -0
- package/dist/index.node.mjs +6575 -0
- package/dist/index.node.mjs.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/layout/elk-layouter.ts","../src/layout/size-calculator.ts","../src/layout/edge-routing/geometry-utils.ts","../src/utils/debug.ts","../src/layout/edge-routing/edge-fixer.ts","../src/layout/post-processing/boundary-event/collector.ts","../src/layout/post-processing/boundary-event/mover.ts","../src/layout/post-processing/boundary-event/edge-recalculator.ts","../src/layout/post-processing/boundary-event/index.ts","../src/types/bpmn-constants.ts","../src/utils/node-map-builder.ts","../src/layout/post-processing/artifact-positioner.ts","../src/layout/post-processing/group-positioner.ts","../src/layout/post-processing/lane-arranger.ts","../src/layout/post-processing/pool-arranger.ts","../src/layout/post-processing/gateway-edge-adjuster.ts","../src/layout/default-options.ts","../src/layout/preparation/elk-graph-preparer.ts","../src/layout/preparation/result-merger.ts","../src/layout/normalization/main-flow-normalizer.ts","../src/layout/normalization/gateway-propagator.ts","../src/transform/reference-resolver.ts","../src/transform/lane-resolver.ts","../src/layout/edge-routing/gateway-endpoint-adjuster.ts","../src/transform/diagram-builder.ts","../src/transform/model-builder.ts","../src/generators/bpmn-xml-generator.ts","../src/converter.ts"],"sourcesContent":["/**\n * ELK Layout Engine Wrapper\n * Orchestrates the BPMN layout pipeline using specialized handlers.\n */\n\nimport ELK from 'elkjs';\nimport type { ElkNode } from 'elkjs';\nimport type { ElkBpmnGraph, ElkLayoutOptions } from '../types';\nimport type { LayoutedGraph } from '../types/elk-output';\nimport type { NodeMoveInfo } from '../types/internal';\nimport { SizeCalculator } from './size-calculator';\nimport { EdgeFixer } from './edge-routing/edge-fixer';\nimport { BoundaryEventHandler } from './post-processing/boundary-event';\nimport { ArtifactPositioner } from './post-processing/artifact-positioner';\nimport { GroupPositioner } from './post-processing/group-positioner';\nimport { LaneArranger } from './post-processing/lane-arranger';\nimport { PoolArranger } from './post-processing/pool-arranger';\nimport { GatewayEdgeAdjuster } from './post-processing/gateway-edge-adjuster';\nimport { ElkGraphPreparer } from './preparation/elk-graph-preparer';\nimport { ResultMerger } from './preparation/result-merger';\nimport { MainFlowNormalizer } from './normalization/main-flow-normalizer';\nimport { GatewayPropagator } from './normalization/gateway-propagator';\nimport { DEBUG } from '../utils/debug';\n\nexport interface ElkLayouterOptions {\n elkOptions?: ElkLayoutOptions;\n}\n\nexport class ElkLayouter {\n private elk: InstanceType<typeof ELK>;\n private userOptions: ElkLayoutOptions;\n private sizeCalculator: SizeCalculator;\n private edgeFixer: EdgeFixer;\n private boundaryEventHandler: BoundaryEventHandler;\n private artifactPositioner: ArtifactPositioner;\n private groupPositioner: GroupPositioner;\n private laneArranger: LaneArranger;\n private poolArranger: PoolArranger;\n private gatewayEdgeAdjuster: GatewayEdgeAdjuster;\n private graphPreparer: ElkGraphPreparer;\n private resultMerger: ResultMerger;\n private mainFlowNormalizer: MainFlowNormalizer;\n private gatewayPropagator: GatewayPropagator;\n\n constructor(options?: ElkLayouterOptions) {\n this.elk = new ELK();\n this.userOptions = options?.elkOptions ?? {};\n this.sizeCalculator = new SizeCalculator();\n this.edgeFixer = new EdgeFixer();\n this.boundaryEventHandler = new BoundaryEventHandler();\n this.artifactPositioner = new ArtifactPositioner();\n this.groupPositioner = new GroupPositioner();\n this.laneArranger = new LaneArranger();\n this.poolArranger = new PoolArranger();\n this.gatewayEdgeAdjuster = new GatewayEdgeAdjuster();\n this.graphPreparer = new ElkGraphPreparer();\n this.resultMerger = new ResultMerger();\n this.mainFlowNormalizer = new MainFlowNormalizer();\n this.gatewayPropagator = new GatewayPropagator();\n }\n\n /**\n * Run ELK layout on the graph\n */\n async layout(graph: ElkBpmnGraph): Promise<LayoutedGraph> {\n // Deep clone to avoid mutating the original\n const graphCopy = JSON.parse(JSON.stringify(graph)) as ElkBpmnGraph;\n\n // Apply default sizes to all nodes\n const sizedGraph = this.sizeCalculator.applyDefaultSizes(graphCopy);\n\n // Collect boundary event info for post-processing\n const boundaryEventInfo = this.boundaryEventHandler.collectInfo(sizedGraph);\n\n // Collect boundary event target IDs for ELK constraint assignment\n const boundaryEventTargetIds = this.graphPreparer.collectBoundaryEventTargetIds(boundaryEventInfo);\n\n // Collect artifact association info for post-processing\n const artifactInfo = this.artifactPositioner.collectInfo(sizedGraph);\n\n // Collect Group info for post-processing (Groups will be repositioned after layout)\n const groupInfo = this.groupPositioner.collectInfo(sizedGraph);\n\n // Prepare graph for ELK (convert to ELK format)\n const elkGraph = this.graphPreparer.prepare(sizedGraph, this.userOptions, boundaryEventTargetIds);\n\n // Run ELK layout\n const layoutedElkGraph = await this.elk.layout(elkGraph);\n\n // Identify main flow nodes for normalization\n const mainFlowNodes = this.graphPreparer.identifyMainFlowNodes(sizedGraph, boundaryEventTargetIds);\n\n // Normalize main flow to the top of the diagram\n // This ensures the primary flow path stays at a consistent Y position\n this.mainFlowNormalizer.normalize(layoutedElkGraph, mainFlowNodes, boundaryEventTargetIds, sizedGraph);\n\n // Check if boundary event targets need repositioning\n // Pass sizedGraph to access node type information (bpmn.type) which is not preserved in ELK graph\n const movedNodes = this.boundaryEventHandler.identifyNodesToMove(layoutedElkGraph, boundaryEventInfo, sizedGraph, DEBUG);\n\n if (movedNodes.size > 0) {\n // Move nodes and recalculate affected edges\n this.boundaryEventHandler.applyNodeMoves(layoutedElkGraph, movedNodes);\n\n // Reposition converging gateways based on incoming edge positions\n const gatewayMoves = this.boundaryEventHandler.repositionConvergingGateways(\n layoutedElkGraph, movedNodes, boundaryEventInfo, DEBUG\n );\n\n if (gatewayMoves.size > 0) {\n // Apply gateway moves\n this.boundaryEventHandler.applyNodeMoves(layoutedElkGraph, gatewayMoves);\n\n // Also move downstream nodes of the gateway\n this.gatewayPropagator.propagate(layoutedElkGraph, gatewayMoves, mainFlowNodes);\n }\n\n // Merge gateway moves into movedNodes for edge recalculation\n for (const [id, move] of gatewayMoves) {\n movedNodes.set(id, move);\n }\n\n this.boundaryEventHandler.recalculateEdgesForMovedNodes(layoutedElkGraph, movedNodes, boundaryEventInfo, DEBUG);\n }\n\n // Reposition artifacts (data objects, data stores, annotations) to be near their associated tasks\n this.artifactPositioner.reposition(layoutedElkGraph, artifactInfo);\n\n // Rearrange lanes to stack vertically within pools (ELK's partitioning doesn't do this correctly)\n this.laneArranger.rearrange(layoutedElkGraph, sizedGraph);\n\n // Rearrange pools to stack vertically within collaborations\n this.poolArranger.rearrange(layoutedElkGraph, sizedGraph);\n\n // Reposition Groups to surround their grouped elements\n this.groupPositioner.reposition(layoutedElkGraph, groupInfo, sizedGraph);\n\n // Recalculate artifact edges with obstacle avoidance\n this.artifactPositioner.recalculateWithObstacleAvoidance(layoutedElkGraph, artifactInfo);\n\n // Fix edges that cross through nodes (especially return edges in complex flows)\n this.edgeFixer.fix(layoutedElkGraph);\n\n // Update container bounds to include all moved children\n this.updateContainerBounds(layoutedElkGraph);\n\n // Note: Gateway edge endpoint adjustment is now handled in model-builder.ts\n // during the buildEdge() step, which has access to the correct coordinate system.\n\n // Merge layout results back with BPMN metadata\n return this.resultMerger.merge(sizedGraph, layoutedElkGraph);\n }\n\n /**\n * Update container bounds to include all children after post-processing\n * This is needed because post-processing may move nodes outside the original ELK-calculated bounds\n */\n private updateContainerBounds(graph: ElkNode): void {\n const updateBounds = (node: ElkNode): { maxX: number; maxY: number } => {\n let maxX = (node.x ?? 0) + (node.width ?? 0);\n let maxY = (node.y ?? 0) + (node.height ?? 0);\n\n // Recursively update children first\n if (node.children) {\n for (const child of node.children) {\n const childBounds = updateBounds(child);\n // Child coordinates are relative to parent, so add parent offset\n const childMaxX = (node.x ?? 0) + childBounds.maxX;\n const childMaxY = (node.y ?? 0) + childBounds.maxY;\n maxX = Math.max(maxX, childMaxX);\n maxY = Math.max(maxY, childMaxY);\n }\n\n // Check if this container has lanes (children positioned at x=30, which is the lane header width)\n // Pools with lanes should not have padding added - lanes fill the pool completely\n const hasLanes = node.children.length > 0 &&\n node.children.every(child => (child.x ?? 0) === 30);\n\n // If children extend beyond current bounds, expand the container\n const nodeX = node.x ?? 0;\n const nodeY = node.y ?? 0;\n // Don't add padding for pools with lanes - lanes already fill the container\n const padding = hasLanes ? 0 : 12;\n\n // Calculate required dimensions based on children\n let requiredWidth = 0;\n let requiredHeight = 0;\n for (const child of node.children) {\n const childRight = (child.x ?? 0) + (child.width ?? 0) + padding;\n const childBottom = (child.y ?? 0) + (child.height ?? 0) + padding;\n requiredWidth = Math.max(requiredWidth, childRight);\n requiredHeight = Math.max(requiredHeight, childBottom);\n }\n\n // Update node dimensions if needed\n if (requiredWidth > (node.width ?? 0)) {\n node.width = requiredWidth;\n maxX = nodeX + requiredWidth;\n }\n if (requiredHeight > (node.height ?? 0)) {\n node.height = requiredHeight;\n maxY = nodeY + requiredHeight;\n }\n }\n\n return { maxX, maxY };\n };\n\n updateBounds(graph);\n }\n}\n","/**\n * Size Calculator\n * Handles calculating and applying default sizes to BPMN elements.\n * Also estimates label widths based on text content.\n */\n\nimport type { ElkBpmnGraph } from '../types';\nimport type { NodeWithBpmn } from '../types/internal';\n\n/**\n * Default size dimensions for various BPMN element types\n */\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/**\n * Size Calculator for BPMN elements\n * Applies default sizes based on element type and properties\n */\nexport class SizeCalculator {\n /**\n * Apply default sizes to all nodes in the graph\n */\n applyDefaultSizes(graph: ElkBpmnGraph): ElkBpmnGraph {\n if (graph.children) {\n graph.children = graph.children.map((child) => {\n return this.applyDefaultSizesRecursive(child);\n });\n }\n return graph;\n }\n\n /**\n * Recursively apply default sizes to a node and its children\n */\n private applyDefaultSizesRecursive<T extends object>(node: T): T {\n const result = { ...node };\n\n // Apply sizes if this is a node with bpmn type\n if ('bpmn' in result && 'id' in result) {\n const bpmn = (result as unknown as NodeWithBpmn).bpmn;\n const nodeResult = result as { width?: number; height?: number };\n\n // Get default size based on type\n const defaultSize = this.getDefaultSizeForType(bpmn.type, bpmn.name, bpmn.isExpanded);\n\n if (nodeResult.width === undefined) {\n nodeResult.width = defaultSize.width;\n }\n if (nodeResult.height === undefined) {\n nodeResult.height = defaultSize.height;\n }\n }\n\n // Process children recursively\n if ('children' in result && Array.isArray((result as { children: unknown[] }).children)) {\n (result as { children: unknown[] }).children = (result as { children: object[] }).children.map(\n (child) => this.applyDefaultSizesRecursive(child)\n );\n }\n\n // Process boundary events\n if ('boundaryEvents' in result && Array.isArray((result as { boundaryEvents: unknown[] }).boundaryEvents)) {\n const boundaryEvents = (result as { boundaryEvents: object[] }).boundaryEvents;\n (result as { boundaryEvents: unknown[] }).boundaryEvents = boundaryEvents.map(\n (be) => this.applyDefaultSizesRecursive(be)\n );\n\n // Ensure host node is wide enough to accommodate all boundary events with spacing\n // Each boundary event is 36px wide, and we need at least 20px spacing between them\n const beCount = boundaryEvents.length;\n if (beCount > 1) {\n const beWidth = 36;\n const beSpacing = 20;\n // Need: margin + (beWidth + spacing) * beCount - spacing + margin\n // Simplified: (beCount * (beWidth + beSpacing)) + margin\n const minWidth = beCount * (beWidth + beSpacing) + beSpacing;\n const nodeResult = result as { width?: number };\n if (nodeResult.width !== undefined && nodeResult.width < minWidth) {\n nodeResult.width = minWidth;\n }\n }\n }\n\n // Process artifacts\n if ('artifacts' in result && Array.isArray((result as { artifacts: unknown[] }).artifacts)) {\n (result as { artifacts: unknown[] }).artifacts = (result as { artifacts: object[] }).artifacts.map(\n (artifact) => this.applyDefaultSizesRecursive(artifact)\n );\n }\n\n return result;\n }\n\n /**\n * Estimate label width based on text content\n * Uses approximate character width of 14px for CJK and 7px for ASCII\n */\n estimateLabelWidth(text?: string): number {\n if (!text) return 50;\n\n let width = 0;\n for (const char of text) {\n // CJK characters are wider\n if (char.charCodeAt(0) > 255) {\n width += 14; // ~14px for CJK characters\n } else {\n width += 7; // ~7px for ASCII characters\n }\n }\n\n return Math.max(30, Math.min(width, 200)); // Clamp between 30 and 200\n }\n\n /**\n * Get default size for a BPMN element type\n */\n getDefaultSizeForType(type: string, name?: string, isExpanded?: boolean): ElementSize {\n // Expanded subprocesses\n if (isExpanded === true) {\n return { width: 300, height: 200 };\n }\n\n // Events\n if (type.includes('Event')) {\n return { width: 36, height: 36 };\n }\n\n // Gateways\n if (type.includes('Gateway')) {\n return { width: 50, height: 50 };\n }\n\n // Tasks and activities\n if (type.includes('Task') || type === 'task' || type === 'callActivity') {\n const nameLen = name?.length ?? 0;\n if (nameLen > 12) return { width: 150, height: 80 };\n if (nameLen > 8) return { width: 120, height: 80 };\n return { width: 100, height: 80 };\n }\n\n // Collapsed subprocesses\n if (type === 'subProcess' || type === 'transaction' || type === 'adHocSubProcess' || type === 'eventSubProcess') {\n return { width: 100, height: 80 };\n }\n\n // Data objects\n if (type === 'dataObject' || type === 'dataObjectReference' || type === 'dataInput' || type === 'dataOutput') {\n return { width: 36, height: 50 };\n }\n\n // Data store\n if (type === 'dataStoreReference') {\n return { width: 50, height: 50 };\n }\n\n // Text annotation\n if (type === 'textAnnotation') {\n return { width: 100, height: 30 };\n }\n\n // Participant/Pool - let ELK calculate\n if (type === 'participant') {\n return { width: 680, height: 200 };\n }\n\n // Lane - let ELK calculate\n if (type === 'lane') {\n return { width: 680, height: 150 };\n }\n\n // Default\n return { width: 100, height: 80 };\n }\n}\n\n/**\n * Standalone function to apply default sizes to a graph\n * Convenience wrapper around SizeCalculator\n */\nexport function applyDefaultSizes(graph: ElkBpmnGraph): ElkBpmnGraph {\n const calculator = new SizeCalculator();\n return calculator.applyDefaultSizes(graph);\n}\n\n/**\n * Standalone function to estimate label width\n * Convenience wrapper around SizeCalculator\n */\nexport function estimateLabelWidth(text?: string): number {\n const calculator = new SizeCalculator();\n return calculator.estimateLabelWidth(text);\n}\n\n/**\n * Standalone function to get default size for a type\n * Convenience wrapper around SizeCalculator\n */\nexport function getDefaultSizeForType(type: string, name?: string, isExpanded?: boolean): ElementSize {\n const calculator = new SizeCalculator();\n return calculator.getDefaultSizeForType(type, name, isExpanded);\n}\n","/**\n * Geometry Utilities for Edge Routing\n * Provides geometric calculation functions for edge routing and obstacle avoidance.\n */\n\nimport type { Point, Bounds } from '../../types/internal';\n\n/**\n * Calculate Euclidean distance between two points\n */\nexport function distance(p1: Point, p2: Point): number {\n return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));\n}\n\n/**\n * Calculate total path length of a series of waypoints\n */\nexport function calculatePathLength(waypoints: Point[]): number {\n let length = 0;\n for (let i = 0; i < waypoints.length - 1; i++) {\n const p1 = waypoints[i];\n const p2 = waypoints[i + 1];\n if (p1 && p2) {\n length += distance(p1, p2);\n }\n }\n return length;\n}\n\n/**\n * Check if a line segment intersects a rectangle\n * Used for detecting edge-node collisions\n */\nexport function segmentIntersectsRect(\n p1: Point,\n p2: Point,\n rect: Bounds\n): boolean {\n const margin = 5;\n const left = rect.x - margin;\n const right = rect.x + rect.width + margin;\n const top = rect.y - margin;\n const bottom = rect.y + rect.height + margin;\n\n // Check if both points are on the same side of the rectangle\n if ((p1.x < left && p2.x < left) || (p1.x > right && p2.x > right)) return false;\n if ((p1.y < top && p2.y < top) || (p1.y > bottom && p2.y > bottom)) return false;\n\n // Check if segment is horizontal or vertical\n if (Math.abs(p1.x - p2.x) < 1) {\n // Vertical segment\n const x = p1.x;\n const minY = Math.min(p1.y, p2.y);\n const maxY = Math.max(p1.y, p2.y);\n return x >= left && x <= right && maxY >= top && minY <= bottom;\n }\n\n if (Math.abs(p1.y - p2.y) < 1) {\n // Horizontal segment\n const y = p1.y;\n const minX = Math.min(p1.x, p2.x);\n const maxX = Math.max(p1.x, p2.x);\n return y >= top && y <= bottom && maxX >= left && minX <= right;\n }\n\n // For diagonal segments (shouldn't happen in orthogonal routing)\n return true; // Assume intersection if not axis-aligned\n}\n\n/**\n * Check if a line segment crosses through a node's interior\n * More strict than segmentIntersectsRect - requires passing through the interior\n */\nexport function segmentCrossesNode(\n p1: Point,\n p2: Point,\n node: Bounds\n): boolean {\n const margin = 5;\n const nodeLeft = node.x - margin;\n const nodeRight = node.x + node.width + margin;\n const nodeTop = node.y - margin;\n const nodeBottom = node.y + node.height + margin;\n\n // Check if segment is horizontal\n if (Math.abs(p1.y - p2.y) < 1) {\n const segY = p1.y;\n const segMinX = Math.min(p1.x, p2.x);\n const segMaxX = Math.max(p1.x, p2.x);\n\n // Segment crosses if: y is within node's vertical range AND segment spans node's horizontal range\n if (segY > nodeTop && segY < nodeBottom) {\n if (segMinX < nodeRight && segMaxX > nodeLeft) {\n // Check if segment actually passes through the interior (not just touching edges)\n const interiorLeft = node.x + margin;\n const interiorRight = node.x + node.width - margin;\n if (segMinX < interiorRight && segMaxX > interiorLeft) {\n return true;\n }\n }\n }\n }\n\n // Check if segment is vertical\n if (Math.abs(p1.x - p2.x) < 1) {\n const segX = p1.x;\n const segMinY = Math.min(p1.y, p2.y);\n const segMaxY = Math.max(p1.y, p2.y);\n\n // Segment crosses if: x is within node's horizontal range AND segment spans node's vertical range\n if (segX > nodeLeft && segX < nodeRight) {\n if (segMinY < nodeBottom && segMaxY > nodeTop) {\n // Check if segment actually passes through the interior\n const interiorTop = node.y + margin;\n const interiorBottom = node.y + node.height - margin;\n if (segMinY < interiorBottom && segMaxY > interiorTop) {\n return true;\n }\n }\n }\n }\n\n return false;\n}\n\n/**\n * Check if two rectangles overlap\n */\nexport function boundsOverlap(a: Bounds, b: Bounds, margin: number = 0): boolean {\n return !(\n a.x + a.width + margin < b.x ||\n b.x + b.width + margin < a.x ||\n a.y + a.height + margin < b.y ||\n b.y + b.height + margin < a.y\n );\n}\n\n/**\n * Get the center point of a bounds\n */\nexport function getCenter(bounds: Bounds): Point {\n return {\n x: bounds.x + bounds.width / 2,\n y: bounds.y + bounds.height / 2,\n };\n}\n\n/**\n * Calculate the midpoint between two points\n */\nexport function getMidpoint(p1: Point, p2: Point): Point {\n return {\n x: (p1.x + p2.x) / 2,\n y: (p1.y + p2.y) / 2,\n };\n}\n\n/**\n * Calculate connection point on a node based on direction\n */\nexport type ConnectionSide = 'left' | 'right' | 'top' | 'bottom';\n\nexport function getConnectionPoint(\n bounds: Bounds,\n side: ConnectionSide\n): Point {\n const center = getCenter(bounds);\n\n switch (side) {\n case 'left':\n return { x: bounds.x, y: center.y };\n case 'right':\n return { x: bounds.x + bounds.width, y: center.y };\n case 'top':\n return { x: center.x, y: bounds.y };\n case 'bottom':\n return { x: center.x, y: bounds.y + bounds.height };\n }\n}\n\n/**\n * Determine the best connection side based on relative positions\n */\nexport function determineBestConnectionSide(\n source: Bounds,\n target: Bounds\n): { sourceSide: ConnectionSide; targetSide: ConnectionSide } {\n const sourceCenter = getCenter(source);\n const targetCenter = getCenter(target);\n\n const dx = targetCenter.x - sourceCenter.x;\n const dy = targetCenter.y - sourceCenter.y;\n\n // Determine primary direction\n if (Math.abs(dx) > Math.abs(dy)) {\n // Horizontal movement\n if (dx > 0) {\n return { sourceSide: 'right', targetSide: 'left' };\n } else {\n return { sourceSide: 'left', targetSide: 'right' };\n }\n } else {\n // Vertical movement\n if (dy > 0) {\n return { sourceSide: 'bottom', targetSide: 'top' };\n } else {\n return { sourceSide: 'top', targetSide: 'bottom' };\n }\n }\n}\n\n/**\n * Create an orthogonal path between two points with L-shaped or Z-shaped routing\n */\nexport function createOrthogonalPath(\n start: Point,\n end: Point,\n primaryDirection: 'horizontal' | 'vertical' = 'horizontal'\n): Point[] {\n const waypoints: Point[] = [start];\n\n const dx = Math.abs(end.x - start.x);\n const dy = Math.abs(end.y - start.y);\n\n // If already aligned, direct connection\n if (dx < 5 || dy < 5) {\n waypoints.push(end);\n return waypoints;\n }\n\n // Create L-shaped routing\n if (primaryDirection === 'horizontal') {\n const midX = (start.x + end.x) / 2;\n waypoints.push({ x: midX, y: start.y });\n waypoints.push({ x: midX, y: end.y });\n } else {\n const midY = (start.y + end.y) / 2;\n waypoints.push({ x: start.x, y: midY });\n waypoints.push({ x: end.x, y: midY });\n }\n\n waypoints.push(end);\n return waypoints;\n}\n\n/**\n * Score a route based on obstacle crossings and path length\n * Lower score = better route\n */\nexport function scoreRoute(\n start: Point,\n bendPoints: Point[],\n end: Point,\n obstacles: Bounds[]\n): number {\n let score = 0;\n const crossingPenalty = 1000;\n const lengthWeight = 0.1;\n\n // Build full path\n const path = [start, ...bendPoints, end];\n\n // Check for crossings with each obstacle\n for (const obs of obstacles) {\n for (let i = 0; i < path.length - 1; i++) {\n const p1 = path[i];\n const p2 = path[i + 1];\n if (p1 && p2 && segmentIntersectsRect(p1, p2, obs)) {\n score += crossingPenalty;\n }\n }\n }\n\n // Add path length to score\n for (let i = 0; i < path.length - 1; i++) {\n const p1 = path[i];\n const p2 = path[i + 1];\n if (p1 && p2) {\n score += distance(p1, p2) * lengthWeight;\n }\n }\n\n return score;\n}\n\n/**\n * Find a clear vertical path that avoids obstacles\n * Returns the Y coordinate to route through, or null if direct path is clear\n */\nexport function findClearVerticalPath(\n x: number,\n startY: number,\n endY: number,\n obstacles: Bounds[]\n): number | null {\n const minY = Math.min(startY, endY);\n const maxY = Math.max(startY, endY);\n const margin = 10;\n\n // Check if any obstacle blocks the vertical path\n for (const obs of obstacles) {\n const obsLeft = obs.x - margin;\n const obsRight = obs.x + obs.width + margin;\n const obsTop = obs.y;\n const obsBottom = obs.y + obs.height;\n\n // Check if x is within obstacle's horizontal range\n if (x >= obsLeft && x <= obsRight) {\n // Check if obstacle is in our vertical path\n if (obsBottom > minY && obsTop < maxY) {\n // Found an obstacle - return a Y that goes around it\n // Prefer going below the obstacle if there's more space\n const spaceAbove = obsTop - minY;\n const spaceBelow = maxY - obsBottom;\n\n if (spaceBelow > spaceAbove && obsBottom + margin < maxY) {\n return obsBottom + margin;\n } else if (obsTop - margin > minY) {\n return obsTop - margin;\n }\n }\n }\n }\n\n return null; // No obstacle found, direct path is clear\n}\n\n/**\n * Calculate intersection point of two line segments.\n * Returns null if lines don't intersect within both segments.\n * Used for diamond edge intersection calculations.\n */\nexport function lineIntersection(\n p1: Point,\n p2: Point,\n p3: Point,\n p4: Point\n): Point | null {\n const denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);\n if (Math.abs(denom) < 0.0001) return null; // Lines are parallel\n\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom;\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom;\n\n // Check if intersection is within both line segments\n if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {\n return {\n x: p1.x + ua * (p2.x - p1.x),\n y: p1.y + ua * (p2.y - p1.y),\n };\n }\n\n return null;\n}\n\n/**\n * Find a clear horizontal path that avoids obstacles\n * Returns the X coordinate to route through, or null if direct path is clear\n */\nexport function findClearHorizontalPath(\n y: number,\n startX: number,\n endX: number,\n obstacles: Bounds[]\n): number | null {\n const minX = Math.min(startX, endX);\n const maxX = Math.max(startX, endX);\n const margin = 10;\n\n // Check if any obstacle blocks the horizontal path\n for (const obs of obstacles) {\n const obsTop = obs.y - margin;\n const obsBottom = obs.y + obs.height + margin;\n const obsLeft = obs.x;\n const obsRight = obs.x + obs.width;\n\n // Check if y is within obstacle's vertical range\n if (y >= obsTop && y <= obsBottom) {\n // Check if obstacle is in our horizontal path\n if (obsRight > minX && obsLeft < maxX) {\n // Found an obstacle - return an X that goes around it\n // Prefer going right of the obstacle if there's more space\n const spaceLeft = obsLeft - minX;\n const spaceRight = maxX - obsRight;\n\n if (spaceRight > spaceLeft && obsRight + margin < maxX) {\n return obsRight + margin;\n } else if (obsLeft - margin > minX) {\n return obsLeft - margin;\n }\n }\n }\n }\n\n return null; // No obstacle found, direct path is clear\n}\n","/**\n * Shared Debug Utilities\n * Centralized debug flag for consistent debug logging across the codebase.\n */\n\n/**\n * Debug flag from environment variable.\n * Set DEBUG=true to enable debug logging.\n *\n * @example\n * ```bash\n * DEBUG=true bun run test -- -t \"21-subprocess\"\n * ```\n */\nexport const DEBUG =\n typeof process !== 'undefined' && process.env?.['DEBUG'] === 'true';\n","/**\n * Edge Fixer\n * Detects and fixes edges that cross through nodes.\n * Ensures edges connect perpendicular to node boundaries.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { Point, Bounds, NodeWithBpmn } from '../../types/internal';\nimport { segmentCrossesNode } from './geometry-utils';\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Handler for edge crossing detection and fixing\n */\nexport class EdgeFixer {\n private readonly margin = 15;\n\n /**\n * Fix edges that cross through nodes\n */\n fix(graph: ElkNode): void {\n // Build node positions organized by container (pool/process)\n const nodesByContainer = new Map<string, Map<string, Bounds>>();\n\n // Flow node ID patterns (tasks, gateways, events) - excluding boundary events\n // Boundary events are small elements attached to tasks and should not block edges\n const flowNodePatterns = [\n /^task_/, /^gateway_/, /^start_/, /^end_/,\n /^subprocess_/, /^call_/,\n /^intermediate_/, /^event_/, /^catch_/,\n ];\n\n // Boundary event pattern - these should not be treated as obstacles\n const boundaryEventPattern = /^boundary_/;\n\n // Container ID patterns that define pool/process boundaries\n const poolPatterns = [\n /^pool_/, /^participant_/, /^process_/,\n ];\n\n const collectNodePositions = (\n node: ElkNode,\n offsetX: number = 0,\n offsetY: number = 0,\n containerId: string = 'root'\n ) => {\n const id = node.id || '';\n const isBoundaryEvent = boundaryEventPattern.test(id);\n const isFlowNode = flowNodePatterns.some(pattern => pattern.test(id));\n const isPool = poolPatterns.some(pattern => pattern.test(id));\n const bpmn = (node as unknown as NodeWithBpmn).bpmn;\n\n if (DEBUG && (id.includes('lane') || id.includes('pool') || id.includes('end_fast') || id.includes('gateway_fast'))) {\n console.log(`[BPMN] EdgeFixer.collectNodePositions: id=${id}, offsetX=${offsetX}, offsetY=${offsetY}, bpmn=${JSON.stringify(bpmn)}`);\n console.log(`[BPMN] node.x=${node.x}, node.y=${node.y}, isFlowNode=${isFlowNode}, isPool=${isPool}`);\n }\n\n // If this is a pool/process container, use it as the new container context\n const currentContainerId = isPool ? id : containerId;\n\n // For flow nodes (excluding boundary events), store their position under their container\n // Boundary events should not be obstacles as they're small elements attached to tasks\n if (isFlowNode && !isBoundaryEvent && node.x !== undefined && node.y !== undefined) {\n const absX = offsetX + node.x;\n const absY = offsetY + node.y;\n\n if (!nodesByContainer.has(currentContainerId)) {\n nodesByContainer.set(currentContainerId, new Map());\n }\n nodesByContainer.get(currentContainerId)!.set(node.id, {\n x: absX,\n y: absY,\n width: node.width ?? 100,\n height: node.height ?? 80,\n });\n }\n\n // Recursively process children\n // Use same container detection logic as model-builder:\n // - Containers that offset children: pools (participants), lanes, expanded subprocesses\n // - Regular processes do NOT offset their children (unlike pools)\n const isExpandedSubprocess = bpmn?.isExpanded === true &&\n (bpmn?.type === 'subProcess' || bpmn?.type === 'transaction' ||\n bpmn?.type === 'adHocSubProcess' || bpmn?.type === 'eventSubProcess');\n const isPoolOrLane = bpmn?.type === 'participant' || bpmn?.type === 'lane';\n const isContainer = isExpandedSubprocess || isPoolOrLane;\n\n if (node.children) {\n const newOffsetX = isContainer ? offsetX + (node.x ?? 0) : offsetX;\n const newOffsetY = isContainer ? offsetY + (node.y ?? 0) : offsetY;\n for (const child of node.children) {\n collectNodePositions(child, newOffsetX, newOffsetY, currentContainerId);\n }\n }\n };\n collectNodePositions(graph);\n\n // Process all edges in the graph\n const processEdges = (\n node: ElkNode,\n containerOffsetX: number = 0,\n containerOffsetY: number = 0,\n containerId: string = 'root'\n ) => {\n const bpmn = (node as unknown as NodeWithBpmn).bpmn;\n const isPool = poolPatterns.some(pattern => pattern.test(node.id || ''));\n const currentContainerId = isPool ? node.id : containerId;\n\n if (node.edges) {\n // Get only nodes in the same container for crossing detection\n const containerNodes = nodesByContainer.get(currentContainerId) ?? new Map();\n\n for (const edge of node.edges) {\n if (edge.sections && edge.sections.length > 0) {\n this.fixEdgeIfCrossing(edge, containerNodes, containerOffsetX, containerOffsetY);\n }\n }\n }\n\n // Use same container detection logic as model-builder and collectNodePositions\n const isExpandedSubprocess = bpmn?.isExpanded === true &&\n (bpmn?.type === 'subProcess' || bpmn?.type === 'transaction' ||\n bpmn?.type === 'adHocSubProcess' || bpmn?.type === 'eventSubProcess');\n const isPoolOrLane = bpmn?.type === 'participant' || bpmn?.type === 'lane';\n const isContainer = isExpandedSubprocess || isPoolOrLane;\n\n if (node.children) {\n const newOffsetX = isContainer ? containerOffsetX + (node.x ?? 0) : containerOffsetX;\n const newOffsetY = isContainer ? containerOffsetY + (node.y ?? 0) : containerOffsetY;\n for (const child of node.children) {\n processEdges(child, newOffsetX, newOffsetY, currentContainerId);\n }\n }\n };\n processEdges(graph);\n }\n\n /**\n * Check if an edge crosses any node and fix it if so\n */\n private fixEdgeIfCrossing(\n edge: ElkExtendedEdge,\n nodePositions: Map<string, Bounds>,\n containerOffsetX: number,\n containerOffsetY: number\n ): void {\n const section = edge.sections?.[0];\n if (!section) return;\n\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n // Skip edges from boundary events - they're already handled by boundary-event-handler\n // with proper perpendicular routing and obstacle avoidance\n if (sourceId?.startsWith('boundary_')) {\n return;\n }\n\n // Convert waypoints to absolute positions\n const waypoints: Point[] = [\n { x: containerOffsetX + section.startPoint.x, y: containerOffsetY + section.startPoint.y },\n ];\n if (section.bendPoints) {\n for (const bp of section.bendPoints) {\n waypoints.push({ x: containerOffsetX + bp.x, y: containerOffsetY + bp.y });\n }\n }\n waypoints.push({ x: containerOffsetX + section.endPoint.x, y: containerOffsetY + section.endPoint.y });\n\n // Check each segment of the edge for crossings\n const crossedNodes: string[] = [];\n for (let i = 0; i < waypoints.length - 1; i++) {\n const p1 = waypoints[i];\n const p2 = waypoints[i + 1];\n if (!p1 || !p2) continue;\n\n for (const [nodeId, pos] of nodePositions) {\n // Skip source and target nodes for intermediate segments\n if (nodeId === sourceId || nodeId === targetId) continue;\n\n if (segmentCrossesNode(p1, p2, pos)) {\n crossedNodes.push(nodeId);\n }\n }\n }\n\n // Also check if the edge path crosses THROUGH the target node (not just connects to it)\n const targetPos = targetId ? nodePositions.get(targetId) : undefined;\n const sourcePos = sourceId ? nodePositions.get(sourceId) : undefined;\n\n if (DEBUG && edge.id?.includes('back')) {\n console.log(`[BPMN] Edge ${edge.id}: sourceId=${sourceId}, targetId=${targetId}`);\n console.log(`[BPMN] Edge ${edge.id}: sourcePos=${JSON.stringify(sourcePos)}, targetPos=${JSON.stringify(targetPos)}`);\n console.log(`[BPMN] Edge ${edge.id}: waypoints.length=${waypoints.length}`);\n }\n\n if (targetPos && sourcePos && waypoints.length >= 2) {\n // Check the last segment before entering the target\n const lastWaypoint = waypoints[waypoints.length - 1];\n const secondLastWaypoint = waypoints[waypoints.length - 2];\n\n // If this is a return edge (target above source) and the last segment is horizontal\n // going through the target, we need to reroute\n const isReturnEdge = targetPos.y + targetPos.height < sourcePos.y;\n\n if (DEBUG && edge.id?.includes('back')) {\n console.log(`[BPMN] Edge ${edge.id}: isReturnEdge=${isReturnEdge}`);\n if (lastWaypoint) {\n console.log(`[BPMN] Edge ${edge.id}: lastWaypoint=(${lastWaypoint.x},${lastWaypoint.y})`);\n }\n }\n\n if (isReturnEdge && lastWaypoint && secondLastWaypoint) {\n // Check if the horizontal segment crosses through the target interior\n if (Math.abs(secondLastWaypoint.y - lastWaypoint.y) < 5) {\n // Horizontal segment\n const segY = secondLastWaypoint.y;\n const segMinX = Math.min(secondLastWaypoint.x, lastWaypoint.x);\n const segMaxX = Math.max(secondLastWaypoint.x, lastWaypoint.x);\n\n // Check if segment passes through target interior\n if (segY > targetPos.y && segY < targetPos.y + targetPos.height) {\n if (segMinX < targetPos.x + targetPos.width && segMaxX > targetPos.x) {\n crossedNodes.push(targetId + ' (target)');\n }\n }\n }\n }\n }\n\n if (crossedNodes.length === 0) return;\n\n if (DEBUG) {\n console.log(`[BPMN] Edge ${edge.id} crosses nodes: ${crossedNodes.join(', ')}`);\n }\n\n if (!sourcePos || !targetPos) return;\n\n // Collect obstacles (all crossed nodes plus nearby nodes)\n const obstacles: (Bounds & { id: string })[] = [];\n for (const [nodeId, pos] of nodePositions) {\n if (nodeId === sourceId || nodeId === targetId) continue;\n obstacles.push({ ...pos, id: nodeId });\n }\n\n // Determine if this is a return edge (target is above source)\n const isReturnEdge = targetPos.y + targetPos.height < sourcePos.y;\n\n // For return edges that cross through target, adjust endpoint to enter from right side\n const crossesThroughTarget = crossedNodes.some(n => n.includes('(target)'));\n if (isReturnEdge && crossesThroughTarget) {\n const targetWidth = targetPos.width;\n section.endPoint = {\n x: section.endPoint.x + targetWidth,\n y: section.endPoint.y,\n };\n }\n\n // Get the adjusted endpoints in absolute coordinates\n const originalStart = {\n x: containerOffsetX + section.startPoint.x,\n y: containerOffsetY + section.startPoint.y,\n };\n const originalEnd = {\n x: containerOffsetX + section.endPoint.x,\n y: containerOffsetY + section.endPoint.y,\n };\n\n // Calculate new path that avoids obstacles with perpendicular connections\n const result = this.calculatePerpendicularAvoidingPath(\n originalStart,\n originalEnd,\n sourcePos,\n targetPos,\n obstacles,\n isReturnEdge\n );\n\n // Update start and end points if new ones were calculated\n if (result.startPoint) {\n section.startPoint = {\n x: result.startPoint.x - containerOffsetX,\n y: result.startPoint.y - containerOffsetY,\n };\n }\n if (result.endPoint) {\n section.endPoint = {\n x: result.endPoint.x - containerOffsetX,\n y: result.endPoint.y - containerOffsetY,\n };\n }\n\n // Convert bend points back to relative coordinates\n const relativeBendPoints = result.bendPoints.map(bp => ({\n x: bp.x - containerOffsetX,\n y: bp.y - containerOffsetY,\n }));\n\n section.bendPoints = relativeBendPoints.length > 0 ? relativeBendPoints : undefined;\n\n if (DEBUG) {\n console.log(`[BPMN] Fixed edge ${edge.id} with ${relativeBendPoints.length} bend points`);\n }\n }\n\n /**\n * Determine connection side based on the edge direction\n * For BPMN diagrams with left-to-right flow, we prefer horizontal connections\n * even when vertical distance is larger, as long as target is to the right.\n */\n private determineConnectionSide(\n from: Point,\n to: Point,\n nodeBounds: Bounds,\n isSource: boolean\n ): 'top' | 'bottom' | 'left' | 'right' {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n\n // For BPMN left-to-right flow: when target is to the right of source,\n // prefer horizontal connections (exit right from source, enter left to target)\n // This ensures edges follow the natural flow direction.\n // EXCEPTION: If target is significantly above/below (vertical distance > 1.5x horizontal),\n // the target should use vertical entry point (top/bottom) for cleaner routing.\n if (dx > 0) {\n // Target is to the right\n if (isSource) {\n return 'right';\n } else {\n // For target: if it's significantly above or below, use vertical entry\n if (absDy > absDx * 1.5) {\n return dy > 0 ? 'top' : 'bottom';\n }\n return 'left';\n }\n } else if (dx < 0) {\n // Target is to the left (return edge)\n if (isSource) {\n return 'left';\n } else {\n return 'right';\n }\n } else {\n // Same X position - use vertical routing\n if (isSource) {\n return dy > 0 ? 'bottom' : 'top';\n } else {\n return dy > 0 ? 'top' : 'bottom';\n }\n }\n }\n\n /**\n * Get the connection point on a node boundary\n */\n private getConnectionPoint(bounds: Bounds, side: 'top' | 'bottom' | 'left' | 'right'): Point {\n const centerX = bounds.x + bounds.width / 2;\n const centerY = bounds.y + bounds.height / 2;\n\n switch (side) {\n case 'top':\n return { x: centerX, y: bounds.y };\n case 'bottom':\n return { x: centerX, y: bounds.y + bounds.height };\n case 'left':\n return { x: bounds.x, y: centerY };\n case 'right':\n return { x: bounds.x + bounds.width, y: centerY };\n }\n }\n\n /**\n * Calculate bend points that avoid obstacles while ensuring perpendicular connections\n * Uses LOCAL routing - only considers obstacles actually blocking the direct path\n */\n private calculatePerpendicularAvoidingPath(\n originalStart: Point,\n originalEnd: Point,\n source: Bounds,\n target: Bounds,\n obstacles: (Bounds & { id: string })[],\n isReturnEdge: boolean\n ): { bendPoints: Point[]; startPoint?: Point; endPoint?: Point } {\n // Determine the primary direction of travel\n const dx = originalEnd.x - originalStart.x;\n const dy = originalEnd.y - originalStart.y;\n\n // Determine connection sides based on overall direction\n const sourceSide = this.determineConnectionSide(originalStart, originalEnd, source, true);\n const targetSide = this.determineConnectionSide(originalStart, originalEnd, target, false);\n\n // Get actual start and end points on node boundaries\n const startPoint = this.getConnectionPoint(source, sourceSide);\n const endPoint = this.getConnectionPoint(target, targetSide);\n\n // Define the bounding box of direct path from start to end\n const pathMinX = Math.min(startPoint.x, endPoint.x) - this.margin;\n const pathMaxX = Math.max(startPoint.x, endPoint.x) + this.margin;\n const pathMinY = Math.min(startPoint.y, endPoint.y) - this.margin;\n const pathMaxY = Math.max(startPoint.y, endPoint.y) + this.margin;\n\n // Filter obstacles to only those that actually block the path\n const blockingObstacles = obstacles.filter(obs => {\n const obsRight = obs.x + obs.width;\n const obsBottom = obs.y + obs.height;\n\n // Check if obstacle overlaps with the path bounding box\n const overlapX = obs.x < pathMaxX && obsRight > pathMinX;\n const overlapY = obs.y < pathMaxY && obsBottom > pathMinY;\n\n return overlapX && overlapY;\n });\n\n if (blockingObstacles.length === 0) {\n // No obstacles blocking - use simple perpendicular routing\n const bendPoints = this.createPerpendicularPath(startPoint, endPoint, sourceSide, targetSide);\n return { bendPoints, startPoint, endPoint };\n }\n\n // Determine routing strategy based on BOTH horizontal and vertical directions\n // When target is to the right of source, always prefer routing RIGHT (not left)\n const targetIsRight = dx > 0;\n const targetIsAbove = dy < 0;\n const targetIsBelow = dy > 0;\n\n let bendPoints: Point[];\n\n // For diagonal movements where target is to the right, use right-biased routing\n if (targetIsRight) {\n if (targetIsAbove) {\n // Going right and up - route right then up\n bendPoints = this.routeRightThenUp(startPoint, endPoint, blockingObstacles, source, target);\n } else if (targetIsBelow) {\n // Going right and down - route right then down\n bendPoints = this.routeRightThenDown(startPoint, endPoint, blockingObstacles, source, target);\n } else {\n // Purely horizontal right\n bendPoints = this.routeRightWithObstacleAvoidance(startPoint, endPoint, sourceSide, targetSide, blockingObstacles, source, target);\n }\n } else {\n // Target is to the left or same X\n if (targetIsAbove) {\n bendPoints = this.routeUpWithObstacleAvoidance(startPoint, endPoint, sourceSide, targetSide, blockingObstacles, source, target);\n } else if (targetIsBelow) {\n bendPoints = this.routeDownWithObstacleAvoidance(startPoint, endPoint, sourceSide, targetSide, blockingObstacles, source, target);\n } else {\n bendPoints = this.routeLeftWithObstacleAvoidance(startPoint, endPoint, sourceSide, targetSide, blockingObstacles, source, target);\n }\n }\n\n return { bendPoints, startPoint, endPoint };\n }\n\n /**\n * Route right then up - for edges going both right and up\n * Source exits from right side, target enters from left side\n * Strategy: go horizontally right past obstacles, then vertically to target\n */\n private routeRightThenUp(\n start: Point,\n end: Point,\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // Find obstacles that block the direct vertical path from start.x to end.y\n const blockingObstacles = obstacles.filter(obs => {\n // Obstacle blocks if it's horizontally overlapping with the path\n // and vertically between source and target\n const obsRight = obs.x + obs.width;\n const obsBottom = obs.y + obs.height;\n const pathMinY = Math.min(start.y, end.y);\n const pathMaxY = Math.max(start.y, end.y);\n\n return obs.x < end.x && obsRight > start.x - this.margin &&\n obs.y < pathMaxY && obsBottom > pathMinY;\n });\n\n if (blockingObstacles.length === 0) {\n // No obstacles - simple L-route\n bendPoints.push({ x: end.x, y: start.y });\n return bendPoints;\n }\n\n // Find the rightmost edge of blocking obstacles\n let clearX = start.x;\n for (const obs of blockingObstacles) {\n clearX = Math.max(clearX, obs.x + obs.width + this.margin);\n }\n // Ensure we go at least to target X\n clearX = Math.max(clearX, end.x);\n\n // Route: go right to clearX, then up to target Y, then left to target X (if needed)\n if (Math.abs(clearX - end.x) < 5) {\n // clearX is close to end.x - simple L-route\n bendPoints.push({ x: end.x, y: start.y });\n } else {\n // Need to route past obstacles then back\n bendPoints.push({ x: clearX, y: start.y });\n bendPoints.push({ x: clearX, y: end.y });\n }\n\n return bendPoints;\n }\n\n /**\n * Route right then down - for edges going both right and down\n * Source exits from right side, target enters from left side\n * Strategy: go horizontally right past obstacles, then vertically to target\n */\n private routeRightThenDown(\n start: Point,\n end: Point,\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // Find obstacles that block the direct vertical path from start.x to end.y\n const blockingObstacles = obstacles.filter(obs => {\n // Obstacle blocks if it's horizontally overlapping with the path\n // and vertically between source and target\n const obsRight = obs.x + obs.width;\n const obsBottom = obs.y + obs.height;\n const pathMinY = Math.min(start.y, end.y);\n const pathMaxY = Math.max(start.y, end.y);\n\n return obs.x < end.x && obsRight > start.x - this.margin &&\n obs.y < pathMaxY && obsBottom > pathMinY;\n });\n\n if (blockingObstacles.length === 0) {\n // No obstacles - simple L-route\n bendPoints.push({ x: end.x, y: start.y });\n return bendPoints;\n }\n\n // Find the rightmost edge of blocking obstacles\n let clearX = start.x;\n for (const obs of blockingObstacles) {\n clearX = Math.max(clearX, obs.x + obs.width + this.margin);\n }\n // Ensure we go at least to target X\n clearX = Math.max(clearX, end.x);\n\n // Route: go right to clearX, then down to target Y, then left to target X (if needed)\n if (Math.abs(clearX - end.x) < 5) {\n // clearX is close to end.x - simple L-route\n bendPoints.push({ x: end.x, y: start.y });\n } else {\n // Need to route past obstacles then back\n bendPoints.push({ x: clearX, y: start.y });\n bendPoints.push({ x: clearX, y: end.y });\n }\n\n return bendPoints;\n }\n\n /**\n * Create a simple perpendicular path without obstacle avoidance\n */\n private createPerpendicularPath(\n start: Point,\n end: Point,\n sourceSide: 'top' | 'bottom' | 'left' | 'right',\n targetSide: 'top' | 'bottom' | 'left' | 'right'\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // If start and end are aligned, no bend points needed\n if (Math.abs(start.x - end.x) < 5 || Math.abs(start.y - end.y) < 5) {\n return bendPoints;\n }\n\n // Create perpendicular routing based on exit and entry sides\n const isVerticalExit = sourceSide === 'top' || sourceSide === 'bottom';\n const isVerticalEntry = targetSide === 'top' || targetSide === 'bottom';\n\n if (isVerticalExit && isVerticalEntry) {\n // Both vertical - need horizontal middle segment\n const midY = (start.y + end.y) / 2;\n bendPoints.push({ x: start.x, y: midY });\n bendPoints.push({ x: end.x, y: midY });\n } else if (!isVerticalExit && !isVerticalEntry) {\n // Both horizontal - need vertical middle segment\n const midX = (start.x + end.x) / 2;\n bendPoints.push({ x: midX, y: start.y });\n bendPoints.push({ x: midX, y: end.y });\n } else if (isVerticalExit && !isVerticalEntry) {\n // Exit vertical, entry horizontal - L-shape\n bendPoints.push({ x: start.x, y: end.y });\n } else {\n // Exit horizontal, entry vertical - L-shape\n bendPoints.push({ x: end.x, y: start.y });\n }\n\n return bendPoints;\n }\n\n /**\n * Route downward with obstacle avoidance, maintaining perpendicular connections\n */\n private routeDownWithObstacleAvoidance(\n start: Point,\n end: Point,\n sourceSide: 'top' | 'bottom' | 'left' | 'right',\n targetSide: 'top' | 'bottom' | 'left' | 'right',\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // Find the leftmost X we need to route through to avoid obstacles\n let avoidX = Math.min(start.x, end.x);\n for (const obs of obstacles) {\n // If obstacle blocks the vertical path\n if (obs.y <= end.y && obs.y + obs.height >= start.y) {\n if (obs.x <= start.x && obs.x + obs.width >= start.x) {\n avoidX = Math.min(avoidX, obs.x - this.margin);\n }\n if (obs.x <= end.x && obs.x + obs.width >= end.x) {\n avoidX = Math.min(avoidX, obs.x - this.margin);\n }\n }\n }\n\n // Ensure we don't route through the source or target\n avoidX = Math.min(avoidX, source.x - this.margin);\n avoidX = Math.min(avoidX, target.x - this.margin);\n\n // Exit perpendicular from source\n if (sourceSide === 'bottom') {\n // Exit down first\n const exitY = start.y + this.margin;\n bendPoints.push({ x: start.x, y: exitY });\n\n if (avoidX < start.x - 5) {\n // Need to go left to avoid obstacle\n bendPoints.push({ x: avoidX, y: exitY });\n bendPoints.push({ x: avoidX, y: end.y - this.margin });\n bendPoints.push({ x: end.x, y: end.y - this.margin });\n } else if (Math.abs(start.x - end.x) > 5) {\n // Simple L-routing\n bendPoints.push({ x: end.x, y: exitY });\n }\n } else {\n // Exit from side, then go down\n const midY = (start.y + end.y) / 2;\n bendPoints.push({ x: avoidX, y: start.y });\n bendPoints.push({ x: avoidX, y: midY });\n bendPoints.push({ x: end.x, y: midY });\n }\n\n return bendPoints;\n }\n\n /**\n * Route upward with obstacle avoidance, maintaining perpendicular connections\n */\n private routeUpWithObstacleAvoidance(\n start: Point,\n end: Point,\n sourceSide: 'top' | 'bottom' | 'left' | 'right',\n targetSide: 'top' | 'bottom' | 'left' | 'right',\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // For upward routing (return edges), typically exit from right and route around\n let clearX = Math.max(source.x + source.width, target.x + target.width) + this.margin;\n for (const obs of obstacles) {\n clearX = Math.max(clearX, obs.x + obs.width + this.margin);\n }\n\n // Exit perpendicular then route\n if (sourceSide === 'right') {\n bendPoints.push({ x: clearX, y: start.y });\n bendPoints.push({ x: clearX, y: end.y });\n } else if (sourceSide === 'top') {\n const exitY = start.y - this.margin;\n bendPoints.push({ x: start.x, y: exitY });\n bendPoints.push({ x: clearX, y: exitY });\n bendPoints.push({ x: clearX, y: end.y });\n } else {\n bendPoints.push({ x: clearX, y: start.y });\n bendPoints.push({ x: clearX, y: end.y });\n }\n\n return bendPoints;\n }\n\n /**\n * Route rightward with obstacle avoidance, maintaining perpendicular connections\n */\n private routeRightWithObstacleAvoidance(\n start: Point,\n end: Point,\n sourceSide: 'top' | 'bottom' | 'left' | 'right',\n targetSide: 'top' | 'bottom' | 'left' | 'right',\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // Find a clear X position between source and target\n const sourceRight = source.x + source.width;\n const targetLeft = target.x;\n let routeX = sourceRight + this.margin;\n\n // Check if any obstacle blocks this path\n for (const obs of obstacles) {\n const obsLeft = obs.x;\n const obsRight = obs.x + obs.width;\n\n if (obsRight > sourceRight && obsLeft < targetLeft) {\n routeX = Math.max(routeX, obsRight + this.margin);\n }\n }\n\n // Ensure we don't go past the target\n routeX = Math.min(routeX, targetLeft - this.margin);\n\n // If there's no room, route above or below\n if (routeX <= sourceRight) {\n // Route below obstacles\n let clearY = Math.max(source.y + source.height, target.y + target.height) + this.margin;\n for (const obs of obstacles) {\n clearY = Math.max(clearY, obs.y + obs.height + this.margin);\n }\n\n if (sourceSide === 'right') {\n bendPoints.push({ x: start.x + this.margin, y: start.y });\n bendPoints.push({ x: start.x + this.margin, y: clearY });\n bendPoints.push({ x: end.x - this.margin, y: clearY });\n bendPoints.push({ x: end.x - this.margin, y: end.y });\n } else {\n bendPoints.push({ x: start.x, y: clearY });\n bendPoints.push({ x: end.x, y: clearY });\n }\n } else {\n // Normal routing through routeX\n bendPoints.push({ x: routeX, y: start.y });\n bendPoints.push({ x: routeX, y: end.y });\n }\n\n return bendPoints;\n }\n\n /**\n * Route leftward with obstacle avoidance, maintaining perpendicular connections\n */\n private routeLeftWithObstacleAvoidance(\n start: Point,\n end: Point,\n sourceSide: 'top' | 'bottom' | 'left' | 'right',\n targetSide: 'top' | 'bottom' | 'left' | 'right',\n obstacles: (Bounds & { id: string })[],\n source: Bounds,\n target: Bounds\n ): Point[] {\n const bendPoints: Point[] = [];\n\n // Find a clear X position to route through\n let clearX = Math.min(source.x, target.x) - this.margin;\n for (const obs of obstacles) {\n if (obs.x < source.x && obs.x + obs.width > target.x + target.width) {\n clearX = Math.min(clearX, obs.x - this.margin);\n }\n }\n\n if (sourceSide === 'left') {\n bendPoints.push({ x: clearX, y: start.y });\n bendPoints.push({ x: clearX, y: end.y });\n } else {\n // Exit perpendicular first\n const exitX = start.x - this.margin;\n bendPoints.push({ x: exitX, y: start.y });\n bendPoints.push({ x: exitX, y: end.y });\n }\n\n return bendPoints;\n }\n}\n","/**\n * Boundary Event Collector\n * Collects boundary event information from the BPMN graph for post-processing.\n */\n\nimport type { ElkBpmnGraph } from '../../../types';\nimport type { NodeWithBpmn, BoundaryEventInfo } from '../../../types/internal';\n\n/**\n * Collect boundary event information for post-processing.\n * Returns a map of boundary event ID -> { attachedToRef, targets, boundaryIndex, totalBoundaries }\n *\n * @param graph - The ELK-BPMN input graph\n * @returns Map of boundary event ID to BoundaryEventInfo\n */\nexport function collectBoundaryEventInfo(\n graph: ElkBpmnGraph\n): Map<string, BoundaryEventInfo> {\n const info = new Map<string, BoundaryEventInfo>();\n const edgeMap = new Map<string, string[]>(); // source -> targets\n\n // First pass: collect all edges by source\n const collectEdges = (node: NodeWithBpmn) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (!source || !target) continue;\n if (!edgeMap.has(source)) {\n edgeMap.set(source, []);\n }\n edgeMap.get(source)!.push(target);\n }\n }\n if (node.children) {\n for (const child of node.children) {\n collectEdges(child as NodeWithBpmn);\n }\n }\n };\n\n // Second pass: collect boundary events and their targets\n const collectBoundaryEvents = (node: NodeWithBpmn) => {\n if (node.boundaryEvents) {\n const totalBoundaries = node.boundaryEvents.length;\n node.boundaryEvents.forEach((be, index) => {\n const targets = edgeMap.get(be.id) || [];\n info.set(be.id, {\n attachedToRef: be.attachedToRef,\n targets,\n boundaryIndex: index,\n totalBoundaries,\n });\n });\n }\n if (node.children) {\n for (const child of node.children) {\n collectBoundaryEvents(child as NodeWithBpmn);\n }\n }\n };\n\n for (const child of graph.children ?? []) {\n collectEdges(child as NodeWithBpmn);\n collectBoundaryEvents(child as NodeWithBpmn);\n }\n\n return info;\n}\n","/**\n * Boundary Event Mover\n * Handles identification and movement of boundary event target nodes.\n */\n\nimport type { ElkNode } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../../types';\nimport type { NodeWithBpmn, BoundaryEventInfo, NodeMoveInfo } from '../../../types/internal';\n\n/**\n * Branch destination type enum for prioritization\n */\nexport enum BranchDestType {\n MERGE_TO_MAIN = 1, // Branches that merge back to main flow (highest priority - closest to main flow)\n TO_END_EVENT = 2, // Branches that end at end events (medium priority)\n DEAD_END = 3, // Branches with no outgoing edges (lowest priority - furthest from main flow)\n}\n\n/**\n * Placed branch info for collision detection\n */\ninterface PlacedBranch {\n minX: number;\n maxX: number;\n minY: number;\n maxY: number;\n destType: BranchDestType;\n}\n\n/**\n * Build maps for node lookups and edge relationships\n */\nexport function buildNodeAndEdgeMaps(\n graph: ElkNode,\n sizedGraph?: ElkBpmnGraph\n): {\n nodeMap: Map<string, ElkNode>;\n nodeTypeMap: Map<string, string>;\n edgeMap: Map<string, string[]>;\n reverseEdgeMap: Map<string, string[]>;\n} {\n const nodeMap = new Map<string, ElkNode>();\n const nodeTypeMap = new Map<string, string>();\n const edgeMap = new Map<string, string[]>();\n const reverseEdgeMap = new Map<string, string[]>();\n\n // Helper to collect node types from sizedGraph\n const collectNodeTypes = (node: NodeWithBpmn) => {\n if (node.bpmn?.type) {\n nodeTypeMap.set(node.id, node.bpmn.type);\n }\n if (node.children) {\n for (const child of node.children) {\n collectNodeTypes(child as NodeWithBpmn);\n }\n }\n if (node.boundaryEvents) {\n for (const be of node.boundaryEvents) {\n if ((be as NodeWithBpmn).bpmn?.type) {\n nodeTypeMap.set(be.id, (be as NodeWithBpmn).bpmn!.type!);\n }\n }\n }\n };\n\n // Collect node types from sizedGraph if provided\n if (sizedGraph) {\n for (const child of sizedGraph.children ?? []) {\n collectNodeTypes(child as NodeWithBpmn);\n }\n }\n\n const buildMaps = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (source && target) {\n if (!edgeMap.has(source)) {\n edgeMap.set(source, []);\n }\n edgeMap.get(source)!.push(target);\n\n if (!reverseEdgeMap.has(target)) {\n reverseEdgeMap.set(target, []);\n }\n reverseEdgeMap.get(target)!.push(source);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n buildMaps(child);\n }\n }\n };\n buildMaps(graph);\n\n return { nodeMap, nodeTypeMap, edgeMap, reverseEdgeMap };\n}\n\n/**\n * Identify nodes that need to be moved below their attached boundary event parent\n * Returns a map of node ID -> new position info\n */\nexport function identifyNodesToMove(\n graph: ElkNode,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n sizedGraph: ElkBpmnGraph,\n debug = false\n): Map<string, NodeMoveInfo> {\n const movedNodes = new Map<string, NodeMoveInfo>();\n const { nodeMap, nodeTypeMap, edgeMap, reverseEdgeMap } = buildNodeAndEdgeMaps(\n graph,\n sizedGraph\n );\n\n // Collect all boundary event target IDs (direct targets of boundary events)\n const boundaryEventTargetIds = new Set<string>();\n for (const [_beId, info] of boundaryEventInfo) {\n for (const targetId of info.targets) {\n boundaryEventTargetIds.add(targetId);\n }\n }\n\n // Helper to check if a node is a merge point (has incoming edges from non-boundary-event sources)\n const isMergePoint = (nodeId: string): boolean => {\n const incomingSources = reverseEdgeMap.get(nodeId) || [];\n if (incomingSources.length <= 1) return false;\n\n for (const sourceId of incomingSources) {\n if (!boundaryEventTargetIds.has(sourceId) && !movedNodes.has(sourceId)) {\n if (debug) {\n console.log(\n `[BPMN] isMergePoint(${nodeId}): true - source ${sourceId} is from main flow`\n );\n }\n return true;\n }\n }\n if (debug) {\n console.log(\n `[BPMN] isMergePoint(${nodeId}): false - all ${incomingSources.length} sources are boundary event branches`\n );\n }\n return false;\n };\n\n // Helper to trace a branch and determine its destination type\n const getBranchDestinationType = (startNodeId: string): BranchDestType => {\n const visited = new Set<string>();\n const queue = [startNodeId];\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n if (visited.has(nodeId)) continue;\n visited.add(nodeId);\n\n const node = nodeMap.get(nodeId);\n if (!node) continue;\n\n if (isMergePoint(nodeId)) {\n return BranchDestType.MERGE_TO_MAIN;\n }\n\n const outgoingTargets = edgeMap.get(nodeId) || [];\n\n if (outgoingTargets.length === 0) {\n const nodeType = nodeTypeMap.get(nodeId);\n if (nodeType === 'endEvent') {\n return BranchDestType.TO_END_EVENT;\n }\n return BranchDestType.DEAD_END;\n }\n\n for (const targetId of outgoingTargets) {\n if (!visited.has(targetId)) {\n if (isMergePoint(targetId)) {\n return BranchDestType.MERGE_TO_MAIN;\n }\n queue.push(targetId);\n }\n }\n }\n\n return BranchDestType.DEAD_END;\n };\n\n // Collect all boundary events with targets\n const boundaryEventsWithTargets: Array<{\n beId: string;\n info: BoundaryEventInfo;\n attachedNode: ElkNode;\n beX: number;\n attachedRight: number;\n destType: BranchDestType;\n }> = [];\n\n for (const [beId, info] of boundaryEventInfo) {\n if (info.targets.length === 0) continue;\n const attachedNode = nodeMap.get(info.attachedToRef);\n if (\n !attachedNode ||\n attachedNode.y === undefined ||\n attachedNode.height === undefined\n )\n continue;\n\n const attachedX = attachedNode.x ?? 0;\n const attachedWidth = attachedNode.width ?? 100;\n const attachedRight = attachedX + attachedWidth;\n const spacing = attachedWidth / (info.totalBoundaries + 1);\n const beX = attachedX + spacing * (info.boundaryIndex + 1);\n\n const destType =\n info.targets.length > 0\n ? getBranchDestinationType(info.targets[0])\n : BranchDestType.DEAD_END;\n\n boundaryEventsWithTargets.push({\n beId,\n info,\n attachedNode,\n beX,\n attachedRight,\n destType,\n });\n\n if (debug) {\n console.log(\n `[BPMN] Branch ${beId} -> ${info.targets[0]}: destType=${BranchDestType[destType]}`\n );\n }\n }\n\n // Sort boundary events by destination type, then by X position\n boundaryEventsWithTargets.sort((a, b) => {\n if (a.destType !== b.destType) {\n return a.destType - b.destType;\n }\n const xDiff = a.beX - b.beX;\n if (Math.abs(xDiff) > 1) return xDiff;\n return a.info.boundaryIndex - b.info.boundaryIndex;\n });\n\n // Find the global bottom Y of all attached nodes\n let mainFlowBottom = 0;\n for (const be of boundaryEventsWithTargets) {\n const attachedY = be.attachedNode.y ?? 0;\n const attachedHeight = be.attachedNode.height ?? 80;\n const attachedBottom = attachedY + attachedHeight;\n mainFlowBottom = Math.max(mainFlowBottom, attachedBottom);\n }\n\n // Layout constants\n const minGap = 35;\n const mergeToMainBaseY = mainFlowBottom + minGap + 50;\n const toEndEventBaseY = mergeToMainBaseY + 80;\n const deadEndBaseY = toEndEventBaseY + 100;\n const horizontalGap = 50;\n\n // Track placed branches\n const placedBranches: PlacedBranch[] = [];\n\n // Helper to calculate branch bounds\n const calculateBranchBounds = (\n targetId: string,\n newX: number\n ): { minX: number; maxX: number; height: number } => {\n const targetNode = nodeMap.get(targetId);\n const targetWidth = targetNode?.width ?? 100;\n const targetHeight = targetNode?.height ?? 80;\n\n let maxX = newX + targetWidth;\n let totalHeight = targetHeight;\n\n const visited = new Set<string>();\n const queue = [targetId];\n let currentMaxX = newX + targetWidth;\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n if (visited.has(nodeId)) continue;\n visited.add(nodeId);\n\n const downstreamTargets = edgeMap.get(nodeId) || [];\n for (const downId of downstreamTargets) {\n if (isMergePoint(downId)) continue;\n\n const downNode = nodeMap.get(downId);\n if (downNode && !visited.has(downId)) {\n const downWidth = downNode.width ?? 36;\n currentMaxX += 20 + downWidth;\n maxX = Math.max(maxX, currentMaxX);\n totalHeight = Math.max(totalHeight, downNode.height ?? 36);\n queue.push(downId);\n }\n }\n }\n\n return { minX: newX, maxX, height: totalHeight };\n };\n\n // Helper to check if X ranges overlap\n const xRangesOverlap = (\n minX1: number,\n maxX1: number,\n minX2: number,\n maxX2: number\n ): boolean => {\n return !(maxX1 + horizontalGap < minX2 || maxX2 + horizontalGap < minX1);\n };\n\n // Helper to get base Y for each destination type\n const getLayerBaseY = (destType: BranchDestType): number => {\n switch (destType) {\n case BranchDestType.MERGE_TO_MAIN:\n return mergeToMainBaseY;\n case BranchDestType.TO_END_EVENT:\n return toEndEventBaseY;\n case BranchDestType.DEAD_END:\n return deadEndBaseY;\n default:\n return deadEndBaseY;\n }\n };\n\n // Helper to find appropriate Y position for a new branch\n const findYPosition = (\n branchMinX: number,\n branchMaxX: number,\n branchHeight: number,\n destType: BranchDestType\n ): number => {\n const layerBaseY = getLayerBaseY(destType);\n let candidateY = layerBaseY;\n\n const overlappingBranches = placedBranches.filter((b) =>\n xRangesOverlap(branchMinX, branchMaxX, b.minX, b.maxX)\n );\n\n if (overlappingBranches.length === 0) {\n return candidateY;\n }\n\n for (const branch of overlappingBranches) {\n const requiredY = branch.maxY + minGap + 20;\n candidateY = Math.max(candidateY, requiredY);\n }\n\n return candidateY;\n };\n\n // Process all boundary events in sorted order\n for (const beEntry of boundaryEventsWithTargets) {\n const { info, beX, attachedRight, destType } = beEntry;\n\n if (debug) {\n console.log(\n `[BPMN] Processing boundary event at X=${beX} for ${info.attachedToRef}, destType=${BranchDestType[destType]}`\n );\n }\n\n for (const targetId of info.targets) {\n const targetNode = nodeMap.get(targetId);\n if (!targetNode || targetNode.y === undefined) continue;\n\n const targetWidth = targetNode.width ?? 100;\n const targetHeight = targetNode.height ?? 80;\n\n // Calculate new X position based on destination type\n let newX: number;\n if (destType === BranchDestType.MERGE_TO_MAIN) {\n newX = attachedRight + 30;\n } else if (destType === BranchDestType.TO_END_EVENT) {\n newX = beX + 20;\n } else {\n newX = beX;\n }\n\n // Calculate branch bounds\n const branchBounds = calculateBranchBounds(targetId, newX);\n\n // Find appropriate Y position\n const newY = findYPosition(\n branchBounds.minX,\n branchBounds.maxX,\n branchBounds.height,\n destType\n );\n const offset = newY - (targetNode.y ?? 0);\n movedNodes.set(targetId, { newY, offset, newX });\n\n if (debug) {\n console.log(\n `[BPMN] Moving ${targetId}: (${targetNode.x},${targetNode.y}) -> (${newX},${newY}), destType=${BranchDestType[destType]}`\n );\n }\n\n // Propagate movement to downstream nodes\n propagateMovement(\n targetId,\n newY,\n nodeMap,\n edgeMap,\n movedNodes,\n newX,\n isMergePoint,\n debug\n );\n\n // Register this branch\n placedBranches.push({\n minX: branchBounds.minX,\n maxX: branchBounds.maxX,\n minY: newY,\n maxY: newY + branchBounds.height,\n destType,\n });\n }\n }\n\n return movedNodes;\n}\n\n/**\n * Propagate movement to downstream nodes\n */\nexport function propagateMovement(\n sourceId: string,\n sourceNewY: number,\n nodeMap: Map<string, ElkNode>,\n edgeMap: Map<string, string[]>,\n movedNodes: Map<string, NodeMoveInfo>,\n sourceNewX?: number,\n isMergePoint?: (nodeId: string) => boolean,\n debug = false\n): void {\n const sourceNode = nodeMap.get(sourceId);\n const sourceWidth = sourceNode?.width ?? 100;\n const sourceHeight = sourceNode?.height ?? 80;\n\n const targets = edgeMap.get(sourceId) || [];\n for (const targetId of targets) {\n if (movedNodes.has(targetId)) {\n const existingMove = movedNodes.get(targetId)!;\n const currentSourceRight = (sourceNewX ?? 0) + sourceWidth + 20;\n\n if (\n existingMove.newX !== undefined &&\n currentSourceRight > existingMove.newX\n ) {\n existingMove.newX = currentSourceRight;\n if (debug) {\n console.log(\n `[BPMN] propagateMovement: updating ${targetId} X to ${currentSourceRight} (source is further right)`\n );\n }\n } else if (debug) {\n console.log(\n `[BPMN] propagateMovement: skipping ${targetId} - already moved`\n );\n }\n continue;\n }\n\n if (isMergePoint && isMergePoint(targetId)) {\n if (debug) {\n console.log(\n `[BPMN] propagateMovement: skipping ${targetId} - is merge point`\n );\n }\n continue;\n }\n\n const targetNode = nodeMap.get(targetId);\n if (!targetNode || targetNode.y === undefined) continue;\n\n const targetHeight = targetNode.height ?? 36;\n const newY = sourceNewY + (sourceHeight - targetHeight) / 2;\n const offset = newY - (targetNode.y ?? 0);\n\n let newX: number | undefined;\n if (sourceNewX !== undefined) {\n newX = sourceNewX + sourceWidth + 20;\n }\n\n movedNodes.set(targetId, { newY, offset, newX });\n\n if (debug) {\n console.log(\n `[BPMN] propagateMovement: moving ${targetId} to y=${newY}, newX=${newX}`\n );\n }\n\n propagateMovement(\n targetId,\n newY,\n nodeMap,\n edgeMap,\n movedNodes,\n newX,\n isMergePoint,\n debug\n );\n }\n}\n\n/**\n * Reposition converging gateways based on their incoming edges.\n */\nexport function repositionConvergingGateways(\n graph: ElkNode,\n movedNodes: Map<string, NodeMoveInfo>,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n debug = false\n): Map<string, NodeMoveInfo> {\n const gatewayMoves = new Map<string, NodeMoveInfo>();\n\n const nodeMap = new Map<string, ElkNode>();\n const reverseEdgeMap = new Map<string, string[]>();\n\n const buildMaps = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (source && target) {\n if (!reverseEdgeMap.has(target)) {\n reverseEdgeMap.set(target, []);\n }\n reverseEdgeMap.get(target)!.push(source);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n buildMaps(child);\n }\n }\n };\n buildMaps(graph);\n\n // Collect boundary event target IDs\n const boundaryEventTargetIds = new Set<string>();\n for (const [_beId, info] of boundaryEventInfo) {\n for (const targetId of info.targets) {\n boundaryEventTargetIds.add(targetId);\n }\n }\n\n // Find converging gateways\n for (const [nodeId, node] of nodeMap) {\n const incomingSources = reverseEdgeMap.get(nodeId) || [];\n if (incomingSources.length <= 1) continue;\n\n let hasMainFlowInput = false;\n let hasBoundaryBranchInput = false;\n\n for (const sourceId of incomingSources) {\n if (boundaryEventTargetIds.has(sourceId) || movedNodes.has(sourceId)) {\n hasBoundaryBranchInput = true;\n } else if (!sourceId.startsWith('boundary_')) {\n hasMainFlowInput = true;\n }\n }\n\n if (!hasMainFlowInput || !hasBoundaryBranchInput) continue;\n\n let maxSourceRightX = 0;\n for (const sourceId of incomingSources) {\n const sourceNode = nodeMap.get(sourceId);\n if (!sourceNode) continue;\n\n const moveInfo = movedNodes.get(sourceId);\n const sourceX = moveInfo?.newX ?? sourceNode.x ?? 0;\n const sourceWidth = sourceNode.width ?? 100;\n const sourceRightX = sourceX + sourceWidth;\n\n maxSourceRightX = Math.max(maxSourceRightX, sourceRightX);\n }\n\n const gatewayGap = 50;\n const newGatewayX = maxSourceRightX + gatewayGap;\n const currentGatewayX = node.x ?? 0;\n\n if (newGatewayX > currentGatewayX) {\n const currentY = node.y ?? 0;\n gatewayMoves.set(nodeId, {\n newY: currentY,\n offset: 0,\n newX: newGatewayX,\n });\n\n if (debug) {\n console.log(\n `[BPMN] Repositioning converging gateway ${nodeId}: x ${currentGatewayX} -> ${newGatewayX}`\n );\n }\n }\n }\n\n return gatewayMoves;\n}\n\n/**\n * Apply node moves to the layouted graph\n */\nexport function applyNodeMoves(\n graph: ElkNode,\n movedNodes: Map<string, NodeMoveInfo>\n): void {\n const applyMoves = (node: ElkNode) => {\n const moveInfo = movedNodes.get(node.id);\n if (moveInfo && node.y !== undefined) {\n node.y = moveInfo.newY;\n if (moveInfo.newX !== undefined) {\n node.x = moveInfo.newX;\n }\n }\n if (node.children) {\n for (const child of node.children) {\n applyMoves(child);\n }\n }\n };\n applyMoves(graph);\n}\n","/**\n * Edge Recalculator for Boundary Events\n * Handles edge waypoint recalculation for moved boundary event nodes.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { Point, Bounds, BoundaryEventInfo, NodeMoveInfo } from '../../../types/internal';\n\n/**\n * Recalculate edge waypoints for edges connected to moved nodes\n * Implements orthogonal routing with obstacle avoidance\n */\nexport function recalculateEdgesForMovedNodes(\n graph: ElkNode,\n movedNodes: Map<string, NodeMoveInfo>,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n debug = false\n): void {\n // Build node map for position lookups (including boundary events)\n const nodeMap = new Map<string, ElkNode>();\n const buildNodeMap = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.children) {\n for (const child of node.children) {\n buildNodeMap(child);\n }\n }\n // Also include boundary events\n const nodeWithBE = node as unknown as { boundaryEvents?: ElkNode[] };\n if (nodeWithBE.boundaryEvents) {\n for (const be of nodeWithBE.boundaryEvents) {\n nodeMap.set(be.id, be);\n }\n }\n };\n buildNodeMap(graph);\n\n // Get all obstacle IDs: attached nodes + all moved nodes\n const obstacleIds = new Set<string>();\n for (const [, info] of boundaryEventInfo) {\n obstacleIds.add(info.attachedToRef);\n }\n // Add all moved nodes as obstacles (they may block edge paths)\n for (const [nodeId] of movedNodes) {\n obstacleIds.add(nodeId);\n }\n\n // Calculate correct boundary event positions (they are attached to the bottom of their parent)\n const boundaryEventPositions = new Map<string, Bounds>();\n for (const [beId, info] of boundaryEventInfo) {\n const attachedNode = nodeMap.get(info.attachedToRef);\n if (attachedNode && attachedNode.x !== undefined && attachedNode.y !== undefined) {\n const attachedX = attachedNode.x;\n const attachedY = attachedNode.y;\n const attachedWidth = attachedNode.width ?? 100;\n const attachedHeight = attachedNode.height ?? 80;\n const beWidth = 36;\n const beHeight = 36;\n\n // Calculate position on the bottom edge of the attached node\n const spacing = attachedWidth / (info.totalBoundaries + 1);\n const beX = attachedX + spacing * (info.boundaryIndex + 1) - beWidth / 2;\n const beY = attachedY + attachedHeight - beHeight / 2;\n\n boundaryEventPositions.set(beId, { x: beX, y: beY, width: beWidth, height: beHeight });\n }\n }\n\n // Find and recalculate edges in each node\n const processEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n if (!sourceId || !targetId) continue;\n\n // Recalculate if source OR target was moved, OR source is a boundary event\n const sourceMoved = movedNodes.has(sourceId);\n const targetMoved = movedNodes.has(targetId);\n const sourceIsBoundaryEvent = boundaryEventInfo.has(sourceId);\n\n if (sourceMoved || targetMoved || sourceIsBoundaryEvent) {\n let sourceNode = nodeMap.get(sourceId);\n const targetNode = nodeMap.get(targetId);\n\n // For boundary events, use the calculated position\n if (sourceIsBoundaryEvent && boundaryEventPositions.has(sourceId)) {\n const bePos = boundaryEventPositions.get(sourceId)!;\n sourceNode = { ...sourceNode, ...bePos } as ElkNode;\n }\n\n if (sourceNode && targetNode) {\n recalculateEdgeWithObstacleAvoidance(\n edge,\n sourceNode,\n targetNode,\n obstacleIds,\n nodeMap,\n debug\n );\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n processEdges(child);\n }\n }\n };\n processEdges(graph);\n}\n\n/**\n * Recalculate edge waypoints with orthogonal routing that avoids obstacles.\n * Key constraints:\n * 1. Edges MUST connect perpendicular to node boundaries\n * 2. Edges MUST NOT pass through any node\n */\nexport function recalculateEdgeWithObstacleAvoidance(\n edge: ElkExtendedEdge,\n source: ElkNode,\n target: ElkNode,\n obstacleIds: Set<string>,\n nodeMap: Map<string, ElkNode>,\n debug = false\n): void {\n const sx = source.x ?? 0;\n const sy = source.y ?? 0;\n const sw = source.width ?? 100;\n const sh = source.height ?? 80;\n\n const tx = target.x ?? 0;\n const ty = target.y ?? 0;\n const tw = target.width ?? 36;\n const th = target.height ?? 36;\n\n // Collect all obstacles (excluding source and target)\n const obstacles: Bounds[] = [];\n for (const obsId of obstacleIds) {\n const obs = nodeMap.get(obsId);\n if (obs && obs.x !== undefined && obs.y !== undefined) {\n // Skip source and target\n if (obs.x === sx && obs.y === sy) continue;\n if (obs.x === tx && obs.y === ty) continue;\n obstacles.push({\n x: obs.x,\n y: obs.y,\n width: obs.width ?? 100,\n height: obs.height ?? 80,\n });\n }\n }\n\n if (debug) {\n console.log(\n `[BPMN] Edge ${edge.id}: source(${sx},${sy},${sw},${sh}) -> target(${tx},${ty},${tw},${th}), obstacles: ${obstacles.length}`\n );\n }\n\n // Determine primary direction of travel\n const dx = tx - sx;\n const dy = ty - sy;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n const isPrimarilyVertical = absDy > absDx;\n\n const waypoints: Point[] = [];\n\n if (isPrimarilyVertical && dy > 0) {\n // Primary direction is DOWN - exit from bottom, enter from top\n const startX = sx + sw / 2;\n const startY = sy + sh;\n const endX = tx + tw / 2;\n const endY = ty;\n\n waypoints.push({ x: startX, y: startY });\n\n // Check for obstacles that would block a direct vertical path\n const obstaclesToAvoid = findBlockingObstacles(\n startX,\n startY,\n endX,\n endY,\n obstacles,\n 'vertical'\n );\n\n if (obstaclesToAvoid.length > 0) {\n // Calculate left routing X\n let leftAvoidX = Math.min(startX, endX);\n for (const obs of obstaclesToAvoid) {\n leftAvoidX = Math.min(leftAvoidX, obs.x - 30);\n }\n for (const obs of obstacles) {\n if (obs.y < endY && obs.y + obs.height > startY) {\n if (obs.x <= leftAvoidX + 20 && obs.x + obs.width >= leftAvoidX - 20) {\n leftAvoidX = Math.min(leftAvoidX, obs.x - 30);\n }\n }\n }\n\n // Calculate right routing X\n let rightAvoidX = Math.max(startX, endX);\n for (const obs of obstaclesToAvoid) {\n rightAvoidX = Math.max(rightAvoidX, obs.x + obs.width + 30);\n }\n for (const obs of obstacles) {\n if (obs.y < endY && obs.y + obs.height > startY) {\n if (obs.x <= rightAvoidX + 20 && obs.x + obs.width >= rightAvoidX - 20) {\n rightAvoidX = Math.max(rightAvoidX, obs.x + obs.width + 30);\n }\n }\n }\n\n // Choose the shorter detour\n const leftDistance = Math.abs(startX - leftAvoidX) + Math.abs(endX - leftAvoidX);\n const rightDistance = Math.abs(startX - rightAvoidX) + Math.abs(endX - rightAvoidX);\n const avoidX = leftDistance <= rightDistance ? leftAvoidX : rightAvoidX;\n\n const exitY = startY + 20;\n waypoints.push({ x: startX, y: exitY });\n waypoints.push({ x: avoidX, y: exitY });\n waypoints.push({ x: avoidX, y: endY - 20 });\n waypoints.push({ x: endX, y: endY - 20 });\n } else {\n // No obstacles - simple Z-routing\n const midY = (startY + endY) / 2;\n waypoints.push({ x: startX, y: midY });\n waypoints.push({ x: endX, y: midY });\n }\n\n waypoints.push({ x: endX, y: endY });\n } else if (isPrimarilyVertical && dy < 0) {\n // Primary direction is UP - exit from right, enter from bottom\n const startX = sx + sw;\n const startY = sy + sh / 2;\n const endX = tx + tw / 2;\n const endY = ty + th;\n\n waypoints.push({ x: startX, y: startY });\n\n let clearX = Math.max(sx + sw, tx + tw) + 30;\n for (const obs of obstacles) {\n if (obs.y < sy && obs.y + obs.height > ty) {\n clearX = Math.max(clearX, obs.x + obs.width + 30);\n }\n }\n\n waypoints.push({ x: clearX, y: startY });\n waypoints.push({ x: clearX, y: endY });\n waypoints.push({ x: endX, y: endY });\n } else if (!isPrimarilyVertical && dx > 0) {\n // Primary direction is RIGHT - exit from right, enter from left\n const startX = sx + sw;\n const startY = sy + sh / 2;\n const endX = tx;\n const endY = ty + th / 2;\n\n waypoints.push({ x: startX, y: startY });\n\n const obstaclesToAvoid = findBlockingObstacles(\n startX,\n startY,\n endX,\n endY,\n obstacles,\n 'horizontal'\n );\n\n if (obstaclesToAvoid.length > 0) {\n let clearY = Math.max(sy + sh, ty + th) + 30;\n for (const obs of obstaclesToAvoid) {\n clearY = Math.max(clearY, obs.y + obs.height + 30);\n }\n\n waypoints.push({ x: startX + 20, y: startY });\n waypoints.push({ x: startX + 20, y: clearY });\n waypoints.push({ x: endX - 20, y: clearY });\n waypoints.push({ x: endX - 20, y: endY });\n } else {\n // Simple Z-routing\n const midX = (startX + endX) / 2;\n waypoints.push({ x: midX, y: startY });\n waypoints.push({ x: midX, y: endY });\n }\n\n waypoints.push({ x: endX, y: endY });\n } else {\n // Primary direction is LEFT - exit from left, enter from right\n const startX = sx;\n const startY = sy + sh / 2;\n const endX = tx + tw;\n const endY = ty + th / 2;\n\n waypoints.push({ x: startX, y: startY });\n\n let clearX = Math.min(sx, tx) - 30;\n for (const obs of obstacles) {\n clearX = Math.min(clearX, obs.x - 30);\n }\n\n waypoints.push({ x: clearX, y: startY });\n waypoints.push({ x: clearX, y: endY });\n waypoints.push({ x: endX, y: endY });\n }\n\n // Update edge sections\n const firstWaypoint = waypoints[0];\n const lastWaypoint = waypoints[waypoints.length - 1];\n if (waypoints.length >= 2 && firstWaypoint && lastWaypoint) {\n edge.sections = [\n {\n id: `${edge.id}_section_0`,\n startPoint: firstWaypoint,\n endPoint: lastWaypoint,\n bendPoints: waypoints.slice(1, -1),\n },\n ];\n\n if (debug) {\n console.log(`[BPMN] Waypoints for ${edge.id}: ${JSON.stringify(waypoints)}`);\n }\n }\n}\n\n/**\n * Find obstacles that block a path between two points\n */\nexport function findBlockingObstacles(\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n obstacles: Bounds[],\n direction: 'vertical' | 'horizontal'\n): Bounds[] {\n const blocking: Bounds[] = [];\n const margin = 5;\n\n for (const obs of obstacles) {\n const obsRight = obs.x + obs.width;\n const obsBottom = obs.y + obs.height;\n\n if (direction === 'vertical') {\n const pathMinX = Math.min(startX, endX) - margin;\n const pathMaxX = Math.max(startX, endX) + margin;\n const pathMinY = Math.min(startY, endY);\n const pathMaxY = Math.max(startY, endY);\n\n if (obs.y < pathMaxY && obsBottom > pathMinY) {\n if (obs.x < pathMaxX && obsRight > pathMinX) {\n blocking.push(obs);\n }\n }\n } else {\n const pathMinX = Math.min(startX, endX);\n const pathMaxX = Math.max(startX, endX);\n const pathMinY = Math.min(startY, endY) - margin;\n const pathMaxY = Math.max(startY, endY) + margin;\n\n if (obs.x < pathMaxX && obsRight > pathMinX) {\n if (obs.y < pathMaxY && obsBottom > pathMinY) {\n blocking.push(obs);\n }\n }\n }\n }\n\n return blocking;\n}\n","/**\n * Boundary Event Post-Processing Module\n * Re-exports all boundary event related functionality.\n */\n\nimport type { ElkNode } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../../types';\nimport type { BoundaryEventInfo, NodeMoveInfo } from '../../../types/internal';\n\n// Export collector function\nexport { collectBoundaryEventInfo } from './collector';\n\n// Export mover functions\nexport {\n identifyNodesToMove,\n repositionConvergingGateways,\n applyNodeMoves,\n propagateMovement,\n BranchDestType,\n} from './mover';\n\n// Export edge recalculator functions\nexport {\n recalculateEdgesForMovedNodes,\n recalculateEdgeWithObstacleAvoidance,\n findBlockingObstacles,\n} from './edge-recalculator';\n\n// Import for class implementation\nimport { collectBoundaryEventInfo } from './collector';\nimport {\n identifyNodesToMove,\n repositionConvergingGateways,\n applyNodeMoves,\n} from './mover';\nimport { recalculateEdgesForMovedNodes } from './edge-recalculator';\n\n/**\n * Handler for boundary event post-processing\n * Wraps the extracted functions in a class interface for backward compatibility.\n */\nexport class BoundaryEventHandler {\n /**\n * Collect boundary event information for post-processing\n * Returns a map of boundary event ID -> { attachedToRef, targets, boundaryIndex, totalBoundaries }\n */\n collectInfo(graph: ElkBpmnGraph): Map<string, BoundaryEventInfo> {\n return collectBoundaryEventInfo(graph);\n }\n\n /**\n * Identify nodes that need to be moved below their attached boundary event parent\n * Returns a map of node ID -> new position info\n */\n identifyNodesToMove(\n graph: ElkNode,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n sizedGraph: ElkBpmnGraph,\n debug = false\n ): Map<string, NodeMoveInfo> {\n return identifyNodesToMove(graph, boundaryEventInfo, sizedGraph, debug);\n }\n\n /**\n * Reposition converging gateways based on their incoming edges.\n */\n repositionConvergingGateways(\n graph: ElkNode,\n movedNodes: Map<string, NodeMoveInfo>,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n debug = false\n ): Map<string, NodeMoveInfo> {\n return repositionConvergingGateways(graph, movedNodes, boundaryEventInfo, debug);\n }\n\n /**\n * Apply node moves to the layouted graph\n */\n applyNodeMoves(graph: ElkNode, movedNodes: Map<string, NodeMoveInfo>): void {\n applyNodeMoves(graph, movedNodes);\n }\n\n /**\n * Recalculate edge waypoints for edges connected to moved nodes\n */\n recalculateEdgesForMovedNodes(\n graph: ElkNode,\n movedNodes: Map<string, NodeMoveInfo>,\n boundaryEventInfo: Map<string, BoundaryEventInfo>,\n debug = false\n ): void {\n recalculateEdgesForMovedNodes(graph, movedNodes, boundaryEventInfo, debug);\n }\n}\n","/**\n * BPMN Constants and Mappings\n */\n\n// ============================================================================\n// Default Element Sizes\n// ============================================================================\n\nexport const DEFAULT_SIZES = {\n // Events (all types)\n EVENT: { width: 36, height: 36 },\n\n // Tasks (all types)\n TASK: { width: 100, height: 80 },\n TASK_WIDE: { width: 120, height: 80 },\n TASK_WIDER: { width: 150, height: 80 },\n\n // Gateways (all types)\n GATEWAY: { width: 50, height: 50 },\n\n // SubProcesses\n SUBPROCESS_COLLAPSED: { width: 100, height: 80 },\n SUBPROCESS_EXPANDED_MIN: { width: 300, height: 200 },\n\n // Data Objects\n DATA_OBJECT: { width: 36, height: 50 },\n DATA_STORE: { width: 50, height: 50 },\n\n // Text Annotation\n TEXT_ANNOTATION: { width: 100, height: 30 },\n} as const;\n\n// ============================================================================\n// BPMN Element Type to XML Element Mapping\n// ============================================================================\n\nexport const BPMN_ELEMENT_MAP = {\n // Events (bpmn-moddle uses PascalCase)\n startEvent: 'bpmn:StartEvent',\n endEvent: 'bpmn:EndEvent',\n intermediateCatchEvent: 'bpmn:IntermediateCatchEvent',\n intermediateThrowEvent: 'bpmn:IntermediateThrowEvent',\n boundaryEvent: 'bpmn:BoundaryEvent',\n\n // Tasks\n task: 'bpmn:Task',\n userTask: 'bpmn:UserTask',\n serviceTask: 'bpmn:ServiceTask',\n scriptTask: 'bpmn:ScriptTask',\n businessRuleTask: 'bpmn:BusinessRuleTask',\n sendTask: 'bpmn:SendTask',\n receiveTask: 'bpmn:ReceiveTask',\n manualTask: 'bpmn:ManualTask',\n\n // Gateways\n exclusiveGateway: 'bpmn:ExclusiveGateway',\n parallelGateway: 'bpmn:ParallelGateway',\n inclusiveGateway: 'bpmn:InclusiveGateway',\n eventBasedGateway: 'bpmn:EventBasedGateway',\n complexGateway: 'bpmn:ComplexGateway',\n\n // SubProcesses\n subProcess: 'bpmn:SubProcess',\n transaction: 'bpmn:Transaction',\n adHocSubProcess: 'bpmn:AdHocSubProcess',\n eventSubProcess: 'bpmn:SubProcess', // Same element, different attribute\n\n // Call Activity\n callActivity: 'bpmn:CallActivity',\n\n // Artifacts\n dataObject: 'bpmn:DataObject',\n dataObjectReference: 'bpmn:DataObjectReference',\n dataInput: 'bpmn:DataInput',\n dataOutput: 'bpmn:DataOutput',\n dataStoreReference: 'bpmn:DataStoreReference',\n textAnnotation: 'bpmn:TextAnnotation',\n group: 'bpmn:Group',\n\n // Flows\n sequenceFlow: 'bpmn:SequenceFlow',\n messageFlow: 'bpmn:MessageFlow',\n dataInputAssociation: 'bpmn:DataInputAssociation',\n dataOutputAssociation: 'bpmn:DataOutputAssociation',\n association: 'bpmn:Association',\n\n // Containers\n collaboration: 'bpmn:Collaboration',\n participant: 'bpmn:Participant',\n process: 'bpmn:Process',\n lane: 'bpmn:Lane',\n laneSet: 'bpmn:LaneSet',\n} as const;\n\n// ============================================================================\n// Event Definition Type to XML Element Mapping\n// ============================================================================\n\nexport const EVENT_DEFINITION_MAP = {\n none: null,\n message: 'bpmn:MessageEventDefinition',\n timer: 'bpmn:TimerEventDefinition',\n error: 'bpmn:ErrorEventDefinition',\n escalation: 'bpmn:EscalationEventDefinition',\n cancel: 'bpmn:CancelEventDefinition',\n compensation: 'bpmn:CompensateEventDefinition',\n conditional: 'bpmn:ConditionalEventDefinition',\n link: 'bpmn:LinkEventDefinition',\n signal: 'bpmn:SignalEventDefinition',\n terminate: 'bpmn:TerminateEventDefinition',\n multiple: null, // Multiple event definitions\n parallelMultiple: null, // Multiple parallel event definitions\n} as const;\n\n// ============================================================================\n// BPMN XML Namespaces\n// ============================================================================\n\nexport const BPMN_NAMESPACES = {\n bpmn: 'http://www.omg.org/spec/BPMN/20100524/MODEL',\n bpmndi: 'http://www.omg.org/spec/BPMN/20100524/DI',\n dc: 'http://www.omg.org/spec/DD/20100524/DC',\n di: 'http://www.omg.org/spec/DD/20100524/DI',\n xsi: 'http://www.w3.org/2001/XMLSchema-instance',\n camunda: 'http://camunda.org/schema/1.0/bpmn',\n} as const;\n\n// ============================================================================\n// Default ELK Layout Options\n// ============================================================================\n\nexport const DEFAULT_ELK_OPTIONS = {\n 'elk.algorithm': 'layered',\n 'elk.direction': 'RIGHT',\n 'elk.spacing.nodeNode': 50,\n 'elk.spacing.edgeNode': 30,\n 'elk.spacing.edgeEdge': 20,\n 'elk.layered.spacing.nodeNodeBetweenLayers': 80,\n 'elk.layered.spacing.edgeNodeBetweenLayers': 30,\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n 'elk.layered.crossingMinimization.strategy': 'LAYER_SWEEP',\n 'elk.edgeRouting': 'ORTHOGONAL',\n} as const;\n\n// ============================================================================\n// Element Categories\n// ============================================================================\n\nexport const EVENT_TYPES = [\n 'startEvent',\n 'endEvent',\n 'intermediateCatchEvent',\n 'intermediateThrowEvent',\n 'boundaryEvent',\n] as const;\n\nexport const TASK_TYPES = [\n 'task',\n 'userTask',\n 'serviceTask',\n 'scriptTask',\n 'businessRuleTask',\n 'sendTask',\n 'receiveTask',\n 'manualTask',\n] as const;\n\nexport const GATEWAY_TYPES = [\n 'exclusiveGateway',\n 'parallelGateway',\n 'inclusiveGateway',\n 'eventBasedGateway',\n 'complexGateway',\n] as const;\n\nexport const SUBPROCESS_TYPES = [\n 'subProcess',\n 'transaction',\n 'adHocSubProcess',\n 'eventSubProcess',\n] as const;\n\nexport const ARTIFACT_TYPES = [\n 'dataObject',\n 'dataObjectReference',\n 'dataInput',\n 'dataOutput',\n 'dataStoreReference',\n 'textAnnotation',\n 'group',\n] as const;\n\n/**\n * Group element type constant\n */\nexport const GROUP_TYPE = 'group';\n\n/**\n * Set of artifact types for efficient lookup in layout processing.\n * Note: Excludes 'group' because groups are handled separately by GroupPositioner.\n */\nexport const ARTIFACT_TYPES_SET = new Set([\n 'dataObject',\n 'dataObjectReference',\n 'dataStoreReference',\n 'dataInput',\n 'dataOutput',\n 'textAnnotation',\n]);\n\nexport const FLOW_TYPES = [\n 'sequenceFlow',\n 'messageFlow',\n 'dataInputAssociation',\n 'dataOutputAssociation',\n 'association',\n] as const;\n\n// ============================================================================\n// Type Helpers\n// ============================================================================\n\nexport type EventTypeString = (typeof EVENT_TYPES)[number];\nexport type TaskTypeString = (typeof TASK_TYPES)[number];\nexport type GatewayTypeString = (typeof GATEWAY_TYPES)[number];\nexport type SubProcessTypeString = (typeof SUBPROCESS_TYPES)[number];\nexport type ArtifactTypeString = (typeof ARTIFACT_TYPES)[number];\nexport type FlowTypeString = (typeof FLOW_TYPES)[number];\nexport type BpmnElementType = keyof typeof BPMN_ELEMENT_MAP;\n","/**\n * Node Map Builder Utility\n * Provides shared functions for building node maps from ELK graphs.\n * Used by various post-processors to efficiently look up nodes by ID.\n */\n\nimport type { ElkNode } from 'elkjs';\n\n/**\n * Build a flat map of all nodes in the graph, keyed by ID.\n * Recursively traverses the graph to include all nested nodes.\n *\n * @param graph - The root ELK graph node\n * @returns A Map from node ID to ElkNode\n */\nexport function buildNodeMap(graph: ElkNode): Map<string, ElkNode> {\n const nodeMap = new Map<string, ElkNode>();\n\n const traverse = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.children) {\n for (const child of node.children) {\n traverse(child);\n }\n }\n };\n\n traverse(graph);\n return nodeMap;\n}\n\n/**\n * Build a map of nodes with their parent references.\n * Useful when you need to know the parent of each node.\n *\n * @param graph - The root ELK graph node\n * @returns A tuple of [nodeMap, parentMap] where parentMap maps node ID to parent node\n */\nexport function buildNodeMapWithParents(\n graph: ElkNode\n): [Map<string, ElkNode>, Map<string, ElkNode>] {\n const nodeMap = new Map<string, ElkNode>();\n const parentMap = new Map<string, ElkNode>();\n\n const traverse = (node: ElkNode, parent?: ElkNode) => {\n nodeMap.set(node.id, node);\n if (parent) {\n parentMap.set(node.id, parent);\n }\n if (node.children) {\n for (const child of node.children) {\n traverse(child, node);\n }\n }\n };\n\n traverse(graph);\n return [nodeMap, parentMap];\n}\n\n/**\n * Build a map of nodes with accumulated absolute offsets.\n * Useful when you need absolute coordinates for nodes in nested containers.\n *\n * @param graph - The root ELK graph node\n * @param isContainer - Function to determine if a node is a container (adds offset)\n * @returns A Map from node ID to { node, offsetX, offsetY }\n */\nexport function buildNodeMapWithOffsets(\n graph: ElkNode,\n isContainer: (node: ElkNode) => boolean\n): Map<string, { node: ElkNode; offsetX: number; offsetY: number }> {\n const nodeMap = new Map<string, { node: ElkNode; offsetX: number; offsetY: number }>();\n\n const traverse = (node: ElkNode, offsetX: number, offsetY: number) => {\n nodeMap.set(node.id, { node, offsetX, offsetY });\n\n if (node.children) {\n // Calculate new offset for children\n const addOffset = isContainer(node);\n const newOffsetX = addOffset ? offsetX + (node.x ?? 0) : offsetX;\n const newOffsetY = addOffset ? offsetY + (node.y ?? 0) : offsetY;\n\n for (const child of node.children) {\n traverse(child, newOffsetX, newOffsetY);\n }\n }\n };\n\n traverse(graph, 0, 0);\n return nodeMap;\n}\n\n/**\n * Build a map of node absolute positions.\n * Calculates absolute x, y coordinates for each node.\n *\n * @param graph - The root ELK graph node\n * @param isContainer - Function to determine if a node is a container\n * @returns A Map from node ID to { x, y, width, height } in absolute coordinates\n */\nexport function buildAbsolutePositionMap(\n graph: ElkNode,\n isContainer: (node: ElkNode) => boolean\n): Map<string, { x: number; y: number; width: number; height: number }> {\n const positionMap = new Map<string, { x: number; y: number; width: number; height: number }>();\n\n const traverse = (node: ElkNode, offsetX: number, offsetY: number) => {\n const absX = offsetX + (node.x ?? 0);\n const absY = offsetY + (node.y ?? 0);\n\n positionMap.set(node.id, {\n x: absX,\n y: absY,\n width: node.width ?? 0,\n height: node.height ?? 0,\n });\n\n if (node.children) {\n // Calculate new offset for children\n const addOffset = isContainer(node);\n const newOffsetX = addOffset ? absX : offsetX;\n const newOffsetY = addOffset ? absY : offsetY;\n\n for (const child of node.children) {\n traverse(child, newOffsetX, newOffsetY);\n }\n }\n };\n\n traverse(graph, 0, 0);\n return positionMap;\n}\n","/**\n * Artifact Positioner\n * Handles repositioning of BPMN artifacts (data objects, data stores, annotations)\n * to be positioned above/near their associated tasks.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { Point, Bounds, NodeWithBpmn, ArtifactInfo, Obstacle } from '../../types/internal';\nimport {\n segmentIntersectsRect,\n scoreRoute,\n findClearVerticalPath,\n} from '../edge-routing/geometry-utils';\nimport { ARTIFACT_TYPES_SET } from '../../types/bpmn-constants';\nimport { buildNodeMap } from '../../utils/node-map-builder';\n\n/**\n * Artifact types that should be repositioned above their associated tasks\n * @deprecated Use ARTIFACT_TYPES_SET from bpmn-constants instead\n */\nexport const ARTIFACT_TYPES = ARTIFACT_TYPES_SET;\n\n/**\n * Handler for artifact repositioning\n */\nexport class ArtifactPositioner {\n /**\n * Collect artifact information for post-processing\n * Returns a map of artifact ID -> { associatedTaskId, isInput }\n */\n collectInfo(graph: ElkBpmnGraph): Map<string, ArtifactInfo> {\n const info = new Map<string, ArtifactInfo>();\n\n const collectFromNode = (node: NodeWithBpmn) => {\n // Build a set of artifact IDs in this node\n const artifactIds = new Set<string>();\n if (node.children) {\n for (const child of node.children) {\n const childNode = child as NodeWithBpmn;\n if (childNode.bpmn && ARTIFACT_TYPES.has(childNode.bpmn.type)) {\n artifactIds.add(childNode.id);\n }\n }\n }\n\n // Find associations between artifacts and tasks from edges\n if (node.edges) {\n for (const edge of node.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n const edgeType = edge.bpmn?.type;\n\n if (!sourceId || !targetId) continue;\n\n // Skip artifact-to-artifact associations (e.g., between two dataStores)\n // These should not be used for positioning\n if (artifactIds.has(sourceId) && artifactIds.has(targetId)) {\n continue;\n }\n\n // Data input association: artifact -> task\n if (edgeType === 'dataInputAssociation' || edgeType === 'association') {\n if (artifactIds.has(sourceId)) {\n info.set(sourceId, { associatedTaskId: targetId, isInput: true });\n }\n }\n // Data output association: task -> artifact\n if (edgeType === 'dataOutputAssociation') {\n if (artifactIds.has(targetId)) {\n info.set(targetId, { associatedTaskId: sourceId, isInput: false });\n }\n }\n }\n }\n\n // Recurse into children\n if (node.children) {\n for (const child of node.children) {\n collectFromNode(child as NodeWithBpmn);\n }\n }\n };\n\n for (const child of graph.children ?? []) {\n collectFromNode(child as NodeWithBpmn);\n }\n\n return info;\n }\n\n /**\n * Reposition artifacts to be above their associated tasks\n */\n reposition(graph: ElkNode, artifactInfo: Map<string, ArtifactInfo>): void {\n // Build node map\n const nodeMap = buildNodeMap(graph);\n\n // Track horizontal offset for each task (for multiple artifacts)\n const taskInputOffsets = new Map<string, number>();\n const taskOutputOffsets = new Map<string, number>();\n\n // Reposition each artifact\n for (const [artifactId, info] of artifactInfo) {\n const artifactNode = nodeMap.get(artifactId);\n const taskNode = nodeMap.get(info.associatedTaskId);\n\n if (!artifactNode || !taskNode) continue;\n if (taskNode.x === undefined || taskNode.y === undefined) continue;\n\n const artifactWidth = artifactNode.width ?? 36;\n const artifactHeight = artifactNode.height ?? 50;\n const taskWidth = taskNode.width ?? 100;\n\n // Position artifact above the task\n // Input artifacts on the left, output artifacts on the right\n let newX: number;\n if (info.isInput) {\n const currentOffset = taskInputOffsets.get(info.associatedTaskId) ?? 0;\n newX = taskNode.x + currentOffset;\n taskInputOffsets.set(info.associatedTaskId, currentOffset + artifactWidth + 15);\n } else {\n const currentOffset = taskOutputOffsets.get(info.associatedTaskId) ?? 0;\n newX = taskNode.x + taskWidth + 15 + currentOffset; // Position to the right of task\n taskOutputOffsets.set(info.associatedTaskId, currentOffset + artifactWidth + 15);\n }\n const newY = taskNode.y - artifactHeight - 20; // 20px gap above task\n\n artifactNode.x = newX;\n artifactNode.y = newY;\n }\n\n // Recalculate edges for repositioned artifacts\n this.recalculateEdges(graph, artifactInfo, nodeMap);\n }\n\n /**\n * Recalculate edges connected to repositioned artifacts\n */\n private recalculateEdges(\n graph: ElkNode,\n artifactInfo: Map<string, ArtifactInfo>,\n nodeMap: Map<string, ElkNode>\n ): void {\n const processEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n if (!sourceId || !targetId) continue;\n\n // Check if this edge involves an artifact\n const sourceIsArtifact = artifactInfo.has(sourceId);\n const targetIsArtifact = artifactInfo.has(targetId);\n\n if (sourceIsArtifact || targetIsArtifact) {\n const sourceNode = nodeMap.get(sourceId);\n const targetNode = nodeMap.get(targetId);\n\n if (sourceNode && targetNode) {\n this.recalculateArtifactEdge(edge, sourceNode, targetNode, sourceIsArtifact);\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n processEdges(child);\n }\n }\n };\n processEdges(graph);\n }\n\n /**\n * Recalculate a single artifact edge (simple version)\n */\n private recalculateArtifactEdge(\n edge: ElkExtendedEdge,\n source: ElkNode,\n target: ElkNode,\n sourceIsArtifact: boolean\n ): void {\n const sx = source.x ?? 0;\n const sy = source.y ?? 0;\n const sw = source.width ?? 36;\n const sh = source.height ?? 50;\n\n const tx = target.x ?? 0;\n const ty = target.y ?? 0;\n const tw = target.width ?? 100;\n const th = target.height ?? 80;\n\n let startPoint: Point;\n let endPoint: Point;\n\n if (sourceIsArtifact) {\n // Artifact -> Task (input): artifact is above/left of task\n // Start from bottom of artifact, end at top of task\n startPoint = { x: sx + sw / 2, y: sy + sh };\n endPoint = { x: Math.min(Math.max(sx + sw / 2, tx), tx + tw), y: ty };\n } else {\n // Task -> Artifact (output): artifact is above/right of task\n // Start from top-right of task, end at bottom of artifact\n const artifactCenterX = tx + tw / 2;\n startPoint = { x: Math.min(sx + sw, artifactCenterX), y: sy };\n endPoint = { x: artifactCenterX, y: ty + th };\n }\n\n edge.sections = [{\n id: `${edge.id}_section_0`,\n startPoint,\n endPoint,\n bendPoints: [],\n }];\n }\n\n /**\n * Recalculate artifact edges with obstacle avoidance\n * Implements orthogonal routing that avoids crossing other elements\n */\n recalculateWithObstacleAvoidance(\n graph: ElkNode,\n artifactInfo: Map<string, ArtifactInfo>\n ): void {\n // Build node map for position lookups\n const nodeMap = buildNodeMap(graph);\n\n // Collect all obstacles (non-artifact nodes)\n const obstacles: Obstacle[] = [];\n const collectObstacles = (node: ElkNode) => {\n if (node.x !== undefined && node.y !== undefined && !artifactInfo.has(node.id)) {\n // Skip groups (they're just visual overlays)\n const isGroup = node.id.includes('group');\n if (!isGroup) {\n obstacles.push({\n id: node.id,\n x: node.x,\n y: node.y,\n width: node.width ?? 100,\n height: node.height ?? 80,\n });\n }\n }\n if (node.children) {\n for (const child of node.children) {\n collectObstacles(child);\n }\n }\n };\n collectObstacles(graph);\n\n // Process edges\n const processEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n if (!sourceId || !targetId) continue;\n\n // Check if this edge involves an artifact\n const sourceIsArtifact = artifactInfo.has(sourceId);\n const targetIsArtifact = artifactInfo.has(targetId);\n\n if (sourceIsArtifact || targetIsArtifact) {\n const sourceNode = nodeMap.get(sourceId);\n const targetNode = nodeMap.get(targetId);\n\n if (sourceNode && targetNode) {\n this.recalculateEdgeWithObstacles(\n edge,\n sourceNode,\n targetNode,\n sourceIsArtifact,\n obstacles.filter(o => o.id !== sourceId && o.id !== targetId)\n );\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n processEdges(child);\n }\n }\n };\n processEdges(graph);\n }\n\n /**\n * Recalculate a single artifact edge with orthogonal routing and obstacle avoidance\n */\n private recalculateEdgeWithObstacles(\n edge: ElkExtendedEdge,\n source: ElkNode,\n target: ElkNode,\n sourceIsArtifact: boolean,\n obstacles: Obstacle[]\n ): void {\n const sx = source.x ?? 0;\n const sy = source.y ?? 0;\n const sw = source.width ?? 36;\n const sh = source.height ?? 50;\n\n const tx = target.x ?? 0;\n const ty = target.y ?? 0;\n const tw = target.width ?? 100;\n const th = target.height ?? 80;\n\n // Determine connection points based on relative positions\n let startPoint: Point;\n let endPoint: Point;\n const bendPoints: Point[] = [];\n\n const sourceCenterX = sx + sw / 2;\n const sourceCenterY = sy + sh / 2;\n const targetCenterX = tx + tw / 2;\n const targetCenterY = ty + th / 2;\n\n // Determine if we're going up, down, left, or right\n const goingRight = targetCenterX > sourceCenterX + sw / 2;\n const goingLeft = targetCenterX < sourceCenterX - sw / 2;\n const goingDown = targetCenterY > sourceCenterY + sh / 2;\n const goingUp = targetCenterY < sourceCenterY - sh / 2;\n\n if (sourceIsArtifact) {\n // Artifact is source (data input association: artifact -> task)\n if (goingDown) {\n // Source above target: exit from bottom, enter from top\n startPoint = { x: sourceCenterX, y: sy + sh };\n endPoint = { x: targetCenterX, y: ty };\n\n // Check for obstacles and route around them\n const routeY = findClearVerticalPath(startPoint.x, startPoint.y, endPoint.y, obstacles);\n if (Math.abs(startPoint.x - endPoint.x) > 5 || routeY !== null) {\n if (routeY !== null && routeY !== startPoint.y && routeY !== endPoint.y) {\n bendPoints.push({ x: startPoint.x, y: routeY });\n bendPoints.push({ x: endPoint.x, y: routeY });\n } else {\n // Simple L-shaped routing\n const midY = (startPoint.y + endPoint.y) / 2;\n bendPoints.push({ x: startPoint.x, y: midY });\n bendPoints.push({ x: endPoint.x, y: midY });\n }\n }\n } else if (goingUp) {\n // Source below target: exit from top, enter from bottom\n startPoint = { x: sourceCenterX, y: sy };\n endPoint = { x: targetCenterX, y: ty + th };\n\n const midY = (startPoint.y + endPoint.y) / 2;\n if (Math.abs(startPoint.x - endPoint.x) > 5) {\n bendPoints.push({ x: startPoint.x, y: midY });\n bendPoints.push({ x: endPoint.x, y: midY });\n }\n } else if (goingRight) {\n // Source left of target: exit from right, enter from left\n startPoint = { x: sx + sw, y: sourceCenterY };\n endPoint = { x: tx, y: targetCenterY };\n\n // Route with obstacle avoidance\n this.addOrthogonalBendPoints(startPoint, endPoint, bendPoints, obstacles);\n } else {\n // Source right of target: exit from left, enter from right\n startPoint = { x: sx, y: sourceCenterY };\n endPoint = { x: tx + tw, y: targetCenterY };\n\n this.addOrthogonalBendPoints(startPoint, endPoint, bendPoints, obstacles);\n }\n } else {\n // Task is source (data output association: task -> artifact)\n if (goingUp) {\n // Target above source: exit from top, enter from bottom\n startPoint = { x: sourceCenterX, y: sy };\n endPoint = { x: targetCenterX, y: ty + th };\n\n const midY = (startPoint.y + endPoint.y) / 2;\n if (Math.abs(startPoint.x - endPoint.x) > 5) {\n bendPoints.push({ x: startPoint.x, y: midY });\n bendPoints.push({ x: endPoint.x, y: midY });\n }\n } else if (goingDown) {\n // Target below source: exit from bottom, enter from top\n startPoint = { x: sourceCenterX, y: sy + sh };\n endPoint = { x: targetCenterX, y: ty };\n\n const midY = (startPoint.y + endPoint.y) / 2;\n if (Math.abs(startPoint.x - endPoint.x) > 5) {\n bendPoints.push({ x: startPoint.x, y: midY });\n bendPoints.push({ x: endPoint.x, y: midY });\n }\n } else if (goingRight) {\n // Target right of source: exit from right, enter from left\n startPoint = { x: sx + sw, y: sourceCenterY };\n endPoint = { x: tx, y: targetCenterY };\n\n this.addOrthogonalBendPoints(startPoint, endPoint, bendPoints, obstacles);\n } else {\n // Target left of source: exit from left, enter from right\n startPoint = { x: sx, y: sourceCenterY };\n endPoint = { x: tx + tw, y: targetCenterY };\n\n this.addOrthogonalBendPoints(startPoint, endPoint, bendPoints, obstacles);\n }\n }\n\n edge.sections = [{\n id: `${edge.id}_section_0`,\n startPoint,\n endPoint,\n bendPoints: bendPoints.length > 0 ? bendPoints : undefined,\n }];\n }\n\n /**\n * Add orthogonal bend points with obstacle avoidance\n */\n private addOrthogonalBendPoints(\n start: Point,\n end: Point,\n bendPoints: Point[],\n obstacles: Bounds[]\n ): void {\n const margin = 15;\n\n // Check if direct path (with one bend) crosses any obstacle\n const midX = (start.x + end.x) / 2;\n const midY = (start.y + end.y) / 2;\n\n // Try different routing strategies\n const strategies: Array<{ points: Point[]; score: number }> = [];\n\n // Strategy 1: Horizontal first, then vertical\n const s1: Point[] = [\n { x: midX, y: start.y },\n { x: midX, y: end.y },\n ];\n strategies.push({ points: s1, score: scoreRoute(start, s1, end, obstacles) });\n\n // Strategy 2: Vertical first, then horizontal\n const s2: Point[] = [\n { x: start.x, y: midY },\n { x: end.x, y: midY },\n ];\n strategies.push({ points: s2, score: scoreRoute(start, s2, end, obstacles) });\n\n // Strategy 3: Route above obstacles\n const maxObstacleTop = Math.min(...obstacles.map(o => o.y), start.y, end.y);\n const routeAboveY = maxObstacleTop - margin;\n const s3: Point[] = [\n { x: start.x, y: routeAboveY },\n { x: end.x, y: routeAboveY },\n ];\n strategies.push({ points: s3, score: scoreRoute(start, s3, end, obstacles) });\n\n // Strategy 4: Route below obstacles\n const maxObstacleBottom = Math.max(...obstacles.map(o => o.y + o.height), start.y, end.y);\n const routeBelowY = maxObstacleBottom + margin;\n const s4: Point[] = [\n { x: start.x, y: routeBelowY },\n { x: end.x, y: routeBelowY },\n ];\n strategies.push({ points: s4, score: scoreRoute(start, s4, end, obstacles) });\n\n // Strategy 5: Route to the right of obstacles\n const maxObstacleRight = Math.max(...obstacles.map(o => o.x + o.width), start.x, end.x);\n const routeRightX = maxObstacleRight + margin;\n const s5: Point[] = [\n { x: routeRightX, y: start.y },\n { x: routeRightX, y: end.y },\n ];\n strategies.push({ points: s5, score: scoreRoute(start, s5, end, obstacles) });\n\n // Choose the best strategy (lowest score = fewer crossings + shorter path)\n strategies.sort((a, b) => a.score - b.score);\n const best = strategies[0];\n\n // Only add bend points if they're significantly different from start/end\n for (const bp of best.points) {\n if (Math.abs(bp.x - start.x) > 5 || Math.abs(bp.y - start.y) > 5) {\n if (Math.abs(bp.x - end.x) > 5 || Math.abs(bp.y - end.y) > 5) {\n bendPoints.push(bp);\n }\n }\n }\n }\n}\n","/**\n * Group Positioner\n * Handles repositioning of BPMN Group elements to surround their grouped elements.\n * Groups are visual overlays that don't participate in ELK layout.\n */\n\nimport type { ElkNode } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { NodeWithBpmn, GroupInfo } from '../../types/internal';\nimport { GROUP_TYPE } from '../../types/bpmn-constants';\nimport { buildNodeMapWithParents } from '../../utils/node-map-builder';\n\n// Re-export GROUP_TYPE for backward compatibility\nexport { GROUP_TYPE };\n\n/**\n * Handler for group repositioning\n */\nexport class GroupPositioner {\n /**\n * Collect Group information for post-processing\n * Returns a map of group ID -> { groupedElements, padding, name, parentId }\n */\n collectInfo(graph: ElkBpmnGraph): Map<string, GroupInfo> {\n const info = new Map<string, GroupInfo>();\n\n const collectFromNode = (node: NodeWithBpmn, parentId: string) => {\n if (node.children) {\n for (const child of node.children) {\n const childNode = child as NodeWithBpmn;\n if (childNode.bpmn?.type === GROUP_TYPE) {\n const bpmn = childNode.bpmn as { groupedElements?: string[]; padding?: number; name?: string };\n info.set(childNode.id, {\n groupedElements: bpmn.groupedElements ?? [],\n padding: bpmn.padding ?? 20,\n name: bpmn.name,\n parentId,\n });\n }\n // Recurse into children\n collectFromNode(childNode, childNode.id);\n }\n }\n };\n\n for (const child of graph.children ?? []) {\n collectFromNode(child as NodeWithBpmn, (child as NodeWithBpmn).id);\n }\n\n return info;\n }\n\n /**\n * Remove Groups from the graph before ELK layout\n * Groups will be repositioned after layout based on their grouped elements\n */\n removeFromGraph(graph: ElkBpmnGraph, groupInfo: Map<string, GroupInfo>): void {\n const groupIds = new Set(groupInfo.keys());\n\n const removeFromNode = (node: NodeWithBpmn) => {\n if (node.children) {\n node.children = node.children.filter((child) => {\n const childNode = child as NodeWithBpmn;\n return !groupIds.has(childNode.id);\n });\n\n // Recurse into remaining children\n for (const child of node.children) {\n removeFromNode(child as NodeWithBpmn);\n }\n }\n\n // Also remove edges that connect to groups\n if (node.edges) {\n node.edges = node.edges.filter((edge) => {\n const sourceId = edge.sources[0];\n const targetId = edge.targets[0];\n return !groupIds.has(sourceId) && !groupIds.has(targetId);\n });\n }\n };\n\n for (const child of graph.children ?? []) {\n removeFromNode(child as NodeWithBpmn);\n }\n }\n\n /**\n * Reposition Groups to surround their grouped elements\n * Modifies existing Group nodes in the layouted graph\n */\n reposition(\n graph: ElkNode,\n groupInfo: Map<string, GroupInfo>,\n _originalGraph: ElkBpmnGraph\n ): void {\n if (groupInfo.size === 0) return;\n\n // Build node map for position lookups\n const [nodeMap, parentMap] = buildNodeMapWithParents(graph);\n\n // Process each group\n for (const [groupId, info] of groupInfo) {\n // Find the existing group node in the layouted graph\n const groupNode = nodeMap.get(groupId);\n if (!groupNode) continue;\n\n // If no grouped elements specified, keep the ELK-calculated position\n if (info.groupedElements.length === 0) continue;\n\n // Calculate bounding box of grouped elements\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n for (const elementId of info.groupedElements) {\n const elementNode = nodeMap.get(elementId);\n if (!elementNode || elementNode.x === undefined || elementNode.y === undefined) continue;\n\n // Get position of the element relative to the same parent container as the group\n // Elements might be nested in lanes, so we need to traverse up to the group's parent\n let absX = elementNode.x ?? 0;\n let absY = elementNode.y ?? 0;\n let currentParent = parentMap.get(elementId);\n const groupParent = parentMap.get(groupId);\n\n // Traverse up to find common ancestor or group's parent\n while (currentParent && currentParent !== groupParent && currentParent.id !== info.parentId) {\n absX += currentParent.x ?? 0;\n absY += currentParent.y ?? 0;\n currentParent = parentMap.get(currentParent.id);\n }\n\n const w = elementNode.width ?? 100;\n const h = elementNode.height ?? 80;\n\n minX = Math.min(minX, absX);\n minY = Math.min(minY, absY);\n maxX = Math.max(maxX, absX + w);\n maxY = Math.max(maxY, absY + h);\n }\n\n // Check if we found any valid elements\n if (minX === Infinity) continue;\n\n // Add padding\n const padding = info.padding;\n minX -= padding;\n minY -= padding;\n maxX += padding;\n maxY += padding;\n\n // Update the group node's position and size\n groupNode.x = minX;\n groupNode.y = minY;\n groupNode.width = maxX - minX;\n groupNode.height = maxY - minY;\n }\n }\n}\n","/**\n * Lane Arranger\n * Handles rearranging lanes to stack vertically within pools.\n * ELK's partitioning doesn't correctly handle BPMN lanes, so we need\n * to rearrange them after layout.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { NodeWithBpmn, Point } from '../../types/internal';\n\ntype ElkNodeWithBpmn = ElkNode & { bpmn?: NodeWithBpmn['bpmn'] };\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Handler for lane rearrangement\n */\nexport class LaneArranger {\n private readonly laneHeaderWidth = 30;\n private readonly lanePadding = 0; // No extra padding - tight fit\n private readonly laneExtraWidth = 50; // Extra width for each lane\n private readonly laneExtraHeight = 80; // Extra height for each lane\n\n /**\n * Rearrange lanes within pools to stack vertically\n */\n rearrange(layouted: ElkNode, original: ElkBpmnGraph): void {\n // Find pools in collaborations and process them\n if (layouted.children) {\n for (let i = 0; i < layouted.children.length; i++) {\n const child = layouted.children[i];\n const origChild = original.children?.[i] as NodeWithBpmn | undefined;\n\n // Check if this is a collaboration with pools\n if (origChild?.bpmn?.type === 'collaboration' && child.children) {\n for (let j = 0; j < child.children.length; j++) {\n const pool = child.children[j];\n const origPool = (origChild.children as NodeWithBpmn[] | undefined)?.[j];\n if (origPool?.bpmn?.type === 'participant') {\n this.processPool(pool, origPool);\n }\n }\n } else if (origChild?.bpmn?.type === 'participant') {\n // Direct pool (not in collaboration)\n this.processPool(child, origChild);\n }\n }\n }\n }\n\n /**\n * Process a single pool to arrange its lanes\n */\n private processPool(pool: ElkNode, origPool: NodeWithBpmn | undefined): void {\n if (!pool.children || !origPool?.children) return;\n\n // Check if this pool has lanes\n const hasLanes = (origPool.children as NodeWithBpmn[]).some(c => c.bpmn?.type === 'lane');\n if (!hasLanes) return;\n\n // Build node -> lane mapping (handles nested lanes)\n const nodeToLane = new Map<string, string>();\n this.buildNodeToLaneMap(origPool.children as NodeWithBpmn[], nodeToLane);\n\n // Get layouted nodes (flattened at pool level after ELK)\n const layoutedNodes = new Map<string, ElkNode>();\n for (const child of pool.children) {\n layoutedNodes.set(child.id, child);\n }\n\n // Calculate max content width\n let maxRight = 0;\n for (const child of pool.children) {\n maxRight = Math.max(maxRight, (child.x ?? 0) + (child.width ?? 100));\n }\n\n // Calculate pool width (content width + extra width)\n const poolContentWidth = maxRight + this.laneExtraWidth;\n\n // Build lane structure - lanes fill the full pool width\n const result = this.buildLaneStructure(\n origPool.children as NodeWithBpmn[],\n layoutedNodes,\n nodeToLane,\n 0,\n poolContentWidth // Lanes fill full width\n );\n\n // Update pool - lanes fill the entire pool, no gaps\n pool.children = result.lanes;\n pool.width = this.laneHeaderWidth + poolContentWidth;\n pool.height = result.totalHeight;\n\n // Recalculate edge waypoints\n if (pool.edges) {\n this.recalculatePoolEdges(pool, result.lanes);\n }\n }\n\n /**\n * Build a map of node ID -> deepest lane ID (for nested lanes)\n */\n private buildNodeToLaneMap(children: NodeWithBpmn[], map: Map<string, string>): void {\n for (const child of children) {\n if (child.bpmn?.type === 'lane') {\n // Check if this lane has nested lanes\n const hasNestedLanes = child.children?.some((c: unknown) => (c as NodeWithBpmn).bpmn?.type === 'lane');\n if (hasNestedLanes) {\n // Recurse into nested lanes\n this.buildNodeToLaneMap(child.children as NodeWithBpmn[], map);\n } else if (child.children) {\n // Leaf lane - map its children to this lane\n for (const node of child.children) {\n map.set((node as NodeWithBpmn).id, child.id);\n }\n }\n }\n }\n }\n\n /**\n * Recursively build lane structure with positioned nodes\n */\n private buildLaneStructure(\n origChildren: NodeWithBpmn[],\n layoutedNodes: Map<string, ElkNode>,\n nodeToLane: Map<string, string>,\n startY: number,\n maxRight: number\n ): { lanes: ElkNode[]; totalHeight: number } {\n const lanes: ElkNode[] = [];\n let currentY = startY;\n\n // Filter to get only lanes and sort by partition\n const origLanes = origChildren.filter(c => c.bpmn?.type === 'lane');\n origLanes.sort((a, b) => {\n const partA = a.layoutOptions?.['elk.partitioning.partition'];\n const partB = b.layoutOptions?.['elk.partitioning.partition'];\n return (partA !== undefined ? Number(partA) : 0) - (partB !== undefined ? Number(partB) : 0);\n });\n\n for (const origLane of origLanes) {\n const hasNestedLanes = origLane.children?.some((c: unknown) => (c as NodeWithBpmn).bpmn?.type === 'lane');\n\n if (hasNestedLanes) {\n // Recursively process nested lanes\n // Nested lanes are offset by laneHeaderWidth inside their parent,\n // so they need reduced width to avoid overflow\n const nestedWidth = maxRight - this.laneHeaderWidth;\n const nested = this.buildLaneStructure(\n origLane.children as NodeWithBpmn[],\n layoutedNodes,\n nodeToLane,\n 0,\n nestedWidth\n );\n\n // Ensure nested lanes fill parent lane width (minus header)\n for (const nestedLane of nested.lanes) {\n nestedLane.width = nestedWidth;\n }\n\n const laneNode: ElkNodeWithBpmn = {\n id: origLane.id,\n x: this.laneHeaderWidth,\n y: currentY,\n width: maxRight, // Fill full width\n height: nested.totalHeight, // Tight fit\n children: nested.lanes,\n bpmn: origLane.bpmn,\n };\n lanes.push(laneNode);\n currentY += laneNode.height!;\n } else {\n // Leaf lane - collect its nodes\n const nodesInLane: ElkNode[] = [];\n if (origLane.children) {\n for (const child of origLane.children) {\n const node = layoutedNodes.get((child as NodeWithBpmn).id);\n if (node) nodesInLane.push(node);\n }\n }\n\n // Calculate lane height based on content + extra height\n let minY = Infinity, maxY = 0;\n for (const node of nodesInLane) {\n minY = Math.min(minY, node.y ?? 0);\n maxY = Math.max(maxY, (node.y ?? 0) + (node.height ?? 80));\n }\n // Add extra height to each lane\n const contentHeight = nodesInLane.length > 0 ? maxY - minY : 50;\n const laneHeight = contentHeight + this.laneExtraHeight;\n\n // Center content vertically within the lane\n const yOffset = nodesInLane.length > 0 ? (this.laneExtraHeight / 2) - minY : 0;\n for (const node of nodesInLane) {\n node.y = (node.y ?? 0) + yOffset;\n }\n\n const laneNode: ElkNodeWithBpmn = {\n id: origLane.id,\n x: this.laneHeaderWidth,\n y: currentY,\n width: maxRight,\n height: laneHeight,\n children: nodesInLane,\n bpmn: origLane.bpmn,\n };\n lanes.push(laneNode);\n currentY += laneHeight;\n }\n }\n\n return { lanes, totalHeight: currentY - startY };\n }\n\n /**\n * Rearrange nested lanes within a parent lane\n */\n rearrangeNested(lane: ElkNode, origLane: NodeWithBpmn | undefined): void {\n if (!lane.children) return;\n\n // Check if this lane has nested lanes\n const nestedLanes: ElkNode[] = [];\n const nonLanes: ElkNode[] = [];\n\n for (const child of lane.children) {\n const origChild = origLane?.children?.find((c: unknown) => (c as NodeWithBpmn).id === child.id) as NodeWithBpmn | undefined;\n if (origChild?.bpmn?.type === 'lane') {\n nestedLanes.push(child);\n } else {\n nonLanes.push(child);\n }\n }\n\n if (nestedLanes.length > 0) {\n // Stack nested lanes vertically\n let currentY = 12;\n let maxWidth = 0;\n\n for (const nestedLane of nestedLanes) {\n const contentHeight = this.calculateContentHeight(nestedLane);\n const laneHeight = Math.max(contentHeight + 24, 60);\n\n nestedLane.x = 30; // Nested lane header offset\n nestedLane.y = currentY;\n nestedLane.height = laneHeight;\n\n const contentWidth = this.calculateContentWidth(nestedLane);\n nestedLane.width = contentWidth + 24;\n maxWidth = Math.max(maxWidth, nestedLane.width ?? 0);\n\n currentY += laneHeight;\n }\n\n // Update all nested lanes to have the same width\n for (const nestedLane of nestedLanes) {\n nestedLane.width = maxWidth;\n }\n\n // Update parent lane dimensions\n lane.width = 30 + maxWidth + 12;\n lane.height = currentY + 12;\n }\n }\n\n /**\n * Calculate the width needed to contain all children of a node\n */\n calculateContentWidth(node: ElkNode): number {\n if (!node.children || node.children.length === 0) {\n return 100; // Default minimum width\n }\n\n let maxRight = 0;\n for (const child of node.children) {\n const right = (child.x ?? 0) + (child.width ?? 100);\n maxRight = Math.max(maxRight, right);\n }\n\n return maxRight;\n }\n\n /**\n * Calculate the height needed to contain all children of a node\n */\n calculateContentHeight(node: ElkNode): number {\n if (!node.children || node.children.length === 0) {\n return 60; // Default minimum height\n }\n\n let maxBottom = 0;\n for (const child of node.children) {\n const bottom = (child.y ?? 0) + (child.height ?? 80);\n maxBottom = Math.max(maxBottom, bottom);\n }\n\n return maxBottom;\n }\n\n /**\n * Recalculate edge waypoints after lanes have been rearranged\n */\n private recalculatePoolEdges(pool: ElkNode, lanes: ElkNode[]): void {\n if (!pool.edges) return;\n\n // Build a map of node positions within the pool\n const nodePositions = new Map<string, { x: number; y: number; width: number; height: number }>();\n\n const collectNodePositions = (container: ElkNode, offsetX: number, offsetY: number) => {\n if (container.children) {\n for (const child of container.children) {\n const absX = offsetX + (child.x ?? 0);\n const absY = offsetY + (child.y ?? 0);\n nodePositions.set(child.id, {\n x: absX,\n y: absY,\n width: child.width ?? 100,\n height: child.height ?? 80,\n });\n // Recursively collect from nested containers\n collectNodePositions(child, absX, absY);\n }\n }\n };\n\n // Collect positions from all lanes\n for (const lane of lanes) {\n collectNodePositions(lane, lane.x ?? 0, lane.y ?? 0);\n }\n\n // Recalculate edge waypoints\n for (const edge of pool.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n const sourcePos = sourceId ? nodePositions.get(sourceId) : undefined;\n const targetPos = targetId ? nodePositions.get(targetId) : undefined;\n\n if (DEBUG) {\n console.log(`[BPMN] recalculatePoolEdges ${edge.id}: source=${sourceId}, target=${targetId}`);\n console.log(`[BPMN] sourcePos=${JSON.stringify(sourcePos)}`);\n console.log(`[BPMN] targetPos=${JSON.stringify(targetPos)}`);\n }\n\n if (sourcePos && targetPos) {\n // Calculate connection points\n const startX = sourcePos.x + sourcePos.width;\n const startY = sourcePos.y + sourcePos.height / 2;\n const endX = targetPos.x;\n const endY = targetPos.y + targetPos.height / 2;\n\n if (DEBUG) {\n console.log(`[BPMN] startX=${startX}, startY=${startY}, endX=${endX}, endY=${endY}`);\n }\n\n // Create new waypoints\n const waypoints: Point[] = [];\n waypoints.push({ x: startX, y: startY });\n\n // Add bend points for orthogonal routing if source and target are in different lanes\n if (Math.abs(startY - endY) > 10) {\n const midX = (startX + endX) / 2;\n waypoints.push({ x: midX, y: startY });\n waypoints.push({ x: midX, y: endY });\n }\n\n waypoints.push({ x: endX, y: endY });\n\n if (DEBUG) {\n console.log(`[BPMN] waypoints=${JSON.stringify(waypoints)}`);\n }\n\n // Update edge sections\n // Mark as pool-relative coords (model-builder should use pool offset, not source node offset)\n (edge as ElkExtendedEdge & { _poolRelativeCoords?: boolean })._poolRelativeCoords = true;\n edge.sections = [{\n id: `${edge.id}_s0`,\n startPoint: { x: startX, y: startY },\n endPoint: { x: endX, y: endY },\n bendPoints: waypoints.length > 2 ? waypoints.slice(1, -1) : undefined,\n }];\n }\n }\n }\n}\n","/**\n * Pool Arranger\n * Handles rearranging pools (participants) within collaborations.\n * Pools are stacked vertically and message flows are recalculated.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { NodeWithBpmn, Point, Bounds, ArtifactInfo } from '../../types/internal';\nimport { ARTIFACT_TYPES } from './artifact-positioner';\n\n/**\n * Handler for pool arrangement\n */\nexport class PoolArranger {\n private readonly poolHeaderWidth = 55;\n private readonly poolPaddingX = 25;\n private readonly poolPaddingY = 20;\n private readonly minPoolHeight = 100;\n private readonly poolExtraWidth = 50;\n private readonly poolExtraHeight = 80;\n\n /**\n * Rearrange pools within collaborations\n */\n rearrange(layouted: ElkNode, original: ElkBpmnGraph): void {\n if (!layouted.children) return;\n\n for (let i = 0; i < layouted.children.length; i++) {\n const child = layouted.children[i];\n const origChild = original.children?.[i] as NodeWithBpmn | undefined;\n\n // Check if this is a collaboration\n if (origChild?.bpmn?.type === 'collaboration' && child.children && child.children.length > 0) {\n // Check if this collaboration had cross-pool edges (nodes were flattened)\n const hasCrossPoolEdges = origChild.edges && origChild.edges.length > 0;\n const hasMultiplePools = ((origChild.children as NodeWithBpmn[] | undefined)?.filter(\n c => c.bpmn?.type === 'participant'\n ).length ?? 0) > 1;\n\n // Check if children were flattened\n const origPools = (origChild.children as NodeWithBpmn[] | undefined)?.filter(\n c => c.bpmn?.type === 'participant'\n ) ?? [];\n const poolIdsInLayouted = new Set(child.children.map(c => c.id));\n const poolsFoundInLayouted = origPools.filter(p => poolIdsInLayouted.has(p.id)).length;\n const childrenAreFlattened = poolsFoundInLayouted < origPools.length / 2;\n\n if (hasCrossPoolEdges && hasMultiplePools && childrenAreFlattened) {\n this.rearrangeCollaborationWithCrossPoolEdges(child, origChild);\n } else {\n this.stackPoolsVertically(child, origChild);\n }\n }\n }\n }\n\n /**\n * Stack pools vertically within a collaboration\n */\n private stackPoolsVertically(collab: ElkNode, origCollab: NodeWithBpmn): void {\n if (!collab.children || collab.children.length === 0) return;\n\n const pools: ElkNode[] = [];\n const origPoolMap = new Map<string, NodeWithBpmn>();\n\n // Collect pools and build original pool map\n for (const child of collab.children) {\n const origPool = origCollab.children?.find((c: unknown) => (c as NodeWithBpmn).id === child.id) as NodeWithBpmn | undefined;\n if (origPool?.bpmn?.type === 'participant') {\n pools.push(child);\n origPoolMap.set(child.id, origPool);\n }\n }\n\n if (pools.length === 0) return;\n\n // Sort pools by original order\n const poolOrder = new Map<string, number>();\n origCollab.children?.forEach((c: unknown, idx: number) => {\n const node = c as NodeWithBpmn;\n if (node.bpmn?.type === 'participant') {\n poolOrder.set(node.id, idx);\n }\n });\n pools.sort((a, b) => (poolOrder.get(a.id) ?? 0) - (poolOrder.get(b.id) ?? 0));\n\n // Calculate the maximum width needed\n let maxPoolWidth = 0;\n for (const pool of pools) {\n const origPool = origPoolMap.get(pool.id);\n const hasLanes = (origPool?.children as NodeWithBpmn[] | undefined)?.some(c => c.bpmn?.type === 'lane');\n if (hasLanes) {\n maxPoolWidth = Math.max(maxPoolWidth, pool.width ?? 680);\n } else {\n maxPoolWidth = Math.max(maxPoolWidth, (pool.width ?? 680) + this.poolExtraWidth);\n }\n }\n\n // Stack pools vertically\n let currentY = 0;\n const nodePositions = new Map<string, Bounds>();\n\n for (const pool of pools) {\n const origPool = origPoolMap.get(pool.id);\n const isBlackBox = origPool?.bpmn?.isBlackBox === true;\n const hasLanes = (origPool?.children as NodeWithBpmn[] | undefined)?.some(c => c.bpmn?.type === 'lane');\n\n pool.x = 0;\n pool.y = currentY;\n\n if (isBlackBox) {\n pool.width = maxPoolWidth;\n pool.height = pool.height ?? 60;\n } else if (hasLanes) {\n pool.width = maxPoolWidth;\n } else {\n pool.width = maxPoolWidth;\n pool.height = (pool.height ?? 200) + this.poolExtraHeight;\n this.offsetPoolChildren(pool, this.poolExtraHeight / 2);\n }\n\n // Store pool position\n nodePositions.set(pool.id, {\n x: pool.x,\n y: pool.y,\n width: pool.width ?? 680,\n height: pool.height ?? 200,\n });\n\n // Collect node positions\n this.collectNodePositionsInPool(pool, pool.x, pool.y, nodePositions);\n\n currentY += (pool.height ?? 200);\n }\n\n // Update collaboration dimensions\n collab.width = maxPoolWidth;\n collab.height = currentY;\n\n // Recalculate message flows\n if (collab.edges && origCollab.edges) {\n this.recalculateMessageFlows(collab.edges, nodePositions, pools, origCollab.edges);\n }\n }\n\n /**\n * Rearrange collaboration with cross-pool edges\n */\n private rearrangeCollaborationWithCrossPoolEdges(\n collab: ElkNode,\n origCollab: NodeWithBpmn\n ): void {\n if (!collab.children || !origCollab.children) return;\n\n // Build map of node ID -> pool ID and identify artifacts\n const nodeToPool = new Map<string, string>();\n const artifactIds = new Set<string>();\n\n for (const origPool of origCollab.children as NodeWithBpmn[]) {\n if (origPool.bpmn?.type === 'participant' && origPool.children) {\n const hasLanes = origPool.children.some((c: unknown) => (c as NodeWithBpmn).bpmn?.type === 'lane');\n if (hasLanes) {\n const mapNodesInLanes = (children: NodeWithBpmn[]) => {\n for (const child of children) {\n if (child.bpmn?.type === 'lane') {\n if (child.children) mapNodesInLanes(child.children as NodeWithBpmn[]);\n } else {\n nodeToPool.set(child.id, origPool.id);\n if (ARTIFACT_TYPES.has(child.bpmn?.type)) {\n artifactIds.add(child.id);\n }\n }\n }\n };\n mapNodesInLanes(origPool.children as NodeWithBpmn[]);\n } else {\n for (const child of origPool.children) {\n const childNode = child as NodeWithBpmn;\n nodeToPool.set(childNode.id, origPool.id);\n if (ARTIFACT_TYPES.has(childNode.bpmn?.type)) {\n artifactIds.add(childNode.id);\n }\n }\n }\n }\n }\n\n // Get layouted nodes\n const layoutedNodes = new Map<string, ElkNode>();\n for (const child of collab.children) {\n layoutedNodes.set(child.id, child);\n }\n\n // Group nodes by pool and calculate X bounds\n const poolNodesMap = new Map<string, ElkNode[]>();\n const poolXBounds = new Map<string, { minX: number; maxX: number }>();\n let globalMinX = Infinity;\n\n for (const [nodeId, poolId] of nodeToPool) {\n const node = layoutedNodes.get(nodeId);\n if (!node) continue;\n\n if (!poolNodesMap.has(poolId)) {\n poolNodesMap.set(poolId, []);\n }\n poolNodesMap.get(poolId)!.push(node);\n\n if (!artifactIds.has(nodeId)) {\n const x = node.x ?? 0;\n const w = node.width ?? 100;\n const bounds = poolXBounds.get(poolId) ?? { minX: Infinity, maxX: 0 };\n bounds.minX = Math.min(bounds.minX, x);\n bounds.maxX = Math.max(bounds.maxX, x + w);\n poolXBounds.set(poolId, bounds);\n globalMinX = Math.min(globalMinX, x);\n }\n }\n\n // Sort pools by original order\n const origPools = (origCollab.children as NodeWithBpmn[]).filter(c => c.bpmn?.type === 'participant');\n origPools.sort((a, b) => {\n const partA = a.layoutOptions?.['elk.partitioning.partition'];\n const partB = b.layoutOptions?.['elk.partitioning.partition'];\n if (partA !== undefined && partB !== undefined) {\n return Number(partA) - Number(partB);\n }\n return 0;\n });\n\n // Calculate max content width\n let globalMaxX = 0;\n for (const bounds of poolXBounds.values()) {\n globalMaxX = Math.max(globalMaxX, bounds.maxX);\n }\n const maxContentWidth = globalMaxX - globalMinX;\n const poolWidth = this.poolHeaderWidth + maxContentWidth + this.poolPaddingX * 2;\n\n // Build pool structures\n const pools: ElkNode[] = [];\n let currentY = 0;\n\n for (const origPool of origPools) {\n const poolNodes = poolNodesMap.get(origPool.id) ?? [];\n const isBlackBox = origPool.bpmn?.isBlackBox === true || !origPool.children?.length;\n\n if (isBlackBox) {\n pools.push({\n id: origPool.id,\n x: 0,\n y: currentY,\n width: poolWidth,\n height: 60,\n children: [],\n });\n currentY += 60;\n } else {\n const regularNodes = poolNodes.filter(n => !artifactIds.has(n.id));\n const artifactNodes = poolNodes.filter(n => artifactIds.has(n.id));\n\n let maxNodeHeight = 0;\n for (const node of regularNodes) {\n maxNodeHeight = Math.max(maxNodeHeight, node.height ?? 80);\n }\n const poolHeight = Math.max(this.minPoolHeight, maxNodeHeight + this.poolPaddingY * 2);\n\n const adjustedNodes: ElkNode[] = [];\n for (const node of regularNodes) {\n const nodeHeight = node.height ?? 80;\n const newY = (poolHeight - nodeHeight) / 2;\n const newX = this.poolHeaderWidth + (node.x ?? 0) - globalMinX + this.poolPaddingX;\n\n adjustedNodes.push({\n ...node,\n x: newX,\n y: newY,\n });\n }\n\n // Position artifacts\n for (const artifact of artifactNodes) {\n const { task: associatedTask, isInput } = this.findArtifactAssociatedTask(\n artifact.id,\n origCollab.edges ?? [],\n adjustedNodes\n );\n\n if (associatedTask) {\n const artifactWidth = artifact.width ?? 36;\n const artifactHeight = artifact.height ?? 50;\n const taskX = associatedTask.x ?? 0;\n const taskY = associatedTask.y ?? 0;\n const taskWidth = associatedTask.width ?? 100;\n const taskHeight = associatedTask.height ?? 80;\n\n const newX = taskX + taskWidth + 15;\n const newY = taskY + (taskHeight - artifactHeight) / 2;\n\n adjustedNodes.push({\n ...artifact,\n x: newX,\n y: Math.max(5, newY),\n });\n } else {\n const newX = this.poolHeaderWidth + (artifact.x ?? 0) - globalMinX + this.poolPaddingX;\n const artifactHeight = artifact.height ?? 50;\n const newY = (poolHeight - artifactHeight) / 2;\n\n adjustedNodes.push({\n ...artifact,\n x: newX,\n y: newY,\n });\n }\n }\n\n pools.push({\n id: origPool.id,\n x: 0,\n y: currentY,\n width: poolWidth,\n height: poolHeight,\n children: adjustedNodes,\n });\n currentY += poolHeight;\n }\n }\n\n // Update collaboration\n collab.children = pools;\n collab.width = poolWidth;\n collab.height = currentY;\n\n // Recalculate edges\n if (collab.edges) {\n const nodePositions = new Map<string, Bounds>();\n\n for (const pool of pools) {\n const poolX = pool.x ?? 0;\n const poolY = pool.y ?? 0;\n\n nodePositions.set(pool.id, {\n x: poolX,\n y: poolY,\n width: pool.width ?? 680,\n height: pool.height ?? 200,\n });\n\n if (pool.children) {\n for (const child of pool.children) {\n nodePositions.set(child.id, {\n x: poolX + (child.x ?? 0),\n y: poolY + (child.y ?? 0),\n width: child.width ?? 100,\n height: child.height ?? 80,\n });\n }\n }\n }\n\n this.recalculateMessageFlows(collab.edges, nodePositions, pools, origCollab.edges);\n }\n }\n\n /**\n * Offset all children within a pool\n */\n private offsetPoolChildren(pool: ElkNode, offsetY: number): void {\n if (!pool.children) return;\n\n for (const child of pool.children) {\n if (child.y !== undefined) {\n child.y += offsetY;\n }\n this.offsetPoolChildren(child, 0);\n }\n\n if (pool.edges) {\n for (const edge of pool.edges) {\n if (edge.sections) {\n for (const section of edge.sections) {\n if (section.startPoint) section.startPoint.y += offsetY;\n if (section.endPoint) section.endPoint.y += offsetY;\n if (section.bendPoints) {\n for (const bp of section.bendPoints) bp.y += offsetY;\n }\n }\n }\n }\n }\n }\n\n /**\n * Collect node positions within a pool\n */\n private collectNodePositionsInPool(\n container: ElkNode,\n offsetX: number,\n offsetY: number,\n positions: Map<string, Bounds>\n ): void {\n if (!container.children) return;\n\n for (const child of container.children) {\n const absX = offsetX + (child.x ?? 0);\n const absY = offsetY + (child.y ?? 0);\n\n positions.set(child.id, {\n x: absX,\n y: absY,\n width: child.width ?? 100,\n height: child.height ?? 80,\n });\n\n this.collectNodePositionsInPool(child, absX, absY, positions);\n }\n }\n\n /**\n * Recalculate message flows after pools have been repositioned\n */\n private recalculateMessageFlows(\n edges: ElkExtendedEdge[],\n nodePositions: Map<string, Bounds>,\n pools: ElkNode[],\n originalEdges?: Array<{ id: string; sources: string[]; targets: string[]; bpmn?: { type?: string } }>\n ): void {\n const edgeTypeMap = new Map<string, string>();\n if (originalEdges) {\n for (const origEdge of originalEdges) {\n if (origEdge.bpmn?.type) {\n edgeTypeMap.set(origEdge.id, origEdge.bpmn.type);\n }\n }\n }\n\n for (const edge of edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n const edgeType = edgeTypeMap.get(edge.id) ?? (edge as { bpmn?: { type?: string } }).bpmn?.type;\n\n const sourcePos = sourceId ? nodePositions.get(sourceId) : undefined;\n const targetPos = targetId ? nodePositions.get(targetId) : undefined;\n\n if (!sourcePos || !targetPos) continue;\n\n const isSequenceFlow = edgeType === 'sequenceFlow';\n const isMessageFlow = edgeType === 'messageFlow';\n const isDataAssociation = edgeType === 'dataInputAssociation' || edgeType === 'dataOutputAssociation';\n\n const waypoints: Point[] = [];\n\n if (isSequenceFlow) {\n this.createSequenceFlowWaypoints(sourcePos, targetPos, waypoints);\n } else if (isMessageFlow) {\n this.createMessageFlowWaypoints(sourcePos, targetPos, waypoints);\n } else if (isDataAssociation) {\n (edge as ElkExtendedEdge & { _absoluteCoords?: boolean })._absoluteCoords = true;\n edge.sections = [];\n continue;\n } else {\n this.createSequenceFlowWaypoints(sourcePos, targetPos, waypoints);\n }\n\n (edge as ElkExtendedEdge & { _absoluteCoords?: boolean })._absoluteCoords = true;\n edge.sections = [{\n id: `${edge.id}_s0`,\n startPoint: waypoints[0],\n endPoint: waypoints[waypoints.length - 1],\n bendPoints: waypoints.length > 2 ? waypoints.slice(1, -1) : undefined,\n }];\n\n // Update label positions\n if (edge.labels && edge.labels.length > 0) {\n const midIdx = Math.floor(waypoints.length / 2);\n const labelPoint = waypoints[midIdx] ?? waypoints[0];\n for (const label of edge.labels) {\n const labelWidth = label.width ?? 50;\n const labelHeight = label.height ?? 14;\n label.x = labelPoint.x - labelWidth / 2;\n label.y = labelPoint.y - labelHeight - 5;\n }\n }\n }\n }\n\n /**\n * Create waypoints for sequence flows\n */\n private createSequenceFlowWaypoints(\n sourcePos: Bounds,\n targetPos: Bounds,\n waypoints: Point[]\n ): void {\n const sourceCenterX = sourcePos.x + sourcePos.width / 2;\n const sourceCenterY = sourcePos.y + sourcePos.height / 2;\n const targetCenterX = targetPos.x + targetPos.width / 2;\n const targetCenterY = targetPos.y + targetPos.height / 2;\n\n const goingRight = targetCenterX > sourceCenterX;\n const goingDown = targetCenterY > sourceCenterY + 30;\n const goingUp = targetCenterY < sourceCenterY - 30;\n const sameLevel = !goingDown && !goingUp;\n\n if (goingRight) {\n if (sameLevel) {\n const startX = sourcePos.x + sourcePos.width;\n const startY = sourceCenterY;\n const endX = targetPos.x;\n const endY = targetCenterY;\n\n waypoints.push({ x: startX, y: startY });\n if (Math.abs(startY - endY) > 10) {\n const midX = (startX + endX) / 2;\n waypoints.push({ x: midX, y: startY });\n waypoints.push({ x: midX, y: endY });\n }\n waypoints.push({ x: endX, y: endY });\n } else if (goingDown) {\n const startX = sourceCenterX;\n const startY = sourcePos.y + sourcePos.height;\n const endX = targetPos.x;\n const endY = targetCenterY;\n\n waypoints.push({ x: startX, y: startY });\n waypoints.push({ x: startX, y: endY });\n waypoints.push({ x: endX, y: endY });\n } else {\n const startX = sourceCenterX;\n const startY = sourcePos.y;\n const endX = targetPos.x;\n const endY = targetCenterY;\n\n waypoints.push({ x: startX, y: startY });\n waypoints.push({ x: startX, y: endY });\n waypoints.push({ x: endX, y: endY });\n }\n } else {\n const startX = sourcePos.x;\n const startY = sourceCenterY;\n const endX = targetPos.x + targetPos.width;\n const endY = targetCenterY;\n\n waypoints.push({ x: startX, y: startY });\n\n const loopY = Math.max(sourcePos.y + sourcePos.height, targetPos.y + targetPos.height) + 30;\n waypoints.push({ x: startX, y: loopY });\n waypoints.push({ x: endX, y: loopY });\n\n waypoints.push({ x: endX, y: endY });\n }\n }\n\n /**\n * Create waypoints for message flows\n */\n private createMessageFlowWaypoints(\n sourcePos: Bounds,\n targetPos: Bounds,\n waypoints: Point[]\n ): void {\n let startX: number, startY: number, endX: number, endY: number;\n\n if (sourcePos.y + sourcePos.height < targetPos.y) {\n startX = sourcePos.x + sourcePos.width / 2;\n startY = sourcePos.y + sourcePos.height;\n endX = targetPos.x + targetPos.width / 2;\n endY = targetPos.y;\n } else {\n startX = sourcePos.x + sourcePos.width / 2;\n startY = sourcePos.y;\n endX = targetPos.x + targetPos.width / 2;\n endY = targetPos.y + targetPos.height;\n }\n\n waypoints.push({ x: startX, y: startY });\n\n const horizontalDist = Math.abs(startX - endX);\n if (horizontalDist > 5) {\n const routeY = horizontalDist > 200 ? endY - 20 : (startY + endY) / 2;\n waypoints.push({ x: startX, y: routeY });\n waypoints.push({ x: endX, y: routeY });\n }\n\n waypoints.push({ x: endX, y: endY });\n }\n\n /**\n * Find the task associated with an artifact\n */\n private findArtifactAssociatedTask(\n artifactId: string,\n edges: Array<{ id: string; sources: string[]; targets: string[]; bpmn?: { type?: string } }>,\n adjustedNodes: ElkNode[]\n ): { task: ElkNode | undefined; isInput: boolean } {\n const nodeMap = new Map<string, ElkNode>();\n for (const node of adjustedNodes) {\n nodeMap.set(node.id, node);\n }\n\n for (const edge of edges) {\n const edgeType = edge.bpmn?.type;\n\n if (edgeType === 'dataInputAssociation' || edgeType === 'association') {\n if (edge.sources.includes(artifactId)) {\n const targetId = edge.targets[0];\n const targetNode = nodeMap.get(targetId);\n if (targetNode) return { task: targetNode, isInput: true };\n }\n }\n\n if (edgeType === 'dataOutputAssociation') {\n if (edge.targets.includes(artifactId)) {\n const sourceId = edge.sources[0];\n const sourceNode = nodeMap.get(sourceId);\n if (sourceNode) return { task: sourceNode, isInput: false };\n }\n }\n }\n\n return { task: undefined, isInput: false };\n }\n}\n","/**\n * Gateway Edge Adjuster\n * Adjusts edge endpoints that connect to gateways (diamond shapes).\n *\n * ELK calculates edge endpoints based on rectangular bounding boxes,\n * but gateways are diamond-shaped. This adjuster ensures edges connect\n * properly to the diamond's actual corners or edges.\n *\n * Gateway diamond has 4 corners:\n * - Left: (x, y + height/2)\n * - Top: (x + width/2, y)\n * - Right: (x + width, y + height/2)\n * - Bottom: (x + width/2, y + height)\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { Point, Bounds, NodeWithBpmn } from '../../types/internal';\nimport type { ElkBpmnGraph } from '../../types';\nimport { DEBUG } from '../../utils/debug';\nimport { distance, lineIntersection } from '../edge-routing/geometry-utils';\n\ninterface GatewayInfo {\n id: string;\n bounds: Bounds;\n corners: {\n left: Point;\n top: Point;\n right: Point;\n bottom: Point;\n };\n}\n\n/**\n * Handler for adjusting edge endpoints connecting to gateways\n */\nexport class GatewayEdgeAdjuster {\n /**\n * Adjust edges that connect to gateways\n * @param layoutedGraph - The ELK layouted graph (contains edge coordinates)\n * @param originalGraph - The original BPMN graph (contains bpmn metadata)\n */\n adjust(layoutedGraph: ElkNode, originalGraph: ElkBpmnGraph): void {\n // Collect all gateway positions from the layouted graph using original for type info\n const gateways = new Map<string, GatewayInfo>();\n\n this.collectGateways(layoutedGraph, originalGraph, gateways, 0, 0);\n\n if (gateways.size === 0) return;\n\n if (DEBUG) {\n console.log(`[BPMN] GatewayEdgeAdjuster: Found ${gateways.size} gateways`);\n for (const [id, info] of gateways) {\n console.log(`[BPMN] - ${id}: bounds=(${info.bounds.x},${info.bounds.y},${info.bounds.width},${info.bounds.height})`);\n }\n }\n\n // Process all edges and adjust endpoints\n this.processEdges(layoutedGraph, originalGraph, gateways, 0, 0);\n }\n\n /**\n * Collect all gateway nodes and calculate their diamond corners\n * Uses originalGraph for BPMN type info and layoutedGraph for positions\n */\n private collectGateways(\n layoutedNode: ElkNode,\n originalNode: ElkBpmnGraph | NodeWithBpmn,\n gateways: Map<string, GatewayInfo>,\n offsetX: number,\n offsetY: number\n ): void {\n const bpmn = (originalNode as NodeWithBpmn).bpmn;\n\n // Check if this node is a gateway\n if (this.isGateway(bpmn?.type)) {\n const x = offsetX + (layoutedNode.x ?? 0);\n const y = offsetY + (layoutedNode.y ?? 0);\n const width = layoutedNode.width ?? 50;\n const height = layoutedNode.height ?? 50;\n\n gateways.set(layoutedNode.id, {\n id: layoutedNode.id,\n bounds: { x, y, width, height },\n corners: {\n left: { x: x, y: y + height / 2 },\n top: { x: x + width / 2, y: y },\n right: { x: x + width, y: y + height / 2 },\n bottom: { x: x + width / 2, y: y + height },\n },\n });\n }\n\n // Process children with accumulated offset\n if (layoutedNode.children && originalNode.children) {\n const isContainer = this.isContainer(bpmn?.type);\n const newOffsetX = isContainer ? offsetX + (layoutedNode.x ?? 0) : offsetX;\n const newOffsetY = isContainer ? offsetY + (layoutedNode.y ?? 0) : offsetY;\n\n // Create a map of original children by id for lookup\n const originalChildMap = new Map<string, NodeWithBpmn>();\n for (const child of originalNode.children) {\n const childNode = child as NodeWithBpmn;\n if (childNode.id) {\n originalChildMap.set(childNode.id, childNode);\n }\n }\n\n for (const layoutedChild of layoutedNode.children) {\n const originalChild = originalChildMap.get(layoutedChild.id);\n if (originalChild) {\n this.collectGateways(layoutedChild, originalChild, gateways, newOffsetX, newOffsetY);\n }\n }\n }\n }\n\n /**\n * Process all edges and adjust endpoints connecting to gateways\n */\n private processEdges(\n layoutedNode: ElkNode,\n originalNode: ElkBpmnGraph | NodeWithBpmn,\n gateways: Map<string, GatewayInfo>,\n offsetX: number,\n offsetY: number\n ): void {\n const bpmn = (originalNode as NodeWithBpmn).bpmn;\n\n if (layoutedNode.edges) {\n for (const edge of layoutedNode.edges) {\n if (edge.sections && edge.sections.length > 0) {\n this.adjustEdgeEndpoints(edge, gateways, offsetX, offsetY);\n }\n }\n }\n\n // Process children\n if (layoutedNode.children && originalNode.children) {\n const isContainer = this.isContainer(bpmn?.type);\n const newOffsetX = isContainer ? offsetX + (layoutedNode.x ?? 0) : offsetX;\n const newOffsetY = isContainer ? offsetY + (layoutedNode.y ?? 0) : offsetY;\n\n // Create a map of original children by id for lookup\n const originalChildMap = new Map<string, NodeWithBpmn>();\n for (const child of originalNode.children) {\n const childNode = child as NodeWithBpmn;\n if (childNode.id) {\n originalChildMap.set(childNode.id, childNode);\n }\n }\n\n for (const layoutedChild of layoutedNode.children) {\n const originalChild = originalChildMap.get(layoutedChild.id);\n if (originalChild) {\n this.processEdges(layoutedChild, originalChild, gateways, newOffsetX, newOffsetY);\n }\n }\n }\n }\n\n /**\n * Adjust edge endpoints if they connect to a gateway\n */\n private adjustEdgeEndpoints(\n edge: ElkExtendedEdge,\n gateways: Map<string, GatewayInfo>,\n offsetX: number,\n offsetY: number\n ): void {\n const section = edge.sections![0];\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n if (DEBUG) {\n console.log(`[BPMN] GatewayEdgeAdjuster: Processing edge ${edge.id}, offset=(${offsetX},${offsetY})`);\n console.log(`[BPMN] sourceId=${sourceId}, targetId=${targetId}`);\n console.log(`[BPMN] startPoint=(${section.startPoint.x},${section.startPoint.y}), endPoint=(${section.endPoint.x},${section.endPoint.y})`);\n console.log(`[BPMN] available gateways: ${Array.from(gateways.keys()).join(', ')}`);\n }\n\n // Check if source is a gateway\n const sourceGateway = sourceId ? gateways.get(sourceId) : undefined;\n if (sourceGateway) {\n this.adjustStartPoint(section, sourceGateway, offsetX, offsetY);\n }\n\n // Check if target is a gateway\n const targetGateway = targetId ? gateways.get(targetId) : undefined;\n if (targetGateway) {\n if (DEBUG) {\n console.log(`[BPMN] target gateway: ${targetId}, bounds=(${targetGateway.bounds.x},${targetGateway.bounds.y})`);\n console.log(`[BPMN] left corner: (${targetGateway.corners.left.x},${targetGateway.corners.left.y})`);\n }\n this.adjustEndPoint(edge, section, targetGateway, offsetX, offsetY);\n }\n }\n\n /**\n * Adjust the start point of an edge leaving a gateway\n */\n private adjustStartPoint(\n section: NonNullable<ElkExtendedEdge['sections']>[0],\n gateway: GatewayInfo,\n offsetX: number,\n offsetY: number\n ): void {\n const startX = offsetX + section.startPoint.x;\n const startY = offsetY + section.startPoint.y;\n\n // Find which corner is closest to the current start point\n const corner = this.findClosestCorner(\n { x: startX, y: startY },\n gateway\n );\n\n // Adjust start point to the corner\n section.startPoint = {\n x: corner.x - offsetX,\n y: corner.y - offsetY,\n };\n\n // If there are bend points, adjust the first one to maintain orthogonal routing\n if (section.bendPoints && section.bendPoints.length > 0) {\n const firstBend = section.bendPoints[0];\n const adjustedStart = section.startPoint;\n\n // Check if we need to adjust the bend point for orthogonal routing\n if (Math.abs((offsetX + firstBend.x) - corner.x) < 20) {\n // Bend point is roughly aligned horizontally with corner\n firstBend.x = adjustedStart.x;\n } else if (Math.abs((offsetY + firstBend.y) - corner.y) < 20) {\n // Bend point is roughly aligned vertically with corner\n firstBend.y = adjustedStart.y;\n }\n }\n }\n\n /**\n * Adjust the end point of an edge entering a gateway\n */\n private adjustEndPoint(\n edge: ElkExtendedEdge,\n section: NonNullable<ElkExtendedEdge['sections']>[0],\n gateway: GatewayInfo,\n offsetX: number,\n offsetY: number\n ): void {\n const endX = offsetX + section.endPoint.x;\n const endY = offsetY + section.endPoint.y;\n\n // Determine approach direction from the previous point\n let prevPoint: Point;\n if (section.bendPoints && section.bendPoints.length > 0) {\n const lastBend = section.bendPoints[section.bendPoints.length - 1];\n prevPoint = { x: offsetX + lastBend.x, y: offsetY + lastBend.y };\n } else {\n prevPoint = { x: offsetX + section.startPoint.x, y: offsetY + section.startPoint.y };\n }\n\n // Calculate the approach direction\n const dx = endX - prevPoint.x;\n const dy = endY - prevPoint.y;\n\n // Determine which corner to use based on approach direction\n let targetCorner: Point;\n\n if (Math.abs(dx) > Math.abs(dy)) {\n // Horizontal approach - use left or right corner\n targetCorner = dx > 0 ? gateway.corners.left : gateway.corners.right;\n } else {\n // Vertical approach - use top or bottom corner\n targetCorner = dy > 0 ? gateway.corners.top : gateway.corners.bottom;\n }\n\n // Check if the endpoint is significantly off from the target corner\n const distToCorner = Math.sqrt(\n Math.pow(endX - targetCorner.x, 2) +\n Math.pow(endY - targetCorner.y, 2)\n );\n\n // If endpoint is close to a corner, snap to it\n if (distToCorner < 30) {\n const oldEndX = section.endPoint.x;\n const oldEndY = section.endPoint.y;\n\n section.endPoint = {\n x: targetCorner.x - offsetX,\n y: targetCorner.y - offsetY,\n };\n\n // Adjust the last bend point to maintain orthogonal routing\n if (section.bendPoints && section.bendPoints.length > 0) {\n const lastBend = section.bendPoints[section.bendPoints.length - 1];\n const newEnd = section.endPoint;\n\n // Check if last segment was horizontal\n if (Math.abs((offsetY + lastBend.y) - (offsetY + oldEndY)) < 5) {\n // Was horizontal, keep it horizontal to the new endpoint\n lastBend.y = newEnd.y;\n }\n // Check if last segment was vertical\n else if (Math.abs((offsetX + lastBend.x) - (offsetX + oldEndX)) < 5) {\n // Was vertical, keep it vertical to the new endpoint\n lastBend.x = newEnd.x;\n }\n }\n\n if (DEBUG) {\n console.log(`[BPMN] GatewayEdgeAdjuster: Adjusted edge ${edge.id} endpoint from (${endX},${endY}) to (${targetCorner.x},${targetCorner.y})`);\n }\n } else {\n // Endpoint is far from any corner - might need more complex routing\n // Try to find intersection with diamond edge\n const intersectionPoint = this.findDiamondIntersection(\n prevPoint,\n { x: endX, y: endY },\n gateway\n );\n\n if (intersectionPoint) {\n section.endPoint = {\n x: intersectionPoint.x - offsetX,\n y: intersectionPoint.y - offsetY,\n };\n\n if (DEBUG) {\n console.log(`[BPMN] GatewayEdgeAdjuster: Adjusted edge ${edge.id} endpoint to diamond intersection (${intersectionPoint.x},${intersectionPoint.y})`);\n }\n }\n }\n }\n\n /**\n * Find the closest corner of a gateway to a given point\n */\n private findClosestCorner(point: Point, gateway: GatewayInfo): Point {\n const corners = [\n gateway.corners.left,\n gateway.corners.top,\n gateway.corners.right,\n gateway.corners.bottom,\n ];\n\n let closest = corners[0];\n let minDist = distance(point, closest);\n\n for (let i = 1; i < corners.length; i++) {\n const dist = distance(point, corners[i]);\n if (dist < minDist) {\n minDist = dist;\n closest = corners[i];\n }\n }\n\n return closest;\n }\n\n /**\n * Find intersection point between a line segment and the diamond edges\n */\n private findDiamondIntersection(\n from: Point,\n to: Point,\n gateway: GatewayInfo\n ): Point | null {\n const { corners } = gateway;\n\n // Diamond edges\n const edges: [Point, Point][] = [\n [corners.left, corners.top], // top-left edge\n [corners.top, corners.right], // top-right edge\n [corners.right, corners.bottom], // bottom-right edge\n [corners.bottom, corners.left], // bottom-left edge\n ];\n\n // Find intersection with each edge\n for (const [p1, p2] of edges) {\n const intersection = lineIntersection(from, to, p1, p2);\n if (intersection) {\n return intersection;\n }\n }\n\n return null;\n }\n\n /**\n * Check if a BPMN type is a gateway\n */\n private isGateway(type?: string): boolean {\n if (!type) return false;\n return [\n 'exclusiveGateway',\n 'parallelGateway',\n 'inclusiveGateway',\n 'eventBasedGateway',\n 'complexGateway',\n ].includes(type);\n }\n\n /**\n * Check if a BPMN type is a container\n */\n private isContainer(type?: string): boolean {\n if (!type) return false;\n return [\n 'lane',\n 'participant',\n 'collaboration',\n 'process',\n 'subProcess',\n 'transaction',\n 'adHocSubProcess',\n 'eventSubProcess',\n ].includes(type);\n }\n}\n","/**\n * Default ELK Layout Options\n */\n\nimport type { ElkLayoutOptions } from '../types';\n\nexport const DEFAULT_ELK_OPTIONS: ElkLayoutOptions = {\n 'elk.algorithm': 'layered',\n 'elk.direction': 'RIGHT',\n 'elk.spacing.nodeNode': 50,\n 'elk.spacing.edgeNode': 30,\n 'elk.spacing.edgeEdge': 20,\n 'elk.layered.spacing.nodeNodeBetweenLayers': 80,\n 'elk.layered.spacing.edgeNodeBetweenLayers': 30,\n 'elk.layered.spacing.edgeEdgeBetweenLayers': 20,\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n 'elk.layered.crossingMinimization.strategy': 'LAYER_SWEEP',\n 'elk.layered.nodePlacement.strategy': 'BRANDES_KOEPF',\n 'elk.edgeRouting': 'ORTHOGONAL',\n};\n\n/**\n * Merge user options with default options\n */\nexport function mergeElkOptions(\n userOptions?: ElkLayoutOptions,\n graphOptions?: ElkLayoutOptions\n): ElkLayoutOptions {\n return {\n ...DEFAULT_ELK_OPTIONS,\n ...graphOptions,\n ...userOptions,\n };\n}\n","/**\n * ELK Graph Preparer\n * Prepares BPMN graphs for ELK layout by:\n * - Merging layout options\n * - Converting to ELK-compatible format\n * - Flattening pool/lane structures when needed for cross-pool edges\n * - Handling boundary events as siblings for proper edge routing\n * - Identifying main flow nodes for layout priority\n */\n\nimport type { ElkNode, ElkExtendedEdge, LayoutOptions } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { NodeWithBpmn, BoundaryEventInfo } from '../../types/internal';\nimport { mergeElkOptions } from '../default-options';\nimport { SizeCalculator } from '../size-calculator';\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Handler for preparing graphs for ELK layout\n */\nexport class ElkGraphPreparer {\n private sizeCalculator: SizeCalculator;\n\n constructor() {\n this.sizeCalculator = new SizeCalculator();\n }\n\n /**\n * Prepare the graph for ELK layout\n */\n prepare(\n graph: ElkBpmnGraph,\n userOptions: Record<string, unknown> = {},\n boundaryEventTargetIds: Set<string> = new Set()\n ): ElkNode {\n let layoutOptions = mergeElkOptions(userOptions as Record<string, string | number | boolean | undefined>, graph.layoutOptions);\n\n // Check if this graph contains a cross-pool collaboration\n // If so, force RIGHT direction for better horizontal layout\n if (this.hasCrossPoolCollaboration(graph)) {\n layoutOptions = {\n ...layoutOptions,\n 'elk.direction': 'RIGHT',\n };\n }\n\n // Identify main flow nodes to give them layout priority\n const mainFlowNodes = this.identifyMainFlowNodes(graph, boundaryEventTargetIds);\n\n return {\n id: graph.id ?? 'root',\n layoutOptions: layoutOptions as LayoutOptions,\n children: this.prepareChildrenForElk(graph.children, boundaryEventTargetIds, mainFlowNodes),\n };\n }\n\n /**\n * Check if the graph contains a collaboration with cross-pool sequence flows\n */\n hasCrossPoolCollaboration(graph: ElkBpmnGraph): boolean {\n if (!graph.children) return false;\n\n for (const child of graph.children) {\n const node = child as unknown as NodeWithBpmn;\n if (node.bpmn?.type !== 'collaboration') continue;\n\n // Check if collaboration has multiple pools\n const pools = (node.children as NodeWithBpmn[] | undefined)?.filter(\n c => c.bpmn?.type === 'participant'\n ) ?? [];\n if (pools.length <= 1) continue;\n\n // Check if collaboration has cross-pool sequence flows\n const hasCrossPoolFlows = node.edges?.some(\n edge => edge.bpmn?.type === 'sequenceFlow' ||\n edge.bpmn?.type === 'dataInputAssociation' ||\n edge.bpmn?.type === 'dataOutputAssociation'\n );\n\n if (hasCrossPoolFlows) return true;\n }\n\n return false;\n }\n\n /**\n * Collect all boundary event target IDs from boundary event info\n */\n collectBoundaryEventTargetIds(boundaryEventInfo: Map<string, BoundaryEventInfo>): Set<string> {\n const targetIds = new Set<string>();\n for (const [_beId, info] of boundaryEventInfo) {\n for (const targetId of info.targets) {\n targetIds.add(targetId);\n }\n }\n return targetIds;\n }\n\n /**\n * Collect all boundary event IDs and their target nodes from edges\n */\n collectBoundaryEventTargets(node: NodeWithBpmn): Set<string> {\n const boundaryEventIds = new Set<string>();\n const targetNodeIds = new Set<string>();\n\n // Collect boundary event IDs from this node and children\n const collectBoundaryEventIds = (n: NodeWithBpmn) => {\n if (n.boundaryEvents) {\n for (const be of n.boundaryEvents) {\n boundaryEventIds.add(be.id);\n }\n }\n if (n.children) {\n for (const child of n.children) {\n collectBoundaryEventIds(child as NodeWithBpmn);\n }\n }\n };\n collectBoundaryEventIds(node);\n\n // Find edges where source is a boundary event\n const findTargets = (n: NodeWithBpmn) => {\n if (n.edges) {\n for (const edge of n.edges) {\n const sourceId = edge.sources[0];\n if (boundaryEventIds.has(sourceId)) {\n targetNodeIds.add(edge.targets[0]);\n }\n }\n }\n if (n.children) {\n for (const child of n.children) {\n findTargets(child as NodeWithBpmn);\n }\n }\n };\n findTargets(node);\n\n return targetNodeIds;\n }\n\n /**\n * Identify main flow nodes - nodes that are in the primary path from start to end,\n * not including boundary event branches.\n * Main flow nodes should be prioritized in layout to stay at the top.\n */\n identifyMainFlowNodes(graph: ElkBpmnGraph, boundaryEventTargetIds: Set<string>): Set<string> {\n const mainFlowNodes = new Set<string>();\n const edgeMap = new Map<string, string[]>(); // source -> targets\n const boundaryEventIds = new Set<string>();\n\n // Collect all boundary event IDs and edges\n const collectInfo = (node: NodeWithBpmn) => {\n if (node.boundaryEvents) {\n for (const be of node.boundaryEvents) {\n boundaryEventIds.add(be.id);\n }\n }\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (source && target) {\n if (!edgeMap.has(source)) {\n edgeMap.set(source, []);\n }\n edgeMap.get(source)!.push(target);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n collectInfo(child as NodeWithBpmn);\n }\n }\n };\n\n // Find start events\n const findStartEvents = (node: NodeWithBpmn): string[] => {\n const starts: string[] = [];\n if (node.bpmn?.type === 'startEvent') {\n starts.push(node.id);\n }\n if (node.children) {\n for (const child of node.children) {\n starts.push(...findStartEvents(child as NodeWithBpmn));\n }\n }\n return starts;\n };\n\n // Traverse from start events, following only non-boundary-event edges\n const traverseMainFlow = (nodeId: string) => {\n if (mainFlowNodes.has(nodeId)) return;\n // Don't include boundary event targets as main flow\n if (boundaryEventTargetIds.has(nodeId)) return;\n // Don't include boundary events themselves\n if (boundaryEventIds.has(nodeId)) return;\n\n mainFlowNodes.add(nodeId);\n\n const targets = edgeMap.get(nodeId) || [];\n for (const targetId of targets) {\n // Skip if this edge originates from a boundary event\n if (!boundaryEventIds.has(nodeId)) {\n traverseMainFlow(targetId);\n }\n }\n };\n\n for (const child of graph.children ?? []) {\n collectInfo(child as NodeWithBpmn);\n }\n\n const startEvents = findStartEvents({ children: graph.children } as NodeWithBpmn);\n for (const startId of startEvents) {\n traverseMainFlow(startId);\n }\n\n if (DEBUG) {\n console.log(`[BPMN] Main flow nodes: ${Array.from(mainFlowNodes).join(', ')}`);\n }\n\n return mainFlowNodes;\n }\n\n /**\n * Prepare children for ELK layout\n */\n private prepareChildrenForElk(\n children: ElkBpmnGraph['children'],\n boundaryEventTargetIds: Set<string> = new Set(),\n mainFlowNodes: Set<string> = new Set()\n ): ElkNode[] {\n if (!children) return [];\n\n const result: ElkNode[] = [];\n\n for (const child of children) {\n const node = child as unknown as NodeWithBpmn;\n result.push(this.prepareNodeForElk(node, boundaryEventTargetIds, mainFlowNodes));\n\n // Add boundary events as sibling nodes (not children of the task)\n // This allows ELK to route edges from boundary events correctly\n if (node.boundaryEvents && node.boundaryEvents.length > 0) {\n for (const be of node.boundaryEvents) {\n result.push({\n id: be.id,\n width: be.width ?? 36,\n height: be.height ?? 36,\n });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Prepare a single node for ELK layout\n */\n private prepareNodeForElk(\n node: NodeWithBpmn,\n boundaryEventTargetIds: Set<string> = new Set(),\n mainFlowNodes: Set<string> = new Set()\n ): ElkNode {\n let layoutOptions = node.layoutOptions as LayoutOptions | undefined;\n\n // Add ELK layer constraints for start/end events to ensure proper flow direction\n // startEvent should be in the first layer (leftmost in RIGHT direction)\n // endEvent should be in the last layer (rightmost in RIGHT direction)\n const nodeType = node.bpmn?.type;\n if (nodeType === 'startEvent') {\n layoutOptions = {\n ...layoutOptions,\n 'elk.layered.layering.layerConstraint': 'FIRST',\n } as LayoutOptions;\n } else if (nodeType === 'endEvent') {\n layoutOptions = {\n ...layoutOptions,\n 'elk.layered.layering.layerConstraint': 'LAST',\n } as LayoutOptions;\n }\n\n // Give main flow nodes higher priority so ELK keeps them aligned at the top\n // This ensures the primary flow path is laid out first and stays in optimal position\n if (mainFlowNodes.has(node.id)) {\n layoutOptions = {\n ...layoutOptions,\n 'elk.priority': '10',\n } as LayoutOptions;\n }\n\n // Give boundary event targets lower priority so ELK prioritizes main flow layout\n // This helps prevent exception branches from pulling main flow nodes out of alignment\n if (boundaryEventTargetIds.has(node.id)) {\n layoutOptions = {\n ...layoutOptions,\n 'elk.priority': '0',\n } as LayoutOptions;\n }\n\n // For expanded subprocesses, add top padding for the label header\n const isExpandedSubprocess = node.bpmn?.isExpanded === true &&\n (node.bpmn?.type === 'subProcess' || node.bpmn?.type === 'transaction' ||\n node.bpmn?.type === 'adHocSubProcess' || node.bpmn?.type === 'eventSubProcess');\n\n // Save user-specified padding to preserve it\n const userPadding = layoutOptions?.['elk.padding'];\n\n if (isExpandedSubprocess) {\n layoutOptions = {\n 'elk.padding': '[top=30,left=12,bottom=30,right=12]',\n ...layoutOptions,\n } as LayoutOptions;\n // Restore user padding if specified (it takes precedence)\n if (userPadding) {\n layoutOptions['elk.padding'] = userPadding;\n }\n }\n\n // Check if this is a collaboration with multiple pools and cross-pool sequence flow edges\n // Only flatten nodes when there are actual sequenceFlow edges crossing pools\n // (messageFlow edges are normal for collaborations and don't require flattening)\n const isCollaboration = node.bpmn?.type === 'collaboration';\n const hasMultiplePools = isCollaboration &&\n ((node.children as NodeWithBpmn[] | undefined)?.filter((c) => c.bpmn?.type === 'participant').length ?? 0) > 1;\n\n // Check if any collaboration-level edges are sequenceFlow (cross-pool flow)\n const hasCrossPoolSequenceFlows = isCollaboration && node.edges?.some(\n (edge) => edge.bpmn?.type === 'sequenceFlow' ||\n edge.bpmn?.type === 'dataInputAssociation' ||\n edge.bpmn?.type === 'dataOutputAssociation'\n );\n\n if (isCollaboration && hasCrossPoolSequenceFlows && hasMultiplePools) {\n // For collaborations with cross-pool edges, flatten all pool contents\n // to collaboration level for unified layout\n layoutOptions = {\n ...layoutOptions,\n 'elk.algorithm': 'layered',\n 'elk.direction': 'RIGHT',\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n 'elk.padding': '[top=12,left=12,bottom=12,right=12]',\n } as LayoutOptions;\n\n const elkNode: ElkNode & { bpmn?: NodeWithBpmn['bpmn'] } = {\n id: node.id,\n width: node.width,\n height: node.height,\n layoutOptions,\n bpmn: node.bpmn,\n };\n\n // Flatten all pool contents to collaboration level\n const childNodes: ElkNode[] = [];\n this.extractNodesFromPools(node.children as NodeWithBpmn[], childNodes, boundaryEventTargetIds, mainFlowNodes);\n elkNode.children = childNodes;\n\n // Copy edges to ELK format\n if (node.edges && node.edges.length > 0) {\n elkNode.edges = this.prepareEdges(node.edges);\n }\n\n return elkNode;\n }\n\n // Check if this is a pool (participant)\n const isPool = node.bpmn?.type === 'participant';\n const hasLanes = isPool &&\n (node.children as NodeWithBpmn[] | undefined)?.some((c) => c.bpmn?.type === 'lane');\n\n if (hasLanes) {\n // For pools with lanes, use a different layout strategy:\n // - Use partitioning to create horizontal swim lanes (rows, not columns)\n // - Set direction to RIGHT for flow within lanes\n // - Use 'elk.partitioning.activate' with vertical partitions\n layoutOptions = {\n ...layoutOptions,\n 'elk.algorithm': 'layered',\n 'elk.direction': 'RIGHT',\n // Remove partitioning - we'll handle lane stacking differently\n 'elk.partitioning.activate': 'false',\n // Add padding for lane header (left side)\n 'elk.padding': '[top=12,left=30,bottom=12,right=12]',\n 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',\n } as LayoutOptions;\n } else if (isPool) {\n // For pools without lanes, still add left padding for pool label\n layoutOptions = {\n ...layoutOptions,\n 'elk.algorithm': 'layered',\n 'elk.direction': 'RIGHT',\n // Add padding for pool header (left side) - 55px to accommodate vertical label\n 'elk.padding': '[top=12,left=55,bottom=12,right=12]',\n } as LayoutOptions;\n }\n\n // Check if this is a lane\n const isLane = node.bpmn?.type === 'lane';\n if (isLane) {\n // For lanes, don't set separate layout algorithm - let parent pool handle layout\n // Just set padding for content spacing\n layoutOptions = {\n 'elk.padding': '[top=12,left=12,bottom=12,right=12]',\n } as LayoutOptions;\n }\n\n const elkNode: ElkNode & { bpmn?: NodeWithBpmn['bpmn'] } = {\n id: node.id,\n width: node.width,\n height: node.height,\n layoutOptions,\n bpmn: node.bpmn,\n };\n\n // Process children (including boundary events as siblings)\n if (node.children && node.children.length > 0) {\n const childNodes: ElkNode[] = [];\n\n // For pools with lanes, flatten all lane contents to pool level for unified layout\n // This allows ELK to consider cross-lane edges when positioning nodes\n if (hasLanes) {\n // Recursively extract all flow nodes from lanes (including nested lanes)\n this.extractNodesFromLanes(node.children as NodeWithBpmn[], childNodes, boundaryEventTargetIds, mainFlowNodes);\n } else {\n // Normal processing for non-lane containers\n for (const child of node.children) {\n const childNode = child as NodeWithBpmn;\n childNodes.push(this.prepareNodeForElk(childNode, boundaryEventTargetIds, mainFlowNodes));\n\n // Add boundary events as siblings\n if (childNode.boundaryEvents && childNode.boundaryEvents.length > 0) {\n for (const be of childNode.boundaryEvents) {\n childNodes.push({\n id: be.id,\n width: be.width ?? 36,\n height: be.height ?? 36,\n bpmn: be.bpmn,\n } as ElkNode & { bpmn?: NodeWithBpmn['bpmn'] });\n }\n }\n }\n }\n elkNode.children = childNodes;\n }\n\n // Process edges\n if (node.edges && node.edges.length > 0) {\n elkNode.edges = this.prepareEdges(node.edges);\n }\n\n // Process labels - ensure all labels have dimensions (ELK requires this)\n if (node.labels && node.labels.length > 0) {\n elkNode.labels = node.labels.map((l) => ({\n text: l.text,\n width: l.width ?? this.sizeCalculator.estimateLabelWidth(l.text),\n height: l.height ?? 14,\n }));\n }\n\n // Process ports\n if (node.ports && node.ports.length > 0) {\n elkNode.ports = node.ports.map((p) => ({\n id: p.id,\n width: p.width ?? 10,\n height: p.height ?? 10,\n }));\n }\n\n return elkNode;\n }\n\n /**\n * Prepare edges for ELK format\n */\n private prepareEdges(edges: NodeWithBpmn['edges']): ElkExtendedEdge[] {\n if (!edges) return [];\n\n return edges.map((edge) => ({\n id: edge.id,\n sources: edge.sources,\n targets: edge.targets,\n layoutOptions: edge.layoutOptions as LayoutOptions | undefined,\n labels: edge.labels?.map((l) => ({\n text: l.text,\n width: l.width ?? 50,\n height: l.height ?? 14,\n })),\n })) as ElkExtendedEdge[];\n }\n\n /**\n * Extract all flow nodes from pools to flatten them for unified layout\n * This is used for collaborations with cross-pool edges\n */\n private extractNodesFromPools(\n children: NodeWithBpmn[],\n result: ElkNode[],\n boundaryEventTargetIds: Set<string> = new Set(),\n mainFlowNodes: Set<string> = new Set()\n ): void {\n for (const child of children) {\n if (child.bpmn?.type === 'participant') {\n // Check if this is an empty/black box pool\n const isEmpty = !child.children || child.children.length === 0;\n\n if (isEmpty) {\n // Add the pool itself as a node (for message flows targeting the pool)\n result.push({\n id: child.id,\n width: child.width ?? 680,\n height: child.height ?? 60,\n bpmn: child.bpmn,\n } as ElkNode & { bpmn?: NodeWithBpmn['bpmn'] });\n } else {\n // Extract nodes from this pool\n // Check if pool has lanes\n const hasLanes = child.children!.some((c) => (c as NodeWithBpmn).bpmn?.type === 'lane');\n if (hasLanes) {\n this.extractNodesFromLanes(child.children! as NodeWithBpmn[], result, boundaryEventTargetIds, mainFlowNodes);\n } else {\n // Direct children of pool (no lanes)\n for (const poolChild of child.children!) {\n const node = poolChild as NodeWithBpmn;\n result.push(this.prepareNodeForElk(node, boundaryEventTargetIds, mainFlowNodes));\n\n // Add boundary events as siblings\n if (node.boundaryEvents && node.boundaryEvents.length > 0) {\n for (const be of node.boundaryEvents) {\n result.push({\n id: be.id,\n width: be.width ?? 36,\n height: be.height ?? 36,\n bpmn: be.bpmn,\n } as ElkNode & { bpmn?: NodeWithBpmn['bpmn'] });\n }\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Recursively extract all flow nodes from lanes (including nested lanes)\n * and add them to the result array for unified ELK layout\n */\n private extractNodesFromLanes(\n children: NodeWithBpmn[],\n result: ElkNode[],\n boundaryEventTargetIds: Set<string> = new Set(),\n mainFlowNodes: Set<string> = new Set()\n ): void {\n for (const child of children) {\n if (child.bpmn?.type === 'lane') {\n // Recursively extract from nested lanes\n if (child.children) {\n this.extractNodesFromLanes(child.children as NodeWithBpmn[], result, boundaryEventTargetIds, mainFlowNodes);\n }\n } else {\n // Non-lane node - add to result\n result.push(this.prepareNodeForElk(child, boundaryEventTargetIds, mainFlowNodes));\n\n // Add boundary events as siblings\n if (child.boundaryEvents && child.boundaryEvents.length > 0) {\n for (const be of child.boundaryEvents) {\n result.push({\n id: be.id,\n width: be.width ?? 36,\n height: be.height ?? 36,\n bpmn: be.bpmn,\n } as ElkNode & { bpmn?: NodeWithBpmn['bpmn'] });\n }\n }\n }\n }\n }\n}\n","/**\n * Result Merger\n * Merges ELK layout results back with original BPMN metadata.\n * Preserves BPMN-specific properties while applying layout coordinates.\n */\n\nimport type { ElkNode, ElkExtendedEdge } from 'elkjs';\nimport type { ElkBpmnGraph, LayoutedGraph } from '../../types';\nimport type { NodeWithBpmn } from '../../types/internal';\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Handler for merging layout results with original BPMN data\n */\nexport class ResultMerger {\n /**\n * Merge ELK layout results back with original BPMN metadata\n */\n merge(original: ElkBpmnGraph, layouted: ElkNode): LayoutedGraph {\n const result: LayoutedGraph = {\n ...original,\n x: layouted.x,\n y: layouted.y,\n width: layouted.width,\n height: layouted.height,\n children: [],\n };\n\n // Merge children by ID\n if (original.children && layouted.children) {\n const layoutedChildMap = new Map(layouted.children.map((c) => [c.id, c]));\n\n result.children = original.children.map((origChild) => {\n const layoutedChild = layoutedChildMap.get(origChild.id);\n if (layoutedChild) {\n return this.mergeNodeResults(\n origChild as unknown as NodeWithBpmn,\n layoutedChild\n );\n }\n return origChild as unknown as LayoutedGraph['children'][number];\n }) as LayoutedGraph['children'];\n }\n\n return result;\n }\n\n /**\n * Merge a single node's layout results with original BPMN data\n */\n private mergeNodeResults(original: NodeWithBpmn, layouted: ElkNode): NodeWithBpmn {\n const result: NodeWithBpmn = {\n ...original,\n x: layouted.x ?? 0,\n y: layouted.y ?? 0,\n width: layouted.width ?? original.width,\n height: layouted.height ?? original.height,\n };\n\n // Merge children\n if (original.children && layouted.children) {\n const layoutedChildMap = new Map(layouted.children.map((c) => [c.id, c]));\n\n result.children = original.children.map((origChild) => {\n const layoutedChild = layoutedChildMap.get((origChild as NodeWithBpmn).id);\n if (layoutedChild) {\n return this.mergeNodeResults(origChild as NodeWithBpmn, layoutedChild);\n }\n return origChild;\n });\n }\n\n // Keep boundary events as-is (their positions are calculated in model-builder.ts)\n if (original.boundaryEvents) {\n result.boundaryEvents = original.boundaryEvents;\n }\n\n // Merge edges\n if (original.edges && layouted.edges) {\n result.edges = this.mergeEdges(original.edges, layouted.edges);\n }\n\n // Merge labels\n if (original.labels && layouted.labels) {\n result.labels = original.labels.map((label, idx) => {\n const layoutedLabel = layouted.labels?.[idx];\n if (layoutedLabel) {\n return {\n ...label,\n x: layoutedLabel.x ?? 0,\n y: layoutedLabel.y ?? 0,\n width: layoutedLabel.width ?? label.width,\n height: layoutedLabel.height ?? label.height,\n };\n }\n return label;\n });\n }\n\n return result;\n }\n\n /**\n * Merge edge layout results\n */\n private mergeEdges(\n originalEdges: NodeWithBpmn['edges'],\n layoutedEdges: ElkExtendedEdge[]\n ): NodeWithBpmn['edges'] {\n if (!originalEdges) return undefined;\n\n const layoutedEdgeMap = new Map(layoutedEdges.map((e) => [e.id, e]));\n\n return originalEdges.map((origEdge) => {\n const layoutedEdge = layoutedEdgeMap.get(origEdge.id);\n if (layoutedEdge) {\n if (DEBUG && layoutedEdge.sections?.[0]?.bendPoints?.length) {\n console.log(`[BPMN] Merge ${origEdge.id}: bendPoints=${JSON.stringify(layoutedEdge.sections[0].bendPoints)}`);\n }\n\n const mergedEdge: typeof origEdge & { _absoluteCoords?: boolean; _poolRelativeCoords?: boolean } = {\n ...origEdge,\n sections: layoutedEdge.sections ?? [],\n labels: origEdge.labels?.map((label, idx) => {\n const layoutedLabel = layoutedEdge.labels?.[idx];\n if (layoutedLabel) {\n return {\n ...label,\n x: layoutedLabel.x ?? 0,\n y: layoutedLabel.y ?? 0,\n width: layoutedLabel.width ?? label.width ?? 50,\n height: layoutedLabel.height ?? label.height ?? 14,\n };\n }\n return label;\n }),\n };\n\n // Preserve the _absoluteCoords flag for message flows\n if ((layoutedEdge as { _absoluteCoords?: boolean })._absoluteCoords) {\n mergedEdge._absoluteCoords = true;\n }\n\n // Preserve the _poolRelativeCoords flag for pool edges\n if ((layoutedEdge as { _poolRelativeCoords?: boolean })._poolRelativeCoords) {\n mergedEdge._poolRelativeCoords = true;\n }\n\n return mergedEdge;\n }\n return origEdge;\n });\n }\n}\n","/**\n * Main Flow Normalizer\n * Normalizes main flow position to keep it at the top of the diagram.\n * ELK may place the main flow lower to accommodate boundary event branches,\n * but we want the main flow to stay at a consistent top position.\n */\n\nimport type { ElkNode } from 'elkjs';\nimport type { ElkBpmnGraph } from '../../types';\nimport type { NodeWithBpmn } from '../../types/internal';\nimport { DEBUG } from '../../utils/debug';\n\nconst TARGET_MAIN_FLOW_Y = 12; // Target Y position for main flow (with padding)\nconst GATEWAY_OFFSET_Y = 150; // How far below main flow the converging gateway should be\n\n/**\n * Handler for normalizing main flow position\n */\nexport class MainFlowNormalizer {\n /**\n * Normalize main flow position to keep it at the top of the diagram.\n *\n * Strategy:\n * 1. Identify \"upstream main flow\" nodes (before converging gateway)\n * 2. Shift these nodes up to target Y\n * 3. Position converging gateway below the main flow\n * 4. Position downstream nodes (after gateway) relative to gateway\n */\n normalize(\n graph: ElkNode,\n mainFlowNodes: Set<string>,\n boundaryEventTargetIds: Set<string>,\n originalGraph: ElkBpmnGraph\n ): void {\n // Build node map and track which nodes are inside subprocesses (have local coordinates)\n const nodeMap = new Map<string, ElkNode>();\n const nodesInsideContainers = new Set<string>(); // Nodes that shouldn't be moved (local coords)\n const buildNodeMap = (node: ElkNode, parentIsContainer = false) => {\n nodeMap.set(node.id, node);\n if (parentIsContainer) {\n nodesInsideContainers.add(node.id);\n }\n if (node.children) {\n // Check if this node is a container (subprocess, transaction, etc.)\n const nodeType = this.getNodeTypeFromOriginal(node.id, originalGraph);\n const isContainer = nodeType === 'subProcess' || nodeType === 'transaction' ||\n nodeType === 'adHocSubProcess' || nodeType === 'eventSubProcess';\n for (const child of node.children) {\n buildNodeMap(child, isContainer || parentIsContainer);\n }\n }\n };\n buildNodeMap(graph);\n\n // Find converging gateways and separate main flow into upstream/downstream\n const convergingGatewayIds = new Set<string>();\n const upstreamMainFlow: ElkNode[] = []; // Nodes before converging gateway\n const downstreamMainFlow: ElkNode[] = []; // Nodes after converging gateway (including gateway)\n\n // First pass: identify converging gateways\n // Note: endEvents should stay on main flow line even if they receive boundary inputs\n for (const nodeId of mainFlowNodes) {\n if (this.isConvergingGatewayWithBoundaryInputs(nodeId, graph, boundaryEventTargetIds)) {\n // Check if this is an endEvent - if so, keep it on main flow line\n // Use originalGraph to access BPMN type info (not preserved in ELK graph)\n const nodeType = this.getNodeTypeFromOriginal(nodeId, originalGraph);\n const isEndEvent = nodeType === 'endEvent';\n if (!isEndEvent) {\n convergingGatewayIds.add(nodeId);\n }\n }\n }\n\n // Second pass: categorize nodes as upstream or downstream of converging gateway\n // Build edge map to trace flow\n const edgeMap = new Map<string, string[]>();\n const collectEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (source && target) {\n if (!edgeMap.has(source)) edgeMap.set(source, []);\n edgeMap.get(source)!.push(target);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n collectEdges(child);\n }\n }\n };\n collectEdges(graph);\n\n // Find nodes downstream of converging gateways\n const downstreamNodeIds = new Set<string>();\n const markDownstream = (nodeId: string) => {\n if (downstreamNodeIds.has(nodeId)) return;\n downstreamNodeIds.add(nodeId);\n const targets = edgeMap.get(nodeId) || [];\n for (const targetId of targets) {\n if (mainFlowNodes.has(targetId)) {\n markDownstream(targetId);\n }\n }\n };\n for (const gatewayId of convergingGatewayIds) {\n markDownstream(gatewayId);\n }\n\n // Categorize main flow nodes (excluding nodes inside containers - they have local coordinates)\n for (const nodeId of mainFlowNodes) {\n // Skip nodes that are inside subprocesses - they have local coordinates\n if (nodesInsideContainers.has(nodeId)) continue;\n\n const node = nodeMap.get(nodeId);\n if (!node || node.y === undefined) continue;\n\n if (downstreamNodeIds.has(nodeId)) {\n downstreamMainFlow.push(node);\n } else {\n upstreamMainFlow.push(node);\n }\n }\n\n // Separate endEvents from other upstream nodes - they need special alignment\n const endEventNodes: ElkNode[] = [];\n const otherUpstreamNodes: ElkNode[] = [];\n for (const node of upstreamMainFlow) {\n const nodeType = this.getNodeTypeFromOriginal(node.id, originalGraph);\n if (nodeType === 'endEvent') {\n endEventNodes.push(node);\n } else {\n otherUpstreamNodes.push(node);\n }\n }\n\n // Find current min Y of non-endEvent upstream main flow nodes\n let currentMinY = Infinity;\n for (const node of otherUpstreamNodes) {\n if (node.y !== undefined) {\n currentMinY = Math.min(currentMinY, node.y);\n }\n }\n\n if (currentMinY === Infinity || currentMinY <= TARGET_MAIN_FLOW_Y) {\n // Main flow is already at or above target position, no normalization needed\n return;\n }\n\n // Calculate the offset to shift upstream main flow up\n const offsetY = currentMinY - TARGET_MAIN_FLOW_Y;\n\n if (DEBUG) {\n console.log(`[BPMN] Normalizing main flow: currentMinY=${currentMinY}, offsetY=${offsetY}`);\n console.log(`[BPMN] Upstream nodes: ${upstreamMainFlow.map(n => n.id).join(', ')}`);\n console.log(`[BPMN] Downstream nodes: ${downstreamMainFlow.map(n => n.id).join(', ')}`);\n }\n\n // Shift non-endEvent upstream main flow nodes up\n for (const node of otherUpstreamNodes) {\n if (node.y !== undefined) {\n node.y -= offsetY;\n if (DEBUG) {\n console.log(`[BPMN] Shifted upstream ${node.id} to y=${node.y}`);\n }\n }\n }\n\n // Align endEvents with their predecessor's vertical center\n // Find the main container (e.g., subprocess, task) that precedes the endEvent\n for (const endNode of endEventNodes) {\n const predecessorId = this.findPredecessorOnMainFlow(endNode.id, graph, mainFlowNodes);\n if (predecessorId) {\n const predecessor = nodeMap.get(predecessorId);\n if (predecessor && predecessor.y !== undefined) {\n // Align endEvent center with predecessor's vertical center\n const predecessorCenterY = predecessor.y + (predecessor.height ?? 80) / 2;\n const endNodeCenterY = (endNode.height ?? 36) / 2;\n endNode.y = predecessorCenterY - endNodeCenterY;\n if (DEBUG) {\n console.log(`[BPMN] Aligned endEvent ${endNode.id} with predecessor ${predecessorId}: y=${endNode.y}`);\n }\n }\n } else {\n // Fallback: shift like other nodes\n if (endNode.y !== undefined) {\n endNode.y -= offsetY;\n if (DEBUG) {\n console.log(`[BPMN] Shifted upstream ${endNode.id} to y=${endNode.y} (no predecessor found)`);\n }\n }\n }\n }\n\n // Fix overlapping endEvents at the same X position\n // Group endEvents by X position and adjust Y to prevent overlaps\n const endEventsByX = new Map<number, ElkNode[]>();\n for (const endNode of endEventNodes) {\n const x = endNode.x ?? 0;\n if (!endEventsByX.has(x)) {\n endEventsByX.set(x, []);\n }\n endEventsByX.get(x)!.push(endNode);\n }\n\n // Track nodes that were adjusted for overlap (need edge updates)\n const adjustedEndEvents = new Map<string, number>(); // nodeId -> new Y position\n\n const MIN_SPACING = 50; // Minimum spacing between endEvents\n for (const [x, nodesAtX] of endEventsByX) {\n if (nodesAtX.length <= 1) continue;\n\n // Sort by Y position\n nodesAtX.sort((a, b) => (a.y ?? 0) - (b.y ?? 0));\n\n // Check for overlaps and adjust\n for (let i = 1; i < nodesAtX.length; i++) {\n const prevNode = nodesAtX[i - 1];\n const currNode = nodesAtX[i];\n const prevBottom = (prevNode.y ?? 0) + (prevNode.height ?? 36);\n const currTop = currNode.y ?? 0;\n\n if (currTop < prevBottom + MIN_SPACING) {\n // Move current node down to avoid overlap\n const newY = prevBottom + MIN_SPACING;\n currNode.y = newY;\n adjustedEndEvents.set(currNode.id, newY);\n if (DEBUG) {\n console.log(`[BPMN] Adjusted overlapping endEvent ${currNode.id} at x=${x}: y=${currNode.y}`);\n }\n }\n }\n }\n\n // Update edges that connect to adjusted endEvents\n // Track which edges had their endpoint updated (so we skip endpoint update later, but still update source side)\n const edgesWithAdjustedEndpoint = new Set<string>();\n if (adjustedEndEvents.size > 0) {\n this.updateEdgesForAdjustedEndEvents(graph, adjustedEndEvents, nodeMap, edgesWithAdjustedEndpoint);\n }\n\n // Calculate target Y for downstream nodes (converging gateway and after)\n // The gateway should be positioned below the main flow\n const mainFlowBottom = Math.max(...upstreamMainFlow.map(n => (n.y ?? 0) + (n.height ?? 80)));\n const targetGatewayY = mainFlowBottom + GATEWAY_OFFSET_Y;\n\n // Find current gateway Y to calculate downstream offset\n let currentGatewayY = Infinity;\n for (const gatewayId of convergingGatewayIds) {\n const gateway = nodeMap.get(gatewayId);\n if (gateway && gateway.y !== undefined) {\n currentGatewayY = Math.min(currentGatewayY, gateway.y);\n }\n }\n\n if (currentGatewayY !== Infinity) {\n const downstreamOffsetY = currentGatewayY - targetGatewayY;\n\n // Shift downstream nodes (gateway and nodes after it)\n for (const node of downstreamMainFlow) {\n if (node.y !== undefined) {\n node.y -= downstreamOffsetY;\n if (DEBUG) {\n console.log(`[BPMN] Shifted downstream ${node.id} to y=${node.y}`);\n }\n }\n }\n }\n\n // Update boundary event positions\n for (const [nodeId, node] of nodeMap) {\n if (node.y !== undefined && nodeId.startsWith('boundary_')) {\n const attachedNodeId = this.findBoundaryAttachedNode(nodeId, graph);\n if (attachedNodeId && mainFlowNodes.has(attachedNodeId)) {\n const attachedNode = nodeMap.get(attachedNodeId);\n if (attachedNode && attachedNode.y !== undefined) {\n const attachedBottom = attachedNode.y + (attachedNode.height ?? 80);\n node.y = attachedBottom - (node.height ?? 36) / 2;\n }\n }\n }\n }\n\n // Update edges that connect main flow nodes\n // For edges with adjusted endpoints, only update source side (startPoint and early bendPoints)\n this.updateEdgesAfterNormalization(graph, [...upstreamMainFlow, ...downstreamMainFlow], offsetY, edgesWithAdjustedEndpoint);\n }\n\n /**\n * Find the predecessor node of a given node on the main flow\n */\n private findPredecessorOnMainFlow(\n nodeId: string,\n graph: ElkNode,\n mainFlowNodes: Set<string>\n ): string | undefined {\n // Find incoming edges to this node from main flow\n const findIncoming = (node: ElkNode): string | undefined => {\n if (node.edges) {\n for (const edge of node.edges) {\n const target = edge.targets?.[0];\n const source = edge.sources?.[0];\n if (target === nodeId && source && mainFlowNodes.has(source)) {\n // Skip boundary events\n if (!source.includes('boundary')) {\n return source;\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n const result = findIncoming(child);\n if (result) return result;\n }\n }\n return undefined;\n };\n return findIncoming(graph);\n }\n\n /**\n * Get the BPMN type of a node by searching the original graph (with BPMN info preserved)\n */\n private getNodeTypeFromOriginal(nodeId: string, graph: ElkBpmnGraph): string | undefined {\n const findType = (children: ElkBpmnGraph['children']): string | undefined => {\n if (!children) return undefined;\n for (const child of children) {\n const node = child as unknown as NodeWithBpmn;\n if (node.id === nodeId) {\n return node.bpmn?.type;\n }\n // Check in nested children\n if (node.children) {\n const result = findType(node.children as ElkBpmnGraph['children']);\n if (result) return result;\n }\n }\n return undefined;\n };\n return findType(graph.children);\n }\n\n /**\n * Check if a node is a converging gateway that receives edges from both\n * main flow and boundary event branches (should be positioned below main flow)\n */\n private isConvergingGatewayWithBoundaryInputs(\n nodeId: string,\n graph: ElkNode,\n boundaryEventTargetIds: Set<string>\n ): boolean {\n // Collect all incoming edges to this node\n const incomingSources: string[] = [];\n\n const collectIncoming = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const target = edge.targets?.[0];\n const source = edge.sources?.[0];\n if (target === nodeId && source) {\n incomingSources.push(source);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n collectIncoming(child);\n }\n }\n };\n collectIncoming(graph);\n\n if (incomingSources.length <= 1) return false;\n\n // Check if any incoming source is a boundary event target (or downstream of one)\n let hasMainFlowInput = false;\n let hasBoundaryInput = false;\n\n for (const sourceId of incomingSources) {\n if (boundaryEventTargetIds.has(sourceId) || this.isDownstreamOfBoundaryTarget(sourceId, graph, boundaryEventTargetIds)) {\n hasBoundaryInput = true;\n } else if (!sourceId.startsWith('boundary_')) {\n hasMainFlowInput = true;\n }\n }\n\n return hasMainFlowInput && hasBoundaryInput;\n }\n\n /**\n * Check if a node is downstream of a boundary event target\n */\n private isDownstreamOfBoundaryTarget(\n nodeId: string,\n graph: ElkNode,\n boundaryEventTargetIds: Set<string>,\n visited: Set<string> = new Set()\n ): boolean {\n if (visited.has(nodeId)) return false;\n visited.add(nodeId);\n\n if (boundaryEventTargetIds.has(nodeId)) return true;\n\n // Find incoming edges to this node\n const findIncoming = (node: ElkNode): string[] => {\n const sources: string[] = [];\n if (node.edges) {\n for (const edge of node.edges) {\n if (edge.targets?.[0] === nodeId) {\n sources.push(edge.sources?.[0] ?? '');\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n sources.push(...findIncoming(child));\n }\n }\n return sources.filter(s => s);\n };\n\n const sources = findIncoming(graph);\n for (const sourceId of sources) {\n if (this.isDownstreamOfBoundaryTarget(sourceId, graph, boundaryEventTargetIds, visited)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Find the node that a boundary event is attached to\n */\n private findBoundaryAttachedNode(boundaryEventId: string, graph: ElkNode): string | null {\n // In our graph structure, boundary events are defined in the original sizedGraph\n // but in ELK they're siblings. We need to check the original structure.\n // For now, use a heuristic: boundary event ID contains the parent node name\n // e.g., \"boundary_error_call_order\" is attached to \"call_activity_order\"\n\n // This is a simplified approach - in a real implementation, we'd track this mapping\n const parts = boundaryEventId.replace('boundary_', '').split('_');\n if (parts.length >= 2) {\n // Try to reconstruct the parent node ID\n // e.g., \"error_call_order\" -> try \"call_activity_order\"\n const suffix = parts.slice(1).join('_');\n const possibleParents = ['call_activity_' + suffix, 'task_' + suffix, suffix];\n\n const nodeMap = new Map<string, ElkNode>();\n const buildMap = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.children) {\n for (const child of node.children) {\n buildMap(child);\n }\n }\n };\n buildMap(graph);\n\n for (const parentId of possibleParents) {\n if (nodeMap.has(parentId)) {\n return parentId;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Update edges after normalization to adjust waypoints\n */\n /**\n * Update edges that connect to endEvents that were adjusted for overlap\n */\n private updateEdgesForAdjustedEndEvents(\n graph: ElkNode,\n adjustedEndEvents: Map<string, number>,\n nodeMap: Map<string, ElkNode>,\n edgesWithAdjustedEndpoint: Set<string>\n ): void {\n const updateEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const targetId = edge.targets?.[0];\n if (targetId && adjustedEndEvents.has(targetId)) {\n const targetNode = nodeMap.get(targetId);\n if (!targetNode) continue;\n\n // Calculate new endpoint Y: center of the adjusted endEvent\n const newTargetY = (targetNode.y ?? 0) + (targetNode.height ?? 36) / 2;\n\n if (edge.sections) {\n for (const section of edge.sections) {\n // Also update last bendPoint if the last segment is horizontal\n // (i.e., last bendPoint and endPoint have same Y)\n if (section.bendPoints && section.bendPoints.length > 0 && section.endPoint) {\n const lastBend = section.bendPoints[section.bendPoints.length - 1];\n const oldEndY = section.endPoint.y;\n\n // If last segment is horizontal (same Y), update both bendPoint and endpoint\n if (Math.abs(lastBend.y - oldEndY) < 1) {\n lastBend.y = newTargetY;\n section.endPoint.y = newTargetY;\n edgesWithAdjustedEndpoint.add(edge.id);\n if (DEBUG) {\n console.log(`[BPMN] Updated edge ${edge.id} last bendPoint and endpoint to y=${newTargetY}`);\n }\n } else {\n // Last segment is vertical, just update endpoint\n section.endPoint.y = newTargetY;\n edgesWithAdjustedEndpoint.add(edge.id);\n if (DEBUG) {\n console.log(`[BPMN] Updated edge ${edge.id} endpoint to y=${newTargetY}`);\n }\n }\n } else if (section.endPoint) {\n // No bendPoints, just update endpoint\n section.endPoint.y = newTargetY;\n edgesWithAdjustedEndpoint.add(edge.id);\n if (DEBUG) {\n console.log(`[BPMN] Updated edge ${edge.id} endpoint to y=${newTargetY}`);\n }\n }\n }\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n updateEdges(child);\n }\n }\n };\n updateEdges(graph);\n }\n\n private updateEdgesAfterNormalization(\n graph: ElkNode,\n movedNodes: ElkNode[],\n offsetY: number,\n edgesWithAdjustedEndpoint: Set<string> = new Set()\n ): void {\n const movedNodeIds = new Set(movedNodes.map(n => n.id));\n\n const updateEdges = (node: ElkNode) => {\n if (node.edges) {\n for (const edge of node.edges) {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n const sourceMoved = sourceId && movedNodeIds.has(sourceId);\n const targetMoved = targetId && movedNodeIds.has(targetId);\n const endpointAlreadyAdjusted = edgesWithAdjustedEndpoint.has(edge.id);\n\n // If both source and target moved\n if (sourceMoved && targetMoved && edge.sections) {\n for (const section of edge.sections) {\n // Always update startPoint\n if (section.startPoint) {\n section.startPoint.y -= offsetY;\n }\n // Update endPoint only if not already adjusted\n if (section.endPoint && !endpointAlreadyAdjusted) {\n section.endPoint.y -= offsetY;\n }\n // Update bendPoints - for adjusted endpoint edges, skip the last one\n if (section.bendPoints) {\n const bendCount = section.bendPoints.length;\n for (let i = 0; i < bendCount; i++) {\n // Skip last bendPoint if endpoint was already adjusted\n if (endpointAlreadyAdjusted && i === bendCount - 1) continue;\n section.bendPoints[i].y -= offsetY;\n }\n }\n }\n }\n // If only source moved, adjust start point\n else if (sourceMoved && !targetMoved && edge.sections) {\n for (const section of edge.sections) {\n if (section.startPoint) {\n section.startPoint.y -= offsetY;\n }\n }\n }\n // If only target moved, adjust end point (but not if already adjusted)\n else if (!sourceMoved && targetMoved && edge.sections && !endpointAlreadyAdjusted) {\n for (const section of edge.sections) {\n if (section.endPoint) {\n section.endPoint.y -= offsetY;\n }\n }\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n updateEdges(child);\n }\n }\n };\n updateEdges(graph);\n }\n}\n","/**\n * Gateway Propagator\n * Propagates gateway movement to downstream nodes.\n * When a gateway is moved, its downstream nodes in the main flow\n * need to be repositioned accordingly to maintain proper layout.\n */\n\nimport type { ElkNode } from 'elkjs';\nimport type { NodeMoveInfo } from '../../types/internal';\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Handler for propagating gateway movement to downstream nodes\n */\nexport class GatewayPropagator {\n /**\n * Propagate gateway movement to downstream nodes (nodes after the gateway in the flow)\n */\n propagate(\n graph: ElkNode,\n gatewayMoves: Map<string, NodeMoveInfo>,\n mainFlowNodes: Set<string>\n ): void {\n // Build node and edge maps\n const nodeMap = new Map<string, ElkNode>();\n const edgeMap = new Map<string, string[]>(); // source -> targets\n\n const buildMaps = (node: ElkNode) => {\n nodeMap.set(node.id, node);\n if (node.edges) {\n for (const edge of node.edges) {\n const source = edge.sources?.[0];\n const target = edge.targets?.[0];\n if (source && target) {\n if (!edgeMap.has(source)) edgeMap.set(source, []);\n edgeMap.get(source)!.push(target);\n }\n }\n }\n if (node.children) {\n for (const child of node.children) {\n buildMaps(child);\n }\n }\n };\n buildMaps(graph);\n\n // For each moved gateway, move its downstream main flow nodes\n for (const [gatewayId, gatewayMove] of gatewayMoves) {\n if (gatewayMove.newX === undefined) continue;\n\n const gateway = nodeMap.get(gatewayId);\n if (!gateway) continue;\n\n const gatewayRight = gatewayMove.newX + (gateway.width ?? 50);\n const downstreamTargets = edgeMap.get(gatewayId) || [];\n\n for (const targetId of downstreamTargets) {\n // Only move main flow nodes downstream of gateway\n if (!mainFlowNodes.has(targetId)) continue;\n\n const targetNode = nodeMap.get(targetId);\n if (!targetNode) continue;\n\n // Position target to the right of gateway\n const newX = gatewayRight + 50;\n const currentX = targetNode.x ?? 0;\n\n if (newX > currentX) {\n targetNode.x = newX;\n gatewayMoves.set(targetId, {\n newY: targetNode.y ?? 0,\n offset: 0,\n newX: newX,\n });\n\n if (DEBUG) {\n console.log(`[BPMN] Propagating gateway movement to ${targetId}: x ${currentX} -> ${newX}`);\n }\n\n // Recursively move further downstream nodes\n this.propagateDownstreamX(targetId, newX, targetNode.width ?? 100, nodeMap, edgeMap, mainFlowNodes, gatewayMoves);\n }\n }\n }\n }\n\n /**\n * Recursively propagate X movement to downstream main flow nodes\n */\n private propagateDownstreamX(\n sourceId: string,\n sourceX: number,\n sourceWidth: number,\n nodeMap: Map<string, ElkNode>,\n edgeMap: Map<string, string[]>,\n mainFlowNodes: Set<string>,\n moves: Map<string, NodeMoveInfo>\n ): void {\n const targets = edgeMap.get(sourceId) || [];\n const sourceRight = sourceX + sourceWidth;\n\n for (const targetId of targets) {\n if (!mainFlowNodes.has(targetId)) continue;\n if (moves.has(targetId)) continue; // Already moved\n\n const targetNode = nodeMap.get(targetId);\n if (!targetNode) continue;\n\n const newX = sourceRight + 50;\n const currentX = targetNode.x ?? 0;\n\n if (newX > currentX) {\n targetNode.x = newX;\n moves.set(targetId, {\n newY: targetNode.y ?? 0,\n offset: 0,\n newX: newX,\n });\n\n if (DEBUG) {\n console.log(`[BPMN] Propagating X to ${targetId}: x ${currentX} -> ${newX}`);\n }\n\n this.propagateDownstreamX(targetId, newX, targetNode.width ?? 100, nodeMap, edgeMap, mainFlowNodes, moves);\n }\n }\n }\n}\n","/**\n * Reference Resolver\n * Builds incoming/outgoing references for BPMN flow nodes\n */\n\nimport type { LayoutedGraph } from '../types/elk-output';\n\ninterface EdgeInfo {\n id: string;\n sourceRef: string;\n targetRef: string;\n type: 'sequenceFlow' | 'messageFlow' | 'dataInputAssociation' | 'dataOutputAssociation' | 'association';\n}\n\ninterface NodeInfo {\n id: string;\n type: string;\n parentId?: string;\n}\n\nexport class ReferenceResolver {\n private nodeMap: Map<string, NodeInfo> = new Map();\n private edgesBySource: Map<string, EdgeInfo[]> = new Map();\n private edgesByTarget: Map<string, EdgeInfo[]> = new Map();\n private allEdges: EdgeInfo[] = [];\n\n /**\n * Resolve all references in the graph\n */\n resolve(graph: LayoutedGraph): void {\n this.clear();\n this.indexGraph(graph);\n }\n\n /**\n * Clear all cached data\n */\n clear(): void {\n this.nodeMap.clear();\n this.edgesBySource.clear();\n this.edgesByTarget.clear();\n this.allEdges = [];\n }\n\n /**\n * Get incoming edge IDs for a node\n */\n getIncoming(nodeId: string): string[] {\n const edges = this.edgesByTarget.get(nodeId);\n return edges?.map((e) => e.id) ?? [];\n }\n\n /**\n * Get outgoing edge IDs for a node\n */\n getOutgoing(nodeId: string): string[] {\n const edges = this.edgesBySource.get(nodeId);\n return edges?.map((e) => e.id) ?? [];\n }\n\n /**\n * Get incoming sequence flows for a node\n */\n getIncomingSequenceFlows(nodeId: string): string[] {\n const edges = this.edgesByTarget.get(nodeId);\n return edges?.filter((e) => e.type === 'sequenceFlow').map((e) => e.id) ?? [];\n }\n\n /**\n * Get outgoing sequence flows for a node\n */\n getOutgoingSequenceFlows(nodeId: string): string[] {\n const edges = this.edgesBySource.get(nodeId);\n return edges?.filter((e) => e.type === 'sequenceFlow').map((e) => e.id) ?? [];\n }\n\n /**\n * Get all edges\n */\n getAllEdges(): EdgeInfo[] {\n return this.allEdges;\n }\n\n /**\n * Get node by ID\n */\n getNode(nodeId: string): NodeInfo | undefined {\n return this.nodeMap.get(nodeId);\n }\n\n /**\n * Get all nodes\n */\n getAllNodes(): Map<string, NodeInfo> {\n return this.nodeMap;\n }\n\n /**\n * Check if a node exists\n */\n hasNode(nodeId: string): boolean {\n return this.nodeMap.has(nodeId);\n }\n\n /**\n * Index the entire graph\n */\n private indexGraph(graph: LayoutedGraph): void {\n for (const child of graph.children) {\n this.indexNode(child as unknown as GraphNode);\n }\n }\n\n /**\n * Recursively index a node and its children\n */\n private indexNode(node: GraphNode, parentId?: string): void {\n // Index the node itself (skip containers like collaboration)\n if (node.bpmn && node.bpmn.type !== 'collaboration') {\n this.nodeMap.set(node.id, {\n id: node.id,\n type: node.bpmn.type,\n parentId,\n });\n }\n\n // Index children\n if (node.children) {\n for (const child of node.children) {\n this.indexNode(child as GraphNode, node.id);\n }\n }\n\n // Index boundary events\n if (node.boundaryEvents) {\n for (const be of node.boundaryEvents) {\n this.nodeMap.set(be.id, {\n id: be.id,\n type: 'boundaryEvent',\n parentId: node.id,\n });\n }\n }\n\n // Index edges\n if (node.edges) {\n for (const edge of node.edges) {\n this.indexEdge(edge);\n }\n }\n }\n\n /**\n * Index an edge\n */\n private indexEdge(edge: GraphEdge): void {\n const sourceRef = edge.sources[0];\n const targetRef = edge.targets[0];\n\n if (!sourceRef || !targetRef) return;\n\n const edgeType = edge.bpmn?.type;\n const validTypes = ['sequenceFlow', 'messageFlow', 'dataInputAssociation', 'dataOutputAssociation', 'association'] as const;\n const edgeInfo: EdgeInfo = {\n id: edge.id,\n sourceRef,\n targetRef,\n type: (validTypes.includes(edgeType as typeof validTypes[number]) ? edgeType : 'sequenceFlow') as EdgeInfo['type'],\n };\n\n this.allEdges.push(edgeInfo);\n\n // Index by source\n if (!this.edgesBySource.has(sourceRef)) {\n this.edgesBySource.set(sourceRef, []);\n }\n this.edgesBySource.get(sourceRef)!.push(edgeInfo);\n\n // Index by target\n if (!this.edgesByTarget.has(targetRef)) {\n this.edgesByTarget.set(targetRef, []);\n }\n this.edgesByTarget.get(targetRef)!.push(edgeInfo);\n }\n}\n\n// Internal types\ninterface GraphNode {\n id: string;\n bpmn?: { type: string };\n children?: GraphNode[];\n edges?: GraphEdge[];\n boundaryEvents?: Array<{ id: string; bpmn: { type: string } }>;\n}\n\ninterface GraphEdge {\n id: string;\n sources: string[];\n targets: string[];\n bpmn?: { type: string };\n}\n","/**\n * Lane Resolver\n * Builds flowNodeRef arrays for BPMN lanes\n */\n\nexport interface LaneInfo {\n id: string;\n name?: string;\n flowNodeRefs: string[];\n childLaneSet?: LaneSetInfo;\n}\n\nexport interface LaneSetInfo {\n id: string;\n lanes: LaneInfo[];\n}\n\nexport class LaneResolver {\n private laneIdCounter = 0;\n\n /**\n * Resolve lanes from a participant or process\n */\n resolve(container: ContainerNode): LaneSetInfo | undefined {\n const lanes = this.findLanes(container.children);\n\n if (lanes.length === 0) {\n return undefined;\n }\n\n return {\n id: this.generateLaneSetId(),\n lanes: lanes.map((lane) => this.processLane(lane)),\n };\n }\n\n /**\n * Find all lanes in children\n */\n private findLanes(children?: ChildNode[]): LaneNode[] {\n if (!children) return [];\n return children.filter((c): c is LaneNode => c.bpmn?.type === 'lane');\n }\n\n /**\n * Process a lane and collect all flow node refs\n */\n private processLane(lane: LaneNode): LaneInfo {\n const flowNodeRefs = this.collectFlowNodeRefs(lane.children);\n const nestedLanes = this.findLanes(lane.children);\n\n const result: LaneInfo = {\n id: lane.id,\n name: lane.bpmn?.name,\n flowNodeRefs,\n };\n\n // Handle nested lanes\n if (nestedLanes.length > 0) {\n result.childLaneSet = {\n id: this.generateLaneSetId(),\n lanes: nestedLanes.map((l) => this.processLane(l)),\n };\n }\n\n return result;\n }\n\n /**\n * Collect all flow node IDs within a lane (excluding nested lanes)\n */\n private collectFlowNodeRefs(children?: ChildNode[]): string[] {\n if (!children) return [];\n\n const refs: string[] = [];\n\n for (const child of children) {\n // Skip lanes - their content belongs to them\n if (child.bpmn?.type === 'lane') {\n continue;\n }\n\n // Add this node's ID\n refs.push(child.id);\n\n // For subprocesses, don't traverse children - they're internal\n // Boundary events are still part of the lane though\n if (child.boundaryEvents) {\n for (const be of child.boundaryEvents) {\n refs.push(be.id);\n }\n }\n }\n\n return refs;\n }\n\n /**\n * Generate a unique lane set ID\n */\n private generateLaneSetId(): string {\n return `LaneSet_${++this.laneIdCounter}`;\n }\n\n /**\n * Reset the ID counter\n */\n reset(): void {\n this.laneIdCounter = 0;\n }\n}\n\n// Internal types\ninterface ChildNode {\n id: string;\n bpmn?: { type: string; name?: string };\n children?: ChildNode[];\n boundaryEvents?: Array<{ id: string }>;\n}\n\ninterface LaneNode extends ChildNode {\n bpmn: { type: 'lane'; name?: string };\n}\n\ninterface ContainerNode {\n id: string;\n children?: ChildNode[];\n}\n","/**\n * Gateway Endpoint Adjuster\n * Handles the calculation of edge endpoint positions for gateway diamond shapes.\n * Gateways in BPMN are rendered as diamonds, so edge endpoints need to be adjusted\n * to connect to the diamond edges rather than the rectangular bounding box.\n */\n\nimport type { Point, Bounds } from '../../types/internal';\nimport { DEBUG } from '../../utils/debug';\n\n/**\n * Adjust an edge endpoint to connect to a gateway's diamond shape.\n * Gateway diamonds have 4 corners: left, top, right, bottom (at midpoints of bounding box edges).\n *\n * @param endpoint - The current endpoint position\n * @param adjacentPoint - The adjacent point on the edge (used to determine approach direction)\n * @param gatewayBounds - The bounding box of the gateway\n * @param isSource - Whether this endpoint is the source (true) or target (false) of the edge\n * @returns The adjusted endpoint position on the diamond edge\n */\nexport function adjustGatewayEndpoint(\n endpoint: Point,\n adjacentPoint: Point,\n gatewayBounds: Bounds,\n isSource: boolean\n): Point {\n const gatewayCenterX = gatewayBounds.x + gatewayBounds.width / 2;\n const gatewayCenterY = gatewayBounds.y + gatewayBounds.height / 2;\n const tolerance = 1; // Tolerance for corner detection\n\n if (DEBUG) {\n console.log(`[BPMN] adjustGatewayEndpoint: isSource=${isSource}`);\n console.log(` endpoint: (${endpoint.x}, ${endpoint.y})`);\n console.log(` gatewayBounds: x=${gatewayBounds.x}, y=${gatewayBounds.y}, w=${gatewayBounds.width}, h=${gatewayBounds.height}`);\n console.log(` gatewayCenter: (${gatewayCenterX}, ${gatewayCenterY})`);\n console.log(` right edge x: ${gatewayBounds.x + gatewayBounds.width}`);\n }\n\n // Diamond corners (at midpoints of bounding box edges)\n const leftCorner = { x: gatewayBounds.x, y: gatewayCenterY };\n const rightCorner = { x: gatewayBounds.x + gatewayBounds.width, y: gatewayCenterY };\n const topCorner = { x: gatewayCenterX, y: gatewayBounds.y };\n const bottomCorner = { x: gatewayCenterX, y: gatewayBounds.y + gatewayBounds.height };\n\n // Check if endpoint is already at a diamond corner (no adjustment needed)\n // Left corner: x at left edge AND y at center\n if (Math.abs(endpoint.x - gatewayBounds.x) < tolerance &&\n Math.abs(endpoint.y - gatewayCenterY) < tolerance) {\n if (DEBUG) console.log(` -> Already at LEFT corner, no adjustment`);\n return endpoint;\n }\n // Right corner: x at right edge AND y at center\n if (Math.abs(endpoint.x - (gatewayBounds.x + gatewayBounds.width)) < tolerance &&\n Math.abs(endpoint.y - gatewayCenterY) < tolerance) {\n if (DEBUG) console.log(` -> Already at RIGHT corner, no adjustment`);\n return endpoint;\n }\n // Top corner: y at top edge AND x at center\n if (Math.abs(endpoint.y - gatewayBounds.y) < tolerance &&\n Math.abs(endpoint.x - gatewayCenterX) < tolerance) {\n if (DEBUG) console.log(` -> Already at TOP corner, no adjustment`);\n return endpoint;\n }\n // Bottom corner: y at bottom edge AND x at center\n if (Math.abs(endpoint.y - (gatewayBounds.y + gatewayBounds.height)) < tolerance &&\n Math.abs(endpoint.x - gatewayCenterX) < tolerance) {\n if (DEBUG) console.log(` -> Already at BOTTOM corner, no adjustment`);\n return endpoint;\n }\n\n if (DEBUG) {\n console.log(` -> NOT at corner, will adjust`);\n }\n\n // Endpoint is NOT at a corner - calculate intersection with diamond edge\n const result = calculateDiamondIntersection(\n endpoint,\n gatewayBounds,\n gatewayCenterX,\n gatewayCenterY,\n isSource,\n adjacentPoint\n );\n if (DEBUG) {\n console.log(` -> Adjusted to: (${result.x}, ${result.y})`);\n }\n return result;\n}\n\n/**\n * Calculate the intersection point with the diamond edge.\n * The diamond is defined by connecting the midpoints of the bounding box edges.\n *\n * @param endpoint - The current endpoint position\n * @param gatewayBounds - The bounding box of the gateway\n * @param gatewayCenterX - X coordinate of gateway center\n * @param gatewayCenterY - Y coordinate of gateway center\n * @param isSource - Whether this endpoint is the source of the edge\n * @param adjacentPoint - The adjacent point on the edge\n * @returns The intersection point on the diamond edge\n */\nexport function calculateDiamondIntersection(\n endpoint: Point,\n gatewayBounds: Bounds,\n gatewayCenterX: number,\n gatewayCenterY: number,\n isSource: boolean,\n adjacentPoint: Point\n): Point {\n const tolerance = 1;\n\n const leftCorner = { x: gatewayBounds.x, y: gatewayCenterY };\n const rightCorner = { x: gatewayBounds.x + gatewayBounds.width, y: gatewayCenterY };\n const topCorner = { x: gatewayCenterX, y: gatewayBounds.y };\n const bottomCorner = { x: gatewayCenterX, y: gatewayBounds.y + gatewayBounds.height };\n\n // Determine which side based on endpoint position relative to gateway\n const isOnLeftEdge = Math.abs(endpoint.x - gatewayBounds.x) < tolerance;\n const isOnRightEdge = Math.abs(endpoint.x - (gatewayBounds.x + gatewayBounds.width)) < tolerance;\n const isOnTopEdge = Math.abs(endpoint.y - gatewayBounds.y) < tolerance;\n const isOnBottomEdge = Math.abs(endpoint.y - (gatewayBounds.y + gatewayBounds.height)) < tolerance;\n\n const halfWidth = gatewayBounds.width / 2;\n const halfHeight = gatewayBounds.height / 2;\n\n if (isOnLeftEdge || isOnRightEdge) {\n // Endpoint is on left or right edge of bounding box but not at corner\n // Calculate diamond edge intersection at this Y position\n const yDistFromCenter = Math.abs(endpoint.y - gatewayCenterY);\n\n if (yDistFromCenter >= halfHeight) {\n // Outside diamond vertically - snap to corner\n return isOnLeftEdge ? leftCorner : rightCorner;\n }\n\n // Diamond edge equation: |x - centerX| / halfWidth + |y - centerY| / halfHeight = 1\n const xOffsetFromCenter = halfWidth * (1 - yDistFromCenter / halfHeight);\n const intersectX = isOnLeftEdge\n ? gatewayCenterX - xOffsetFromCenter\n : gatewayCenterX + xOffsetFromCenter;\n\n return { x: intersectX, y: endpoint.y };\n }\n\n if (isOnTopEdge || isOnBottomEdge) {\n // Endpoint is on top or bottom edge of bounding box but not at corner\n // Calculate diamond edge intersection at this X position\n const xDistFromCenter = Math.abs(endpoint.x - gatewayCenterX);\n\n if (xDistFromCenter >= halfWidth) {\n // Outside diamond horizontally - snap to corner\n return isOnTopEdge ? topCorner : bottomCorner;\n }\n\n const yOffsetFromCenter = halfHeight * (1 - xDistFromCenter / halfWidth);\n const intersectY = isOnTopEdge\n ? gatewayCenterY - yOffsetFromCenter\n : gatewayCenterY + yOffsetFromCenter;\n\n return { x: endpoint.x, y: intersectY };\n }\n\n // Endpoint is not on any edge - use approach direction to determine corner\n const dx = isSource ? adjacentPoint.x - endpoint.x : endpoint.x - adjacentPoint.x;\n const dy = isSource ? adjacentPoint.y - endpoint.y : endpoint.y - adjacentPoint.y;\n\n if (Math.abs(dx) > Math.abs(dy)) {\n // Horizontal approach\n if (isSource) {\n return dx > 0 ? rightCorner : leftCorner;\n } else {\n return dx > 0 ? leftCorner : rightCorner;\n }\n } else {\n // Vertical approach\n if (isSource) {\n return dy > 0 ? bottomCorner : topCorner;\n } else {\n return dy > 0 ? topCorner : bottomCorner;\n }\n }\n}\n\n/**\n * Get the four corner points of a gateway diamond.\n *\n * @param gatewayBounds - The bounding box of the gateway\n * @returns Object containing all four corner points\n */\nexport function getDiamondCorners(gatewayBounds: Bounds): {\n left: Point;\n right: Point;\n top: Point;\n bottom: Point;\n} {\n const centerX = gatewayBounds.x + gatewayBounds.width / 2;\n const centerY = gatewayBounds.y + gatewayBounds.height / 2;\n\n return {\n left: { x: gatewayBounds.x, y: centerY },\n right: { x: gatewayBounds.x + gatewayBounds.width, y: centerY },\n top: { x: centerX, y: gatewayBounds.y },\n bottom: { x: centerX, y: gatewayBounds.y + gatewayBounds.height },\n };\n}\n\n/**\n * Check if a point is on the diamond edge (within tolerance).\n *\n * @param point - The point to check\n * @param gatewayBounds - The bounding box of the gateway\n * @param tolerance - Distance tolerance for edge detection\n * @returns True if the point is on the diamond edge\n */\nexport function isPointOnDiamondEdge(\n point: Point,\n gatewayBounds: Bounds,\n tolerance: number = 2\n): boolean {\n const centerX = gatewayBounds.x + gatewayBounds.width / 2;\n const centerY = gatewayBounds.y + gatewayBounds.height / 2;\n const halfWidth = gatewayBounds.width / 2;\n const halfHeight = gatewayBounds.height / 2;\n\n // Diamond edge equation: |x - centerX| / halfWidth + |y - centerY| / halfHeight = 1\n // Check if point satisfies this equation within tolerance\n const normalizedX = Math.abs(point.x - centerX) / halfWidth;\n const normalizedY = Math.abs(point.y - centerY) / halfHeight;\n const edgeValue = normalizedX + normalizedY;\n\n return Math.abs(edgeValue - 1) < tolerance / Math.min(halfWidth, halfHeight);\n}\n","/**\n * Diagram Builder\n * Handles building the visual diagram (shapes and edges) from a layouted graph.\n * This module is responsible for converting layouted node positions into\n * BPMN DI (Diagram Interchange) format.\n */\n\nimport type { LayoutedGraph } from '../types/elk-output';\nimport type {\n DiagramModel,\n ShapeModel,\n EdgeModel,\n PointModel,\n DefinitionsModel,\n LayoutedNode,\n LayoutedEdge,\n NodePosition,\n NodeOffset,\n NodeBpmnInfo,\n} from './model-types';\nimport { DEBUG } from '../utils/debug';\nimport {\n adjustGatewayEndpoint,\n distance,\n calculatePathLength,\n} from '../layout/edge-routing';\n\n// ============================================================================\n// Diagram Builder\n// ============================================================================\n\nexport class DiagramBuilder {\n // Map to track boundary event positions: id -> { x, y, width, height }\n private boundaryEventPositions: Map<string, NodePosition> = new Map();\n // Map to track all node positions for edge routing: id -> { x, y, width, height }\n private nodePositions: Map<string, NodePosition> = new Map();\n // Map to track the offset used for each node (for edge coordinate transformation)\n private nodeOffsets: Map<string, NodeOffset> = new Map();\n // Map to track node BPMN metadata for gateway detection\n private nodeBpmn: Map<string, NodeBpmnInfo> = new Map();\n\n /**\n * Build the diagram model from a layouted graph\n */\n build(graph: LayoutedGraph, definitions: DefinitionsModel): DiagramModel {\n // Reset all maps\n this.boundaryEventPositions.clear();\n this.nodePositions.clear();\n this.nodeOffsets.clear();\n this.nodeBpmn.clear();\n\n const shapes: ShapeModel[] = [];\n const edges: EdgeModel[] = [];\n\n // Find the main bpmn element for the plane\n const mainElement = definitions.rootElements[0];\n const planeElement = mainElement?.type === 'collaboration' ? mainElement.id : mainElement?.id ?? graph.id;\n\n // Build shapes and edges\n for (const child of graph.children) {\n this.collectShapesAndEdges(child as LayoutedNode, shapes, edges);\n }\n\n return {\n id: `BPMNDiagram_${graph.id}`,\n name: 'BPMNDiagram',\n plane: {\n id: `BPMNPlane_${graph.id}`,\n bpmnElement: planeElement,\n shapes,\n edges,\n },\n };\n }\n\n /**\n * Get stored node positions (for external access if needed)\n */\n getNodePositions(): Map<string, NodePosition> {\n return this.nodePositions;\n }\n\n /**\n * Collect shapes and edges recursively\n * @param offsetX - Parent container's absolute X offset\n * @param offsetY - Parent container's absolute Y offset\n * @param insideParticipant - Whether we are inside a participant container\n */\n private collectShapesAndEdges(\n node: LayoutedNode,\n shapes: ShapeModel[],\n edges: EdgeModel[],\n offsetX: number = 0,\n offsetY: number = 0,\n insideParticipant: boolean = false\n ): void {\n // Add shape for this node (if it has coordinates)\n if (node.x !== undefined && node.y !== undefined) {\n const absoluteX = offsetX + node.x;\n const absoluteY = offsetY + node.y;\n const nodeWidth = node.width ?? 100;\n const nodeHeight = node.height ?? 80;\n\n // Store node position for edge routing\n this.nodePositions.set(node.id, {\n x: absoluteX,\n y: absoluteY,\n width: nodeWidth,\n height: nodeHeight,\n });\n\n // Store node BPMN metadata for gateway detection\n if (node.bpmn) {\n this.storeNodeBpmn(node.id, { type: node.bpmn.type });\n }\n\n // Store the offset used for this node (needed for edge coordinate transformation)\n this.nodeOffsets.set(node.id, { x: offsetX, y: offsetY });\n\n shapes.push(this.buildShape(node, offsetX, offsetY));\n }\n\n // Calculate offset for children\n // Containers that offset their children: pools (participants), lanes, and expanded subprocesses\n const isExpandedSubprocess = node.bpmn?.isExpanded === true &&\n (node.bpmn?.type === 'subProcess' || node.bpmn?.type === 'transaction' ||\n node.bpmn?.type === 'adHocSubProcess' || node.bpmn?.type === 'eventSubProcess' ||\n (node.bpmn as { triggeredByEvent?: boolean })?.triggeredByEvent === true);\n\n const isPoolOrLane = node.bpmn?.type === 'participant' || node.bpmn?.type === 'lane';\n\n // Process nested inside participant also acts as a container for coordinate offsets\n const isNestedProcess = node.bpmn?.type === 'process' && insideParticipant;\n\n const isContainer = isExpandedSubprocess || isPoolOrLane || isNestedProcess;\n\n const childOffsetX = isContainer ? offsetX + (node.x ?? 0) : offsetX;\n const childOffsetY = isContainer ? offsetY + (node.y ?? 0) : offsetY;\n\n // Track if we're entering a participant\n const childInsideParticipant = insideParticipant || node.bpmn?.type === 'participant';\n\n // Process children\n if (node.children) {\n for (const child of node.children) {\n this.collectShapesAndEdges(child as LayoutedNode, shapes, edges, childOffsetX, childOffsetY, childInsideParticipant);\n }\n }\n\n // Process boundary events - position them on the bottom edge of the task\n if (node.boundaryEvents) {\n const nodeX = offsetX + (node.x ?? 0);\n const nodeY = offsetY + (node.y ?? 0);\n const nodeWidth = node.width ?? 100;\n const nodeHeight = node.height ?? 80;\n const beCount = node.boundaryEvents.length;\n\n node.boundaryEvents.forEach((be, index) => {\n const beWidth = be.width ?? 36;\n const beHeight = be.height ?? 36;\n\n // Calculate position on the bottom edge of the task\n // Distribute multiple boundary events evenly along the bottom\n const spacing = nodeWidth / (beCount + 1);\n const beX = nodeX + spacing * (index + 1) - beWidth / 2;\n const beY = nodeY + nodeHeight - beHeight / 2; // Half inside, half outside\n\n // Store boundary event position for edge routing\n this.boundaryEventPositions.set(be.id, {\n x: beX,\n y: beY,\n width: beWidth,\n height: beHeight,\n });\n\n shapes.push({\n id: `${be.id}_di`,\n bpmnElement: be.id,\n bounds: {\n x: beX,\n y: beY,\n width: beWidth,\n height: beHeight,\n },\n });\n });\n }\n\n // Process edges\n // Edge waypoints from ELK are relative to the source node's parent container,\n // not necessarily the edge's container. We use the source node's stored offset.\n if (node.edges) {\n for (const edge of node.edges) {\n if (edge.sections && edge.sections.length > 0) {\n // Check if edge has absolute coordinates (set by rearrangePools for message flows)\n const hasAbsoluteCoords = (edge as { _absoluteCoords?: boolean })._absoluteCoords === true;\n // Check if edge has pool-relative coordinates (set by recalculatePoolEdges for pool edges with lanes)\n const hasPoolRelativeCoords = (edge as { _poolRelativeCoords?: boolean })._poolRelativeCoords === true;\n\n if (hasAbsoluteCoords) {\n // Edge already has absolute coordinates - don't add offset\n edges.push(this.buildEdge(edge, 0, 0));\n } else if (hasPoolRelativeCoords) {\n // Edge waypoints are relative to pool (already include lane offsets within pool)\n // Use container's offset (pool's offset), not source node's offset\n edges.push(this.buildEdge(edge, offsetX + (node.x ?? 0), offsetY + (node.y ?? 0)));\n } else {\n const sourceId = edge.sources?.[0];\n // Use the source node's offset if available, otherwise fall back to childOffset\n const sourceOffset = sourceId ? this.nodeOffsets.get(sourceId) : undefined;\n const edgeOffsetX = sourceOffset?.x ?? childOffsetX;\n const edgeOffsetY = sourceOffset?.y ?? childOffsetY;\n edges.push(this.buildEdge(edge, edgeOffsetX, edgeOffsetY));\n }\n }\n }\n }\n }\n\n /**\n * Check if a node type is an event type\n */\n private isEventType(type?: string): boolean {\n if (!type) return false;\n return type.includes('Event') || type === 'startEvent' || type === 'endEvent' ||\n type === 'intermediateThrowEvent' || type === 'intermediateCatchEvent';\n }\n\n /**\n * Check if a node type is a gateway type\n */\n private isGatewayType(type?: string): boolean {\n if (!type) return false;\n return type.includes('Gateway');\n }\n\n /**\n * Store node BPMN metadata for later gateway detection\n */\n private storeNodeBpmn(nodeId: string, bpmn: NodeBpmnInfo): void {\n this.nodeBpmn.set(nodeId, bpmn);\n }\n\n /**\n * Find node BPMN metadata by id\n */\n private findNodeBpmn(nodeId: string): NodeBpmnInfo | undefined {\n return this.nodeBpmn.get(nodeId);\n }\n\n /**\n * Estimate number of lines needed for a label based on text and width\n * Uses approximate character width of 14px for CJK and 7px for ASCII\n */\n private estimateLabelLines(text: string, maxWidth: number): number {\n if (!text || maxWidth <= 0) return 1;\n\n let currentLineWidth = 0;\n let lines = 1;\n\n for (const char of text) {\n // CJK characters are wider\n const charWidth = char.charCodeAt(0) > 255 ? 14 : 7;\n\n if (currentLineWidth + charWidth > maxWidth) {\n lines++;\n currentLineWidth = charWidth;\n } else {\n currentLineWidth += charWidth;\n }\n }\n\n return lines;\n }\n\n /**\n * Build a shape model\n */\n private buildShape(node: LayoutedNode, offsetX: number = 0, offsetY: number = 0): ShapeModel {\n const absoluteX = offsetX + (node.x ?? 0);\n const absoluteY = offsetY + (node.y ?? 0);\n\n const shape: ShapeModel = {\n id: `${node.id}_di`,\n bpmnElement: node.id,\n bounds: {\n x: absoluteX,\n y: absoluteY,\n width: node.width ?? 100,\n height: node.height ?? 80,\n },\n };\n\n // Add isExpanded for subprocesses\n if (node.bpmn?.isExpanded !== undefined) {\n shape.isExpanded = node.bpmn.isExpanded;\n }\n\n // Add isHorizontal for pools/lanes\n if (node.bpmn?.type === 'participant' || node.bpmn?.type === 'lane') {\n shape.isHorizontal = true;\n }\n\n // Add label if present\n if (node.labels && node.labels.length > 0) {\n const label = node.labels[0];\n if (!label) return shape;\n const nodeWidth = node.width ?? 36;\n const nodeHeight = node.height ?? 36;\n\n // For events (circles), position the label below the shape (bpmn-js default behavior)\n if (this.isEventType(node.bpmn?.type)) {\n const labelWidth = label.width ?? 100;\n const labelHeight = label.height ?? 14;\n\n // Position label below the event circle, horizontally centered (using absolute coords)\n shape.label = {\n bounds: {\n x: absoluteX + (nodeWidth - labelWidth) / 2,\n y: absoluteY + nodeHeight + 4, // 4px gap below the circle\n width: labelWidth,\n height: labelHeight,\n },\n };\n } else if (this.isGatewayType(node.bpmn?.type)) {\n // For gateways (diamonds), position the label above the shape (bpmn-js default behavior)\n const labelWidth = label?.width ?? 100;\n // Calculate label height based on text content (may need multiple lines)\n // Use bpmn.name as the display text since that's what bpmn-js renders\n const labelText = node.bpmn?.name ?? label?.text ?? '';\n const estimatedLines = this.estimateLabelLines(labelText, labelWidth);\n const labelHeight = estimatedLines * 14; // 14px per line\n\n // Position label above the gateway diamond, horizontally centered\n // Adjust Y position upward based on label height\n shape.label = {\n bounds: {\n x: absoluteX + (nodeWidth - labelWidth) / 2,\n y: absoluteY - labelHeight - 4, // 4px gap above the diamond\n width: labelWidth,\n height: labelHeight,\n },\n };\n } else if (label?.x !== undefined && label?.y !== undefined) {\n // For other elements, use ELK-calculated position (relative to node, converted to absolute)\n shape.label = {\n bounds: {\n x: absoluteX + label.x,\n y: absoluteY + label.y,\n width: label?.width ?? 100,\n height: label?.height ?? 20,\n },\n };\n }\n }\n\n return shape;\n }\n\n /**\n * Build an edge model\n */\n private buildEdge(edge: LayoutedEdge, offsetX: number = 0, offsetY: number = 0): EdgeModel {\n const sourceId = edge.sources?.[0];\n const targetId = edge.targets?.[0];\n\n // Check if source is a boundary event\n const bePosition = sourceId ? this.boundaryEventPositions.get(sourceId) : undefined;\n const targetPosition = targetId ? this.nodePositions.get(targetId) : undefined;\n\n // Check if source or target is a gateway (for diamond shape adjustment)\n const sourceNode = sourceId ? this.findNodeBpmn(sourceId) : undefined;\n const targetNode = targetId ? this.findNodeBpmn(targetId) : undefined;\n const sourceIsGateway = this.isGatewayType(sourceNode?.type);\n const targetIsGateway = this.isGatewayType(targetNode?.type);\n\n let waypoints: PointModel[] = [];\n\n // Check if edge has pre-calculated sections with bendPoints (from obstacle avoidance)\n const hasPreCalculatedSections = edge.sections &&\n edge.sections.length > 0 &&\n edge.sections[0]?.bendPoints &&\n edge.sections[0].bendPoints.length > 0;\n\n if (DEBUG && bePosition) {\n console.log(`[BPMN] buildEdge ${edge.id}: preCalculated=${hasPreCalculatedSections}`);\n }\n\n if (bePosition && targetPosition && !hasPreCalculatedSections) {\n // Source is a boundary event without pre-calculated routing - calculate simple waypoints\n // Start from bottom center of boundary event\n const startX = bePosition.x + bePosition.width / 2;\n const startY = bePosition.y + bePosition.height;\n\n // End at left center of target (or top center if target is below)\n let endX: number;\n let endY: number;\n\n // Determine connection point based on relative position\n if (targetPosition.y > bePosition.y + bePosition.height) {\n // Target is below - connect to top center\n endX = targetPosition.x + targetPosition.width / 2;\n endY = targetPosition.y;\n } else if (targetPosition.x > bePosition.x + bePosition.width) {\n // Target is to the right - connect to left center\n endX = targetPosition.x;\n endY = targetPosition.y + targetPosition.height / 2;\n } else if (targetPosition.x + targetPosition.width < bePosition.x) {\n // Target is to the left - connect to right center\n endX = targetPosition.x + targetPosition.width;\n endY = targetPosition.y + targetPosition.height / 2;\n } else {\n // Target is above - connect to bottom center\n endX = targetPosition.x + targetPosition.width / 2;\n endY = targetPosition.y + targetPosition.height;\n }\n\n waypoints.push({ x: startX, y: startY });\n\n // Add bend point if needed for orthogonal routing\n if (Math.abs(startX - endX) > 10 && Math.abs(startY - endY) > 10) {\n // Go down first, then turn\n const midY = startY + 20;\n waypoints.push({ x: startX, y: midY });\n waypoints.push({ x: endX, y: midY });\n }\n\n waypoints.push({ x: endX, y: endY });\n } else {\n // Normal edge - use ELK calculated waypoints\n for (const section of edge.sections) {\n // Start point\n waypoints.push({ x: offsetX + section.startPoint.x, y: offsetY + section.startPoint.y });\n\n // Bend points\n if (section.bendPoints) {\n for (const bp of section.bendPoints) {\n waypoints.push({ x: offsetX + bp.x, y: offsetY + bp.y });\n }\n }\n\n // End point\n waypoints.push({ x: offsetX + section.endPoint.x, y: offsetY + section.endPoint.y });\n }\n\n // Adjust endpoints for gateway diamond shapes\n // This calculates the actual intersection with the diamond edge to maintain\n // visual separation when multiple edges connect to the same gateway side\n if (waypoints.length >= 2) {\n // Adjust start point if source is a gateway\n if (sourceIsGateway && sourceId) {\n const sourcePos = this.nodePositions.get(sourceId);\n if (sourcePos) {\n const wp0 = waypoints[0];\n const wp1 = waypoints[1];\n if (wp0 && wp1) {\n waypoints[0] = adjustGatewayEndpoint(\n wp0,\n wp1,\n sourcePos,\n true // isSource\n );\n // No adjacent point adjustment needed - the intersection calculation\n // preserves the original Y (or X) coordinate, maintaining orthogonality\n }\n }\n }\n\n // Adjust end point if target is a gateway\n if (targetIsGateway && targetId) {\n const targetPos = this.nodePositions.get(targetId);\n if (targetPos) {\n const lastIdx = waypoints.length - 1;\n const prevIdx = lastIdx - 1;\n const wpLast = waypoints[lastIdx];\n const wpPrev = waypoints[prevIdx];\n if (wpLast && wpPrev) {\n waypoints[lastIdx] = adjustGatewayEndpoint(\n wpLast,\n wpPrev,\n targetPos,\n false // isSource\n );\n // No adjacent point adjustment needed - the intersection calculation\n // preserves the original Y (or X) coordinate, maintaining orthogonality\n }\n }\n }\n }\n }\n\n const edgeModel: EdgeModel = {\n id: `${edge.id}_di`,\n bpmnElement: edge.id,\n waypoints,\n };\n\n // Add label if present - center it on the edge\n if (edge.labels && edge.labels.length > 0) {\n const label = edge.labels[0];\n const labelWidth = label?.width ?? 50;\n const labelHeight = label?.height ?? 14;\n\n // Calculate edge midpoint for label placement\n const labelPos = this.calculateEdgeLabelPosition(waypoints, labelWidth, labelHeight);\n\n edgeModel.label = {\n bounds: {\n x: labelPos.x,\n y: labelPos.y,\n width: labelWidth,\n height: labelHeight,\n },\n };\n }\n\n return edgeModel;\n }\n\n /**\n * Calculate label position centered on the edge\n * Places label at the midpoint of the edge, offset above the line\n */\n private calculateEdgeLabelPosition(\n waypoints: PointModel[],\n labelWidth: number,\n labelHeight: number\n ): { x: number; y: number } {\n if (waypoints.length < 2) {\n return { x: 0, y: 0 };\n }\n\n // Find the midpoint segment of the edge\n const totalLength = calculatePathLength(waypoints);\n const halfLength = totalLength / 2;\n\n // Walk along the path to find the midpoint\n let accumulatedLength = 0;\n for (let i = 0; i < waypoints.length - 1; i++) {\n const wpCurrent = waypoints[i];\n const wpNext = waypoints[i + 1];\n if (!wpCurrent || !wpNext) continue;\n const segmentLength = distance(wpCurrent, wpNext);\n const nextAccumulated = accumulatedLength + segmentLength;\n\n if (nextAccumulated >= halfLength) {\n // Midpoint is in this segment\n const ratio = (halfLength - accumulatedLength) / segmentLength;\n const midX = wpCurrent.x + (wpNext.x - wpCurrent.x) * ratio;\n const midY = wpCurrent.y + (wpNext.y - wpCurrent.y) * ratio;\n\n // Determine if segment is horizontal or vertical\n const dx = wpNext.x - wpCurrent.x;\n const dy = wpNext.y - wpCurrent.y;\n\n if (Math.abs(dy) < Math.abs(dx)) {\n // Horizontal segment - place label above the line\n return {\n x: midX - labelWidth / 2,\n y: midY - labelHeight - 4, // 4px above the line\n };\n } else {\n // Vertical segment - place label to the left of the line\n return {\n x: midX - labelWidth - 4, // 4px to the left\n y: midY - labelHeight / 2,\n };\n }\n }\n accumulatedLength = nextAccumulated;\n }\n\n // Fallback: use the geometric center\n const lastPoint = waypoints[waypoints.length - 1];\n return {\n x: (lastPoint?.x ?? 0) - labelWidth / 2,\n y: (lastPoint?.y ?? 0) - labelHeight - 4,\n };\n }\n}\n","/**\n * Model Builder\n * Builds the intermediate BPMN model from layouted ELK-BPMN graph.\n * This module focuses on building the BPMN process/collaboration structure,\n * while DiagramBuilder handles the visual diagram (shapes and edges).\n */\n\nimport type { LayoutedGraph } from '../types/elk-output';\nimport type {\n MessageDefinition,\n SignalDefinition,\n ErrorDefinition,\n EscalationDefinition,\n} from '../types';\nimport { ReferenceResolver } from './reference-resolver';\nimport { LaneResolver, type LaneSetInfo } from './lane-resolver';\nimport { DiagramBuilder } from './diagram-builder';\nimport type {\n BpmnModel,\n DefinitionsModel,\n CollaborationModel,\n ProcessModel,\n FlowElementModel,\n ArtifactModel,\n DiagramModel,\n CollaborationNode,\n ParticipantNode,\n ProcessNode,\n ChildNode,\n BoundaryEventNode,\n EdgeNode,\n ArtifactNode,\n} from './model-types';\n\n// Re-export types for external consumers\nexport type {\n BpmnModel,\n DefinitionsModel,\n CollaborationModel,\n ProcessModel,\n FlowElementModel,\n ArtifactModel,\n DiagramModel,\n ShapeModel,\n EdgeModel,\n BoundsModel,\n PointModel,\n LabelModel,\n PlaneModel,\n ParticipantModel,\n MessageFlowModel,\n SequenceFlowModel,\n DataAssociationModel,\n RootElement,\n} from './model-types';\n\n// ============================================================================\n// Model Builder\n// ============================================================================\n\nexport class ModelBuilder {\n private refResolver: ReferenceResolver;\n private laneResolver: LaneResolver;\n private diagramBuilder: DiagramBuilder;\n\n constructor() {\n this.refResolver = new ReferenceResolver();\n this.laneResolver = new LaneResolver();\n this.diagramBuilder = new DiagramBuilder();\n }\n\n /**\n * Build the complete BPMN model from a layouted graph\n */\n build(graph: LayoutedGraph): BpmnModel {\n // Reset resolvers\n this.laneResolver.reset();\n\n // Resolve references first\n this.refResolver.resolve(graph);\n\n // Build definitions model\n const definitions = this.buildDefinitions(graph);\n\n // Build diagram model using DiagramBuilder\n const diagram = this.diagramBuilder.build(graph, definitions);\n\n return { definitions, diagram };\n }\n\n /**\n * Get the reference resolver\n */\n getRefResolver(): ReferenceResolver {\n return this.refResolver;\n }\n\n /**\n * Build definitions model\n */\n private buildDefinitions(graph: LayoutedGraph): DefinitionsModel {\n const definitions: DefinitionsModel = {\n id: graph.id,\n targetNamespace: graph.bpmn?.targetNamespace ?? 'http://bpmn.io/schema/bpmn',\n exporter: graph.bpmn?.exporter ?? 'bpmn-elk-layout',\n exporterVersion: graph.bpmn?.exporterVersion ?? '1.0.0',\n messages: graph.messages ?? [],\n signals: graph.signals ?? [],\n errors: graph.errors ?? [],\n escalations: graph.escalations ?? [],\n rootElements: [],\n };\n\n // Process top-level children\n for (const child of graph.children) {\n const bpmnType = (child as { bpmn: { type: string } }).bpmn.type;\n\n if (bpmnType === 'collaboration') {\n definitions.rootElements.push(this.buildCollaboration(child as CollaborationNode));\n\n // Also add processes for each non-black-box participant\n const collab = child as CollaborationNode;\n for (const participant of collab.children ?? []) {\n if (!participant.bpmn?.isBlackBox) {\n const processId = participant.bpmn?.processRef ?? `Process_${participant.id}`;\n definitions.rootElements.push(\n this.buildProcessFromParticipant(participant, processId)\n );\n }\n }\n } else if (bpmnType === 'process') {\n definitions.rootElements.push(this.buildProcess(child as ProcessNode));\n }\n }\n\n return definitions;\n }\n\n /**\n * Build collaboration model\n */\n private buildCollaboration(collab: CollaborationNode): CollaborationModel {\n return {\n type: 'collaboration',\n id: collab.id,\n name: collab.bpmn?.name,\n isClosed: collab.bpmn?.isClosed,\n participants: (collab.children ?? []).map((p) => ({\n id: p.id,\n name: p.bpmn?.name,\n processRef: p.bpmn?.processRef ?? `Process_${p.id}`,\n isBlackBox: p.bpmn?.isBlackBox,\n participantMultiplicity: p.bpmn?.participantMultiplicity,\n })),\n messageFlows: (collab.edges ?? [])\n .filter((e): e is typeof e & { sources: [string, ...string[]]; targets: [string, ...string[]] } =>\n e.sources[0] !== undefined && e.targets[0] !== undefined)\n .map((e) => ({\n id: e.id,\n name: e.bpmn?.name,\n sourceRef: e.sources[0],\n targetRef: e.targets[0],\n messageRef: e.bpmn?.messageRef,\n })),\n };\n }\n\n /**\n * Build process model from participant\n */\n private buildProcessFromParticipant(\n participant: ParticipantNode,\n processId: string\n ): ProcessModel {\n const process: ProcessModel = {\n type: 'process',\n id: processId,\n name: participant.bpmn?.name,\n isExecutable: true,\n laneSet: this.laneResolver.resolve(participant),\n flowElements: [],\n artifacts: [],\n };\n\n // Collect all flow elements\n this.collectFlowElements(participant.children ?? [], process.flowElements);\n\n // Collect sequence flows\n this.collectSequenceFlows(participant.edges ?? [], process.flowElements);\n\n // Collect data associations and attach to flow elements (BPMN spec compliance)\n this.collectDataAssociations(participant.edges ?? [], process.flowElements);\n\n return process;\n }\n\n /**\n * Build process model\n */\n private buildProcess(processNode: ProcessNode): ProcessModel {\n const process: ProcessModel = {\n type: 'process',\n id: processNode.id,\n name: processNode.bpmn?.name,\n isExecutable: processNode.bpmn?.isExecutable ?? true,\n processType: processNode.bpmn?.processType,\n isClosed: processNode.bpmn?.isClosed,\n laneSet: this.laneResolver.resolve(processNode),\n flowElements: [],\n artifacts: [],\n };\n\n // Collect all flow elements\n this.collectFlowElements(processNode.children ?? [], process.flowElements);\n\n // Collect sequence flows\n this.collectSequenceFlows(processNode.edges ?? [], process.flowElements);\n\n // Collect artifacts\n if (processNode.artifacts) {\n for (const artifact of processNode.artifacts) {\n process.artifacts.push(this.buildArtifact(artifact));\n }\n }\n\n // Collect associations from edges\n this.collectAssociations(processNode.edges ?? [], process.artifacts);\n\n // Collect data associations and attach to flow elements (BPMN spec compliance)\n this.collectDataAssociations(processNode.edges ?? [], process.flowElements);\n\n return process;\n }\n\n /**\n * Collect flow elements recursively\n */\n private collectFlowElements(children: ChildNode[], elements: FlowElementModel[]): void {\n for (const child of children) {\n // Skip lanes - just traverse their children\n if (child.bpmn?.type === 'lane') {\n this.collectFlowElements(child.children ?? [], elements);\n continue;\n }\n\n // Skip nested process - traverse its children and edges\n // This handles the case where participant > children > [process > children: [flowNodes]]\n if (child.bpmn?.type === 'process') {\n this.collectFlowElements(child.children ?? [], elements);\n this.collectSequenceFlows(child.edges ?? [], elements);\n continue;\n }\n\n // Build flow element\n const flowElement = this.buildFlowElement(child);\n elements.push(flowElement);\n\n // For expanded subprocesses, collect nested elements into the subprocess itself\n if (child.bpmn?.isExpanded && child.children) {\n flowElement.flowElements = [];\n flowElement.artifacts = [];\n this.collectFlowElements(child.children, flowElement.flowElements);\n // Collect nested sequence flows into subprocess\n if (child.edges) {\n this.collectSequenceFlows(child.edges, flowElement.flowElements);\n }\n } else if (child.edges) {\n // Collect nested sequence flows for non-expanded containers\n this.collectSequenceFlows(child.edges, elements);\n }\n\n // Add boundary events (after subprocess content processing)\n if (child.boundaryEvents) {\n for (const be of child.boundaryEvents) {\n elements.push(this.buildBoundaryEvent(be));\n }\n }\n }\n }\n\n /**\n * Build a flow element model\n */\n private buildFlowElement(node: ChildNode): FlowElementModel {\n const incoming = this.refResolver.getIncomingSequenceFlows(node.id);\n const outgoing = this.refResolver.getOutgoingSequenceFlows(node.id);\n\n return {\n type: node.bpmn?.type ?? 'task',\n id: node.id,\n name: node.bpmn?.name,\n incoming,\n outgoing,\n properties: this.extractProperties(node.bpmn ?? {}),\n };\n }\n\n /**\n * Build a boundary event model\n */\n private buildBoundaryEvent(be: BoundaryEventNode): FlowElementModel {\n const incoming = this.refResolver.getIncomingSequenceFlows(be.id);\n const outgoing = this.refResolver.getOutgoingSequenceFlows(be.id);\n\n return {\n type: 'boundaryEvent',\n id: be.id,\n name: be.bpmn?.name,\n incoming,\n outgoing,\n attachedToRef: be.attachedToRef,\n cancelActivity: be.bpmn?.isInterrupting ?? be.bpmn?.cancelActivity ?? true,\n properties: this.extractProperties(be.bpmn ?? {}),\n };\n }\n\n /**\n * Collect sequence flows\n */\n private collectSequenceFlows(edges: EdgeNode[], elements: FlowElementModel[]): void {\n for (const edge of edges) {\n if (edge.bpmn?.type === 'sequenceFlow') {\n elements.push({\n type: 'sequenceFlow',\n id: edge.id,\n name: edge.bpmn?.name,\n incoming: [],\n outgoing: [],\n properties: {\n sourceRef: edge.sources[0],\n targetRef: edge.targets[0],\n conditionExpression: edge.bpmn?.conditionExpression,\n isDefault: edge.bpmn?.isDefault,\n },\n });\n }\n }\n }\n\n /**\n * Collect associations from edges\n */\n private collectAssociations(edges: EdgeNode[], artifacts: ArtifactModel[]): void {\n for (const edge of edges) {\n if (edge.bpmn?.type === 'association') {\n artifacts.push({\n type: 'association',\n id: edge.id,\n name: edge.bpmn?.name,\n properties: {\n sourceRef: edge.sources[0],\n targetRef: edge.targets[0],\n associationDirection: (edge.bpmn as { associationDirection?: string })?.associationDirection ?? 'None',\n },\n });\n }\n }\n }\n\n /**\n * Collect data associations from edges and attach them to flow elements\n * Per BPMN 2.0 spec: dataInputAssociation/dataOutputAssociation are child elements of Activity\n */\n private collectDataAssociations(edges: EdgeNode[], elements: FlowElementModel[]): void {\n // Build a map of element IDs to their models for quick lookup\n const elementMap = new Map<string, FlowElementModel>();\n for (const element of elements) {\n elementMap.set(element.id, element);\n }\n\n for (const edge of edges) {\n const edgeType = edge.bpmn?.type;\n\n if (edgeType === 'dataInputAssociation') {\n // dataInputAssociation: data object (source) -> task (target)\n // The association is a child of the TARGET task\n const targetId = edge.targets[0];\n const sourceId = edge.sources[0];\n if (!targetId || !sourceId) continue;\n const targetElement = elementMap.get(targetId);\n\n if (targetElement) {\n if (!targetElement.dataInputAssociations) {\n targetElement.dataInputAssociations = [];\n }\n targetElement.dataInputAssociations.push({\n id: edge.id,\n sourceRef: sourceId,\n });\n }\n } else if (edgeType === 'dataOutputAssociation') {\n // dataOutputAssociation: task (source) -> data object (target)\n // The association is a child of the SOURCE task\n const sourceId = edge.sources[0];\n const targetId = edge.targets[0];\n if (!sourceId || !targetId) continue;\n const sourceElement = elementMap.get(sourceId);\n\n if (sourceElement) {\n if (!sourceElement.dataOutputAssociations) {\n sourceElement.dataOutputAssociations = [];\n }\n sourceElement.dataOutputAssociations.push({\n id: edge.id,\n sourceRef: sourceId,\n targetRef: targetId,\n });\n }\n }\n }\n }\n\n /**\n * Build an artifact model\n */\n private buildArtifact(artifact: ArtifactNode): ArtifactModel {\n return {\n type: artifact.bpmn?.type ?? 'textAnnotation',\n id: artifact.id,\n name: artifact.bpmn?.name,\n properties: this.extractProperties(artifact.bpmn ?? {}),\n };\n }\n\n /**\n * Extract properties from bpmn object (excluding type and name)\n */\n private extractProperties(bpmn: Record<string, unknown>): Record<string, unknown> {\n const { type, name, ...rest } = bpmn;\n return rest;\n }\n}\n","/**\n * BPMN XML Generator\n * Generates BPMN 2.0 XML from the intermediate model using bpmn-moddle\n */\n\nimport BpmnModdle from 'bpmn-moddle';\nimport type {\n BpmnModel,\n DefinitionsModel,\n DiagramModel,\n ProcessModel,\n CollaborationModel,\n FlowElementModel,\n ArtifactModel,\n ShapeModel,\n EdgeModel,\n} from '../transform/model-builder';\nimport type { LaneSetInfo, LaneInfo } from '../transform/lane-resolver';\nimport { BPMN_ELEMENT_MAP, EVENT_DEFINITION_MAP } from '../types/bpmn-constants';\n\n// Type definitions for bpmn-moddle elements\ninterface ModdleElement {\n $type: string;\n id?: string;\n [key: string]: unknown;\n}\n\nexport class BpmnXmlGenerator {\n private moddle: BpmnModdle;\n\n constructor() {\n this.moddle = new BpmnModdle();\n }\n\n /**\n * Generate BPMN 2.0 XML from the model\n */\n async generate(model: BpmnModel): Promise<string> {\n // Build the definitions element\n const definitions = this.buildDefinitions(model.definitions, model.diagram);\n\n // Serialize to XML\n const { xml } = await this.moddle.toXML(definitions, {\n format: true,\n preamble: true,\n });\n\n return xml;\n }\n\n /**\n * Build the root definitions element\n */\n private buildDefinitions(def: DefinitionsModel, diagram: DiagramModel): ModdleElement {\n const definitions = this.moddle.create('bpmn:Definitions', {\n id: def.id,\n targetNamespace: def.targetNamespace,\n exporter: def.exporter,\n exporterVersion: def.exporterVersion,\n });\n\n const rootElements: ModdleElement[] = [];\n\n // Add global definitions (messages, signals, errors, escalations)\n for (const msg of def.messages) {\n rootElements.push(\n this.moddle.create('bpmn:Message', {\n id: msg.id,\n name: msg.name,\n })\n );\n }\n\n for (const sig of def.signals) {\n rootElements.push(\n this.moddle.create('bpmn:Signal', {\n id: sig.id,\n name: sig.name,\n })\n );\n }\n\n for (const err of def.errors) {\n rootElements.push(\n this.moddle.create('bpmn:Error', {\n id: err.id,\n name: err.name,\n errorCode: err.errorCode,\n })\n );\n }\n\n for (const esc of def.escalations) {\n rootElements.push(\n this.moddle.create('bpmn:Escalation', {\n id: esc.id,\n name: esc.name,\n escalationCode: esc.escalationCode,\n })\n );\n }\n\n // Add root elements (collaborations and processes)\n for (const element of def.rootElements) {\n if (element.type === 'collaboration') {\n rootElements.push(this.buildCollaboration(element));\n } else if (element.type === 'process') {\n rootElements.push(this.buildProcess(element));\n }\n }\n\n definitions.rootElements = rootElements;\n\n // Add diagram\n definitions.diagrams = [this.buildDiagram(diagram)];\n\n return definitions;\n }\n\n /**\n * Build a collaboration element\n */\n private buildCollaboration(collab: CollaborationModel): ModdleElement {\n const collaboration = this.moddle.create('bpmn:Collaboration', {\n id: collab.id,\n name: collab.name,\n isClosed: collab.isClosed,\n });\n\n // Add participants\n collaboration.participants = collab.participants.map((p) => {\n const participant = this.moddle.create('bpmn:Participant', {\n id: p.id,\n name: p.name,\n processRef: p.processRef ? { id: p.processRef } : undefined,\n });\n\n if (p.participantMultiplicity) {\n participant.participantMultiplicity = this.moddle.create(\n 'bpmn:ParticipantMultiplicity',\n {\n minimum: p.participantMultiplicity.minimum,\n maximum: p.participantMultiplicity.maximum,\n }\n );\n }\n\n return participant;\n });\n\n // Add message flows\n collaboration.messageFlows = collab.messageFlows.map((mf) =>\n this.moddle.create('bpmn:MessageFlow', {\n id: mf.id,\n name: mf.name,\n sourceRef: { id: mf.sourceRef },\n targetRef: { id: mf.targetRef },\n messageRef: mf.messageRef ? { id: mf.messageRef } : undefined,\n })\n );\n\n return collaboration;\n }\n\n /**\n * Build a process element\n */\n private buildProcess(process: ProcessModel): ModdleElement {\n const bpmnProcess = this.moddle.create('bpmn:Process', {\n id: process.id,\n name: process.name,\n isExecutable: process.isExecutable ?? true,\n processType: process.processType,\n isClosed: process.isClosed,\n });\n\n const flowElements: ModdleElement[] = [];\n\n // Add lane set if present\n if (process.laneSet) {\n bpmnProcess.laneSets = [this.buildLaneSet(process.laneSet)];\n }\n\n // Add flow elements\n for (const element of process.flowElements) {\n flowElements.push(this.buildFlowElement(element));\n }\n\n bpmnProcess.flowElements = flowElements;\n\n // Add artifacts\n if (process.artifacts.length > 0) {\n bpmnProcess.artifacts = process.artifacts.map((a) => this.buildArtifact(a));\n }\n\n return bpmnProcess;\n }\n\n /**\n * Build a lane set\n */\n private buildLaneSet(laneSet: LaneSetInfo): ModdleElement {\n const bpmnLaneSet = this.moddle.create('bpmn:LaneSet', {\n id: laneSet.id,\n });\n\n bpmnLaneSet.lanes = laneSet.lanes.map((lane) => this.buildLane(lane));\n\n return bpmnLaneSet;\n }\n\n /**\n * Build a lane\n */\n private buildLane(lane: LaneInfo): ModdleElement {\n const bpmnLane = this.moddle.create('bpmn:Lane', {\n id: lane.id,\n name: lane.name,\n });\n\n // Add flow node references\n bpmnLane.flowNodeRef = lane.flowNodeRefs.map((ref) => ({ id: ref }));\n\n // Add child lane set if present\n if (lane.childLaneSet) {\n bpmnLane.childLaneSet = this.buildLaneSet(lane.childLaneSet);\n }\n\n return bpmnLane;\n }\n\n /**\n * Build a flow element (event, task, gateway, subprocess, sequence flow)\n */\n private buildFlowElement(element: FlowElementModel): ModdleElement {\n const elementType = BPMN_ELEMENT_MAP[element.type as keyof typeof BPMN_ELEMENT_MAP];\n if (!elementType) {\n throw new Error(`Unknown element type: ${element.type}`);\n }\n\n const bpmnElement = this.moddle.create(elementType, {\n id: element.id,\n name: element.name,\n });\n\n // Add incoming/outgoing references\n if (element.incoming.length > 0) {\n bpmnElement.incoming = element.incoming.map((id) => ({ id }));\n }\n if (element.outgoing.length > 0) {\n bpmnElement.outgoing = element.outgoing.map((id) => ({ id }));\n }\n\n // Handle specific element types\n this.applyElementProperties(bpmnElement, element);\n\n // Add data associations (BPMN 2.0 spec: child elements of Activity)\n this.applyDataAssociations(bpmnElement, element);\n\n return bpmnElement;\n }\n\n /**\n * Apply element-specific properties\n */\n private applyElementProperties(bpmnElement: ModdleElement, element: FlowElementModel): void {\n const props = element.properties;\n\n // Events\n if (element.type.includes('Event')) {\n this.applyEventProperties(bpmnElement, element);\n }\n\n // Tasks\n if (element.type.includes('Task') || element.type === 'task') {\n this.applyTaskProperties(bpmnElement, props);\n }\n\n // Gateways\n if (element.type.includes('Gateway')) {\n this.applyGatewayProperties(bpmnElement, props);\n }\n\n // SubProcesses\n if (element.type === 'subProcess' || element.type === 'transaction' ||\n element.type === 'adHocSubProcess' || element.type === 'eventSubProcess') {\n this.applySubProcessProperties(bpmnElement, props);\n\n // Add nested flow elements for expanded subprocesses\n if (element.flowElements && element.flowElements.length > 0) {\n bpmnElement.flowElements = element.flowElements.map((fe) => this.buildFlowElement(fe));\n }\n if (element.artifacts && element.artifacts.length > 0) {\n bpmnElement.artifacts = element.artifacts.map((a) => this.buildArtifact(a));\n }\n }\n\n // Call Activity\n if (element.type === 'callActivity') {\n this.applyCallActivityProperties(bpmnElement, props);\n }\n\n // Boundary Event\n if (element.type === 'boundaryEvent') {\n bpmnElement.attachedToRef = { id: element.attachedToRef };\n bpmnElement.cancelActivity = element.cancelActivity ?? true;\n }\n\n // Sequence Flow\n if (element.type === 'sequenceFlow') {\n this.applySequenceFlowProperties(bpmnElement, props);\n }\n\n // Loop characteristics\n if (props.loopCharacteristics) {\n bpmnElement.loopCharacteristics = this.buildLoopCharacteristics(\n props.loopCharacteristics as LoopCharacteristicsProps\n );\n }\n }\n\n /**\n * Apply event-specific properties\n */\n private applyEventProperties(bpmnElement: ModdleElement, element: FlowElementModel): void {\n const props = element.properties;\n const eventDefType = props.eventDefinitionType as string | undefined;\n\n if (!eventDefType || eventDefType === 'none') {\n return;\n }\n\n const eventDefElementType = EVENT_DEFINITION_MAP[eventDefType as keyof typeof EVENT_DEFINITION_MAP];\n if (!eventDefElementType) {\n return;\n }\n\n const eventDef = this.moddle.create(eventDefElementType, {});\n\n // Apply event definition specific properties\n switch (eventDefType) {\n case 'message':\n if (props.messageRef) {\n eventDef.messageRef = { id: props.messageRef as string };\n }\n break;\n case 'signal':\n if (props.signalRef) {\n eventDef.signalRef = { id: props.signalRef as string };\n }\n break;\n case 'error':\n if (props.errorRef) {\n eventDef.errorRef = { id: props.errorRef as string };\n }\n break;\n case 'escalation':\n if (props.escalationRef) {\n eventDef.escalationRef = { id: props.escalationRef as string };\n }\n break;\n case 'timer':\n if (props.timerEventDefinition) {\n const timerDef = props.timerEventDefinition as TimerEventDefinitionProps;\n if (timerDef.timeDate) {\n eventDef.timeDate = this.moddle.create('bpmn:FormalExpression', {\n body: timerDef.timeDate,\n });\n }\n if (timerDef.timeDuration) {\n eventDef.timeDuration = this.moddle.create('bpmn:FormalExpression', {\n body: timerDef.timeDuration,\n });\n }\n if (timerDef.timeCycle) {\n eventDef.timeCycle = this.moddle.create('bpmn:FormalExpression', {\n body: timerDef.timeCycle,\n });\n }\n }\n break;\n case 'conditional':\n if (props.conditionalEventDefinition) {\n const condDef = props.conditionalEventDefinition as ConditionalEventDefinitionProps;\n if (condDef.condition) {\n eventDef.condition = this.moddle.create('bpmn:FormalExpression', {\n language: condDef.condition.language,\n body: condDef.condition.body,\n });\n }\n }\n break;\n case 'link':\n if (props.linkEventDefinition) {\n const linkDef = props.linkEventDefinition as LinkEventDefinitionProps;\n eventDef.name = linkDef.name;\n if (linkDef.target) {\n eventDef.target = { id: linkDef.target };\n }\n }\n break;\n }\n\n bpmnElement.eventDefinitions = [eventDef];\n }\n\n /**\n * Apply task-specific properties\n */\n private applyTaskProperties(bpmnElement: ModdleElement, props: Record<string, unknown>): void {\n // User Task properties (Camunda extensions would go here)\n // For standard BPMN, we just set the basic properties\n if (props.implementation) {\n bpmnElement.implementation = props.implementation;\n }\n\n // Script Task\n if (props.script) {\n const script = props.script as ScriptProps;\n bpmnElement.scriptFormat = script.scriptFormat;\n bpmnElement.script = script.script;\n }\n\n // Send/Receive Task\n if (props.messageRef) {\n bpmnElement.messageRef = { id: props.messageRef as string };\n }\n if (props.instantiate !== undefined) {\n bpmnElement.instantiate = props.instantiate;\n }\n }\n\n /**\n * Apply gateway-specific properties\n */\n private applyGatewayProperties(bpmnElement: ModdleElement, props: Record<string, unknown>): void {\n if (props.gatewayDirection) {\n bpmnElement.gatewayDirection = props.gatewayDirection;\n }\n if (props.default) {\n bpmnElement.default = { id: props.default as string };\n }\n if (props.instantiate !== undefined) {\n bpmnElement.instantiate = props.instantiate;\n }\n if (props.eventGatewayType) {\n bpmnElement.eventGatewayType = props.eventGatewayType;\n }\n if (props.activationCondition) {\n bpmnElement.activationCondition = this.moddle.create('bpmn:FormalExpression', {\n body: props.activationCondition as string,\n });\n }\n }\n\n /**\n * Apply subprocess-specific properties\n */\n private applySubProcessProperties(bpmnElement: ModdleElement, props: Record<string, unknown>): void {\n if (props['triggeredByEvent'] !== undefined) {\n bpmnElement['triggeredByEvent'] = props['triggeredByEvent'];\n }\n\n // AdHoc SubProcess\n if (props['adHocOrdering']) {\n bpmnElement['ordering'] = props['adHocOrdering'];\n }\n if (props['adHocCompletionCondition']) {\n bpmnElement['completionCondition'] = this.moddle.create('bpmn:FormalExpression', {\n body: props['adHocCompletionCondition'] as string,\n });\n }\n if (props['cancelRemainingInstances'] !== undefined) {\n bpmnElement['cancelRemainingInstances'] = props['cancelRemainingInstances'];\n }\n\n // Transaction\n if (props['transactionProtocol']) {\n bpmnElement['protocol'] = props['transactionProtocol'];\n }\n }\n\n /**\n * Apply call activity properties\n */\n private applyCallActivityProperties(bpmnElement: ModdleElement, props: Record<string, unknown>): void {\n if (props['calledElement']) {\n bpmnElement['calledElement'] = props['calledElement'];\n }\n }\n\n /**\n * Apply sequence flow properties\n */\n private applySequenceFlowProperties(bpmnElement: ModdleElement, props: Record<string, unknown>): void {\n bpmnElement['sourceRef'] = { id: props['sourceRef'] as string };\n bpmnElement['targetRef'] = { id: props['targetRef'] as string };\n\n if (props['conditionExpression']) {\n const condExpr = props['conditionExpression'] as ConditionExpressionProps;\n bpmnElement['conditionExpression'] = this.moddle.create('bpmn:FormalExpression', {\n language: condExpr.language,\n body: condExpr.body,\n });\n }\n }\n\n /**\n * Apply data associations (BPMN 2.0 spec: dataInputAssociation/dataOutputAssociation are child elements of Activity)\n */\n private applyDataAssociations(bpmnElement: ModdleElement, element: FlowElementModel): void {\n // Add dataInputAssociations\n if (element.dataInputAssociations && element.dataInputAssociations.length > 0) {\n bpmnElement['dataInputAssociations'] = element.dataInputAssociations.map((assoc) => {\n const dataInputAssoc = this.moddle.create('bpmn:DataInputAssociation', {\n id: assoc.id,\n });\n // sourceRef is an array of references\n dataInputAssoc.sourceRef = [{ id: assoc.sourceRef }];\n return dataInputAssoc;\n });\n }\n\n // Add dataOutputAssociations\n if (element.dataOutputAssociations && element.dataOutputAssociations.length > 0) {\n bpmnElement['dataOutputAssociations'] = element.dataOutputAssociations.map((assoc) => {\n const dataOutputAssoc = this.moddle.create('bpmn:DataOutputAssociation', {\n id: assoc.id,\n });\n // targetRef is a single reference\n if (assoc.targetRef) {\n dataOutputAssoc.targetRef = { id: assoc.targetRef };\n }\n return dataOutputAssoc;\n });\n }\n }\n\n /**\n * Build loop characteristics\n */\n private buildLoopCharacteristics(props: LoopCharacteristicsProps): ModdleElement {\n if (props.loopType === 'standard') {\n const loop = this.moddle.create('bpmn:StandardLoopCharacteristics', {\n testBefore: props.testBefore,\n loopMaximum: props.loopMaximum,\n });\n if (props.loopCondition) {\n loop.loopCondition = this.moddle.create('bpmn:FormalExpression', {\n body: props.loopCondition,\n });\n }\n return loop;\n }\n\n // Multi-instance (default)\n const multiInstance = this.moddle.create('bpmn:MultiInstanceLoopCharacteristics', {\n isSequential: props.isSequential ?? false,\n });\n\n if (props.loopCardinality) {\n multiInstance.loopCardinality = this.moddle.create('bpmn:FormalExpression', {\n body: props.loopCardinality,\n });\n }\n if (props.loopDataInputRef) {\n multiInstance.loopDataInputRef = { id: props.loopDataInputRef };\n }\n if (props.loopDataOutputRef) {\n multiInstance.loopDataOutputRef = { id: props.loopDataOutputRef };\n }\n if (props.completionCondition) {\n multiInstance.completionCondition = this.moddle.create('bpmn:FormalExpression', {\n body: props.completionCondition,\n });\n }\n\n return multiInstance;\n }\n\n /**\n * Build an artifact element\n */\n private buildArtifact(artifact: ArtifactModel): ModdleElement {\n const elementType = BPMN_ELEMENT_MAP[artifact.type as keyof typeof BPMN_ELEMENT_MAP];\n if (!elementType) {\n throw new Error(`Unknown artifact type: ${artifact.type}`);\n }\n\n const bpmnArtifact = this.moddle.create(elementType, {\n id: artifact.id,\n name: artifact.name,\n });\n\n // Apply artifact-specific properties\n const props = artifact.properties;\n\n if (artifact.type === 'textAnnotation') {\n bpmnArtifact['text'] = props['text'] as string | undefined;\n bpmnArtifact['textFormat'] = props['textFormat'] as string | undefined;\n }\n\n if (artifact.type === 'dataObjectReference' || artifact.type === 'dataObject') {\n if (props['isCollection'] !== undefined) {\n bpmnArtifact['isCollection'] = props['isCollection'];\n }\n if (props['dataState']) {\n const state = props['dataState'] as { name?: string };\n bpmnArtifact['dataState'] = this.moddle.create('bpmn:DataState', {\n name: state.name,\n });\n }\n }\n\n if (artifact.type === 'dataStoreReference') {\n if (props['capacity'] !== undefined) {\n bpmnArtifact['capacity'] = props['capacity'];\n }\n if (props['isUnlimited'] !== undefined) {\n bpmnArtifact['isUnlimited'] = props['isUnlimited'];\n }\n }\n\n if (artifact.type === 'group') {\n if (props['categoryValueRef']) {\n bpmnArtifact['categoryValueRef'] = { id: props['categoryValueRef'] as string };\n }\n }\n\n if (artifact.type === 'association') {\n if (props['sourceRef']) {\n bpmnArtifact['sourceRef'] = { id: props['sourceRef'] as string };\n }\n if (props['targetRef']) {\n bpmnArtifact['targetRef'] = { id: props['targetRef'] as string };\n }\n if (props['associationDirection']) {\n bpmnArtifact['associationDirection'] = props['associationDirection'] as string;\n }\n }\n\n return bpmnArtifact;\n }\n\n /**\n * Build the diagram element\n */\n private buildDiagram(diagram: DiagramModel): ModdleElement {\n const bpmnDiagram = this.moddle.create('bpmndi:BPMNDiagram', {\n id: diagram.id,\n name: diagram.name,\n });\n\n const plane = this.moddle.create('bpmndi:BPMNPlane', {\n id: diagram.plane.id,\n bpmnElement: { id: diagram.plane.bpmnElement },\n });\n\n const planeElements: ModdleElement[] = [];\n\n // Add shapes\n for (const shape of diagram.plane.shapes) {\n planeElements.push(this.buildShape(shape));\n }\n\n // Add edges\n for (const edge of diagram.plane.edges) {\n planeElements.push(this.buildEdge(edge));\n }\n\n plane.planeElement = planeElements;\n bpmnDiagram.plane = plane;\n\n return bpmnDiagram;\n }\n\n /**\n * Build a shape element\n */\n private buildShape(shape: ShapeModel): ModdleElement {\n const bpmnShape = this.moddle.create('bpmndi:BPMNShape', {\n id: shape.id,\n bpmnElement: { id: shape.bpmnElement },\n });\n\n bpmnShape.bounds = this.moddle.create('dc:Bounds', {\n x: shape.bounds.x,\n y: shape.bounds.y,\n width: shape.bounds.width,\n height: shape.bounds.height,\n });\n\n if (shape.isExpanded !== undefined) {\n bpmnShape.isExpanded = shape.isExpanded;\n }\n\n if (shape.isHorizontal !== undefined) {\n bpmnShape.isHorizontal = shape.isHorizontal;\n }\n\n if (shape.label?.bounds) {\n bpmnShape.label = this.moddle.create('bpmndi:BPMNLabel', {\n bounds: this.moddle.create('dc:Bounds', {\n x: shape.label.bounds.x,\n y: shape.label.bounds.y,\n width: shape.label.bounds.width,\n height: shape.label.bounds.height,\n }),\n });\n }\n\n return bpmnShape;\n }\n\n /**\n * Build an edge element\n */\n private buildEdge(edge: EdgeModel): ModdleElement {\n const bpmnEdge = this.moddle.create('bpmndi:BPMNEdge', {\n id: edge.id,\n bpmnElement: { id: edge.bpmnElement },\n });\n\n bpmnEdge.waypoint = edge.waypoints.map((wp) =>\n this.moddle.create('dc:Point', {\n x: wp.x,\n y: wp.y,\n })\n );\n\n if (edge.label?.bounds) {\n bpmnEdge.label = this.moddle.create('bpmndi:BPMNLabel', {\n bounds: this.moddle.create('dc:Bounds', {\n x: edge.label.bounds.x,\n y: edge.label.bounds.y,\n width: edge.label.bounds.width,\n height: edge.label.bounds.height,\n }),\n });\n }\n\n return bpmnEdge;\n }\n}\n\n// Property type definitions\ninterface TimerEventDefinitionProps {\n timeDate?: string;\n timeDuration?: string;\n timeCycle?: string;\n}\n\ninterface ConditionalEventDefinitionProps {\n condition?: {\n type?: string;\n language?: string;\n body?: string;\n };\n}\n\ninterface LinkEventDefinitionProps {\n name?: string;\n source?: string[];\n target?: string;\n}\n\ninterface ScriptProps {\n scriptFormat?: string;\n script?: string;\n resultVariable?: string;\n}\n\ninterface ConditionExpressionProps {\n type?: string;\n language?: string;\n body?: string;\n}\n\ninterface LoopCharacteristicsProps {\n loopType?: 'standard' | 'multiInstance';\n isSequential?: boolean;\n loopCardinality?: string;\n loopDataInputRef?: string;\n loopDataOutputRef?: string;\n inputDataItem?: string;\n outputDataItem?: string;\n completionCondition?: string;\n loopCondition?: string;\n loopMaximum?: number;\n testBefore?: boolean;\n}\n","/**\n * BpmnElkLayout - Main Converter Class\n *\n * Converts ELK-BPMN JSON to:\n * - BPMN 2.0 XML (with diagram interchange)\n * - Layouted ELK-BPMN JSON (with coordinates)\n */\n\nimport type { ElkBpmnGraph, ElkLayoutOptions } from './types';\nimport type { LayoutedGraph } from './types/elk-output';\nimport { ElkLayouter } from './layout';\nimport { ModelBuilder } from './transform';\nimport { BpmnXmlGenerator } from './generators';\n\nexport interface BpmnElkLayoutOptions {\n /**\n * ELK layout options to override defaults\n */\n elkOptions?: ElkLayoutOptions;\n}\n\nexport class BpmnElkLayout {\n private layouter: ElkLayouter;\n private modelBuilder: ModelBuilder;\n private xmlGenerator: BpmnXmlGenerator;\n\n constructor(options?: BpmnElkLayoutOptions) {\n this.layouter = new ElkLayouter({ elkOptions: options?.elkOptions });\n this.modelBuilder = new ModelBuilder();\n this.xmlGenerator = new BpmnXmlGenerator();\n }\n\n /**\n * Convert ELK-BPMN JSON to BPMN 2.0 XML\n *\n * @param input - ELK-BPMN JSON (without coordinates)\n * @returns BPMN 2.0 XML string with diagram interchange\n *\n * @example\n * ```typescript\n * const converter = new BpmnElkLayout();\n * const xml = await converter.to_bpmn(elkBpmnJson);\n * console.log(xml);\n * ```\n */\n async to_bpmn(input: ElkBpmnGraph): Promise<string> {\n // Step 1: Run ELK layout to get coordinates\n const layouted = await this.layouter.layout(input);\n\n // Step 2: Build intermediate model\n const model = this.modelBuilder.build(layouted);\n\n // Step 3: Generate BPMN XML\n const xml = await this.xmlGenerator.generate(model);\n\n return xml;\n }\n\n /**\n * Convert ELK-BPMN JSON to layouted JSON with coordinates\n *\n * @param input - ELK-BPMN JSON (without coordinates)\n * @returns ELK-BPMN JSON with x, y coordinates for all nodes and edges\n *\n * @example\n * ```typescript\n * const converter = new BpmnElkLayout();\n * const layouted = await converter.to_json(elkBpmnJson);\n * console.log(layouted.children[0].x, layouted.children[0].y);\n * ```\n */\n async to_json(input: ElkBpmnGraph): Promise<LayoutedGraph> {\n return this.layouter.layout(input);\n }\n\n /**\n * Create a new instance with different options\n */\n static create(options?: BpmnElkLayoutOptions): BpmnElkLayout {\n return new BpmnElkLayout(options);\n }\n}\n\n// Re-export types for convenience\nexport type { ElkBpmnGraph, ElkLayoutOptions } from './types';\nexport type { LayoutedGraph } from './types/elk-output';\n"],"mappings":"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","names":["isReturnEdge","bendPoints","BranchDestType","buildNodeMap","ARTIFACT_TYPES","ARTIFACT_TYPES","DEFAULT_ELK_OPTIONS","elkNode","buildNodeMap","sources","process","process"]}
|