@aranzatech/diagrams-bpmn 0.2.13 → 0.2.15
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/{catalog-Di2nzGs9.d.ts → catalog-CK3_4cOb.d.ts} +1 -1
- package/dist/{catalog-BiLXVn-2.d.cts → catalog-xOMF2ifW.d.cts} +1 -1
- package/dist/{chunk-UAWLUDKC.js → chunk-HOWK3ZOO.js} +105 -13
- package/dist/chunk-HOWK3ZOO.js.map +1 -0
- package/dist/{chunk-O3NWJ5H7.js → chunk-QSMP34CT.js} +38 -5
- package/dist/chunk-QSMP34CT.js.map +1 -0
- package/dist/{chunk-IMW6RG6F.js → chunk-X54NHLBA.js} +43 -190
- package/dist/chunk-X54NHLBA.js.map +1 -0
- package/dist/chunk-XMVV7FRZ.js +163 -0
- package/dist/chunk-XMVV7FRZ.js.map +1 -0
- package/dist/edges/index.cjs +35 -2
- package/dist/edges/index.cjs.map +1 -1
- package/dist/edges/index.js +1 -1
- package/dist/elements/index.d.cts +4 -4
- package/dist/elements/index.d.ts +4 -4
- package/dist/elk-FSFIEL6O.js +6 -0
- package/dist/elk-FSFIEL6O.js.map +1 -0
- package/dist/{guards-DPHXfpY8.d.cts → guards-C70uIY_O.d.cts} +1 -1
- package/dist/{guards-qgSeZEU4.d.ts → guards-foB6XIfZ.d.ts} +1 -1
- package/dist/index.cjs +180 -200
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/layout/index.cjs +1428 -755
- package/dist/layout/index.cjs.map +1 -1
- package/dist/layout/index.d.cts +23 -12
- package/dist/layout/index.d.ts +23 -12
- package/dist/layout/index.js +547 -72
- package/dist/layout/index.js.map +1 -1
- package/dist/modeling/index.cjs +103 -10
- package/dist/modeling/index.cjs.map +1 -1
- package/dist/modeling/index.d.cts +23 -6
- package/dist/modeling/index.d.ts +23 -6
- package/dist/modeling/index.js +1 -1
- package/dist/nodes/index.cjs +42 -188
- package/dist/nodes/index.cjs.map +1 -1
- package/dist/nodes/index.d.cts +1 -1
- package/dist/nodes/index.d.ts +1 -1
- package/dist/nodes/index.js +1 -1
- package/dist/{types-rEfHsPr5.d.ts → types-DG5yPKld.d.ts} +1 -1
- package/dist/{types-s2_VvPGf.d.cts → types-jIDz306Y.d.cts} +1 -1
- package/dist/{types-Dfrt0wVs.d.cts → types-y-ZbX-ff.d.cts} +3 -0
- package/dist/{types-Dfrt0wVs.d.ts → types-y-ZbX-ff.d.ts} +3 -0
- package/dist/validation/index.d.cts +2 -2
- package/dist/validation/index.d.ts +2 -2
- package/dist/xml/index.d.cts +3 -3
- package/dist/xml/index.d.ts +3 -3
- package/package.json +2 -2
- package/dist/chunk-IMW6RG6F.js.map +0 -1
- package/dist/chunk-O3NWJ5H7.js.map +0 -1
- package/dist/chunk-UAWLUDKC.js.map +0 -1
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/elk.ts","../../src/layout/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { elkLayout } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode, DiagramEdge } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport type { BpmnElementType } from \"../elements/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\n\n// Container types that ELK auto-sizes based on their children.\nconst BPMN_CONTAINER_TYPES = new Set<BpmnElementType>([\n \"Pool\",\n \"Lane\",\n \"SubProcess\",\n \"Transaction\",\n \"EventSubProcess\",\n \"AdHocSubProcess\",\n]);\n\nconst CONTAINER_MIN_SIZE: Partial<Record<BpmnElementType, { w: number; h: number }>> = {\n Pool: { w: 560, h: 160 },\n Lane: { w: 480, h: 100 },\n SubProcess: { w: 200, h: 120 },\n Transaction: { w: 200, h: 120 },\n EventSubProcess: { w: 200, h: 120 },\n AdHocSubProcess: { w: 200, h: 120 },\n};\n\n// Left padding: label strip (≈30 px) + breathing room before first node.\nconst CONTAINER_PADDING: Partial<Record<BpmnElementType, string>> = {\n Pool: \"[top=30,left=55,bottom=30,right=40]\",\n Lane: \"[top=25,left=60,bottom=25,right=40]\",\n SubProcess: \"[top=25,left=35,bottom=25,right=35]\",\n Transaction: \"[top=25,left=35,bottom=25,right=35]\",\n EventSubProcess: \"[top=25,left=35,bottom=25,right=35]\",\n AdHocSubProcess: \"[top=25,left=35,bottom=25,right=35]\",\n};\n\n/**\n * ELK-based auto-layout for BPMN diagrams.\n *\n * Direction policy — always LEFT-TO-RIGHT to match screen anatomy:\n * - Root: RIGHT — free nodes and pools flow LR on the canvas.\n * - Pool that contains Lanes: DOWN internally so lanes stack top-to-bottom\n * (standard horizontal-pool anatomy); the pool itself is still placed LR.\n * - Pool without lanes, Lane, SubProcess, Transaction, AdHoc: RIGHT — content\n * flows left-to-right inside the container.\n * - All edges get ORTHOGONAL routing in a single INCLUDE_CHILDREN pass so\n * cross-pool and cross-lane edges are routed correctly.\n * - Containers auto-resize to fit their children.\n */\nexport async function bpmnElkLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n): Promise<{ nodes: BpmnRFNode[]; edges: BpmnRFEdge[] }> {\n // Pools that contain at least one Lane child need DOWN internal direction so\n // the lanes stack vertically (standard horizontal BPMN pool).\n const poolsWithLanes = new Set<string>();\n for (const node of nodes) {\n if (node.data.elementType === \"Lane\" && node.parentId) {\n poolsWithLanes.add(node.parentId);\n }\n }\n\n const result = await elkLayout(\n nodes as unknown as DiagramNode[],\n edges as unknown as DiagramEdge[],\n {\n direction: \"LR\",\n getNodeSize: (node) => {\n const bNode = node as unknown as BpmnRFNode;\n if (BPMN_CONTAINER_TYPES.has(bNode.data.elementType)) return undefined;\n return getBpmnNodeSize(bNode);\n },\n isContainerNode: (node) =>\n BPMN_CONTAINER_TYPES.has((node as unknown as BpmnRFNode).data.elementType),\n getNodeLayoutOptions: (node) => {\n const type = (node as unknown as BpmnRFNode).data.elementType;\n if (!BPMN_CONTAINER_TYPES.has(type)) return undefined;\n const min = CONTAINER_MIN_SIZE[type];\n // Pool with Lanes: DOWN so lanes stack top-to-bottom inside the pool.\n // Everything else (Lane content, SubProcess, free tasks): RIGHT (LR).\n const dir = type === \"Pool\" && poolsWithLanes.has(node.id) ? \"DOWN\" : \"RIGHT\";\n return {\n \"elk.direction\": dir,\n \"elk.nodeSize.constraints\": \"MINIMUM_SIZE\",\n ...(min ? { \"elk.nodeSize.minimum\": `[w=${min.w},h=${min.h}]` } : {}),\n ...(CONTAINER_PADDING[type] ? { \"elk.padding\": CONTAINER_PADDING[type] } : {}),\n };\n },\n elk: {\n \"elk.algorithm\": \"layered\",\n \"elk.direction\": \"RIGHT\",\n \"elk.hierarchyHandling\": \"INCLUDE_CHILDREN\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.layered.spacing.nodeNodeBetweenLayers\": \"100\",\n \"elk.layered.spacing.edgeNodeBetweenLayers\": \"40\",\n \"elk.spacing.nodeNode\": \"60\",\n \"elk.spacing.componentComponent\": \"80\",\n },\n },\n );\n\n const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));\n const edgeMap = new Map(result.edges.map((e) => [e.id, e]));\n\n const updatedNodes = nodes.map((node) => {\n const laid = nodeMap.get(node.id);\n if (!laid) return node;\n return { ...node, position: laid.position, width: laid.width, height: laid.height };\n });\n\n const updatedEdges = edges.map((edge) => {\n const laid = edgeMap.get(edge.id);\n if (!laid) return edge;\n const nextData = { ...edge.data };\n if (laid.points && laid.points.length > 0) {\n nextData.routingPoints = laid.points;\n } else {\n delete nextData.routingPoints;\n }\n return { ...edge, data: nextData };\n });\n\n return { nodes: updatedNodes, edges: updatedEdges as BpmnRFEdge[] };\n}\n","import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\nexport { bpmnElkLayout } from \"./elk\";\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/layout/bpmn-layout-graph.ts","../../src/layout/bpmn-custom-layout.ts","../../src/layout/index.ts"],"names":["bpmnElkLayout"],"mappings":";;;;;;;;AAKO,IAAM,sBAAA,uBAA6B,GAAA,CAAqB;AAAA,EAC7D,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,YAAA;AAAA,EAAc,aAAA;AAAA,EAAe,iBAAA;AAAA,EAAmB;AAClE,CAAC,CAAA;AAEM,IAAM,oBAAA,uBAA2B,GAAA,CAAqB;AAAA,EAC3D,kBAAA;AAAA,EAAoB,kBAAA;AAAA,EAAoB,iBAAA;AAAA,EACxC,mBAAA;AAAA,EAAqB;AACvB,CAAC,CAAA;AAmBM,SAAS,eAAA,CACd,SACA,QAAA,EACa;AACb,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAuB;AACzC,EAAA,KAAA,MAAW,EAAA,IAAM,OAAA,EAAS,KAAA,CAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAEzC,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAuD;AACvE,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,EAAE,CAAA;AACxC,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA,CAAE,EAAA,EAAI,CAAA;AAAA,EAC5D;AAGA,EAAA,KAAA,MAAW,WAAW,OAAA,EAAS;AAC7B,IAAA,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,KAAM,CAAA,EAAG;AAE9B,IAAA,MAAM,QAA4C,CAAC,EAAE,IAAI,OAAA,EAAS,GAAA,EAAK,GAAG,CAAA;AAC1E,IAAA,KAAA,CAAM,GAAA,CAAI,SAAS,CAAC,CAAA;AAEpB,IAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAClC,MAAA,MAAM,YAAY,GAAA,CAAI,GAAA,CAAI,GAAA,CAAI,EAAE,KAAK,EAAC;AACtC,MAAA,IAAI,GAAA,CAAI,GAAA,IAAO,SAAA,CAAU,MAAA,EAAQ;AAC/B,QAAA,KAAA,CAAM,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,CAAC,CAAA;AACnB,QAAA,KAAA,CAAM,GAAA,EAAI;AACV,QAAA;AAAA,MACF;AACA,MAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,SAAA,CAAU,IAAI,GAAA,EAAK,CAAA;AAC9C,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC/B,MAAA,IAAI,WAAW,CAAA,EAAG;AAChB,QAAA,WAAA,CAAY,IAAI,MAAM,CAAA;AAAA,MACxB,CAAA,MAAA,IAAW,WAAW,CAAA,EAAG;AACvB,QAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAC,CAAA;AACnB,QAAA,KAAA,CAAM,KAAK,EAAE,EAAA,EAAI,MAAA,EAAQ,GAAA,EAAK,GAAG,CAAA;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,WAAA;AACT;AAIO,SAAS,eAAA,CACd,OACA,OAAA,EACkB;AAClB,EAAA,OAAO,KAAA,CACJ,OAAO,CAAA,CAAA,KAAK;AACX,IAAA,MAAM,CAAA,GAAK,CAAA,CAAE,IAAA,EAAM,QAAA,IAAY,CAAA,CAAE,IAAA;AACjC,IAAA,OAAO,CAAA,KAAM,cAAA,IAAkB,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,IAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AAAA,EAC9E,CAAC,CAAA,CACA,GAAA,CAAI,QAAM,EAAE,EAAA,EAAI,EAAE,EAAA,EAAI,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,QAAQ,CAAA,CAAE,MAAA,EAAQ,cAAc,CAAA,CAAE,YAAA,IAAgB,MAAK,CAAE,CAAA;AACtG;AAIO,SAAS,eAAA,CACd,SACA,YAAA,EACU;AACV,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAoB,OAAA,CAAQ,GAAA,CAAI,QAAM,CAAC,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAChE,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAsB,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAA,KAAM,CAAC,EAAA,EAAI,EAAE,CAAC,CAAC,CAAA;AAEjE,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,IAAK,CAAC,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG;AAClD,IAAA,GAAA,CAAI,IAAI,CAAA,CAAE,MAAM,CAAA,CAAG,IAAA,CAAK,EAAE,MAAM,CAAA;AAChC,IAAA,KAAA,CAAM,GAAA,CAAI,EAAE,MAAA,EAAA,CAAS,KAAA,CAAM,IAAI,CAAA,CAAE,MAAM,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAA,CAAO,CAAA,EAAA,KAAA,CAAO,MAAM,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA,MAAO,CAAC,CAAA;AAC7D,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,EAAA,GAAK,MAAM,KAAA,EAAM;AACvB,IAAA,MAAA,CAAO,KAAK,EAAE,CAAA;AACd,IAAA,KAAA,MAAW,QAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,IAAK,EAAC,EAAG;AACpC,MAAA,MAAM,CAAA,GAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,KAAK,CAAA,IAAK,CAAA;AACnC,MAAA,KAAA,CAAM,GAAA,CAAI,MAAM,CAAC,CAAA;AACjB,MAAA,IAAI,CAAA,KAAM,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAAA,IAC9B;AAAA,EACF;AAGA,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,MAAM,CAAA;AAC3B,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG,MAAA,CAAO,KAAK,EAAE,CAAA;AAAA,EACnC;AAEA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,aAAA,CACd,SACA,YAAA,EACqB;AACrB,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,EAAS,YAAY,CAAA;AACnD,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAoB,OAAA,CAAQ,GAAA,CAAI,QAAM,CAAC,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAE9D,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAsB,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAA,KAAM,CAAC,EAAA,EAAI,EAAE,CAAC,CAAC,CAAA;AACnE,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,KAAA,CAAM,IAAI,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,CAAK,EAAE,MAAM,CAAA;AAAA,EACpC;AAEA,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,MAAM,QAAA,GAAA,CAAY,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA,IAAK,EAAC,EAAG,GAAA,CAAI,CAAA,CAAA,KAAK,GAAA,CAAI,GAAA,CAAI,CAAC,KAAK,CAAC,CAAA;AAC/D,IAAA,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,QAAA,CAAS,MAAA,GAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA;AAAA,EACjE;AAEA,EAAA,OAAO,GAAA;AACT;AAQO,SAAS,kBAAA,CACd,OACA,YAAA,EACqB;AACrB,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAoB;AACtC,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA;AAEnC,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAsB,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,CAAC,CAAC,CAAA;AAClE,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,KAAA,CAAM,IAAI,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,CAAK,EAAE,MAAM,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,EAAS,YAAY,CAAA;AACnD,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,EAAI,CAAA,KAAM,CAAC,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAErD,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AAAA,IAAO,CAAA,CAAA,KAC1B,oBAAA,CAAqB,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,WAAW,CAAA,IAAA,CAC1C,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,EAAG,UAAU,CAAA,IAAK;AAAA,GACnC;AAEA,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,WAAW,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,EAAE,KAAK,EAAC;AACzC,IAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AAGzB,IAAA,MAAM,UAAA,GAA4B,QAAA,CAAS,GAAA,CAAI,CAAA,KAAA,KAAS;AACtD,MAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,MAAA,MAAM,CAAA,GAAI,CAAC,KAAK,CAAA;AAChB,MAAA,OAAO,EAAE,MAAA,EAAQ;AACf,QAAA,MAAM,IAAA,GAAO,EAAE,KAAA,EAAM;AACrB,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,QAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,QAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,GAAA,CAAI,IAAI,KAAK,EAAC,EAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MACvD;AACA,MAAA,OAAO,OAAA;AAAA,IACT,CAAC,CAAA;AAGD,IAAA,MAAM,SAAS,CAAC,GAAG,UAAA,CAAW,CAAC,CAAC,CAAA,CAAE,MAAA;AAAA,MAAO,QACvC,UAAA,CAAW,KAAA,CAAM,OAAK,CAAA,CAAE,GAAA,CAAI,EAAE,CAAC;AAAA,KACjC;AACA,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AAGzB,IAAA,MAAM,QAAQ,MAAA,CAAO,MAAA;AAAA,MAAO,CAAC,CAAA,EAAG,CAAA,KAAA,CAC7B,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,IAAK,QAAA,KAAa,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,IAAK,YAAY,CAAA,GAAI;AAAA,KACpE;AAEA,IAAA,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAK,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,KAAA;AACT;AAeA,SAAS,gBAAgB,MAAA,EAAkD;AACzE,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAM,OAAO,EAAA;AACtC,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,EAAG,OAAQ,CAAA;AACvC,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,EAAI,OAAQ,CAAA;AACvC,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,eAAe,KAAA,EAAkE;AACxF,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAwC;AACxD,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,IAAI,CAAC,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,MAAA,kBAAQ,IAAI,GAAA,EAAK,CAAA;AACnD,IAAA,GAAA,CAAI,GAAA,CAAI,EAAE,MAAM,CAAA,CAAG,IAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,YAAA,IAAgB,IAAI,CAAA;AAAA,EACzD;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,UAAA,CACd,KAAA,EACA,YAAA,EACA,OAAA,EACA,YAAA,EACqB;AACrB,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAoB,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAE9D,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAsB,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,CAAC,CAAC,CAAA;AAClE,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,KAAA,CAAM,IAAI,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,CAAK,EAAE,MAAM,CAAA;AAAA,EACpC;AAGA,EAAA,MAAM,SAAA,GAAY,eAAe,YAAY,CAAA;AAI7C,EAAA,MAAM,cAAc,CAAC,GAAG,YAAA,CAAa,OAAA,EAAS,CAAA,CAAE,IAAA;AAAA,IAC9C,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAC,CAAC,CAAA,IAAK,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,CAAC,CAAC,CAAA,IAAK,CAAA;AAAA,GAC7D;AAEA,EAAA,KAAA,MAAW,CAAC,OAAA,EAAS,OAAO,CAAA,IAAK,WAAA,EAAa;AAC5C,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,GAAA,CAAI,OAAO,KAAK,EAAC;AACxC,IAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AAEzB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,IAAK,CAAA;AAGtC,IAAA,MAAM,cAAA,GAAiB,CAAC,WAAA,KAAkC;AACxD,MAAA,MAAM,SAAmB,EAAC;AAC1B,MAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,MAAA,MAAM,CAAA,GAAI,CAAC,WAAW,CAAA;AACtB,MAAA,OAAO,EAAE,MAAA,EAAQ;AACf,QAAA,MAAM,IAAA,GAAO,EAAE,KAAA,EAAM;AACrB,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,IAAK,SAAS,OAAA,EAAS;AAC3C,QAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,GAAA,CAAI,IAAI,KAAK,EAAC,EAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MACvD;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,YAAA,GAAe,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,GAAA,CAAI,CAAA,KAAA,MAAU;AAAA,MACxC,KAAA;AAAA,MACA,OAAA,EAAS,eAAe,KAAK,CAAA;AAAA,MAC7B,MAAM,eAAA,CAAgB,YAAA,EAAc,GAAA,CAAI,KAAK,KAAK,IAAI;AAAA,KACxD,CAAE,CAAA;AAKF,IAAA,MAAM,QAAA,GAAc,WAAW,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,IAAA,IAAQ,CAAA,CAAE,IAAA,KAAS,CAAC,CAAA;AAC1E,IAAA,MAAM,WAAA,GAAc,WAAW,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,IAAA,IAAQ,EAAE,IAAA,KAAS,CAAC,EACvE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,QAAQ,MAAA,GAAS,CAAA,CAAE,QAAQ,MAAM,CAAA;AAGrD,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AACzC,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,QAAA,GAAW,EAAE,IAAK,CAAA;AAAA,IAC1C;AACA,IAAA,IAAI,UAAA,GAAa,CAAA;AACjB,IAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,MAAA,OAAO,CAAC,GAAG,QAAA,CAAS,MAAA,EAAQ,CAAA,CAAE,QAAA,CAAS,QAAA,GAAW,UAAU,CAAA,EAAG,UAAA,EAAA;AAC/D,MAAA,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,QAAA,GAAW,UAAU,CAAA;AAC3C,MAAA,UAAA,EAAA;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,IAAK,QAAA;AACrC,MAAA,KAAA,MAAW,EAAA,IAAM,EAAE,OAAA,EAAS;AAC1B,QAAA,IAAA,CAAK,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAMA,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,YAAA,CAAa,MAAM,CAAA;AAEhD,EAAA,MAAM,iBAAiB,KAAA,CAAM,MAAA;AAAA,IAAO,OAClC,oBAAA,CAAqB,GAAA,CAAI,EAAE,IAAA,CAAK,WAAW,KAC3C,CAAC,YAAA,CAAa,IAAI,CAAA,CAAE,EAAE,MACrB,KAAA,CAAM,GAAA,CAAI,EAAE,EAAE,CAAA,EAAG,UAAU,CAAA,IAAK;AAAA,GACnC;AAEA,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,MAAM,WAAW,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,EAAE,KAAK,EAAC;AACzC,IAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AAEzB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,IAAK,CAAA;AAGvC,IAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA4B;AACnD,MAAA,MAAM,SAAmB,EAAC;AAC1B,MAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,MAAA,MAAM,CAAA,GAAI,CAAC,KAAK,CAAA;AAChB,MAAA,OAAO,EAAE,MAAA,EAAQ;AACf,QAAA,MAAM,IAAA,GAAO,EAAE,KAAA,EAAM;AACrB,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,QAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,QAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAChB,QAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,GAAA,CAAI,IAAI,KAAK,EAAC,EAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MACvD;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA;AAC5C,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,GAAA,CAAI,CAAA,KAAA,MAAU;AAAA,MACxC,KAAA;AAAA,MACA,OAAA,EAAS,gBAAgB,KAAK,CAAA;AAAA,MAC9B,MAAM,eAAA,CAAgB,aAAA,EAAe,GAAA,CAAI,KAAK,KAAK,IAAI;AAAA,KACzD,CAAE,CAAA;AAEF,IAAA,MAAM,SAAA,GAAe,WAAW,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,IAAA,IAAQ,CAAA,CAAE,IAAA,KAAS,CAAC,CAAA;AAC3E,IAAA,MAAM,YAAA,GAAe,WAAW,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,IAAA,IAAQ,EAAE,IAAA,KAAS,CAAC,EACxE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,QAAQ,MAAA,GAAS,CAAA,CAAE,QAAQ,MAAM,CAAA;AAErD,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,IAAA,KAAA,MAAW,CAAA,IAAK,WAAW,SAAA,CAAU,GAAA,CAAI,EAAE,KAAA,EAAO,QAAA,GAAW,EAAE,IAAK,CAAA;AACpE,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,MAAA,OAAO,CAAC,GAAG,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,QAAA,CAAS,QAAA,GAAW,OAAO,CAAA,EAAG,OAAA,EAAA;AAC7D,MAAA,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,QAAA,GAAW,OAAO,CAAA;AACzC,MAAA,OAAA,EAAA;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,IAAK,QAAA;AACtC,MAAA,KAAA,MAAW,MAAM,CAAA,CAAE,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,IAC9C;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;;;AC3WA,IAAM,YAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,EAAA;AACvB,IAAM,OAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,EAAA;AACvB,IAAM,OAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,EAAA;AACvB,IAAM,UAAA,GAAiB,GAAA;AACvB,IAAM,UAAA,GAAiB,GAAA;AACvB,IAAM,cAAA,GAAiB,CAAA;AAMvB,SAAS,GAAG,IAAA,EAA0B;AACpC,EAAA,OAAO,IAAA,CAAK,KAAA,IAAU,IAAA,CAAK,QAAA,EAA6C,KAAA,IAAS,GAAA;AACnF;AACA,SAAS,GAAG,IAAA,EAA0B;AACpC,EAAA,OAAO,IAAA,CAAK,MAAA,IAAW,IAAA,CAAK,QAAA,EAA8C,MAAA,IAAU,EAAA;AACtF;AAUA,SAAS,UAAA,CACP,IAAA,EACA,KAAA,EACA,OAAA,EACA,QAAA,EACY;AAEZ,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAExB,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,OAAO,EAAE,KAAA,EAAO,IAAI,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA,EAAI;AAAA,IAC9C;AAEA,IAAA,MAAM,KAAA,GAAQ,UAAA;AACd,IAAA,MAAM,CAAA,GAAI,cAAA,GAAiB,CAAA,GAAI,KAAA,CAAM,MAAA,GAAS,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAI,cAAA;AACtF,IAAA,MAAM,CAAA,GAAI,UAAA;AACV,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,CAAA,MAAO;AAAA,QAC7B,GAAG,IAAA;AAAA,QACH,QAAA,EAAU,EAAE,CAAA,EAAG,cAAA,EAAgB,GAAG,cAAA,GAAiB,CAAA,IAAK,QAAQ,cAAA,CAAA,EAAgB;AAAA,QAChF,KAAA,EAAO,IAAI,cAAA,GAAiB,CAAA;AAAA,QAC5B,MAAA,EAAQ;AAAA,OACV,CAAE,CAAA;AAAA,MACF,KAAA,EAAO,CAAA;AAAA,MACP,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AAIA,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AACjD,EAAA,MAAM,QAAA,GAAa,eAAA,CAAgB,QAAA,EAAU,UAAU,CAAA;AACvD,EAAA,MAAM,UAAa,eAAA,CAAgB,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAA;AAC5D,EAAA,MAAM,QAAA,GAAa,SAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AAE1D,EAAA,MAAM,UAAU,aAAA,CAAc,CAAC,GAAG,UAAU,GAAG,QAAQ,CAAA;AACvD,EAAA,MAAM,KAAA,GAAU,kBAAA,CAAmB,OAAA,EAAS,QAAQ,CAAA;AACpD,EAAA,MAAM,IAAA,GAAU,UAAA,CAAW,OAAA,EAAS,QAAA,EAAU,SAAS,KAAK,CAAA;AAO5D,EAAA,MAAM,qBAAA,GAAwB,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,IAAA,CAAK,IAAI,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,GAAI,EAAE,CAAA;AACzE,EAAA,MAAM,cAAc,qBAAA,GAChB,CAAC,GAAG,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,GACrD,CAAC,GAAG,KAAK,CAAA;AACb,EAAA,MAAM,QAAA,GAAc,YAAY,MAAA,GAAS,CAAA;AAGzC,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAoB;AAC3C,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,IAAA,IAAI,YAAY,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA,KAAa,KAAK,EAAA,EAAI;AAC1D,MAAA,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAA,CAAK,QAAQ,CAAA;AAAA,IACvC,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,QAAQ,CAAA;AAAA,IAClC;AAAA,EACF;AAKA,EAAA,MAAM,OAAA,GAAU,WAAW,WAAA,CAAY,GAAA,CAAI,OAAK,CAAA,CAAE,EAAE,CAAA,GAAI,CAAC,QAAQ,CAAA;AAQjE,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAsB;AAE5C,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,WAAW,OAAA,CACd,MAAA,CAAO,OAAK,UAAA,CAAW,GAAA,CAAI,EAAE,EAAE,CAAA,KAAM,MAAM,CAAA,CAC3C,IAAI,CAAA,CAAA,KAAK,IAAA,CAAK,IAAI,CAAA,CAAE,EAAE,KAAK,CAAC,CAAA;AAE/B,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,SAAA,CAAU,GAAA,CAAI,MAAA,EAAQ,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,QAAA,EAAU,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,CAAA;AAAA,IACjF,CAAA,MAAO;AACL,MAAA,MAAM,MAAA,GAAW,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAA;AACrC,MAAA,MAAM,MAAA,GAAW,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAA;AACrC,MAAA,MAAM,QAAA,GAAW,SAAS,MAAA,GAAS,CAAA;AACnC,MAAA,MAAM,QAAA,GAAW,WAAW,UAAA,GAAa,IAAA,CAAK,IAAI,CAAA,EAAG,QAAA,GAAW,CAAC,CAAA,GAAI,OAAA;AAGrE,MAAA,MAAM,SAAW,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,UAAA,GAAa,IAAI,QAAQ,CAAA;AAC/D,MAAA,SAAA,CAAU,IAAI,MAAA,EAAQ,EAAE,QAAQ,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAA;AAAA,IAC5D;AAAA,EACF;AAKA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,CAAC,GAAG,OAAA,CAAQ,MAAA,EAAQ,CAAC,CAAA;AACnD,EAAA,MAAM,IAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,IAAK,MAAA,EAAQ,KAAK,IAAA,CAAK,GAAA,CAAI,GAAG,CAAC,CAAA;AAC/C,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,IAAK,CAAA;AAClC,IAAA,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,IAAK,CAAA,EAAG,EAAA,CAAG,IAAI,CAAC,CAAC,CAAA;AAAA,EAClD;AAGA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAoB;AACrC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,MAAA,EAAQ,CAAA,EAAA,EAAK;AAChC,IAAA,IAAA,CAAK,GAAA,CAAI,GAAG,IAAI,CAAA;AAChB,IAAA,IAAA,IAAA,CAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,IAAK,GAAA,IAAO,OAAA;AAAA,EACjC;AACA,EAAA,MAAM,WAAW,IAAA,GAAO,OAAA;AAOxB,EAAA,MAAM,MAAA,GAAS,YAAA,GAAe,UAAA,GAAa,QAAA,GAAW,UAAA;AACtD,EAAA,MAAM,QAAS,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,MAAA,GAAS,iBAAiB,CAAC,CAAA;AAC/D,EAAA,MAAM,KAAA,GAAS,QAAQ,cAAA,GAAiB,CAAA;AAKxC,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAoB;AACtC,EAAA,IAAI,IAAA,GAAO,cAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AACxB,IAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,IAAI,CAAA;AACtB,IAAA,IAAA,IAAQ,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA,EAAG,MAAA,IAAU,UAAA;AACzC,IAAA,IAAI,CAAA,GAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,IAAA,IAAQ,cAAA;AAAA,EACtC;AACA,EAAA,MAAM,QAAQ,IAAA,GAAO,cAAA;AAIrB,EAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,CAAA,IAAA,KAAQ;AAC5C,IAAA,MAAM,CAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,IAAK,CAAA;AACxC,IAAA,MAAM,CAAA,GAAU,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,IAAK,CAAA;AACrC,IAAA,MAAM,MAAA,GAAU,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,IAAK,QAAA;AAC3C,IAAA,MAAM,IAAA,GAAU,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA;AACpC,IAAA,MAAM,KAAA,GAAU,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,IAAK,CAAA;AAErC,IAAA,MAAM,SAAA,GAAA,CAAa,IAAA,CAAK,GAAA,CAAI,CAAC,KAAK,CAAA,IAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,IAAK,GAAA,IAAO,CAAA,GAAI,EAAA,CAAG,IAAI,CAAA,GAAI,CAAA;AAC7E,IAAA,MAAM,SAAA,GAAA,CAAa,CAAA,GAAI,IAAA,CAAK,MAAA,KAAW,UAAA,GAAa,WAAW,UAAA,GAAa,CAAA,GAAI,EAAA,CAAG,IAAI,CAAA,GAAI,CAAA;AAM3F,IAAA,MAAM,WAAA,GAAc,YAAY,CAAC,CAAC,KAAK,QAAA,IAAY,IAAA,CAAK,aAAa,IAAA,CAAK,EAAA;AAK1E,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,QAAA,GAAW,UAAA,GAAa,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,QAAA,GAAW,CAAC,CAAA,GAAI,OAAA;AACpF,IAAA,MAAM,gBAAgB,IAAA,CAAK,GAAA,CAAI,aAAa,IAAA,CAAK,MAAA,GAAS,iBAAiB,CAAC,CAAA;AAE5E,IAAA,MAAM,CAAA,GAAI,WAAA,GACN,YAAA,GAAe,UAAA,GAAa,YAC5B,UAAA,GAAa,SAAA;AAEjB,IAAA,MAAM,CAAA,GAAI,WAAA,GACN,aAAA,GAAgB,SAAA,GAChB,QAAQ,aAAA,GAAgB,SAAA;AAE5B,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,UAAU,EAAE,CAAA,EAAG,GAAE,EAAE;AAAA,EACvC,CAAC,CAAA;AAOD,EAAA,MAAM,YAAA,GAAe,EAAA;AACrB,EAAA,MAAM,eAAA,GAAkB,CAAC,GAAG,iBAAiB,CAAA;AAE7C,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAE5B,IAAA,MAAM,eAAA,GAAkB,eAAA,CACrB,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO,EAAE,CAAA,EAAG,CAAA,GAAI,CAAA,CACxB,MAAA,CAAO,CAAC,EAAE,GAAE,KAAA,CAAO,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,IAAK,QAAA,MAAc,MAAM,CAAA,CAC/D,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAE,QAAA,CAAS,CAAA,GAAI,CAAA,CAAE,CAAA,CAAE,SAAS,CAAC,CAAA;AAEjD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA,EAAA,EAAK;AAC/C,MAAA,MAAM,OAAO,eAAA,CAAgB,eAAA,CAAgB,CAAA,GAAI,CAAC,EAAE,CAAC,CAAA;AACrD,MAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,eAAA,CAAgB,CAAC,EAAE,CAAC,CAAA;AAGjD,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,GAAG,IAAI,CAAA;AAC5C,MAAA,MAAM,OAAA,GAAa,KAAK,QAAA,CAAS,CAAA;AACjC,MAAA,MAAM,OAAA,GAAa,KAAK,QAAA,CAAS,CAAA;AACjC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,GAAG,IAAI,CAAA;AAC5C,MAAA,MAAM,QAAA,GAAa,UAAA,GAAa,YAAA,GAAe,OAAA,IAAW,aAAa,YAAA,GAAe,OAAA;AAEtF,MAAA,IAAI,CAAC,QAAA,EAAU;AAEf,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,GAAG,IAAI,CAAA;AAC3C,MAAA,IAAI,SAAA,GAAY,YAAA,GAAe,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG;AAC9C,QAAA,eAAA,CAAgB,eAAA,CAAgB,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI;AAAA,UACtC,GAAG,IAAA;AAAA,UACH,QAAA,EAAU;AAAA,YACR,GAAG,SAAA,GAAY,YAAA;AAAA,YACf,CAAA,EAAG,KAAK,QAAA,CAAS;AAAA;AACnB,SACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,EAAA,MAAM,eAAA,GAAkB,QAAA,GACpB,WAAA,CAAY,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,IACvB,GAAG,IAAA;AAAA;AAAA;AAAA,IAGH,QAAA,EAAU,EAAE,CAAA,EAAG,cAAA,EAAgB,CAAA,EAAG,MAAM,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,IAAK,cAAA,EAAe;AAAA,IACvE,KAAA,EAAO,KAAA;AAAA,IACP,QAAQ,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,EAAE,GAAG,MAAA,IAAU;AAAA,GAC5C,CAAE,IACF,EAAC;AAIL,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,GAAG,eAAA,EAAiB,GAAG,eAAe,CAAA;AAAA,IAC9C,KAAA,EAAO,KAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV;AACF;AAcA,IAAM,mBAAA,GAAsB,EAAA;AAC5B,IAAM,kBAAA,GAAsB,EAAA;AAG5B,SAAS,WAAA,CACP,MAAA,EACA,IAAA,EACA,KAAA,EAC0B;AAC1B,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC/B,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAC/B,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,IAAA,CAAK,QAAA,EAAS;AAC/B,EAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAAE,IAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAG,IAAA,OAAO,GAAA;AAAA,EAAK;AAC1D,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,IAAA,CAAK,QAAA,EAAU,MAAM,KAAK,CAAA;AACrD,EAAA,MAAM,GAAA,GAAM,EAAE,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,GAAA,CAAI,CAAA,EAAE;AACvD,EAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,GAAG,CAAA;AACrB,EAAA,OAAO,GAAA;AACT;AAGA,SAAS,MAAA,CAAO,MAAkB,OAAA,EAA0C;AAC1E,EAAA,OAAO,IAAA,CAAK,YAAY,OAAA,CAAQ,GAAA,CAAI,KAAK,QAAQ,CAAA,GAAI,KAAK,QAAA,GAAW,MAAA;AACvE;AAIA,SAAS,UAAA,CACP,KAAA,EACA,WAAA,EACA,WAAA,EACA,SACA,OAAA,EACc;AACd,EAAA,MAAM,IAAA,GAAQ,IAAI,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AACrD,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAgB;AAClC,EAAA,MAAM,MAAQ,CAAC,EAAA,KAAe,WAAA,CAAY,EAAA,EAAI,MAAM,KAAK,CAAA;AAEzD,EAAA,OAAO,KAAA,CAAM,IAAI,CAAA,IAAA,KAAQ;AACvB,IAAA,MAAM,QAAA,GAAY,IAAA,CAAK,IAAA,EAAM,QAAA,IAAY,IAAA,CAAK,IAAA;AAG9C,IAAA,IAAI,aAAa,cAAA,EAAgB;AAC/B,MAAA,MAAM,CAAA,GAAI,EAAE,GAAG,IAAA,CAAK,IAAA,EAAK;AACzB,MAAA,OAAO,CAAA,CAAE,aAAA;AACT,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,CAAA,EAAE;AAAA,IAC5B;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAChC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAChC,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,EAAK,OAAO,IAAA;AAEzB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACvB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACvB,IAAA,MAAM,KAAK,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,GAAK,GAAG,GAAG,CAAA;AAC/B,IAAA,MAAM,KAAK,EAAA,CAAG,GAAG,CAAA,EAAG,EAAA,GAAK,GAAG,GAAG,CAAA;AAG/B,IAAA,MAAM,GAAA,GAAM,KAAK,CAAA,GAAI,EAAA,GAAK,GAAG,GAAA,GAAM,IAAA,CAAK,IAAI,EAAA,GAAK,CAAA;AACjD,IAAA,MAAM,GAAA,GAAM,KAAK,CAAA,GAAI,EAAA,GAAK,GAAG,GAAA,GAAM,IAAA,CAAK,IAAI,EAAA,GAAK,CAAA;AAGjD,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,GAAI,GAAA,CAAI,QAAA,GAClD,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,EAAG,QAAA,IAAY,EAAE,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,EAAG,QAAA,GAC1F,GAAA,CAAI,QAAA;AACR,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,GAAI,GAAA,CAAI,QAAA,GAClD,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,EAAG,QAAA,IAAY,EAAE,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,QAAA,IAAY,EAAE,CAAA,EAAG,QAAA,GAC1F,GAAA,CAAI,QAAA;AACR,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,MAAM,CAAA,GAAI,EAAE,GAAG,IAAA,CAAK,IAAA,EAAK;AACzB,MAAA,OAAO,CAAA,CAAE,aAAA;AACT,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,CAAA,EAAE;AAAA,IAC5B;AAEA,IAAA,IAAI,aAAA;AAGJ,IAAA,IAAI,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AAC5B,MAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,mBAAA;AACxC,MAAA,aAAA,GAAgB;AAAA,QACd,EAAE,CAAA,EAAG,GAAA,EAAM,CAAA,EAAG,KAAK,CAAA,EAAE;AAAA;AAAA,QACrB,EAAE,CAAA,EAAG,GAAA,EAAM,CAAA,EAAG,IAAA,EAAK;AAAA;AAAA,QACnB,EAAE,CAAA,EAAG,GAAA,EAAM,CAAA,EAAG,IAAA,EAAK;AAAA;AAAA,QACnB,EAAE,CAAA,EAAG,GAAA,EAAM,CAAA,EAAG,KAAK,CAAA;AAAE;AAAA,OACvB;AAAA,IACF,CAAA,MAAA,IAGS,OAAO,GAAA,EAAK,OAAO,MAAM,MAAA,CAAO,GAAA,EAAK,OAAO,CAAA,EAAG;AACtD,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,CAAA;AAIhC,MAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,GAAA,GAAM,GAAG,CAAA,GAAI,EAAA,GAAK,GAAA,GAAA,CAAO,GAAA,GAAM,GAAA,IAAO,CAAA;AAE/D,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,YAAY,EAAE,CAAA;AAC3C,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,YAAY,EAAE,CAAA;AAE3C,MAAA,IAAI,OAAA,IAAW,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,IAAK,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,EAAG;AAC5E,QAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA;AACjC,QAAA,MAAM,UAAU,SAAA,GACZ,UAAA,CAAW,KAAK,OAAA,CAAQ,MAAA,IAAU,OAClC,UAAA,CAAW,CAAA;AAIf,QAAA,aAAA,GAAgB;AAAA,UACd,EAAE,GAAG,GAAA,EAAS,CAAA,EAAG,YAAY,IAAA,CAAK,CAAA,GAAI,EAAA,GAAK,IAAA,CAAK,CAAA,EAAE;AAAA;AAAA,UAClD,EAAE,GAAG,OAAA,EAAS,CAAA,EAAG,YAAY,IAAA,CAAK,CAAA,GAAI,EAAA,GAAK,IAAA,CAAK,CAAA,EAAE;AAAA;AAAA,UAClD,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,OAAA,EAAQ;AAAA;AAAA,UACzB,EAAE,GAAG,OAAA,EAAS,CAAA,EAAG,YAAY,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,CAAA,GAAI,EAAA;AAAG;AAAA,SACpD;AAAA,MACF,CAAA,MAAO;AACL,QAAA,aAAA,GAAgB;AAAA,UACd,EAAE,CAAA,EAAG,GAAA,EAAS,CAAA,EAAG,GAAA,EAAI;AAAA,UACrB,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,GAAA,EAAI;AAAA,UACrB,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA,EAAG,GAAA,EAAI;AAAA,UACrB,EAAE,CAAA,EAAG,GAAA,EAAS,CAAA,EAAG,GAAA;AAAI,SACvB;AAAA,MACF;AAAA,IACF,WAGS,IAAA,CAAK,GAAA,CAAI,GAAA,GAAM,GAAG,KAAK,kBAAA,EAAoB;AAElD,MAAA,MAAM,CAAA,GAAI,EAAE,GAAG,IAAA,CAAK,IAAA,EAAK;AACzB,MAAA,OAAO,CAAA,CAAE,aAAA;AACT,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,CAAA,EAAE;AAAA,IAC5B,CAAA,MAGK;AACH,MAAA,MAAM,MAAA,GAAS,KAAK,YAAA,IAAgB,EAAA;AACpC,MAAA,MAAM,QAAA,GAAc,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA;AACzC,MAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA;AAE5C,MAAA,IAAI,YAAY,WAAA,EAAa;AAG3B,QAAA,aAAA,GAAgB;AAAA,UACd,EAAE,GAAG,GAAA,EAAK,CAAA,EAAG,WAAW,IAAA,CAAK,CAAA,GAAU,IAAA,CAAK,CAAA,GAAI,EAAA,EAAG;AAAA;AAAA,UACnD,EAAE,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAI;AAAA;AAAA,UACjB,EAAE,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAI;AAAA;AAAA,UACjB,EAAE,GAAG,GAAA,EAAK,CAAA,EAAG,WAAW,IAAA,CAAK,CAAA,GAAI,EAAA,GAAM,IAAA,CAAK,CAAA;AAAE;AAAA,SAChD;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,CAAA,IAAK,IAAA,CAAK,CAAA;AAClC,QAAA,MAAM,IAAA,GAAO,aACT,IAAA,CAAK,CAAA,GAAI,KAAK,OAAA,GAAU,CAAA,GACxB,IAAA,CAAK,CAAA,GAAI,OAAA,GAAU,CAAA;AAEvB,QAAA,aAAA,GAAgB;AAAA,UACd,EAAE,CAAA,EAAG,IAAA,CAAK,CAAA,GAAI,EAAA,EAAI,GAAG,GAAA,EAAI;AAAA;AAAA,UACzB,EAAE,CAAA,EAAG,IAAA,EAAc,CAAA,EAAG,GAAA,EAAI;AAAA;AAAA,UAC1B,EAAE,CAAA,EAAG,IAAA,EAAc,CAAA,EAAG,GAAA,EAAI;AAAA;AAAA,UAC1B,EAAE,CAAA,EAAG,IAAA,CAAK,CAAA,EAAS,GAAG,GAAA;AAAI;AAAA,SAC5B;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,GAAG,IAAA,CAAK,IAAA,EAAM,aAAA,EAAc,EAAE;AAAA,EAC1D,CAAC,CAAA;AACH;AAIA,eAAsB,gBAAA,CACpB,OACA,KAAA,EACuD;AACvD,EAAA,MAAM,QAAW,KAAA,CAAM,MAAA,CAAO,OAAK,CAAA,CAAE,IAAA,CAAK,gBAAgB,MAAM,CAAA;AAChE,EAAA,MAAM,QAAW,KAAA,CAAM,MAAA,CAAO,OAAK,CAAA,CAAE,IAAA,CAAK,gBAAgB,MAAM,CAAA;AAChE,EAAA,MAAM,OAAA,GAAW,KAAA,CAAM,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,uBAAuB,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,WAAW,CAAC,CAAA;AAGlF,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,EAAE,aAAA,EAAAA,cAAAA,EAAc,GAAI,MAAM,OAAO,oBAAO,CAAA;AAC9C,IAAA,OAAOA,cAAAA,CAAc,OAAO,KAAK,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,OAAA,GAAY,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AAG/C,EAAA,MAAM,aAAA,GAAgB,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AACpD,EAAA,MAAM,WAAA,GAAgB,KAAA,CAAM,MAAA,CAAO,CAAA,CAAA,KAAK;AACtC,IAAA,MAAM,CAAA,GAAK,CAAA,CAAE,IAAA,EAAM,QAAA,IAAY,CAAA,CAAE,IAAA;AACjC,IAAA,OAAO,CAAA,KAAM,cAAA,IAAkB,aAAA,CAAc,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,IAAK,aAAA,CAAc,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AAAA,EAC1F,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA,CAAE,QAAO,CAAE,CAAA;AAC9D,EAAA,MAAM,iBAAiB,eAAA,CAAgB,CAAC,GAAG,aAAa,GAAG,WAAW,CAAA;AAMtE,EAAA,MAAM,qBAAA,GAAwB,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,IAAA,CAAK,IAAI,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,GAAI,EAAE,CAAA;AACzE,EAAA,MAAM,cAAc,qBAAA,GAChB,CAAC,GAAG,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,CAAS,IAAI,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,GACrD,CAAC,GAAG,KAAK,CAAA;AAEb,EAAA,MAAM,cAA4B,EAAC;AACnC,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,IAAA,MAAM,YAAc,KAAA,CAAM,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,KAAK,EAAE,CAAA;AAC5D,IAAA,MAAM,OAAA,GAAc,IAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AAEpD,IAAA,MAAM,cAAc,OAAA,CAAQ,MAAA;AAAA,MAAO,CAAA,CAAA,KACjC,CAAA,CAAE,QAAA,KAAa,IAAA,CAAK,EAAA,IAAO,CAAA,CAAE,QAAA,IAAY,IAAA,IAAQ,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,QAAQ;AAAA,KACzE;AAEA,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,EAAM,SAAA,EAAW,aAAa,KAAK,CAAA;AAE7D,IAAA,WAAA,CAAY,IAAA,CAAK;AAAA,MACf,GAAG,IAAA;AAAA,MACH,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,MAAA,EAAO;AAAA,MAC5B,OAAQ,MAAA,CAAO,KAAA;AAAA,MACf,QAAQ,MAAA,CAAO;AAAA,KAChB,CAAA;AAED,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,IACvB;AAEA,IAAA,MAAA,IAAU,OAAO,MAAA,GAAS,UAAA;AAAA,EAC5B;AAGA,EAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AACpD,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,UAAU,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,EACpD;AAGA,EAAA,MAAM,cAAc,UAAA,CAAW,KAAA,EAAO,WAAA,EAAa,cAAA,EAAgB,YAAY,OAAO,CAAA;AAEtF,EAAA,OAAO,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,WAAA,EAAY;AAClD;;;AClgBA,eAAsB,eAAA,CACpB,KAAA,EACA,KAAA,EACA,OAAA,GAAyB,EAAC,EACH;AACvB,EAAA,OAAO,WAAA,CAAY,OAAwB,KAAA,EAAwB;AAAA,IACjE,GAAG,OAAA;AAAA,IACH,WAAA,EAAa,CAAC,IAAA,KAAS,eAAA,CAAgB,IAAkB;AAAA,GAC1D,CAAA;AACH;AAMO,SAAS,qBAAA,CACd,OACA,MAAA,EACkB;AAClB,EAAA,OAAO,0BAAA,CAA2B,OAAO,MAAM,CAAA;AACjD","file":"index.js","sourcesContent":["import type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport type { BpmnElementType } from \"../elements/types\";\n\n// ── Constants ──────────────────────────────────────────────────────────────\n\nexport const LAYOUT_CONTAINER_TYPES = new Set<BpmnElementType>([\n \"Pool\", \"Lane\", \"SubProcess\", \"Transaction\", \"EventSubProcess\", \"AdHocSubProcess\",\n]);\n\nexport const LAYOUT_GATEWAY_TYPES = new Set<BpmnElementType>([\n \"ExclusiveGateway\", \"InclusiveGateway\", \"ParallelGateway\",\n \"EventBasedGateway\", \"ComplexGateway\",\n]);\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface LayoutEdgeInfo {\n id: string;\n source: string;\n target: string;\n /** ReactFlow handle id, e.g. \"source-top\" | \"source-right\" | \"source-bottom\" | \"source-left\" */\n sourceHandle?: string | null;\n}\n\n// ── Phase 1A: Back-edge detection (DFS) ───────────────────────────────────\n//\n// An edge A→B is a back-edge if B is in the \"gray\" (currently open) DFS stack\n// when A is processed — meaning B is an ancestor of A, creating a cycle.\n// Back-edges are excluded from column assignment so loops don't generate\n// infinite vertical layers.\n\nexport function detectBackEdges(\n nodeIds: string[],\n seqEdges: LayoutEdgeInfo[],\n): Set<string> {\n const backEdgeIds = new Set<string>();\n const state = new Map<string, 0 | 1 | 2>(); // 0=unvisited 1=open 2=done\n for (const id of nodeIds) state.set(id, 0);\n\n const adj = new Map<string, Array<{ target: string; edgeId: string }>>();\n for (const id of nodeIds) adj.set(id, []);\n for (const e of seqEdges) {\n adj.get(e.source)?.push({ target: e.target, edgeId: e.id });\n }\n\n // Iterative DFS to avoid call-stack overflow on large diagrams.\n for (const startId of nodeIds) {\n if (state.get(startId) !== 0) continue;\n // Stack entries: [nodeId, iteratorIndex] — simulates recursive DFS\n const stack: Array<{ id: string; idx: number }> = [{ id: startId, idx: 0 }];\n state.set(startId, 1);\n\n while (stack.length > 0) {\n const top = stack[stack.length - 1];\n const neighbors = adj.get(top.id) ?? [];\n if (top.idx >= neighbors.length) {\n state.set(top.id, 2);\n stack.pop();\n continue;\n }\n const { target, edgeId } = neighbors[top.idx++];\n const tState = state.get(target);\n if (tState === 1) {\n backEdgeIds.add(edgeId); // gray → back-edge\n } else if (tState === 0) {\n state.set(target, 1);\n stack.push({ id: target, idx: 0 });\n }\n }\n }\n\n return backEdgeIds;\n}\n\n// ── Phase 1B: Sequence-flow extraction ────────────────────────────────────\n\nexport function extractSeqEdges(\n edges: BpmnRFEdge[],\n nodeIds: Set<string>,\n): LayoutEdgeInfo[] {\n return edges\n .filter(e => {\n const t = (e.data?.edgeType ?? e.type) as string;\n return t === \"sequenceFlow\" && nodeIds.has(e.source) && nodeIds.has(e.target);\n })\n .map(e => ({ id: e.id, source: e.source, target: e.target, sourceHandle: e.sourceHandle ?? null }));\n}\n\n// ── Phase 2: Topological sort (Kahn) ──────────────────────────────────────\n\nexport function topologicalSort(\n nodeIds: string[],\n forwardEdges: LayoutEdgeInfo[],\n): string[] {\n const inDeg = new Map<string, number>(nodeIds.map(id => [id, 0]));\n const adj = new Map<string, string[]>(nodeIds.map(id => [id, []]));\n\n for (const e of forwardEdges) {\n if (!inDeg.has(e.source) || !inDeg.has(e.target)) continue;\n adj.get(e.source)!.push(e.target);\n inDeg.set(e.target, (inDeg.get(e.target) ?? 0) + 1);\n }\n\n const queue = nodeIds.filter(id => (inDeg.get(id) ?? 0) === 0);\n const result: string[] = [];\n\n while (queue.length > 0) {\n const id = queue.shift()!;\n result.push(id);\n for (const next of adj.get(id) ?? []) {\n const d = (inDeg.get(next) ?? 1) - 1;\n inDeg.set(next, d);\n if (d === 0) queue.push(next);\n }\n }\n\n // Nodes not reached (isolated or residual cycles) appended at end.\n const seen = new Set(result);\n for (const id of nodeIds) {\n if (!seen.has(id)) result.push(id);\n }\n\n return result;\n}\n\n// ── Phase 2: Column assignment (longest-path on DAG) ──────────────────────\n//\n// column(node) = max(column(predecessors)) + 1\n// Start events / nodes with no predecessors get column 0.\n// Ensures nodes that depend on each other are in increasing columns.\n\nexport function assignColumns(\n nodeIds: string[],\n forwardEdges: LayoutEdgeInfo[],\n): Map<string, number> {\n const order = topologicalSort(nodeIds, forwardEdges);\n const col = new Map<string, number>(nodeIds.map(id => [id, 0]));\n\n const preds = new Map<string, string[]>(nodeIds.map(id => [id, []]));\n for (const e of forwardEdges) {\n preds.get(e.target)?.push(e.source);\n }\n\n for (const id of order) {\n const predCols = (preds.get(id) ?? []).map(p => col.get(p) ?? 0);\n col.set(id, predCols.length > 0 ? Math.max(...predCols) + 1 : 0);\n }\n\n return col;\n}\n\n// ── Phase 1C: Gateway pair detection ──────────────────────────────────────\n//\n// Finds (split gateway) → (merge gateway) pairs.\n// The merge is the earliest node reachable by ALL branches of the split.\n// This defines the \"expansion zone\" for vertical branching.\n\nexport function detectGatewayPairs(\n nodes: BpmnRFNode[],\n forwardEdges: LayoutEdgeInfo[],\n): Map<string, string> {\n const pairs = new Map<string, string>();\n const nodeIds = nodes.map(n => n.id);\n\n const succs = new Map<string, string[]>(nodes.map(n => [n.id, []]));\n for (const e of forwardEdges) {\n succs.get(e.source)?.push(e.target);\n }\n\n const order = topologicalSort(nodeIds, forwardEdges);\n const topoPos = new Map(order.map((id, i) => [id, i]));\n\n const splits = nodes.filter(n =>\n LAYOUT_GATEWAY_TYPES.has(n.data.elementType) &&\n (succs.get(n.id)?.length ?? 0) > 1\n );\n\n for (const split of splits) {\n const branches = succs.get(split.id) ?? [];\n if (branches.length < 2) continue;\n\n // BFS reachability per branch (stops at nodes already visited to stay fast)\n const branchSets: Set<string>[] = branches.map(start => {\n const visited = new Set<string>();\n const q = [start];\n while (q.length) {\n const curr = q.shift()!;\n if (visited.has(curr)) continue;\n visited.add(curr);\n for (const next of succs.get(curr) ?? []) q.push(next);\n }\n return visited;\n });\n\n // Intersection: nodes reachable from ALL branches\n const common = [...branchSets[0]].filter(id =>\n branchSets.every(s => s.has(id))\n );\n if (common.length === 0) continue;\n\n // Pick the topologically earliest common node as the merge gateway\n const merge = common.reduce((a, b) =>\n (topoPos.get(a) ?? Infinity) < (topoPos.get(b) ?? Infinity) ? a : b\n );\n\n pairs.set(split.id, merge);\n }\n\n return pairs;\n}\n\n// ── Phase 3: Row assignment ────────────────────────────────────────────────\n//\n// The main flow stays at row 0. Each branch of a split gateway gets a row\n// offset: primary branch → 0, secondary → +1, tertiary → -1, etc.\n// Nested gateways inherit their parent branch's base row.\n//\n// Row offsets are alternating so branches expand symmetrically:\n// 0, +1, -1, +2, -2, +3, -3 ...\n\nconst ROW_OFFSETS = [0, 1, -1, 2, -2, 3, -3, 4, -4];\n\n// Maps a sourceHandle string (e.g. \"source-top\") to a preferred row direction.\n// \"right\" → 0 (main horizontal flow), \"bottom\" → +1, \"top\" → -1, \"left\" → 0.\nfunction handleToRowBias(handle: string | null | undefined): number | null {\n if (!handle) return null;\n if (handle.includes(\"top\")) return -1;\n if (handle.includes(\"bottom\")) return 1;\n if (handle.includes(\"right\")) return 0;\n return null;\n}\n\n// Build a map: sourceId → Map<targetId, sourceHandle>\nfunction buildHandleMap(edges: LayoutEdgeInfo[]): Map<string, Map<string, string | null>> {\n const map = new Map<string, Map<string, string | null>>();\n for (const e of edges) {\n if (!map.has(e.source)) map.set(e.source, new Map());\n map.get(e.source)!.set(e.target, e.sourceHandle ?? null);\n }\n return map;\n}\n\nexport function assignRows(\n nodes: BpmnRFNode[],\n forwardEdges: LayoutEdgeInfo[],\n columns: Map<string, number>,\n gatewayPairs: Map<string, string>,\n): Map<string, number> {\n const rows = new Map<string, number>(nodes.map(n => [n.id, 0]));\n\n const succs = new Map<string, string[]>(nodes.map(n => [n.id, []]));\n for (const e of forwardEdges) {\n succs.get(e.source)?.push(e.target);\n }\n\n // sourceHandle lookup: for each gateway, which handle connects to each branch start.\n const handleMap = buildHandleMap(forwardEdges);\n\n // Process pairs from deepest (rightmost column) to shallowest so inner\n // gateways inherit the correct base row from their already-assigned nodes.\n const sortedPairs = [...gatewayPairs.entries()].sort(\n (a, b) => (columns.get(b[0]) ?? 0) - (columns.get(a[0]) ?? 0)\n );\n\n for (const [splitId, mergeId] of sortedPairs) {\n const branches = succs.get(splitId) ?? [];\n if (branches.length < 2) continue;\n\n const splitRow = rows.get(splitId) ?? 0;\n\n // Collect nodes strictly between this split and its merge for each branch.\n const getBranchNodes = (branchStart: string): string[] => {\n const result: string[] = [];\n const visited = new Set<string>();\n const q = [branchStart];\n while (q.length) {\n const curr = q.shift()!;\n if (visited.has(curr) || curr === mergeId) continue;\n visited.add(curr);\n result.push(curr);\n for (const next of succs.get(curr) ?? []) q.push(next);\n }\n return result;\n };\n\n const splitHandles = handleMap.get(splitId);\n const branchData = branches.map(start => ({\n start,\n nodeIds: getBranchNodes(start),\n bias: handleToRowBias(splitHandles?.get(start) ?? null),\n }));\n\n // Assign rows: if a branch has a handle bias (top/bottom), use it directly.\n // Otherwise fall back to size-based ordering (largest = row 0).\n // Branches with bias=0 (right handle) or no bias are sorted by size.\n const withBias = branchData.filter(b => b.bias !== null && b.bias !== 0);\n const withoutBias = branchData.filter(b => b.bias === null || b.bias === 0)\n .sort((a, b) => b.nodeIds.length - a.nodeIds.length);\n\n // Place size-ordered branches at row 0, then fill remaining offsets.\n const assigned = new Map<string, number>();\n for (const b of withBias) {\n assigned.set(b.start, splitRow + b.bias!);\n }\n let nextOffset = 0;\n for (const b of withoutBias) {\n while ([...assigned.values()].includes(splitRow + nextOffset)) nextOffset++;\n assigned.set(b.start, splitRow + nextOffset);\n nextOffset++;\n }\n\n for (const b of branchData) {\n const row = assigned.get(b.start) ?? splitRow;\n for (const id of b.nodeIds) {\n rows.set(id, row);\n }\n }\n }\n\n // ── Second pass: terminal splits (no merge detected) ──────────────────────\n // Gateways whose branches all terminate at End Events (no common successor)\n // don't appear in gatewayPairs. Without this pass they'd all share row 0,\n // causing their terminal nodes to overlap.\n const pairedSplits = new Set(gatewayPairs.keys());\n\n const unpairedSplits = nodes.filter(n =>\n LAYOUT_GATEWAY_TYPES.has(n.data.elementType) &&\n !pairedSplits.has(n.id) &&\n (succs.get(n.id)?.length ?? 0) > 1\n );\n\n for (const split of unpairedSplits) {\n const branches = succs.get(split.id) ?? [];\n if (branches.length < 2) continue;\n\n const splitRow = rows.get(split.id) ?? 0;\n\n // Collect all reachable nodes for each branch (no merge to stop at).\n const getAllReachable = (start: string): string[] => {\n const result: string[] = [];\n const visited = new Set<string>();\n const q = [start];\n while (q.length) {\n const curr = q.shift()!;\n if (visited.has(curr)) continue;\n visited.add(curr);\n result.push(curr);\n for (const next of succs.get(curr) ?? []) q.push(next);\n }\n return result;\n };\n\n const splitHandles2 = handleMap.get(split.id);\n const branchData = branches.map(start => ({\n start,\n nodeIds: getAllReachable(start),\n bias: handleToRowBias(splitHandles2?.get(start) ?? null),\n }));\n\n const withBias2 = branchData.filter(b => b.bias !== null && b.bias !== 0);\n const withoutBias2 = branchData.filter(b => b.bias === null || b.bias === 0)\n .sort((a, b) => b.nodeIds.length - a.nodeIds.length);\n\n const assigned2 = new Map<string, number>();\n for (const b of withBias2) assigned2.set(b.start, splitRow + b.bias!);\n let nextOff = 0;\n for (const b of withoutBias2) {\n while ([...assigned2.values()].includes(splitRow + nextOff)) nextOff++;\n assigned2.set(b.start, splitRow + nextOff);\n nextOff++;\n }\n\n for (const b of branchData) {\n const row = assigned2.get(b.start) ?? splitRow;\n for (const id of b.nodeIds) rows.set(id, row);\n }\n }\n\n return rows;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nexport function buildSuccessors(\n nodeIds: string[],\n edges: LayoutEdgeInfo[],\n): Map<string, string[]> {\n const map = new Map<string, string[]>(nodeIds.map(id => [id, []]));\n for (const e of edges) {\n map.get(e.source)?.push(e.target);\n }\n return map;\n}\n\nexport function buildPredecessors(\n nodeIds: string[],\n edges: LayoutEdgeInfo[],\n): Map<string, string[]> {\n const map = new Map<string, string[]>(nodeIds.map(id => [id, []]));\n for (const e of edges) {\n map.get(e.target)?.push(e.source);\n }\n return map;\n}\n","import type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport {\n LAYOUT_CONTAINER_TYPES,\n detectBackEdges,\n extractSeqEdges,\n assignColumns,\n detectGatewayPairs,\n assignRows,\n} from \"./bpmn-layout-graph\";\n\n// ── Layout constants ───────────────────────────────────────────────────────\n//\n// These values produce a generous, readable layout. The column gap gives\n// enough space for edge routing and labels. Row gap ensures branches don't\n// feel cramped. All values are in pixels.\n\nconst LANE_LABEL_W = 28; // Lane left label strip width (vertical text, like Bizagi)\nconst LANE_H_PAD = 20; // horizontal padding between lane label strip and first column\nconst COL_GAP = 80; // horizontal gap between columns\nconst ROW_HEIGHT = 80; // vertical slot height per row (fits a 60px task)\nconst ROW_GAP = 60; // gap between rows within a lane\nconst LANE_V_PAD = 50; // top/bottom breathing room inside a lane\nconst POOL_H_PAD = 60; // padding for nodes placed directly in pool (no lane parent)\nconst POOL_V_GAP = 50; // vertical gap between separate pools\nconst LANE_MIN_H = 160; // minimum lane height even when almost empty\nconst POOL_MIN_W = 720; // minimum pool width\nconst POOL_INNER_PAD = 8; // gap between Pool border and Lane on all sides.\n // 8px = pool border (2px) + 6px visible gap, enough to grab\n // the resize handle without selecting the Pool first.\n\n// ── Node size helpers ──────────────────────────────────────────────────────\n\nfunction nW(node: BpmnRFNode): number {\n return node.width ?? (node.measured as { width?: number } | undefined)?.width ?? 120;\n}\nfunction nH(node: BpmnRFNode): number {\n return node.height ?? (node.measured as { height?: number } | undefined)?.height ?? 60;\n}\n\n// ── Per-pool layout ────────────────────────────────────────────────────────\n\ninterface PoolResult {\n nodes: BpmnRFNode[]; // updated pool + lanes + content\n width: number;\n height: number;\n}\n\nfunction layoutPool(\n pool: BpmnRFNode,\n lanes: BpmnRFNode[], // Lane nodes whose parentId === pool.id\n content: BpmnRFNode[], // non-container nodes belonging to this pool\n allEdges: BpmnRFEdge[],\n): PoolResult {\n // ── Empty pool ────────────────────────────────────────────────────────────\n if (content.length === 0) {\n // Completely empty pool (no lanes, no content) → compact minimum size.\n if (lanes.length === 0) {\n return { nodes: [], width: 240, height: 120 };\n }\n // Pool with lanes but no content nodes — size to fit stacked empty lanes.\n const laneH = LANE_MIN_H;\n const h = POOL_INNER_PAD * 2 + lanes.length * laneH + Math.max(0, lanes.length - 1) * POOL_INNER_PAD;\n const w = POOL_MIN_W;\n return {\n nodes: lanes.map((lane, i) => ({\n ...lane,\n position: { x: POOL_INNER_PAD, y: POOL_INNER_PAD + i * (laneH + POOL_INNER_PAD) },\n width: w - POOL_INNER_PAD * 2,\n height: laneH,\n })),\n width: w,\n height: h,\n };\n }\n\n // ── Graph analysis (Phases 1-3) ───────────────────────────────────────────\n\n const contentIds = new Set(content.map(n => n.id));\n const seqEdges = extractSeqEdges(allEdges, contentIds);\n const backIds = detectBackEdges([...contentIds], seqEdges);\n const fwdEdges = seqEdges.filter(e => !backIds.has(e.id));\n\n const columns = assignColumns([...contentIds], fwdEdges);\n const pairs = detectGatewayPairs(content, fwdEdges);\n const rows = assignRows(content, fwdEdges, columns, pairs);\n\n // ── Lane ordering ─────────────────────────────────────────────────────────\n // Sort by stored pool-relative Y only when lanes have distinct positions\n // (i.e., after a previous layout pass). When all lanes are at y≈0 (freshly\n // created by AI or palette), preserve original array order (= creation order\n // = intended visual order: Usuario → Sistema → Equipo comercial etc).\n const lanePositionsDistinct = lanes.some(l => Math.abs(l.position.y) > 10);\n const sortedLanes = lanePositionsDistinct\n ? [...lanes].sort((a, b) => a.position.y - b.position.y)\n : [...lanes];\n const hasLanes = sortedLanes.length > 0;\n\n // Map each content node to its lane id (or a synthetic \"_pool_\" bucket).\n const nodeLaneId = new Map<string, string>();\n for (const node of content) {\n if (hasLanes && node.parentId && node.parentId !== pool.id) {\n nodeLaneId.set(node.id, node.parentId);\n } else {\n nodeLaneId.set(node.id, \"_pool_\");\n }\n }\n\n // ── Per-lane row statistics ────────────────────────────────────────────────\n // We need to know the min/max rows used in each lane to center the content.\n\n const laneIds = hasLanes ? sortedLanes.map(l => l.id) : [\"_pool_\"];\n\n interface LaneStat {\n minRow: number;\n maxRow: number;\n rowCount: number;\n height: number;\n }\n const laneStats = new Map<string, LaneStat>();\n\n for (const laneId of laneIds) {\n const laneRows = content\n .filter(n => nodeLaneId.get(n.id) === laneId)\n .map(n => rows.get(n.id) ?? 0);\n\n if (laneRows.length === 0) {\n laneStats.set(laneId, { minRow: 0, maxRow: 0, rowCount: 1, height: LANE_MIN_H });\n } else {\n const minRow = Math.min(...laneRows);\n const maxRow = Math.max(...laneRows);\n const rowCount = maxRow - minRow + 1;\n const contentH = rowCount * ROW_HEIGHT + Math.max(0, rowCount - 1) * ROW_GAP;\n // Lane label is now on the LEFT (vertical strip), not the top.\n // Total height = vertical padding + content.\n const height = Math.max(LANE_MIN_H, LANE_V_PAD * 2 + contentH);\n laneStats.set(laneId, { minRow, maxRow, rowCount, height });\n }\n }\n\n // ── Column widths ─────────────────────────────────────────────────────────\n // Each column is as wide as the widest node assigned to it.\n\n const maxCol = Math.max(0, ...[...columns.values()]);\n const colW = new Map<number, number>();\n for (let c = 0; c <= maxCol; c++) colW.set(c, 0);\n for (const node of content) {\n const c = columns.get(node.id) ?? 0;\n colW.set(c, Math.max(colW.get(c) ?? 0, nW(node)));\n }\n\n // Cumulative X offsets for each column.\n const colX = new Map<number, number>();\n let cumX = 0;\n for (let c = 0; c <= maxCol; c++) {\n colX.set(c, cumX);\n cumX += (colW.get(c) ?? 120) + COL_GAP;\n }\n const contentW = cumX - COL_GAP; // remove trailing gap\n\n // ── Pool/Lane dimensions ──────────────────────────────────────────────────\n\n // Pool has POOL_INNER_PAD (8px) on all sides — visible gap for resize handles.\n // Lane body has pointer-events:none so Pool border is always accessible.\n // Content within Lane starts after: Lane label strip (28px) + padding (20px).\n const innerW = LANE_LABEL_W + LANE_H_PAD + contentW + LANE_H_PAD;\n const poolW = Math.max(POOL_MIN_W, innerW + POOL_INNER_PAD * 2);\n const laneW = poolW - POOL_INNER_PAD * 2; // Lane fills pool minus 8px each side\n\n // Compute cumulative Y offsets for lanes (stacked, starting after top padding).\n // POOL_INNER_PAD (8px) is added between consecutive lanes to match the gap\n // that the manual lane-add flow produces.\n const laneY = new Map<string, number>();\n let cumY = POOL_INNER_PAD; // start after top padding\n for (let i = 0; i < laneIds.length; i++) {\n const laneId = laneIds[i];\n laneY.set(laneId, cumY);\n cumY += laneStats.get(laneId)?.height ?? LANE_MIN_H;\n if (i < laneIds.length - 1) cumY += POOL_INNER_PAD; // 8px gap between lanes\n }\n const poolH = cumY + POOL_INNER_PAD; // add bottom padding\n\n // ── Position content nodes ────────────────────────────────────────────────\n\n const positionedContent = content.map(node => {\n const c = columns.get(node.id) ?? 0;\n const r = rows.get(node.id) ?? 0;\n const laneId = nodeLaneId.get(node.id) ?? \"_pool_\";\n const stat = laneStats.get(laneId)!;\n const lYOff = laneY.get(laneId) ?? 0;\n\n const colOffset = (colX.get(c) ?? 0) + (colW.get(c) ?? 120) / 2 - nW(node) / 2;\n const rowOffset = (r - stat.minRow) * (ROW_HEIGHT + ROW_GAP) + ROW_HEIGHT / 2 - nH(node) / 2;\n\n // Positions must be RELATIVE TO THE NODE'S PARENT (Lane or Pool).\n // ReactFlow places children at parentAbsolutePos + childRelativePos.\n // Storing pool-absolute coords as lane-relative doubles the offsets when\n // the parent is dragged — which breaks all drag/move operations.\n const isLaneChild = hasLanes && !!node.parentId && node.parentId !== pool.id;\n\n // Lane label strip is on the LEFT (LANE_LABEL_W = 28px).\n // Content x (lane-relative): after label strip + horizontal padding.\n // Content y (lane-relative): centered vertically in the full lane height.\n const contentH_stat = stat.rowCount * ROW_HEIGHT + Math.max(0, stat.rowCount - 1) * ROW_GAP;\n const vertTopOffset = Math.max(LANE_V_PAD, (stat.height - contentH_stat) / 2);\n\n const x = isLaneChild\n ? LANE_LABEL_W + LANE_H_PAD + colOffset // Lane-relative: after left label strip + padding\n : POOL_H_PAD + colOffset; // Pool-relative (no lane parent)\n\n const y = isLaneChild\n ? vertTopOffset + rowOffset // Lane-relative: centered vertically\n : lYOff + vertTopOffset + rowOffset; // Pool-relative: lane offset + same\n\n return { ...node, position: { x, y } };\n });\n\n // ── Overlap resolution ────────────────────────────────────────────────────\n // After position assignment, sweep each lane left-to-right and nudge any\n // node that overlaps its left neighbour. This handles cases where nested\n // gateway branching assigns two nodes to the same (col, row) slot.\n\n const NODE_MIN_GAP = 20;\n const resolvedContent = [...positionedContent];\n\n for (const laneId of laneIds) {\n // Sort nodes in this lane by their computed X position.\n const laneNodeIndices = resolvedContent\n .map((n, i) => ({ n, i }))\n .filter(({ n }) => (nodeLaneId.get(n.id) ?? \"_pool_\") === laneId)\n .sort((a, b) => a.n.position.x - b.n.position.x);\n\n for (let k = 1; k < laneNodeIndices.length; k++) {\n const prev = resolvedContent[laneNodeIndices[k - 1].i];\n const curr = resolvedContent[laneNodeIndices[k].i];\n\n // Only nudge if they are vertically close enough to visually collide.\n const prevBottom = prev.position.y + nH(prev);\n const currTop = curr.position.y;\n const prevTop = prev.position.y;\n const currBottom = curr.position.y + nH(curr);\n const yOverlap = prevBottom + NODE_MIN_GAP > currTop && currBottom + NODE_MIN_GAP > prevTop;\n\n if (!yOverlap) continue;\n\n const prevRight = prev.position.x + nW(prev);\n if (prevRight + NODE_MIN_GAP > curr.position.x) {\n resolvedContent[laneNodeIndices[k].i] = {\n ...curr,\n position: {\n x: prevRight + NODE_MIN_GAP,\n y: curr.position.y,\n },\n };\n }\n }\n }\n\n // ── Position lanes ────────────────────────────────────────────────────────\n\n const positionedLanes = hasLanes\n ? sortedLanes.map(lane => ({\n ...lane,\n // x: after pool label strip + left inner padding\n // y: laneY already includes top POOL_INNER_PAD offset\n position: { x: POOL_INNER_PAD, y: laneY.get(lane.id) ?? POOL_INNER_PAD },\n width: laneW,\n height: laneStats.get(lane.id)?.height ?? LANE_MIN_H,\n }))\n : [];\n\n // ── Result ────────────────────────────────────────────────────────────────\n\n return {\n nodes: [...resolvedContent, ...positionedLanes],\n width: poolW,\n height: poolH,\n };\n}\n\n// ── Phase 5: Orthogonal edge routing ─────────────────────────────────────\n//\n// Computes precise bend points for each sequence flow edge so they render\n// as clean orthogonal paths instead of ReactFlow's default bezier curves.\n//\n// Routing rules:\n// Same lane, same row → straight horizontal (no bend points needed)\n// Same lane, cross row → L-shape through vertical connector in the column gap\n// Cross lane → exit bottom/top → vertical to lane border → enter top/bottom\n// Back-edge (loop) → U-arc above the flow\n// Cross-pool / other → clear routing points, let ReactFlow draw smooth curve\n\nconst BACK_EDGE_CLEARANCE = 50; // px above the topmost node for back-edge arcs\nconst SAME_ROW_THRESHOLD = 15; // px — Y difference below this = \"same row\"\n\n// Compute absolute (viewport) position of a node by walking up the parent chain.\nfunction absolutePos(\n nodeId: string,\n byId: Map<string, BpmnRFNode>,\n cache: Map<string, { x: number; y: number }>,\n): { x: number; y: number } {\n const cached = cache.get(nodeId);\n if (cached) return cached;\n const node = byId.get(nodeId);\n if (!node) return { x: 0, y: 0 };\n const own = { ...node.position };\n if (!node.parentId) { cache.set(nodeId, own); return own; }\n const parent = absolutePos(node.parentId, byId, cache);\n const abs = { x: parent.x + own.x, y: parent.y + own.y };\n cache.set(nodeId, abs);\n return abs;\n}\n\n// Return the lane id a content node belongs to (undefined = directly in pool / no lane).\nfunction laneOf(node: BpmnRFNode, laneIds: Set<string>): string | undefined {\n return node.parentId && laneIds.has(node.parentId) ? node.parentId : undefined;\n}\n\ntype Pt = { x: number; y: number };\n\nfunction routeEdges(\n edges: BpmnRFEdge[],\n layoutNodes: BpmnRFNode[],\n backEdgeIds: Set<string>,\n laneIds: Set<string>,\n poolIds: Set<string>,\n): BpmnRFEdge[] {\n const byId = new Map(layoutNodes.map(n => [n.id, n]));\n const cache = new Map<string, Pt>();\n const abs = (id: string) => absolutePos(id, byId, cache);\n\n return edges.map(edge => {\n const edgeType = (edge.data?.edgeType ?? edge.type) as string;\n\n // Non-sequence edges: clear routing points, ReactFlow smooth curve handles them.\n if (edgeType !== \"sequenceFlow\") {\n const d = { ...edge.data };\n delete d.routingPoints;\n return { ...edge, data: d } as unknown as BpmnRFEdge;\n }\n\n const src = byId.get(edge.source);\n const tgt = byId.get(edge.target);\n if (!src || !tgt) return edge;\n\n const sAbs = abs(src.id);\n const tAbs = abs(tgt.id);\n const sW = nW(src), sH = nH(src);\n const tW = nW(tgt), tH = nH(tgt);\n\n // Center points\n const sCX = sAbs.x + sW / 2, sCY = sAbs.y + sH / 2;\n const tCX = tAbs.x + tW / 2, tCY = tAbs.y + tH / 2;\n\n // Cross-pool edge → no routing, let ReactFlow handle it.\n const srcPool = poolIds.has(src.parentId ?? \"\") ? src.parentId\n : poolIds.has(byId.get(src.parentId ?? \"\")?.parentId ?? \"\") ? byId.get(src.parentId ?? \"\")?.parentId\n : src.parentId;\n const tgtPool = poolIds.has(tgt.parentId ?? \"\") ? tgt.parentId\n : poolIds.has(byId.get(tgt.parentId ?? \"\")?.parentId ?? \"\") ? byId.get(tgt.parentId ?? \"\")?.parentId\n : tgt.parentId;\n if (srcPool !== tgtPool) {\n const d = { ...edge.data };\n delete d.routingPoints;\n return { ...edge, data: d } as unknown as BpmnRFEdge;\n }\n\n let routingPoints: Pt[];\n\n // ── Back-edge: U-arc routed ABOVE the flow ──────────────────────────────\n if (backEdgeIds.has(edge.id)) {\n const topY = Math.min(sAbs.y, tAbs.y) - BACK_EDGE_CLEARANCE;\n routingPoints = [\n { x: sCX, y: sAbs.y }, // [0] discarded\n { x: sCX, y: topY }, // [1] go up\n { x: tCX, y: topY }, // [2] go left/right\n { x: tCX, y: tAbs.y }, // [3] discarded\n ];\n }\n\n // ── Cross-lane: vertical routing through lane border ────────────────────\n else if (laneOf(src, laneIds) !== laneOf(tgt, laneIds)) {\n const goingDown = tAbs.y > sAbs.y;\n\n // Use the shared X midpoint between source and target columns if different,\n // otherwise use source center X to keep the path vertically clean.\n const sharedX = Math.abs(sCX - tCX) < 10 ? sCX : (sCX + tCX) / 2;\n\n const srcLane = byId.get(src.parentId ?? \"\");\n const tgtLane = byId.get(tgt.parentId ?? \"\");\n\n if (srcLane && tgtLane && laneIds.has(srcLane.id) && laneIds.has(tgtLane.id)) {\n const srcLaneAbs = abs(srcLane.id);\n const borderY = goingDown\n ? srcLaneAbs.y + (srcLane.height ?? 160)\n : srcLaneAbs.y;\n\n // SequenceFlowEdge uses pointsToSvgPath([sourceXY, ...points.slice(1,-1), targetXY])\n // so we need 4 points: first and last are discarded, middle two are the bend points.\n routingPoints = [\n { x: sCX, y: goingDown ? sAbs.y + sH : sAbs.y }, // [0] discarded\n { x: sharedX, y: goingDown ? sAbs.y + sH : sAbs.y }, // [1] bend: horizontal exit\n { x: sharedX, y: borderY }, // [2] bend: lane border\n { x: sharedX, y: goingDown ? tAbs.y : tAbs.y + tH }, // [3] discarded\n ];\n } else {\n routingPoints = [\n { x: sCX, y: sCY },\n { x: sharedX, y: sCY },\n { x: sharedX, y: tCY },\n { x: tCX, y: tCY },\n ];\n }\n }\n\n // ── Same lane, same row: straight — no bend points ─────────────────────\n else if (Math.abs(sCY - tCY) <= SAME_ROW_THRESHOLD) {\n // ReactFlow draws a straight edge when source and target handles align.\n const d = { ...edge.data };\n delete d.routingPoints;\n return { ...edge, data: d } as unknown as BpmnRFEdge;\n }\n\n // ── Same lane, cross-row: routing depends on source handle direction ───\n else {\n const handle = edge.sourceHandle ?? \"\";\n const exitsTop = handle.includes(\"top\");\n const exitsBottom = handle.includes(\"bottom\");\n\n if (exitsTop || exitsBottom) {\n // Handle exits vertically: go straight up/down then horizontal to target.\n // No horizontal exit segment needed — avoids the \"dips down before going up\" artefact.\n routingPoints = [\n { x: sCX, y: exitsTop ? sAbs.y : sAbs.y + sH }, // [0] discarded\n { x: sCX, y: tCY }, // [1] vertical to target row\n { x: tCX, y: tCY }, // [2] horizontal to target\n { x: tCX, y: exitsTop ? tAbs.y + tH : tAbs.y }, // [3] discarded\n ];\n } else {\n // Handle exits horizontally (right/left): classic L-shape.\n const goingRight = tAbs.x >= sAbs.x;\n const midX = goingRight\n ? sAbs.x + sW + COL_GAP / 2\n : sAbs.x - COL_GAP / 2;\n\n routingPoints = [\n { x: sAbs.x + sW, y: sCY }, // [0] discarded\n { x: midX, y: sCY }, // [1] horizontal exit\n { x: midX, y: tCY }, // [2] vertical to target row\n { x: tAbs.x, y: tCY }, // [3] discarded\n ];\n }\n }\n\n return { ...edge, data: { ...edge.data, routingPoints } } as unknown as BpmnRFEdge;\n });\n}\n\n// ── Main entry point ───────────────────────────────────────────────────────\n\nexport async function bpmnCustomLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n): Promise<{ nodes: BpmnRFNode[]; edges: BpmnRFEdge[] }> {\n const pools = nodes.filter(n => n.data.elementType === \"Pool\");\n const lanes = nodes.filter(n => n.data.elementType === \"Lane\");\n const content = nodes.filter(n => !LAYOUT_CONTAINER_TYPES.has(n.data.elementType));\n\n // ── Fallback: no pools → use ELK for free-node diagrams ───────────────────\n if (pools.length === 0) {\n const { bpmnElkLayout } = await import(\"./elk\");\n return bpmnElkLayout(nodes, edges);\n }\n\n const poolIds = new Set(pools.map(p => p.id));\n const allLaneIds = new Set(lanes.map(l => l.id));\n\n // ── Collect back-edges across ALL pools for routing ───────────────────────\n const allContentIds = new Set(content.map(n => n.id));\n const allSeqEdges = edges.filter(e => {\n const t = (e.data?.edgeType ?? e.type) as string;\n return t === \"sequenceFlow\" && allContentIds.has(e.source) && allContentIds.has(e.target);\n }).map(e => ({ id: e.id, source: e.source, target: e.target }));\n const allBackEdgeIds = detectBackEdges([...allContentIds], allSeqEdges);\n\n // ── Sort pools by original Y position (preserve author intent) ────────────\n // Sort pools by stored Y only when they have distinct positions (after a\n // prior layout pass). When all are at y≈0 (AI-generated or new diagram),\n // preserve original array order = creation order = intended visual order.\n const poolPositionsDistinct = pools.some(p => Math.abs(p.position.y) > 10);\n const sortedPools = poolPositionsDistinct\n ? [...pools].sort((a, b) => a.position.y - b.position.y)\n : [...pools];\n\n const resultNodes: BpmnRFNode[] = [];\n let stackY = 0;\n\n for (const pool of sortedPools) {\n const poolLanes = lanes.filter(l => l.parentId === pool.id);\n const laneIds = new Set(poolLanes.map(l => l.id));\n\n const poolContent = content.filter(n =>\n n.parentId === pool.id || (n.parentId != null && laneIds.has(n.parentId))\n );\n\n const result = layoutPool(pool, poolLanes, poolContent, edges);\n\n resultNodes.push({\n ...pool,\n position: { x: 0, y: stackY },\n width: result.width,\n height: result.height,\n });\n\n for (const node of result.nodes) {\n resultNodes.push(node);\n }\n\n stackY += result.height + POOL_V_GAP;\n }\n\n // ── Append free nodes not belonging to any pool ───────────────────────────\n const layoutted = new Set(resultNodes.map(n => n.id));\n for (const node of nodes) {\n if (!layoutted.has(node.id)) resultNodes.push(node);\n }\n\n // ── Route edges with absolute positions from the final node layout ─────────\n const routedEdges = routeEdges(edges, resultNodes, allBackEdgeIds, allLaneIds, poolIds);\n\n return { nodes: resultNodes, edges: routedEdges };\n}\n","import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\nexport { bpmnElkLayout } from \"./elk\";\nexport { bpmnCustomLayout } from \"./bpmn-custom-layout\";\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
|
package/dist/modeling/index.cjs
CHANGED
|
@@ -694,7 +694,9 @@ function createBpmnNode(options) {
|
|
|
694
694
|
height: options.height ?? size.height,
|
|
695
695
|
zIndex: getBpmnNodeZIndex(options.elementType),
|
|
696
696
|
...options.parentId ? { parentId: options.parentId } : {},
|
|
697
|
-
|
|
697
|
+
// extent:"parent" is intentionally omitted for Lane — it blocks resize beyond
|
|
698
|
+
// the Pool boundary before the Pool/Lane coupling can expand the Pool.
|
|
699
|
+
// Lane containment during drag is handled programmatically in handleNodeDragStop.
|
|
698
700
|
...dragHandle ? { dragHandle } : {}
|
|
699
701
|
};
|
|
700
702
|
}
|
|
@@ -711,8 +713,13 @@ function withBpmnNodeZIndexes(nodes) {
|
|
|
711
713
|
});
|
|
712
714
|
}
|
|
713
715
|
var BPMN_POOL_LANE_LAYOUT = {
|
|
714
|
-
|
|
715
|
-
|
|
716
|
+
// Pool inner padding on all sides (no left label strip).
|
|
717
|
+
// 8px = pool border (2px) + 6px visible gap.
|
|
718
|
+
poolPad: 8,
|
|
719
|
+
/** @deprecated use poolPad */
|
|
720
|
+
poolHeaderSize: 8,
|
|
721
|
+
// Lane left label strip (vertical text).
|
|
722
|
+
laneHeaderSize: 28,
|
|
716
723
|
laneGap: 0,
|
|
717
724
|
verticalPoolHeaderSize: 28,
|
|
718
725
|
minLaneSize: 96
|
|
@@ -836,6 +843,30 @@ function getBpmnPoolLanes(state, poolId) {
|
|
|
836
843
|
(node) => node.data.elementType === "Lane"
|
|
837
844
|
);
|
|
838
845
|
}
|
|
846
|
+
function getBpmnNodeBounds(state, node) {
|
|
847
|
+
const position = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
|
|
848
|
+
const size = getBpmnNodeSize(node);
|
|
849
|
+
return {
|
|
850
|
+
...position,
|
|
851
|
+
width: size.width,
|
|
852
|
+
height: size.height
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
function findBpmnLaneAt(state, position) {
|
|
856
|
+
return state.nodes.find((node) => {
|
|
857
|
+
if (node.data.elementType !== "Lane") return false;
|
|
858
|
+
const bounds = getBpmnNodeBounds(state, node);
|
|
859
|
+
return position.x >= bounds.x && position.x <= bounds.x + bounds.width && position.y >= bounds.y && position.y <= bounds.y + bounds.height;
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
function getAncestorLaneId(state, node) {
|
|
863
|
+
let current = node;
|
|
864
|
+
while (current) {
|
|
865
|
+
if (current.data.elementType === "Lane") return current.id;
|
|
866
|
+
current = current.parentId ? diagramsCore.getNode(state, current.parentId) : void 0;
|
|
867
|
+
}
|
|
868
|
+
return void 0;
|
|
869
|
+
}
|
|
839
870
|
function getNodeDimension(node, axis) {
|
|
840
871
|
return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
|
|
841
872
|
}
|
|
@@ -844,16 +875,18 @@ function getBpmnLaneOrderPosition(lane, orientation) {
|
|
|
844
875
|
return orientation === "vertical" ? lane.position.x + size.width / 2 : lane.position.y + size.height / 2;
|
|
845
876
|
}
|
|
846
877
|
function resizeHorizontalBpmnLanes(lanes, pool) {
|
|
878
|
+
const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
|
|
847
879
|
const poolSize = getBpmnNodeSize(pool);
|
|
848
|
-
const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width -
|
|
849
|
-
const
|
|
880
|
+
const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width - pad * 2);
|
|
881
|
+
const availH = Math.max(0, poolSize.height - pad * 2);
|
|
882
|
+
const laneHeight = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, availH / Math.max(1, lanes.length));
|
|
850
883
|
return lanes.map((lane, index) => ({
|
|
851
884
|
...lane,
|
|
852
|
-
position: { x:
|
|
885
|
+
position: { x: pad, y: pad + index * laneHeight },
|
|
853
886
|
width: laneWidth,
|
|
854
887
|
height: laneHeight,
|
|
855
888
|
parentId: pool.id,
|
|
856
|
-
extent:
|
|
889
|
+
// extent:"parent" intentionally omitted — blocks resize→Pool coupling.
|
|
857
890
|
zIndex: getBpmnNodeZIndex("Lane"),
|
|
858
891
|
data: { ...lane.data, orientation: "horizontal", laneIndex: index }
|
|
859
892
|
}));
|
|
@@ -884,10 +917,22 @@ function layoutBpmnPoolLaneNodes(nodes, poolId) {
|
|
|
884
917
|
return getBpmnLaneOrderPosition(a, orientation) - getBpmnLaneOrderPosition(b, orientation);
|
|
885
918
|
});
|
|
886
919
|
if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
|
|
887
|
-
const
|
|
888
|
-
|
|
920
|
+
const resizedLanes = orientation === "vertical" ? resizeVerticalBpmnLanes(lanes, pool) : resizeHorizontalBpmnLanes(lanes, pool);
|
|
921
|
+
const laneMap = new Map(resizedLanes.map((lane) => [lane.id, lane]));
|
|
922
|
+
const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
|
|
923
|
+
const totalLaneH = resizedLanes.reduce((sum, l) => sum + (l.height ?? 0), 0);
|
|
924
|
+
const requiredPoolH = totalLaneH + pad * 2;
|
|
925
|
+
const poolMap = /* @__PURE__ */ new Map();
|
|
926
|
+
if (orientation === "horizontal") {
|
|
927
|
+
const currentH = getBpmnNodeSize(pool).height;
|
|
928
|
+
poolMap.set(pool.id, {
|
|
929
|
+
...pool,
|
|
930
|
+
height: Math.max(requiredPoolH, currentH)
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
return withBpmnNodeZIndexes(
|
|
934
|
+
nodes.map((node) => laneMap.get(node.id) ?? poolMap.get(node.id) ?? node)
|
|
889
935
|
);
|
|
890
|
-
return withBpmnNodeZIndexes(nodes.map((node) => laneMap.get(node.id) ?? node));
|
|
891
936
|
}
|
|
892
937
|
function reorderBpmnLaneAfterDrop(nodes, laneId) {
|
|
893
938
|
const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
|
|
@@ -946,6 +991,53 @@ function findBpmnContainerAt(state, options) {
|
|
|
946
991
|
}
|
|
947
992
|
});
|
|
948
993
|
}
|
|
994
|
+
function resolveBpmnDropTarget(state, options) {
|
|
995
|
+
if (options.elementType === "Pool") {
|
|
996
|
+
return { highlightedContainerId: null, invalidContainerId: null, isValid: true };
|
|
997
|
+
}
|
|
998
|
+
if (options.elementType === "Lane") {
|
|
999
|
+
const pool = state.nodes.find((node) => {
|
|
1000
|
+
if (node.data.elementType !== "Pool") return false;
|
|
1001
|
+
const bounds = getBpmnNodeBounds(state, node);
|
|
1002
|
+
return options.position.x >= bounds.x && options.position.x <= bounds.x + bounds.width && options.position.y >= bounds.y && options.position.y <= bounds.y + bounds.height;
|
|
1003
|
+
});
|
|
1004
|
+
return {
|
|
1005
|
+
...pool ? { container: pool } : {},
|
|
1006
|
+
highlightedContainerId: pool?.id ?? null,
|
|
1007
|
+
invalidContainerId: null,
|
|
1008
|
+
isValid: Boolean(pool)
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
const lane = findBpmnLaneAt(state, options.position);
|
|
1012
|
+
if (lane) {
|
|
1013
|
+
return {
|
|
1014
|
+
container: lane,
|
|
1015
|
+
highlightedContainerId: lane.id,
|
|
1016
|
+
invalidContainerId: null,
|
|
1017
|
+
isValid: true
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
const container = findBpmnContainerAt(state, {
|
|
1021
|
+
position: options.position,
|
|
1022
|
+
...options.excludeId ? { excludeId: options.excludeId } : {}
|
|
1023
|
+
});
|
|
1024
|
+
if (container?.data.elementType === "Pool") {
|
|
1025
|
+
const hasLanes = getBpmnPoolLanes(state, container.id).length > 0;
|
|
1026
|
+
if (hasLanes) {
|
|
1027
|
+
return {
|
|
1028
|
+
highlightedContainerId: null,
|
|
1029
|
+
invalidContainerId: container.id,
|
|
1030
|
+
isValid: false
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return {
|
|
1035
|
+
...container ? { container } : {},
|
|
1036
|
+
highlightedContainerId: getAncestorLaneId(state, container) ?? container?.id ?? null,
|
|
1037
|
+
invalidContainerId: null,
|
|
1038
|
+
isValid: true
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
949
1041
|
function getBpmnNodeCenter(node, absolutePosition) {
|
|
950
1042
|
return diagramsCore.getNodeCenterPosition(absolutePosition, getBpmnNodeSize(node));
|
|
951
1043
|
}
|
|
@@ -1567,6 +1659,7 @@ exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
|
|
|
1567
1659
|
exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
|
|
1568
1660
|
exports.resizeBpmnNodeByHandleCommand = resizeBpmnNodeByHandleCommand;
|
|
1569
1661
|
exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
|
|
1662
|
+
exports.resolveBpmnDropTarget = resolveBpmnDropTarget;
|
|
1570
1663
|
exports.restoreBpmnHistory = restoreBpmnHistory;
|
|
1571
1664
|
exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;
|
|
1572
1665
|
exports.runBpmnCommand = runBpmnCommand;
|