@aranzatech/diagrams-bpmn 0.2.14 → 0.3.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.
Files changed (81) hide show
  1. package/README.md +34 -4
  2. package/dist/{catalog-xOMF2ifW.d.cts → catalog-DAGDhO-D.d.cts} +1 -1
  3. package/dist/{catalog-CK3_4cOb.d.ts → catalog-Q1QmKLDD.d.ts} +1 -1
  4. package/dist/{chunk-YUE5EM3W.js → chunk-334WN4JZ.js} +276 -107
  5. package/dist/chunk-334WN4JZ.js.map +1 -0
  6. package/dist/chunk-77L6O76M.js +3 -0
  7. package/dist/chunk-77L6O76M.js.map +1 -0
  8. package/dist/{chunk-QSMP34CT.js → chunk-CPFUQM6H.js} +80 -44
  9. package/dist/chunk-CPFUQM6H.js.map +1 -0
  10. package/dist/chunk-FFWJA5BV.js +163 -0
  11. package/dist/chunk-FFWJA5BV.js.map +1 -0
  12. package/dist/{chunk-FBTGIYZS.js → chunk-JEGYVEJO.js} +80 -3
  13. package/dist/{chunk-FBTGIYZS.js.map → chunk-JEGYVEJO.js.map} +1 -1
  14. package/dist/chunk-TB6V4S5N.js +104 -0
  15. package/dist/chunk-TB6V4S5N.js.map +1 -0
  16. package/dist/{chunk-IMW6RG6F.js → chunk-X54NHLBA.js} +43 -190
  17. package/dist/chunk-X54NHLBA.js.map +1 -0
  18. package/dist/{chunk-UAWLUDKC.js → chunk-YAYZW45I.js} +481 -26
  19. package/dist/chunk-YAYZW45I.js.map +1 -0
  20. package/dist/edges/index.cjs +78 -42
  21. package/dist/edges/index.cjs.map +1 -1
  22. package/dist/edges/index.js +1 -1
  23. package/dist/elements/index.cjs +78 -0
  24. package/dist/elements/index.cjs.map +1 -1
  25. package/dist/elements/index.d.cts +24 -5
  26. package/dist/elements/index.d.ts +24 -5
  27. package/dist/elements/index.js +1 -1
  28. package/dist/elk-QT7H4252.js +6 -0
  29. package/dist/elk-QT7H4252.js.map +1 -0
  30. package/dist/extensions/index.cjs +108 -0
  31. package/dist/extensions/index.cjs.map +1 -0
  32. package/dist/extensions/index.d.cts +145 -0
  33. package/dist/extensions/index.d.ts +145 -0
  34. package/dist/extensions/index.js +4 -0
  35. package/dist/extensions/index.js.map +1 -0
  36. package/dist/index.cjs +1067 -358
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +7 -5
  39. package/dist/index.d.ts +7 -5
  40. package/dist/index.js +7 -5
  41. package/dist/index.js.map +1 -1
  42. package/dist/layout/index.cjs +1396 -749
  43. package/dist/layout/index.cjs.map +1 -1
  44. package/dist/layout/index.d.cts +10 -4
  45. package/dist/layout/index.d.ts +10 -4
  46. package/dist/layout/index.js +543 -104
  47. package/dist/layout/index.js.map +1 -1
  48. package/dist/modeling/index.cjs +490 -23
  49. package/dist/modeling/index.cjs.map +1 -1
  50. package/dist/modeling/index.d.cts +81 -6
  51. package/dist/modeling/index.d.ts +81 -6
  52. package/dist/modeling/index.js +1 -1
  53. package/dist/nodes/index.cjs +42 -188
  54. package/dist/nodes/index.cjs.map +1 -1
  55. package/dist/nodes/index.d.cts +1 -1
  56. package/dist/nodes/index.d.ts +1 -1
  57. package/dist/nodes/index.js +1 -1
  58. package/dist/types-BX_o95GC.d.cts +40 -0
  59. package/dist/{types-y-ZbX-ff.d.cts → types-BYN4Zuee.d.cts} +15 -1
  60. package/dist/{types-y-ZbX-ff.d.ts → types-BYN4Zuee.d.ts} +15 -1
  61. package/dist/{types-jIDz306Y.d.cts → types-CggktCqr.d.cts} +4 -1
  62. package/dist/types-D7zel9dq.d.ts +40 -0
  63. package/dist/{types-DG5yPKld.d.ts → types-DmDODKlh.d.ts} +4 -1
  64. package/dist/validation/index.cjs +81 -125
  65. package/dist/validation/index.cjs.map +1 -1
  66. package/dist/validation/index.d.cts +22 -5
  67. package/dist/validation/index.d.ts +22 -5
  68. package/dist/validation/index.js +82 -126
  69. package/dist/validation/index.js.map +1 -1
  70. package/dist/xml/index.cjs +319 -49
  71. package/dist/xml/index.cjs.map +1 -1
  72. package/dist/xml/index.d.cts +5 -3
  73. package/dist/xml/index.d.ts +5 -3
  74. package/dist/xml/index.js +2 -1
  75. package/package.json +6 -1
  76. package/dist/chunk-IMW6RG6F.js.map +0 -1
  77. package/dist/chunk-QSMP34CT.js.map +0 -1
  78. package/dist/chunk-UAWLUDKC.js.map +0 -1
  79. package/dist/chunk-YUE5EM3W.js.map +0 -1
  80. package/dist/guards-C70uIY_O.d.cts +0 -16
  81. package/dist/guards-foB6XIfZ.d.ts +0 -16
@@ -22,7 +22,9 @@ function createBpmnNode(options) {
22
22
  height: options.height ?? size.height,
23
23
  zIndex: getBpmnNodeZIndex(options.elementType),
24
24
  ...options.parentId ? { parentId: options.parentId } : {},
25
- ...options.elementType === "Lane" && options.parentId ? { extent: "parent" } : {},
25
+ // extent:"parent" is intentionally omitted for Lane it blocks resize beyond
26
+ // the Pool boundary before the Pool/Lane coupling can expand the Pool.
27
+ // Lane containment during drag is handled programmatically in handleNodeDragStop.
26
28
  ...dragHandle ? { dragHandle } : {}
27
29
  };
28
30
  }
@@ -39,12 +41,24 @@ function withBpmnNodeZIndexes(nodes) {
39
41
  });
40
42
  }
41
43
  var BPMN_POOL_LANE_LAYOUT = {
42
- poolHeaderSize: 30,
43
- laneHeaderSize: 24,
44
+ // Pool inner padding on all sides (no left label strip).
45
+ // 8px = pool border (2px) + 6px visible gap.
46
+ poolPad: 8,
47
+ /** @deprecated use poolPad */
48
+ poolHeaderSize: 8,
49
+ // Lane left label strip (vertical text).
50
+ laneHeaderSize: 28,
44
51
  laneGap: 0,
45
52
  verticalPoolHeaderSize: 28,
46
53
  minLaneSize: 96
47
54
  };
55
+ var BPMN_POOL_LANE_STACK_LAYOUT = {
56
+ poolInnerPad: 8,
57
+ laneGap: 8,
58
+ minLaneWidth: 240,
59
+ minLaneHeight: 80,
60
+ defaultLaneHeight: 120
61
+ };
48
62
  function getBpmnDragHandleSelector(elementType) {
49
63
  if (elementType === "Pool") return ".pool-drag-handle";
50
64
  if (elementType === "Lane") return ".lane-drag-handle";
@@ -115,7 +129,9 @@ function inferBpmnEdgeType(state, sourceId, targetId) {
115
129
  if (source.data.elementType === "Conversation" || source.data.elementType === "SubConversation" || source.data.elementType === "CallConversation" || target.data.elementType === "Conversation" || target.data.elementType === "SubConversation" || target.data.elementType === "CallConversation") {
116
130
  return "conversationLink";
117
131
  }
118
- if (source.parentId && target.parentId && source.parentId !== target.parentId) {
132
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
133
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
134
+ if (sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId) {
119
135
  return "messageFlow";
120
136
  }
121
137
  return "sequenceFlow";
@@ -164,6 +180,67 @@ function getBpmnPoolLanes(state, poolId) {
164
180
  (node) => node.data.elementType === "Lane"
165
181
  );
166
182
  }
183
+ function getBpmnNodeBounds(state, node) {
184
+ const position = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
185
+ const size = getBpmnNodeSize(node);
186
+ return {
187
+ ...position,
188
+ width: size.width,
189
+ height: size.height
190
+ };
191
+ }
192
+ var BPMN_BOUNDARY_ATTACH_MARGIN = 32;
193
+ function clampBoundaryCoordinate(value, min, max) {
194
+ return Math.min(max, Math.max(min, value));
195
+ }
196
+ function isPointInsideExpandedBounds(point, origin, size) {
197
+ return point.x >= origin.x - BPMN_BOUNDARY_ATTACH_MARGIN && point.x <= origin.x + size.width + BPMN_BOUNDARY_ATTACH_MARGIN && point.y >= origin.y - BPMN_BOUNDARY_ATTACH_MARGIN && point.y <= origin.y + size.height + BPMN_BOUNDARY_ATTACH_MARGIN;
198
+ }
199
+ function snapBoundaryCenterToHostBorder(center, hostOrigin, hostSize) {
200
+ const distances = [
201
+ { side: "left", value: Math.abs(center.x - hostOrigin.x) },
202
+ { side: "right", value: Math.abs(center.x - (hostOrigin.x + hostSize.width)) },
203
+ { side: "top", value: Math.abs(center.y - hostOrigin.y) },
204
+ { side: "bottom", value: Math.abs(center.y - (hostOrigin.y + hostSize.height)) }
205
+ ].sort((a, b) => a.value - b.value);
206
+ const side = distances[0]?.side;
207
+ if (side === "left") {
208
+ return { x: hostOrigin.x, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
209
+ }
210
+ if (side === "right") {
211
+ return { x: hostOrigin.x + hostSize.width, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
212
+ }
213
+ if (side === "top") {
214
+ return { x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width), y: hostOrigin.y };
215
+ }
216
+ return {
217
+ x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width),
218
+ y: hostOrigin.y + hostSize.height
219
+ };
220
+ }
221
+ function findBpmnLaneAt(state, position) {
222
+ return state.nodes.find((node) => {
223
+ if (node.data.elementType !== "Lane") return false;
224
+ const bounds = getBpmnNodeBounds(state, node);
225
+ return position.x >= bounds.x && position.x <= bounds.x + bounds.width && position.y >= bounds.y && position.y <= bounds.y + bounds.height;
226
+ });
227
+ }
228
+ function getAncestorLaneId(state, node) {
229
+ let current = node;
230
+ while (current) {
231
+ if (current.data.elementType === "Lane") return current.id;
232
+ current = current.parentId ? getNode(state, current.parentId) : void 0;
233
+ }
234
+ return void 0;
235
+ }
236
+ function getAncestorContainerId(state, node, elementType) {
237
+ let current = node;
238
+ while (current) {
239
+ if (current.data.elementType === elementType) return current.id;
240
+ current = current.parentId ? getNode(state, current.parentId) : void 0;
241
+ }
242
+ return void 0;
243
+ }
167
244
  function getNodeDimension(node, axis) {
168
245
  return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
169
246
  }
@@ -171,17 +248,250 @@ function getBpmnLaneOrderPosition(lane, orientation) {
171
248
  const size = getBpmnNodeSize(lane);
172
249
  return orientation === "vertical" ? lane.position.x + size.width / 2 : lane.position.y + size.height / 2;
173
250
  }
251
+ function getBpmnPoolOrientation(pool) {
252
+ return pool.data.orientation === "vertical" ? "vertical" : "horizontal";
253
+ }
254
+ function getBpmnPoolLanesOrderedByStack(nodes, poolId, orientation) {
255
+ return nodes.filter((node) => node.parentId === poolId && node.data.elementType === "Lane").sort((a, b) => {
256
+ const aIndex = typeof a.data.laneIndex === "number" ? a.data.laneIndex : void 0;
257
+ const bIndex = typeof b.data.laneIndex === "number" ? b.data.laneIndex : void 0;
258
+ if (aIndex !== void 0 || bIndex !== void 0) return (aIndex ?? 0) - (bIndex ?? 0);
259
+ return orientation === "vertical" ? (a.position?.x ?? 0) - (b.position?.x ?? 0) : (a.position?.y ?? 0) - (b.position?.y ?? 0);
260
+ });
261
+ }
262
+ function layoutBpmnPoolLaneNodesPreservingHeights(nodes, poolId) {
263
+ const pool = nodes.find((node) => node.id === poolId && node.data.elementType === "Pool");
264
+ if (!pool) return nodes;
265
+ const orientation = getBpmnPoolOrientation(pool);
266
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
267
+ if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
268
+ const poolW = pool.measured?.width ?? pool.width ?? 720;
269
+ const poolH = pool.measured?.height ?? pool.height ?? 200;
270
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
271
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
272
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
273
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
274
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
275
+ if (orientation === "vertical") {
276
+ const laneWidth2 = Math.max(
277
+ minLaneW,
278
+ Math.floor((poolW - pad * 2 - gap * Math.max(0, lanes.length - 1)) / Math.max(1, lanes.length))
279
+ );
280
+ const laneHeight = Math.max(minLaneH, poolH - pad * 2);
281
+ let cumX = pad;
282
+ const laneMap2 = new Map(
283
+ lanes.map((lane, index) => {
284
+ const nextLane = {
285
+ ...lane,
286
+ position: { x: cumX, y: pad },
287
+ width: laneWidth2,
288
+ height: laneHeight,
289
+ parentId: pool.id,
290
+ data: { ...lane.data, orientation: "vertical", laneIndex: index }
291
+ };
292
+ cumX += laneWidth2 + gap;
293
+ return [lane.id, nextLane];
294
+ })
295
+ );
296
+ const requiredPoolW = cumX - gap + pad;
297
+ return withBpmnNodeZIndexes(
298
+ nodes.map(
299
+ (node) => laneMap2.get(node.id) ?? (node.id === pool.id ? { ...pool, width: Math.max(requiredPoolW, poolW) } : node)
300
+ )
301
+ );
302
+ }
303
+ const laneWidth = Math.max(minLaneW, poolW - pad * 2);
304
+ let cumY = pad;
305
+ const laneMap = new Map(
306
+ lanes.map((lane, index) => {
307
+ const laneHeight = Math.max(minLaneH, lane.measured?.height ?? lane.height ?? defaultLaneH);
308
+ const nextLane = {
309
+ ...lane,
310
+ position: { x: pad, y: cumY },
311
+ width: laneWidth,
312
+ height: laneHeight,
313
+ parentId: pool.id,
314
+ data: { ...lane.data, orientation: "horizontal", laneIndex: index }
315
+ };
316
+ cumY += laneHeight + gap;
317
+ return [lane.id, nextLane];
318
+ })
319
+ );
320
+ const requiredPoolH = cumY - gap + pad;
321
+ return withBpmnNodeZIndexes(
322
+ nodes.map(
323
+ (node) => laneMap.get(node.id) ?? (node.id === pool.id ? { ...pool, height: Math.max(requiredPoolH, poolH) } : node)
324
+ )
325
+ );
326
+ }
327
+ function reorderBpmnPoolLaneAfterDropPreservingHeights(nodes, laneId) {
328
+ const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
329
+ if (!lane?.parentId) return nodes;
330
+ const pool = nodes.find((node) => node.id === lane.parentId && node.data.elementType === "Pool");
331
+ if (!pool) return nodes;
332
+ const orientation = getBpmnPoolOrientation(pool);
333
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
334
+ const moved = lanes.find((candidate) => candidate.id === lane.id);
335
+ if (!moved) return layoutBpmnPoolLaneNodesPreservingHeights(nodes, pool.id);
336
+ const withoutMoved = lanes.filter((candidate) => candidate.id !== lane.id);
337
+ const movedCenter = orientation === "vertical" ? (lane.position?.x ?? 0) + (lane.width ?? 0) / 2 : (lane.position?.y ?? 0) + (lane.height ?? 0) / 2;
338
+ const insertIndex = withoutMoved.findIndex((candidate) => {
339
+ const candidateCenter = orientation === "vertical" ? (candidate.position?.x ?? 0) + (candidate.width ?? 0) / 2 : (candidate.position?.y ?? 0) + (candidate.height ?? 0) / 2;
340
+ return movedCenter < candidateCenter;
341
+ });
342
+ const ordered = [...withoutMoved];
343
+ ordered.splice(insertIndex === -1 ? ordered.length : insertIndex, 0, moved);
344
+ const orderedMap = new Map(ordered.map((candidate, index) => [candidate.id, index]));
345
+ return layoutBpmnPoolLaneNodesPreservingHeights(
346
+ nodes.map(
347
+ (node) => node.parentId === pool.id && node.data.elementType === "Lane" ? { ...node, data: { ...node.data, laneIndex: orderedMap.get(node.id) ?? 0 } } : node
348
+ ),
349
+ pool.id
350
+ );
351
+ }
352
+ function getAppendedBpmnLaneFrame(nodes, poolOrId) {
353
+ const pool = typeof poolOrId === "string" ? nodes.find((node) => node.id === poolOrId && node.data.elementType === "Pool") : poolOrId;
354
+ if (!pool || pool.data.elementType !== "Pool") return null;
355
+ const orientation = getBpmnPoolOrientation(pool);
356
+ const existingLanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
357
+ const poolW = pool.measured?.width ?? pool.width ?? 600;
358
+ const poolH = pool.measured?.height ?? pool.height ?? 400;
359
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
360
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
361
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
362
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
363
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
364
+ if (orientation === "horizontal") {
365
+ const lastLane2 = existingLanes[existingLanes.length - 1];
366
+ return {
367
+ position: {
368
+ x: pad,
369
+ y: lastLane2 ? (lastLane2.position?.y ?? pad) + (lastLane2.height ?? defaultLaneH) + gap : pad
370
+ },
371
+ width: Math.max(minLaneW, poolW - pad * 2),
372
+ height: existingLanes.length === 0 ? Math.max(minLaneH, poolH - pad * 2) : defaultLaneH,
373
+ laneIndex: existingLanes.length,
374
+ orientation
375
+ };
376
+ }
377
+ const lastLane = existingLanes[existingLanes.length - 1];
378
+ return {
379
+ position: {
380
+ x: lastLane ? (lastLane.position?.x ?? pad) + (lastLane.width ?? defaultLaneH) + gap : pad,
381
+ y: pad
382
+ },
383
+ width: existingLanes.length === 0 ? Math.max(minLaneW, poolW - pad * 2) : defaultLaneH,
384
+ height: Math.max(minLaneH, poolH - pad * 2),
385
+ laneIndex: existingLanes.length,
386
+ orientation
387
+ };
388
+ }
389
+ function getBpmnPoolLaneNodeMaxSize(state, nodeId) {
390
+ const n = getNode(state, nodeId);
391
+ if (n?.data.elementType === "Lane" && n.parentId) {
392
+ const pool = getNode(state, n.parentId);
393
+ if (pool) {
394
+ const siblings = state.nodes.filter(
395
+ (x) => x.parentId === n.parentId && x.data.elementType === "Lane" && x.id !== n.id
396
+ );
397
+ const poolH = pool.measured?.height ?? pool.height ?? 500;
398
+ const siblingsMinH = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
399
+ const siblingGaps = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
400
+ const maxH = Math.max(
401
+ BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight,
402
+ poolH - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 - siblingsMinH - siblingGaps
403
+ );
404
+ return {
405
+ width: (pool.width ?? 720) - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2,
406
+ height: maxH
407
+ };
408
+ }
409
+ }
410
+ return void 0;
411
+ }
412
+ function getBpmnPoolLaneNodeMinSize(state, nodeId) {
413
+ const n = getNode(state, nodeId);
414
+ if (n?.data.elementType === "Pool") {
415
+ const lanes = state.nodes.filter((x) => x.parentId === nodeId && x.data.elementType === "Lane");
416
+ if (lanes.length > 0) {
417
+ const minW = Math.max(...lanes.map((l) => (l.width ?? 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2));
418
+ const minH = lanes.reduce((s, l) => s + (l.height ?? BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight), 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 + Math.max(0, lanes.length - 1) * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
419
+ return { width: minW, height: minH };
420
+ }
421
+ }
422
+ return void 0;
423
+ }
424
+ function applyBpmnPoolLaneDimensionChange(nodes, previousNodes, nodeId, width, height) {
425
+ const node = nodes.find((candidate) => candidate.id === nodeId);
426
+ const previousNode = previousNodes.find((candidate) => candidate.id === nodeId);
427
+ if (!node) return nodes;
428
+ const curW = previousNode?.measured?.width ?? previousNode?.width ?? 0;
429
+ const curH = previousNode?.measured?.height ?? previousNode?.height ?? 0;
430
+ if (Math.abs(width - curW) < 1 && Math.abs(height - curH) < 1) return nodes;
431
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
432
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
433
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
434
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
435
+ if (node.data.elementType === "Pool") {
436
+ const targetLaneW = Math.max(minLaneW, width - pad * 2);
437
+ return nodes.map(
438
+ (candidate) => candidate.parentId === node.id && candidate.data.elementType === "Lane" ? {
439
+ ...candidate,
440
+ width: targetLaneW,
441
+ measured: {
442
+ width: targetLaneW,
443
+ height: candidate.measured?.height ?? candidate.height ?? defaultLaneH
444
+ },
445
+ position: { x: pad, y: candidate.position?.y ?? pad }
446
+ } : candidate
447
+ );
448
+ }
449
+ if (node.data.elementType === "Lane" && node.parentId) {
450
+ const pool = nodes.find((candidate) => candidate.id === node.parentId && candidate.data.elementType === "Pool");
451
+ if (!pool) return nodes;
452
+ const poolW = Math.max(width + pad * 2, pool.measured?.width ?? pool.width ?? 720);
453
+ const sortedLanes = getBpmnPoolLanesOrderedByStack(nodes, node.parentId, "horizontal");
454
+ let cumY = pad;
455
+ const laneMap = /* @__PURE__ */ new Map();
456
+ for (const lane of sortedLanes) {
457
+ const laneH = lane.id === node.id ? height : lane.measured?.height ?? lane.height ?? defaultLaneH;
458
+ laneMap.set(lane.id, {
459
+ ...lane,
460
+ width,
461
+ height: laneH,
462
+ measured: { width, height: laneH },
463
+ position: { x: pad, y: cumY }
464
+ });
465
+ cumY += laneH + gap;
466
+ }
467
+ const newPoolH = cumY - gap + pad;
468
+ return nodes.map((candidate) => {
469
+ if (candidate.id === pool.id) {
470
+ return {
471
+ ...candidate,
472
+ width: poolW,
473
+ height: newPoolH,
474
+ measured: { width: poolW, height: newPoolH }
475
+ };
476
+ }
477
+ return laneMap.get(candidate.id) ?? candidate;
478
+ });
479
+ }
480
+ return nodes;
481
+ }
174
482
  function resizeHorizontalBpmnLanes(lanes, pool) {
483
+ const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
175
484
  const poolSize = getBpmnNodeSize(pool);
176
- const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width - BPMN_POOL_LANE_LAYOUT.poolHeaderSize);
177
- const laneHeight = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.height / Math.max(1, lanes.length));
485
+ const laneWidth = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, poolSize.width - pad * 2);
486
+ const availH = Math.max(0, poolSize.height - pad * 2);
487
+ const laneHeight = Math.max(BPMN_POOL_LANE_LAYOUT.minLaneSize, availH / Math.max(1, lanes.length));
178
488
  return lanes.map((lane, index) => ({
179
489
  ...lane,
180
- position: { x: BPMN_POOL_LANE_LAYOUT.poolHeaderSize, y: index * laneHeight },
490
+ position: { x: pad, y: pad + index * laneHeight },
181
491
  width: laneWidth,
182
492
  height: laneHeight,
183
493
  parentId: pool.id,
184
- extent: "parent",
494
+ // extent:"parent" intentionally omitted — blocks resize→Pool coupling.
185
495
  zIndex: getBpmnNodeZIndex("Lane"),
186
496
  data: { ...lane.data, orientation: "horizontal", laneIndex: index }
187
497
  }));
@@ -212,10 +522,22 @@ function layoutBpmnPoolLaneNodes(nodes, poolId) {
212
522
  return getBpmnLaneOrderPosition(a, orientation) - getBpmnLaneOrderPosition(b, orientation);
213
523
  });
214
524
  if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
215
- const laneMap = new Map(
216
- (orientation === "vertical" ? resizeVerticalBpmnLanes(lanes, pool) : resizeHorizontalBpmnLanes(lanes, pool)).map((lane) => [lane.id, lane])
525
+ const resizedLanes = orientation === "vertical" ? resizeVerticalBpmnLanes(lanes, pool) : resizeHorizontalBpmnLanes(lanes, pool);
526
+ const laneMap = new Map(resizedLanes.map((lane) => [lane.id, lane]));
527
+ const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
528
+ const totalLaneH = resizedLanes.reduce((sum, l) => sum + (l.height ?? 0), 0);
529
+ const requiredPoolH = totalLaneH + pad * 2;
530
+ const poolMap = /* @__PURE__ */ new Map();
531
+ if (orientation === "horizontal") {
532
+ const currentH = getBpmnNodeSize(pool).height;
533
+ poolMap.set(pool.id, {
534
+ ...pool,
535
+ height: Math.max(requiredPoolH, currentH)
536
+ });
537
+ }
538
+ return withBpmnNodeZIndexes(
539
+ nodes.map((node) => laneMap.get(node.id) ?? poolMap.get(node.id) ?? node)
217
540
  );
218
- return withBpmnNodeZIndexes(nodes.map((node) => laneMap.get(node.id) ?? node));
219
541
  }
220
542
  function reorderBpmnLaneAfterDrop(nodes, laneId) {
221
543
  const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
@@ -274,9 +596,116 @@ function findBpmnContainerAt(state, options) {
274
596
  }
275
597
  });
276
598
  }
599
+ function resolveBpmnDropTarget(state, options) {
600
+ if (options.elementType === "Pool") {
601
+ return { highlightedContainerId: null, invalidContainerId: null, isValid: true };
602
+ }
603
+ if (options.elementType === "Lane") {
604
+ const pool = state.nodes.find((node) => {
605
+ if (node.data.elementType !== "Pool") return false;
606
+ const bounds = getBpmnNodeBounds(state, node);
607
+ 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;
608
+ });
609
+ return {
610
+ ...pool ? { container: pool } : {},
611
+ highlightedContainerId: pool?.id ?? null,
612
+ invalidContainerId: null,
613
+ isValid: Boolean(pool)
614
+ };
615
+ }
616
+ const lane = findBpmnLaneAt(state, options.position);
617
+ if (lane) {
618
+ return {
619
+ container: lane,
620
+ highlightedContainerId: lane.id,
621
+ invalidContainerId: null,
622
+ isValid: true
623
+ };
624
+ }
625
+ const container = findBpmnContainerAt(state, {
626
+ position: options.position,
627
+ ...options.excludeId ? { excludeId: options.excludeId } : {}
628
+ });
629
+ if (container?.data.elementType === "Pool") {
630
+ const hasLanes = getBpmnPoolLanes(state, container.id).length > 0;
631
+ if (hasLanes) {
632
+ return {
633
+ highlightedContainerId: null,
634
+ invalidContainerId: container.id,
635
+ isValid: false
636
+ };
637
+ }
638
+ }
639
+ return {
640
+ ...container ? { container } : {},
641
+ highlightedContainerId: getAncestorLaneId(state, container) ?? container?.id ?? null,
642
+ invalidContainerId: null,
643
+ isValid: true
644
+ };
645
+ }
277
646
  function getBpmnNodeCenter(node, absolutePosition) {
278
647
  return getNodeCenterPosition(absolutePosition, getBpmnNodeSize(node));
279
648
  }
649
+ function getBoundaryEventAttachment(state, boundaryNode) {
650
+ if (boundaryNode.data.elementType !== "BoundaryEvent") return null;
651
+ const boundaryOrigin = getBpmnNodeAbsolutePosition(state, boundaryNode) ?? boundaryNode.position;
652
+ const boundarySize = getBpmnNodeSize(boundaryNode);
653
+ const boundaryCenter = {
654
+ x: boundaryOrigin.x + boundarySize.width / 2,
655
+ y: boundaryOrigin.y + boundarySize.height / 2
656
+ };
657
+ const candidates = state.nodes.filter((node) => node.id !== boundaryNode.id && acceptsBoundaryEvents(node.data.elementType)).map((node) => {
658
+ const origin = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
659
+ const size = getBpmnNodeSize(node);
660
+ const hostCenter = { x: origin.x + size.width / 2, y: origin.y + size.height / 2 };
661
+ return {
662
+ node,
663
+ origin,
664
+ size,
665
+ distance: Math.hypot(boundaryCenter.x - hostCenter.x, boundaryCenter.y - hostCenter.y)
666
+ };
667
+ }).filter(({ origin, size }) => isPointInsideExpandedBounds(boundaryCenter, origin, size)).sort((a, b) => a.distance - b.distance);
668
+ const host = candidates[0];
669
+ if (!host) return null;
670
+ const snappedCenter = snapBoundaryCenterToHostBorder(boundaryCenter, host.origin, host.size);
671
+ return {
672
+ hostId: host.node.id,
673
+ position: {
674
+ x: snappedCenter.x - host.origin.x - boundarySize.width / 2,
675
+ y: snappedCenter.y - host.origin.y - boundarySize.height / 2
676
+ }
677
+ };
678
+ }
679
+ function getBpmnEdgeLaneContext(state, edgeOrId) {
680
+ const edge = typeof edgeOrId === "string" ? state.edges.find((candidate) => candidate.id === edgeOrId) : edgeOrId;
681
+ if (!edge) return void 0;
682
+ const source = getNode(state, edge.source);
683
+ const target = getNode(state, edge.target);
684
+ if (!source || !target) return void 0;
685
+ const sourceLaneId = getAncestorLaneId(state, source);
686
+ const targetLaneId = getAncestorLaneId(state, target);
687
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
688
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
689
+ const sameLane = Boolean(sourceLaneId) && sourceLaneId === targetLaneId;
690
+ const samePool = Boolean(sourcePoolId) && sourcePoolId === targetPoolId;
691
+ const crossesLanesWithinPool = Boolean(
692
+ sourceLaneId && targetLaneId && sourceLaneId !== targetLaneId && samePool
693
+ );
694
+ const crossesPools = Boolean(
695
+ sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId
696
+ );
697
+ return {
698
+ edgeId: edge.id,
699
+ ...sourceLaneId ? { sourceLaneId } : {},
700
+ ...targetLaneId ? { targetLaneId } : {},
701
+ ...sourcePoolId ? { sourcePoolId } : {},
702
+ ...targetPoolId ? { targetPoolId } : {},
703
+ sameLane,
704
+ samePool,
705
+ crossesLanesWithinPool,
706
+ crossesPools
707
+ };
708
+ }
280
709
  function resolvePoolLaneDirection(pool) {
281
710
  return pool.data.orientation === "vertical" ? "horizontal" : "vertical";
282
711
  }
@@ -366,6 +795,14 @@ function validateBpmnConnectionForEdgeType(state, edgeType, source, target) {
366
795
  }
367
796
  return true;
368
797
  }
798
+ function resolveBpmnConnection(state, sourceId, targetId, requestedType) {
799
+ const source = getNode(state, sourceId);
800
+ const target = getNode(state, targetId);
801
+ if (!source || !target) return { ok: false, reason: "No se encontr\xF3 el origen o destino." };
802
+ const validation = validateBpmnConnectionForEdgeType(state, requestedType, source, target);
803
+ if (validation !== true) return { ok: false, reason: validation };
804
+ return { ok: true, edgeType: requestedType };
805
+ }
369
806
  function validateEdgeCardinality(state, edgeType, source, target) {
370
807
  if (edgeType !== "sequenceFlow") return true;
371
808
  const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
@@ -553,6 +990,28 @@ function reparentBpmnNodeAtPosition(state, options) {
553
990
  });
554
991
  }
555
992
  var BE_HALF = 18;
993
+ function getBoundarySpanRatio(value, size) {
994
+ const min = BE_HALF;
995
+ const max = size - BE_HALF;
996
+ if (max <= min) return 0.5;
997
+ return (clampBoundaryCoordinate(value, min, max) - min) / (max - min);
998
+ }
999
+ function fromBoundarySpanRatio(ratio, size) {
1000
+ const min = BE_HALF;
1001
+ const max = size - BE_HALF;
1002
+ if (max <= min) return size / 2;
1003
+ return min + (max - min) * ratio;
1004
+ }
1005
+ function detectBoundarySide(center, hostSize) {
1006
+ const distances = [
1007
+ { side: "left", value: Math.abs(center.x) },
1008
+ { side: "right", value: Math.abs(center.x - hostSize.width) },
1009
+ { side: "top", value: Math.abs(center.y) },
1010
+ { side: "bottom", value: Math.abs(center.y - hostSize.height) }
1011
+ ];
1012
+ distances.sort((a, b) => a.value - b.value);
1013
+ return distances[0]?.side ?? "bottom";
1014
+ }
556
1015
  function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
557
1016
  const boundaryEvents = state.nodes.filter(
558
1017
  (n) => n.data.elementType === "BoundaryEvent" && n.parentId === hostId
@@ -563,25 +1022,21 @@ function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
563
1022
  const py = be.position?.y ?? 0;
564
1023
  const cx = px + BE_HALF;
565
1024
  const cy = py + BE_HALF;
566
- const distLeft = Math.abs(cx);
567
- const distRight = Math.abs(cx - oldW);
568
- const distTop = Math.abs(cy);
569
- const distBottom = Math.abs(cy - oldH);
570
- const minDist = Math.min(distLeft, distRight, distTop, distBottom);
1025
+ const side = detectBoundarySide({ x: cx, y: cy }, { width: oldW, height: oldH });
571
1026
  let newCx;
572
1027
  let newCy;
573
- if (minDist === distBottom) {
1028
+ if (side === "bottom") {
574
1029
  newCy = newH;
575
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
576
- } else if (minDist === distRight) {
1030
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
1031
+ } else if (side === "right") {
577
1032
  newCx = newW;
578
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
579
- } else if (minDist === distTop) {
1033
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
1034
+ } else if (side === "top") {
580
1035
  newCy = 0;
581
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
1036
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
582
1037
  } else {
583
1038
  newCx = 0;
584
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
1039
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
585
1040
  }
586
1041
  next = moveNode(next, be.id, { x: newCx - BE_HALF, y: newCy - BE_HALF });
587
1042
  }
@@ -845,6 +1300,6 @@ function withBpmnLayoutCache(layoutFn, cache) {
845
1300
  return withLayoutCache(layoutFn, cache ?? createLayoutCache());
846
1301
  }
847
1302
 
848
- export { BPMN_EDGE_CONNECTION_RULES, BPMN_MODELING_RULES, BPMN_POOL_LANE_LAYOUT, BPMN_ROUTABLE_EDGE_TYPES, BPMN_SELECTION_STYLE, attachBoundaryEventCommand, bpmnConnectionValidators, canContainBpmnElement, computeBpmnSmartGuides, connectBpmnCommand, copyBpmnElements, createBpmnDiagramDocument, createBpmnEventBus, createBpmnLayoutCache, createBpmnNode, createBpmnNodeCommand, deleteBpmnElementsCommand, deserializeBpmnDiagram, deserializeBpmnDiagramSnapshot, findBpmnContainerAt, getBpmnDragHandleSelector, getBpmnEdgeLabelLayout, getBpmnLaneIndexAtPosition, getBpmnNodeAbsolutePosition, getBpmnNodeCenter, getBpmnNodeSize, getBpmnNodeZIndex, getBpmnPoolLanes, getBpmnTabOrder, groupAsBpmnSubProcessCommand, inferBpmnEdgeType, isBpmnDroppableInContainer, isBpmnEdgeRoutingEditable, isBpmnProcessNode, layoutBpmnPoolLaneNodes, layoutBpmnPoolLanes, moveBpmnLaneCommand, parseBpmnDiagramDocument, pasteBpmnElementsCommand, persistBpmnHistory, reorderBpmnLane, reorderBpmnLaneAfterDrop, reorderBpmnLaneCommand, reparentBpmnNodeAtPosition, reparentBpmnNodeCommand, replaceBpmnNodeCommand, resizeBpmnNodeByHandleCommand, resizeBpmnNodeCommand, restoreBpmnHistory, routeBpmnEdgeCommand, runBpmnCommand, runBpmnCommands, selectBpmnElementsCommand, serializeBpmnDiagram, toBpmnRelativePosition, validateBpmnConnectionForEdgeType, withBpmnLayoutCache, withBpmnNodeZIndexes };
849
- //# sourceMappingURL=chunk-UAWLUDKC.js.map
850
- //# sourceMappingURL=chunk-UAWLUDKC.js.map
1303
+ export { BPMN_EDGE_CONNECTION_RULES, BPMN_MODELING_RULES, BPMN_POOL_LANE_LAYOUT, BPMN_POOL_LANE_STACK_LAYOUT, BPMN_ROUTABLE_EDGE_TYPES, BPMN_SELECTION_STYLE, applyBpmnPoolLaneDimensionChange, attachBoundaryEventCommand, bpmnConnectionValidators, canContainBpmnElement, computeBpmnSmartGuides, connectBpmnCommand, copyBpmnElements, createBpmnDiagramDocument, createBpmnEventBus, createBpmnLayoutCache, createBpmnNode, createBpmnNodeCommand, deleteBpmnElementsCommand, deserializeBpmnDiagram, deserializeBpmnDiagramSnapshot, findBpmnContainerAt, getAppendedBpmnLaneFrame, getBoundaryEventAttachment, getBpmnDragHandleSelector, getBpmnEdgeLabelLayout, getBpmnEdgeLaneContext, getBpmnLaneIndexAtPosition, getBpmnNodeAbsolutePosition, getBpmnNodeCenter, getBpmnNodeSize, getBpmnNodeZIndex, getBpmnPoolLaneNodeMaxSize, getBpmnPoolLaneNodeMinSize, getBpmnPoolLanes, getBpmnPoolOrientation, getBpmnTabOrder, groupAsBpmnSubProcessCommand, inferBpmnEdgeType, isBpmnDroppableInContainer, isBpmnEdgeRoutingEditable, isBpmnProcessNode, layoutBpmnPoolLaneNodes, layoutBpmnPoolLaneNodesPreservingHeights, layoutBpmnPoolLanes, moveBpmnLaneCommand, parseBpmnDiagramDocument, pasteBpmnElementsCommand, persistBpmnHistory, reorderBpmnLane, reorderBpmnLaneAfterDrop, reorderBpmnLaneCommand, reorderBpmnPoolLaneAfterDropPreservingHeights, reparentBpmnNodeAtPosition, reparentBpmnNodeCommand, replaceBpmnNodeCommand, resizeBpmnNodeByHandleCommand, resizeBpmnNodeCommand, resolveBpmnConnection, resolveBpmnDropTarget, restoreBpmnHistory, routeBpmnEdgeCommand, runBpmnCommand, runBpmnCommands, selectBpmnElementsCommand, serializeBpmnDiagram, toBpmnRelativePosition, validateBpmnConnectionForEdgeType, withBpmnLayoutCache, withBpmnNodeZIndexes };
1304
+ //# sourceMappingURL=chunk-YAYZW45I.js.map
1305
+ //# sourceMappingURL=chunk-YAYZW45I.js.map