@aranzatech/diagrams-bpmn 0.2.0 → 0.2.1

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 (63) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/catalog-OVnBDD8R.d.ts +9 -0
  3. package/dist/catalog-OWfI_yHU.d.cts +9 -0
  4. package/dist/{chunk-MF2WE3OM.js → chunk-33AR3PXF.js} +36 -8
  5. package/dist/chunk-33AR3PXF.js.map +1 -0
  6. package/dist/{chunk-3AFZDIMQ.js → chunk-ECTJRD7Z.js} +3 -3
  7. package/dist/{chunk-3AFZDIMQ.js.map → chunk-ECTJRD7Z.js.map} +1 -1
  8. package/dist/{chunk-S3GGEEA5.js → chunk-H3YMTGFG.js} +50 -32
  9. package/dist/chunk-H3YMTGFG.js.map +1 -0
  10. package/dist/chunk-KALSGH4D.js +36 -0
  11. package/dist/chunk-KALSGH4D.js.map +1 -0
  12. package/dist/{chunk-DNR5WBQH.js → chunk-L5Z22RLX.js} +81 -20
  13. package/dist/chunk-L5Z22RLX.js.map +1 -0
  14. package/dist/{chunk-5GRCJ5X6.js → chunk-RLAJNRF2.js} +3 -3
  15. package/dist/{chunk-5GRCJ5X6.js.map → chunk-RLAJNRF2.js.map} +1 -1
  16. package/dist/chunk-YQTIODXH.js +532 -0
  17. package/dist/chunk-YQTIODXH.js.map +1 -0
  18. package/dist/chunk-ZFGQVLHB.js +226 -0
  19. package/dist/chunk-ZFGQVLHB.js.map +1 -0
  20. package/dist/edges/index.cjs +1 -1
  21. package/dist/edges/index.cjs.map +1 -1
  22. package/dist/edges/index.js +2 -2
  23. package/dist/elements/index.cjs +81 -17
  24. package/dist/elements/index.cjs.map +1 -1
  25. package/dist/elements/index.d.cts +4 -6
  26. package/dist/elements/index.d.ts +4 -6
  27. package/dist/elements/index.js +2 -2
  28. package/dist/index.cjs +689 -75
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +6 -4
  31. package/dist/index.d.ts +6 -4
  32. package/dist/index.js +8 -7
  33. package/dist/modeling/index.cjs +383 -36
  34. package/dist/modeling/index.cjs.map +1 -1
  35. package/dist/modeling/index.d.cts +61 -3
  36. package/dist/modeling/index.d.ts +61 -3
  37. package/dist/modeling/index.js +3 -3
  38. package/dist/nodes/index.cjs +62 -32
  39. package/dist/nodes/index.cjs.map +1 -1
  40. package/dist/nodes/index.js +2 -2
  41. package/dist/{types-hj621ZRJ.d.ts → types-BxjCV2oX.d.ts} +1 -1
  42. package/dist/{types-BKA0GZz5.d.cts → types-DznxZxpV.d.cts} +11 -1
  43. package/dist/{types-BKA0GZz5.d.ts → types-DznxZxpV.d.ts} +11 -1
  44. package/dist/{types-CCkHqtC_.d.cts → types-vVi5T7qj.d.cts} +1 -1
  45. package/dist/validation/index.cjs +848 -0
  46. package/dist/validation/index.cjs.map +1 -0
  47. package/dist/validation/index.d.cts +25 -0
  48. package/dist/validation/index.d.ts +25 -0
  49. package/dist/validation/index.js +5 -0
  50. package/dist/validation/index.js.map +1 -0
  51. package/dist/xml/index.cjs +74 -22
  52. package/dist/xml/index.cjs.map +1 -1
  53. package/dist/xml/index.d.cts +2 -2
  54. package/dist/xml/index.d.ts +2 -2
  55. package/dist/xml/index.js +2 -2
  56. package/package.json +8 -3
  57. package/dist/chunk-23B2IGK5.js +0 -24
  58. package/dist/chunk-23B2IGK5.js.map +0 -1
  59. package/dist/chunk-DNR5WBQH.js.map +0 -1
  60. package/dist/chunk-G5S4ASP3.js +0 -277
  61. package/dist/chunk-G5S4ASP3.js.map +0 -1
  62. package/dist/chunk-MF2WE3OM.js.map +0 -1
  63. package/dist/chunk-S3GGEEA5.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -43,7 +43,7 @@ var BPMN_ELEMENT_CATALOG = {
43
43
  },
44
44
  IntermediateCatchEvent: {
45
45
  label: "Intermediate Catch Event",
46
- icon: "Clock",
46
+ icon: "Clock3",
47
47
  category: "event",
48
48
  defaultWidth: 36,
49
49
  defaultHeight: 36,
@@ -57,7 +57,7 @@ var BPMN_ELEMENT_CATALOG = {
57
57
  },
58
58
  IntermediateThrowEvent: {
59
59
  label: "Intermediate Throw Event",
60
- icon: "Zap",
60
+ icon: "Send",
61
61
  category: "event",
62
62
  defaultWidth: 36,
63
63
  defaultHeight: 36,
@@ -71,7 +71,7 @@ var BPMN_ELEMENT_CATALOG = {
71
71
  },
72
72
  BoundaryEvent: {
73
73
  label: "Boundary Event",
74
- icon: "AlertCircle",
74
+ icon: "AlarmClock",
75
75
  category: "event",
76
76
  defaultWidth: 36,
77
77
  defaultHeight: 36,
@@ -87,7 +87,7 @@ var BPMN_ELEMENT_CATALOG = {
87
87
  // ─── Tasks ───────────────────────────────────────────────────────────────────
88
88
  Task: {
89
89
  label: "Task",
90
- icon: "Square",
90
+ icon: "CheckSquare",
91
91
  category: "task",
92
92
  defaultWidth: 120,
93
93
  defaultHeight: 60,
@@ -101,7 +101,7 @@ var BPMN_ELEMENT_CATALOG = {
101
101
  },
102
102
  UserTask: {
103
103
  label: "User Task",
104
- icon: "User",
104
+ icon: "UserRound",
105
105
  category: "task",
106
106
  defaultWidth: 120,
107
107
  defaultHeight: 60,
@@ -115,7 +115,7 @@ var BPMN_ELEMENT_CATALOG = {
115
115
  },
116
116
  ServiceTask: {
117
117
  label: "Service Task",
118
- icon: "Settings",
118
+ icon: "Cog",
119
119
  category: "task",
120
120
  defaultWidth: 120,
121
121
  defaultHeight: 60,
@@ -157,7 +157,7 @@ var BPMN_ELEMENT_CATALOG = {
157
157
  },
158
158
  BusinessRuleTask: {
159
159
  label: "Business Rule Task",
160
- icon: "Scale",
160
+ icon: "Table2",
161
161
  category: "task",
162
162
  defaultWidth: 120,
163
163
  defaultHeight: 60,
@@ -171,7 +171,7 @@ var BPMN_ELEMENT_CATALOG = {
171
171
  },
172
172
  ReceiveTask: {
173
173
  label: "Receive Task",
174
- icon: "Mail",
174
+ icon: "Inbox",
175
175
  category: "task",
176
176
  defaultWidth: 120,
177
177
  defaultHeight: 60,
@@ -214,7 +214,7 @@ var BPMN_ELEMENT_CATALOG = {
214
214
  // ─── Gateways ────────────────────────────────────────────────────────────────
215
215
  ExclusiveGateway: {
216
216
  label: "Exclusive Gateway",
217
- icon: "GitBranch",
217
+ icon: "X",
218
218
  category: "gateway",
219
219
  defaultWidth: 50,
220
220
  defaultHeight: 50,
@@ -227,7 +227,7 @@ var BPMN_ELEMENT_CATALOG = {
227
227
  },
228
228
  InclusiveGateway: {
229
229
  label: "Inclusive Gateway",
230
- icon: "GitMerge",
230
+ icon: "Circle",
231
231
  category: "gateway",
232
232
  defaultWidth: 50,
233
233
  defaultHeight: 50,
@@ -240,7 +240,7 @@ var BPMN_ELEMENT_CATALOG = {
240
240
  },
241
241
  ParallelGateway: {
242
242
  label: "Parallel Gateway",
243
- icon: "GitFork",
243
+ icon: "Plus",
244
244
  category: "gateway",
245
245
  defaultWidth: 50,
246
246
  defaultHeight: 50,
@@ -281,7 +281,7 @@ var BPMN_ELEMENT_CATALOG = {
281
281
  // ─── Containers ───────────────────────────────────────────────────────────────
282
282
  SubProcess: {
283
283
  label: "Sub-Process",
284
- icon: "Layout",
284
+ icon: "PlusSquare",
285
285
  category: "container",
286
286
  defaultWidth: 350,
287
287
  defaultHeight: 200,
@@ -296,7 +296,7 @@ var BPMN_ELEMENT_CATALOG = {
296
296
  },
297
297
  Transaction: {
298
298
  label: "Transaction",
299
- icon: "CreditCard",
299
+ icon: "Receipt",
300
300
  category: "container",
301
301
  defaultWidth: 350,
302
302
  defaultHeight: 200,
@@ -311,7 +311,7 @@ var BPMN_ELEMENT_CATALOG = {
311
311
  },
312
312
  EventSubProcess: {
313
313
  label: "Event Sub-Process",
314
- icon: "Workflow",
314
+ icon: "CircleDotDashed",
315
315
  category: "container",
316
316
  defaultWidth: 350,
317
317
  defaultHeight: 200,
@@ -326,7 +326,7 @@ var BPMN_ELEMENT_CATALOG = {
326
326
  },
327
327
  AdHocSubProcess: {
328
328
  label: "Ad-Hoc Sub-Process",
329
- icon: "Shuffle",
329
+ icon: "Waves",
330
330
  category: "container",
331
331
  defaultWidth: 350,
332
332
  defaultHeight: 200,
@@ -341,7 +341,7 @@ var BPMN_ELEMENT_CATALOG = {
341
341
  },
342
342
  Pool: {
343
343
  label: "Pool",
344
- icon: "Columns",
344
+ icon: "Rows3",
345
345
  category: "container",
346
346
  defaultWidth: 600,
347
347
  defaultHeight: 200,
@@ -356,7 +356,7 @@ var BPMN_ELEMENT_CATALOG = {
356
356
  },
357
357
  Lane: {
358
358
  label: "Lane",
359
- icon: "AlignJustify",
359
+ icon: "PanelTop",
360
360
  category: "container",
361
361
  defaultWidth: 600,
362
362
  defaultHeight: 120,
@@ -575,6 +575,67 @@ var BPMN_ELEMENT_CATALOG = {
575
575
  function getElementMeta(type) {
576
576
  return BPMN_ELEMENT_CATALOG[type];
577
577
  }
578
+ var BPMN_RESIZABLE_ELEMENT_TYPES = [
579
+ "Task",
580
+ "UserTask",
581
+ "ServiceTask",
582
+ "ScriptTask",
583
+ "ManualTask",
584
+ "BusinessRuleTask",
585
+ "ReceiveTask",
586
+ "SendTask",
587
+ "CallActivity",
588
+ "SubProcess",
589
+ "Transaction",
590
+ "EventSubProcess",
591
+ "AdHocSubProcess",
592
+ "Pool",
593
+ "Lane",
594
+ "Annotation",
595
+ "Group",
596
+ "SubConversation",
597
+ "ChoreographyTask",
598
+ "SubChoreography",
599
+ "CallChoreography"
600
+ ];
601
+ var BPMN_MIN_SIZE_OVERRIDES = {
602
+ Task: { minWidth: 80, minHeight: 48 },
603
+ UserTask: { minWidth: 80, minHeight: 48 },
604
+ ServiceTask: { minWidth: 80, minHeight: 48 },
605
+ ScriptTask: { minWidth: 80, minHeight: 48 },
606
+ ManualTask: { minWidth: 80, minHeight: 48 },
607
+ BusinessRuleTask: { minWidth: 80, minHeight: 48 },
608
+ ReceiveTask: { minWidth: 80, minHeight: 48 },
609
+ SendTask: { minWidth: 80, minHeight: 48 },
610
+ CallActivity: { minWidth: 80, minHeight: 48 },
611
+ SubProcess: { minWidth: 160, minHeight: 100 },
612
+ Transaction: { minWidth: 160, minHeight: 100 },
613
+ EventSubProcess: { minWidth: 160, minHeight: 100 },
614
+ AdHocSubProcess: { minWidth: 160, minHeight: 100 },
615
+ Pool: { minWidth: 240, minHeight: 120 },
616
+ Lane: { minWidth: 240, minHeight: 80 },
617
+ Annotation: { minWidth: 80, minHeight: 40 },
618
+ Group: { minWidth: 120, minHeight: 80 },
619
+ SubConversation: { minWidth: 60, minHeight: 52 },
620
+ ChoreographyTask: { minWidth: 100, minHeight: 70 },
621
+ SubChoreography: { minWidth: 100, minHeight: 70 },
622
+ CallChoreography: { minWidth: 100, minHeight: 70 }
623
+ };
624
+ var resizableTypes = new Set(BPMN_RESIZABLE_ELEMENT_TYPES);
625
+ function isBpmnElementResizable(type) {
626
+ return resizableTypes.has(type);
627
+ }
628
+ function getBpmnElementSize(type) {
629
+ const meta = getElementMeta(type);
630
+ const min = BPMN_MIN_SIZE_OVERRIDES[type];
631
+ return {
632
+ width: meta.defaultWidth,
633
+ height: meta.defaultHeight,
634
+ minWidth: meta.minWidth ?? min?.minWidth ?? meta.defaultWidth,
635
+ minHeight: meta.minHeight ?? min?.minHeight ?? meta.defaultHeight,
636
+ resizable: meta.resizable ?? isBpmnElementResizable(type)
637
+ };
638
+ }
578
639
 
579
640
  // src/elements/guards.ts
580
641
  var TASK_TYPES = /* @__PURE__ */ new Set([
@@ -698,13 +759,19 @@ function BpmnHandles({ variant = "all" }) {
698
759
  // src/nodes/shared/theme.ts
699
760
  var BPMN_THEME = {
700
761
  fill: "#ffffff",
701
- stroke: "#404040",
702
- strokeSelected: "#1a56db",
762
+ fillSoft: "#f8fbff",
763
+ fillSubtle: "#eef6ff",
764
+ stroke: "#334155",
765
+ strokeSelected: "#2563eb",
703
766
  strokeWidth: 1.5,
704
767
  strokeWidthSelected: 2.5,
705
768
  fontFamily: "Inter, system-ui, sans-serif",
706
769
  fontSize: 11,
707
- labelColor: "#1a1a1a"};
770
+ labelColor: "#0f172a",
771
+ shadow: "0 4px 12px rgba(15, 23, 42, 0.08)",
772
+ shadowSelected: "0 0 0 4px rgba(37, 99, 235, 0.14), 0 8px 18px rgba(15, 23, 42, 0.12)",
773
+ transition: "box-shadow 140ms ease, filter 140ms ease, transform 140ms ease"
774
+ };
708
775
  function resolveStroke(selected, override) {
709
776
  if (selected) return BPMN_THEME.strokeSelected;
710
777
  return override ?? BPMN_THEME.stroke;
@@ -712,6 +779,12 @@ function resolveStroke(selected, override) {
712
779
  function resolveStrokeWidth(selected) {
713
780
  return selected ? BPMN_THEME.strokeWidthSelected : BPMN_THEME.strokeWidth;
714
781
  }
782
+ function resolveShapeFilter(selected) {
783
+ return selected ? "drop-shadow(0 0 0 rgba(37,99,235,0.2)) drop-shadow(0 8px 14px rgba(15,23,42,0.12))" : "drop-shadow(0 4px 10px rgba(15,23,42,0.08))";
784
+ }
785
+ function resolveNodeShadow(selected) {
786
+ return selected ? BPMN_THEME.shadowSelected : BPMN_THEME.shadow;
787
+ }
715
788
  var EXTERNAL_STYLE = {
716
789
  position: "absolute",
717
790
  top: "100%",
@@ -864,7 +937,7 @@ function StartEventNode({ data, selected }) {
864
937
  const trigger = d.trigger ?? "none";
865
938
  const dashArray = d.isNonInterrupting ? "4 2" : void 0;
866
939
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE, height: SIZE, position: "relative" }, children: [
867
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE, height: SIZE, style: { overflow: "visible", display: "block" }, children: [
940
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE, height: SIZE, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
868
941
  /* @__PURE__ */ jsxRuntime.jsx(
869
942
  "circle",
870
943
  {
@@ -893,7 +966,7 @@ function EndEventNode({ data, selected }) {
893
966
  const fill = d.color?.fill ?? BPMN_THEME.fill;
894
967
  const trigger = d.trigger ?? "none";
895
968
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE2, height: SIZE2, position: "relative" }, children: [
896
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE2, height: SIZE2, style: { overflow: "visible", display: "block" }, children: [
969
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE2, height: SIZE2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
897
970
  /* @__PURE__ */ jsxRuntime.jsx(
898
971
  "circle",
899
972
  {
@@ -921,9 +994,9 @@ function IntermediateCatchEventNode({ data, selected }) {
921
994
  const stroke = resolveStroke(selected, d.color?.stroke);
922
995
  const sw = resolveStrokeWidth(selected);
923
996
  const fill = d.color?.fill ?? BPMN_THEME.fill;
924
- const trigger = d.trigger ?? "none";
997
+ const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "timer";
925
998
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
926
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
999
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
927
1000
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_OUTER, fill, stroke, strokeWidth: sw }),
928
1001
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_INNER, fill: "none", stroke, strokeWidth: sw }),
929
1002
  /* @__PURE__ */ jsxRuntime.jsx(EventMarker, { cx: CX3, cy: CX3, trigger, filled: false, stroke, bg: fill, r: ICON_R })
@@ -937,9 +1010,9 @@ function IntermediateThrowEventNode({ data, selected }) {
937
1010
  const stroke = resolveStroke(selected, d.color?.stroke);
938
1011
  const sw = resolveStrokeWidth(selected);
939
1012
  const fill = d.color?.fill ?? BPMN_THEME.fill;
940
- const trigger = d.trigger ?? "none";
1013
+ const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "message";
941
1014
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
942
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
1015
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
943
1016
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_OUTER, fill, stroke, strokeWidth: sw }),
944
1017
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_INNER, fill: stroke, stroke, strokeWidth: sw }),
945
1018
  /* @__PURE__ */ jsxRuntime.jsx(EventMarker, { cx: CX3, cy: CX3, trigger, filled: true, stroke: fill, bg: stroke, r: ICON_R })
@@ -953,10 +1026,10 @@ function BoundaryEventNode({ data, selected }) {
953
1026
  const stroke = resolveStroke(selected, d.color?.stroke);
954
1027
  const sw = resolveStrokeWidth(selected);
955
1028
  const fill = d.color?.fill ?? BPMN_THEME.fill;
956
- const trigger = d.trigger ?? "none";
1029
+ const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "timer";
957
1030
  const dashArray = d.isNonInterrupting ? "4 2" : void 0;
958
1031
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
959
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
1032
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
960
1033
  /* @__PURE__ */ jsxRuntime.jsx(
961
1034
  "circle",
962
1035
  {
@@ -991,6 +1064,11 @@ function TaskIcon({ type, size = 14, color = "#404040" }) {
991
1064
  const s = size;
992
1065
  const c = color;
993
1066
  switch (type) {
1067
+ case "Task":
1068
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none", children: [
1069
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "10", height: "10", rx: "1.5", stroke: c, strokeWidth: "1.5" }),
1070
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 8.2 7.2 10 10.8 6", stroke: c, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
1071
+ ] });
994
1072
  case "UserTask":
995
1073
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none", children: [
996
1074
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5", r: "3", stroke: c, strokeWidth: "1.5" }),
@@ -1133,20 +1211,22 @@ function TaskNode({ data, selected }) {
1133
1211
  style: {
1134
1212
  width: "100%",
1135
1213
  height: "100%",
1136
- background: d.color?.fill ?? BPMN_THEME.fill,
1214
+ background: d.color?.fill ?? `linear-gradient(180deg, ${BPMN_THEME.fill} 0%, ${BPMN_THEME.fillSoft} 100%)`,
1137
1215
  border: `${borderWidth}px solid ${stroke}`,
1138
- borderRadius: 6,
1216
+ borderRadius: 7,
1139
1217
  boxSizing: "border-box",
1218
+ boxShadow: resolveNodeShadow(selected),
1140
1219
  display: "flex",
1141
1220
  flexDirection: "column",
1142
1221
  alignItems: "center",
1143
1222
  justifyContent: "center",
1144
1223
  padding: hasMarkers ? "4px 8px 22px" : "4px 8px",
1145
1224
  position: "relative",
1146
- fontFamily: BPMN_THEME.fontFamily
1225
+ fontFamily: BPMN_THEME.fontFamily,
1226
+ transition: BPMN_THEME.transition
1147
1227
  },
1148
1228
  children: [
1149
- d.elementType && d.elementType !== "Task" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", top: 5, left: 5 }, children: /* @__PURE__ */ jsxRuntime.jsx(TaskIcon, { type: d.elementType, size: 14, color: stroke }) }),
1229
+ d.elementType && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", top: 5, left: 5 }, children: /* @__PURE__ */ jsxRuntime.jsx(TaskIcon, { type: d.elementType, size: 14, color: stroke }) }),
1150
1230
  /* @__PURE__ */ jsxRuntime.jsx(BpmnLabel, { style: { width: "100%" }, children: d.label ?? d.elementType }),
1151
1231
  d.priority && /* @__PURE__ */ jsxRuntime.jsx(
1152
1232
  "div",
@@ -1224,7 +1304,7 @@ function GatewayNode({ data, selected }) {
1224
1304
  const stroke = resolveStroke(selected, d.color?.stroke);
1225
1305
  const sw = resolveStrokeWidth(selected);
1226
1306
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE4, height: SIZE4, position: "relative" }, children: [
1227
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE4, height: SIZE4, style: { overflow: "visible", display: "block" }, children: [
1307
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE4, height: SIZE4, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1228
1308
  /* @__PURE__ */ jsxRuntime.jsx(
1229
1309
  "polygon",
1230
1310
  {
@@ -1267,12 +1347,14 @@ function SubProcessNode({ data, selected }) {
1267
1347
  style: {
1268
1348
  width: "100%",
1269
1349
  height: "100%",
1270
- background: d.color?.fill ?? "#f8faff",
1350
+ background: d.color?.fill ?? `linear-gradient(180deg, ${BPMN_THEME.fill} 0%, ${BPMN_THEME.fillSubtle} 100%)`,
1271
1351
  border: `${sw}px ${borderStyle} ${stroke}`,
1272
1352
  borderRadius: 6,
1273
1353
  boxSizing: "border-box",
1354
+ boxShadow: resolveNodeShadow(selected),
1274
1355
  position: "relative",
1275
- fontFamily: BPMN_THEME.fontFamily
1356
+ fontFamily: BPMN_THEME.fontFamily,
1357
+ transition: BPMN_THEME.transition
1276
1358
  },
1277
1359
  children: [
1278
1360
  variant === "transaction" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1326,8 +1408,8 @@ function PoolNode({ data, selected }) {
1326
1408
  const stroke = resolveStroke(selected, d.color?.stroke);
1327
1409
  const sw = resolveStrokeWidth(selected);
1328
1410
  const orientation = d.orientation ?? "horizontal";
1329
- const fill = d.color?.fill ?? "#f5f7ff";
1330
- const headerFill = d.color?.fill ?? "#edf0ff";
1411
+ const fill = d.color?.fill ?? "#f8fbff";
1412
+ const headerFill = d.color?.fill ?? "#eaf2ff";
1331
1413
  if (orientation === "vertical") {
1332
1414
  return /* @__PURE__ */ jsxRuntime.jsxs(
1333
1415
  "div",
@@ -1341,8 +1423,10 @@ function PoolNode({ data, selected }) {
1341
1423
  borderRadius: 4,
1342
1424
  boxSizing: "border-box",
1343
1425
  background: fill,
1426
+ boxShadow: resolveNodeShadow(selected),
1344
1427
  overflow: "hidden",
1345
- fontFamily: BPMN_THEME.fontFamily
1428
+ fontFamily: BPMN_THEME.fontFamily,
1429
+ transition: BPMN_THEME.transition
1346
1430
  },
1347
1431
  children: [
1348
1432
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1393,14 +1477,17 @@ function PoolNode({ data, selected }) {
1393
1477
  borderRadius: 4,
1394
1478
  boxSizing: "border-box",
1395
1479
  background: fill,
1480
+ boxShadow: resolveNodeShadow(selected),
1396
1481
  overflow: "hidden",
1397
- fontFamily: BPMN_THEME.fontFamily
1482
+ fontFamily: BPMN_THEME.fontFamily,
1483
+ transition: BPMN_THEME.transition
1398
1484
  },
1399
1485
  children: [
1400
1486
  /* @__PURE__ */ jsxRuntime.jsx(
1401
1487
  "div",
1402
1488
  {
1403
1489
  "aria-label": "pool-header",
1490
+ className: "pool-drag-handle",
1404
1491
  style: {
1405
1492
  width: HEADER_WIDTH,
1406
1493
  minWidth: HEADER_WIDTH,
@@ -1442,8 +1529,8 @@ function LaneNode({ data, selected }) {
1442
1529
  const stroke = resolveStroke(selected, d.color?.stroke);
1443
1530
  const sw = resolveStrokeWidth(selected);
1444
1531
  const orientation = d.orientation ?? "horizontal";
1445
- const fill = d.color?.fill ?? "#fafbff";
1446
- const headerFill = d.color?.fill ?? "#f0f3ff";
1532
+ const fill = d.color?.fill ?? "#fbfdff";
1533
+ const headerFill = d.color?.fill ?? "#eef6ff";
1447
1534
  if (orientation === "vertical") {
1448
1535
  return /* @__PURE__ */ jsxRuntime.jsxs(
1449
1536
  "div",
@@ -1456,8 +1543,10 @@ function LaneNode({ data, selected }) {
1456
1543
  borderRadius: 2,
1457
1544
  boxSizing: "border-box",
1458
1545
  background: fill,
1546
+ boxShadow: resolveNodeShadow(selected),
1459
1547
  overflow: "hidden",
1460
- fontFamily: BPMN_THEME.fontFamily
1548
+ fontFamily: BPMN_THEME.fontFamily,
1549
+ transition: BPMN_THEME.transition
1461
1550
  },
1462
1551
  children: [
1463
1552
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1512,8 +1601,10 @@ function LaneNode({ data, selected }) {
1512
1601
  borderRadius: 2,
1513
1602
  boxSizing: "border-box",
1514
1603
  background: fill,
1604
+ boxShadow: resolveNodeShadow(selected),
1515
1605
  overflow: "hidden",
1516
- fontFamily: BPMN_THEME.fontFamily
1606
+ fontFamily: BPMN_THEME.fontFamily,
1607
+ transition: BPMN_THEME.transition
1517
1608
  },
1518
1609
  children: [
1519
1610
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1649,7 +1740,7 @@ function DataObjectNode({ data, selected }) {
1649
1740
  `L ${W} ${FOLD}`
1650
1741
  ].join(" ");
1651
1742
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W, height: H2, position: "relative" }, children: [
1652
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W, height: H2, style: { overflow: "visible", display: "block" }, children: [
1743
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W, height: H2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1653
1744
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: path, fill, stroke, strokeWidth: sw }),
1654
1745
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath2, fill: "none", stroke, strokeWidth: sw })
1655
1746
  ] }),
@@ -1667,7 +1758,7 @@ function DataStoreNode({ data, selected }) {
1667
1758
  const sw = resolveStrokeWidth(selected);
1668
1759
  const fill = d.color?.fill ?? BPMN_THEME.fill;
1669
1760
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: DS_W, height: DS_H, position: "relative" }, children: [
1670
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W, height: DS_H, style: { overflow: "visible", display: "block" }, children: [
1761
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W, height: DS_H, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1671
1762
  /* @__PURE__ */ jsxRuntime.jsx(
1672
1763
  "path",
1673
1764
  {
@@ -1713,7 +1804,7 @@ function DataObjectReferenceNode({ data, selected }) {
1713
1804
  const sw = resolveStrokeWidth(selected);
1714
1805
  const fill = d.color?.fill ?? BPMN_THEME.fill;
1715
1806
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
1716
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
1807
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1717
1808
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
1718
1809
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
1719
1810
  d.isCollection && collectionLines(stroke, sw)
@@ -1728,7 +1819,7 @@ function DataInputNode({ data, selected }) {
1728
1819
  const sw = resolveStrokeWidth(selected);
1729
1820
  const fill = d.color?.fill ?? BPMN_THEME.fill;
1730
1821
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
1731
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
1822
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1732
1823
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
1733
1824
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
1734
1825
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1752,7 +1843,7 @@ function DataOutputNode({ data, selected }) {
1752
1843
  const sw = resolveStrokeWidth(selected);
1753
1844
  const fill = d.color?.fill ?? BPMN_THEME.fill;
1754
1845
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
1755
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
1846
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1756
1847
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
1757
1848
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
1758
1849
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1780,7 +1871,7 @@ function DataStoreReferenceNode({ data, selected }) {
1780
1871
  const sw = resolveStrokeWidth(selected);
1781
1872
  const fill = d.color?.fill ?? BPMN_THEME.fill;
1782
1873
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: DS_W2, height: DS_H2, position: "relative" }, children: [
1783
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W2, height: DS_H2, style: { overflow: "visible", display: "block" }, children: [
1874
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W2, height: DS_H2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
1784
1875
  /* @__PURE__ */ jsxRuntime.jsx(
1785
1876
  "path",
1786
1877
  {
@@ -2897,9 +2988,15 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
2897
2988
  }
2898
2989
  return false;
2899
2990
  };
2900
- const myNodes = (poolId ? allNodes.filter(
2901
- (n) => n.parentId === poolId || laneNodes.some((l) => l.id === n.parentId && l.parentId === poolId)
2902
- ) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
2991
+ const belongsToPool = (node) => {
2992
+ let parentId = node.parentId;
2993
+ while (parentId) {
2994
+ if (parentId === poolId) return true;
2995
+ parentId = allNodes.find((candidate) => candidate.id === parentId)?.parentId;
2996
+ }
2997
+ return false;
2998
+ };
2999
+ const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
2903
3000
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
2904
3001
  const flowElements = [];
2905
3002
  for (const node of myNodes) {
@@ -2969,8 +3066,8 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
2969
3066
  attrs.attachedToRef = { id: node.data.attachedToRef ?? node.parentId };
2970
3067
  attrs.cancelActivity = node.data.isNonInterrupting ? false : true;
2971
3068
  }
2972
- const isSubProcess2 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
2973
- if (isSubProcess2) {
3069
+ const isSubProcess3 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
3070
+ if (isSubProcess3) {
2974
3071
  attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
2975
3072
  if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
2976
3073
  attrs.triggeredByEvent = true;
@@ -3041,9 +3138,9 @@ function buildBpmnDI(moddle, definitions, nodes, edges) {
3041
3138
  shapes.push(shape);
3042
3139
  }
3043
3140
  for (const edge of edges) {
3044
- const waypoints = edge.data?.routingPoints?.map(
3141
+ const waypoints = resolveEdgeWaypoints(edge, nodes, absolutePositionById).map(
3045
3142
  (p) => moddle.create("dc:Point", { x: p.x, y: p.y })
3046
- ) ?? [];
3143
+ );
3047
3144
  edgeShapes.push(
3048
3145
  moddle.create("bpmndi:BPMNEdge", {
3049
3146
  id: uid("BPMNEdge", edge.id),
@@ -3065,6 +3162,28 @@ function buildBpmnDI(moddle, definitions, nodes, edges) {
3065
3162
  });
3066
3163
  definitions.diagrams = [diagram];
3067
3164
  }
3165
+ function resolveEdgeWaypoints(edge, nodes, absolutePositionById) {
3166
+ if (edge.data?.routingPoints && edge.data.routingPoints.length >= 2) {
3167
+ return edge.data.routingPoints;
3168
+ }
3169
+ const source = nodes.find((node) => node.id === edge.source);
3170
+ const target = nodes.find((node) => node.id === edge.target);
3171
+ if (!source || !target) return [];
3172
+ const sourceMeta = BPMN_ELEMENT_CATALOG[source.data.elementType];
3173
+ const targetMeta = BPMN_ELEMENT_CATALOG[target.data.elementType];
3174
+ const sourcePosition = absolutePositionById.get(source.id) ?? source.position;
3175
+ const targetPosition = absolutePositionById.get(target.id) ?? target.position;
3176
+ return [
3177
+ {
3178
+ x: sourcePosition.x + (source.width ?? sourceMeta.defaultWidth) / 2,
3179
+ y: sourcePosition.y + (source.height ?? sourceMeta.defaultHeight) / 2
3180
+ },
3181
+ {
3182
+ x: targetPosition.x + (target.width ?? targetMeta.defaultWidth) / 2,
3183
+ y: targetPosition.y + (target.height ?? targetMeta.defaultHeight) / 2
3184
+ }
3185
+ ];
3186
+ }
3068
3187
  function buildAbsolutePositionMap(nodes) {
3069
3188
  const nodeById2 = new Map(nodes.map((node) => [node.id, node]));
3070
3189
  const absoluteById = /* @__PURE__ */ new Map();
@@ -3566,21 +3685,88 @@ function setVariable(state, key, value) {
3566
3685
  return { ...state, variables: { ...state.variables, [key]: value } };
3567
3686
  }
3568
3687
  function createBpmnNode(options) {
3688
+ const size = getBpmnElementSize(options.elementType);
3569
3689
  const meta = BPMN_ELEMENT_CATALOG[options.elementType];
3690
+ const orientation = options.data?.orientation ?? meta.orientation;
3691
+ const dragHandle = getBpmnDragHandleSelector(options.elementType);
3570
3692
  return {
3571
3693
  id: options.id,
3572
3694
  type: options.elementType,
3573
3695
  position: options.position,
3574
3696
  data: {
3575
3697
  elementType: options.elementType,
3698
+ orientation,
3576
3699
  ...options.label ? { label: options.label } : {},
3577
3700
  ...options.data ?? {}
3578
3701
  },
3579
- width: options.width ?? meta.defaultWidth,
3580
- height: options.height ?? meta.defaultHeight,
3581
- ...options.parentId ? { parentId: options.parentId } : {}
3702
+ width: options.width ?? size.width,
3703
+ height: options.height ?? size.height,
3704
+ ...options.parentId ? { parentId: options.parentId } : {},
3705
+ ...dragHandle ? { dragHandle } : {}
3582
3706
  };
3583
3707
  }
3708
+ var BPMN_POOL_LANE_LAYOUT = {
3709
+ poolHeaderSize: 30,
3710
+ laneHeaderSize: 24,
3711
+ laneGap: 0
3712
+ };
3713
+ function getBpmnDragHandleSelector(elementType) {
3714
+ if (elementType === "Pool") return ".pool-drag-handle";
3715
+ if (elementType === "Lane") return ".lane-drag-handle";
3716
+ return void 0;
3717
+ }
3718
+ var BPMN_SELECTION_STYLE = {
3719
+ nodeOutline: "#2563eb",
3720
+ edgeStroke: "#2563eb",
3721
+ handleFill: "#ffffff",
3722
+ handleStroke: "#2563eb",
3723
+ resizeHandleSize: 8,
3724
+ routingPointRadius: 5
3725
+ };
3726
+ var BPMN_ROUTABLE_EDGE_TYPES = [
3727
+ "sequenceFlow",
3728
+ "messageFlow",
3729
+ "association",
3730
+ "dataAssociation",
3731
+ "conversationLink"
3732
+ ];
3733
+ var BPMN_EDGE_CONNECTION_RULES = {
3734
+ sequenceFlow: {
3735
+ edgeType: "sequenceFlow",
3736
+ sourceCategories: ["flowNode"],
3737
+ targetCategories: ["flowNode"],
3738
+ allowSameParent: true,
3739
+ allowDifferentParent: false
3740
+ },
3741
+ messageFlow: {
3742
+ edgeType: "messageFlow",
3743
+ sourceCategories: ["flowNode"],
3744
+ targetCategories: ["flowNode"],
3745
+ allowSameParent: false,
3746
+ allowDifferentParent: true
3747
+ },
3748
+ association: {
3749
+ edgeType: "association",
3750
+ sourceCategories: ["flowNode", "artifact", "data"],
3751
+ targetCategories: ["flowNode", "artifact", "data"],
3752
+ allowSameParent: true,
3753
+ allowDifferentParent: true
3754
+ },
3755
+ dataAssociation: {
3756
+ edgeType: "dataAssociation",
3757
+ sourceCategories: ["flowNode", "data"],
3758
+ targetCategories: ["flowNode", "data"],
3759
+ allowSameParent: true,
3760
+ allowDifferentParent: true
3761
+ },
3762
+ conversationLink: {
3763
+ edgeType: "conversationLink",
3764
+ sourceCategories: ["conversation", "flowNode"],
3765
+ targetCategories: ["conversation", "flowNode"],
3766
+ allowSameParent: true,
3767
+ allowDifferentParent: true
3768
+ }
3769
+ };
3584
3770
  function inferBpmnEdgeType(state, sourceId, targetId) {
3585
3771
  const source = diagramsCore.getNode(state, sourceId);
3586
3772
  const target = diagramsCore.getNode(state, targetId);
@@ -3603,6 +3789,135 @@ function canUseSequenceFlow(type) {
3603
3789
  const meta = BPMN_ELEMENT_CATALOG[type];
3604
3790
  return meta.handlePolicy !== "none" && !isDataType(type) && type !== "Annotation" && type !== "Group" && meta.category !== "conversation";
3605
3791
  }
3792
+ function matchesConnectionCategory(type, categories) {
3793
+ return categories.some((category) => {
3794
+ if (category === type) return true;
3795
+ if (category === "flowNode") return canUseSequenceFlow(type);
3796
+ if (category === "data") return isDataType(type);
3797
+ if (category === "artifact") return type === "Annotation" || type === "Group";
3798
+ if (category === "conversation") return BPMN_ELEMENT_CATALOG[type].category === "conversation";
3799
+ return false;
3800
+ });
3801
+ }
3802
+ function isBpmnEdgeRoutingEditable(edgeType) {
3803
+ return BPMN_ROUTABLE_EDGE_TYPES.includes(edgeType);
3804
+ }
3805
+ function isBpmnProcessNode(type) {
3806
+ return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
3807
+ }
3808
+ function canContainBpmnElement(parentType, childType) {
3809
+ if (!parentType) return true;
3810
+ if (parentType === "Pool") {
3811
+ return childType === "Lane" || isBpmnProcessNode(childType) ? true : "Pools can contain lanes or BPMN process nodes.";
3812
+ }
3813
+ if (parentType === "Lane") {
3814
+ return isBpmnProcessNode(childType) ? true : "Lanes can only contain BPMN process nodes.";
3815
+ }
3816
+ if (parentType === "SubProcess" || parentType === "Transaction" || parentType === "EventSubProcess" || parentType === "AdHocSubProcess") {
3817
+ return isBpmnProcessNode(childType) ? true : "Subprocesses can only contain BPMN process nodes.";
3818
+ }
3819
+ return `${parentType} cannot contain BPMN child elements.`;
3820
+ }
3821
+ function getDirectBpmnChildren(state, parentId) {
3822
+ return state.nodes.filter((node) => node.parentId === parentId);
3823
+ }
3824
+ function getBpmnPoolLanes(state, poolId) {
3825
+ return getDirectBpmnChildren(state, poolId).filter(
3826
+ (node) => node.data.elementType === "Lane"
3827
+ );
3828
+ }
3829
+ function getNodeDimension(node, axis) {
3830
+ return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
3831
+ }
3832
+ function resolvePoolLaneDirection(pool) {
3833
+ return pool.data.orientation === "vertical" ? "horizontal" : "vertical";
3834
+ }
3835
+ function getBpmnLaneIndexAtPosition(state, poolId, position) {
3836
+ const pool = diagramsCore.getNode(state, poolId);
3837
+ if (!pool) return 0;
3838
+ const lanes = getBpmnPoolLanes(state, poolId);
3839
+ const direction = resolvePoolLaneDirection(pool);
3840
+ const axis = direction === "vertical" ? "y" : "x";
3841
+ const sizeKey = direction === "vertical" ? "height" : "width";
3842
+ for (let index = 0; index < lanes.length; index += 1) {
3843
+ const lane = lanes[index];
3844
+ const midpoint = lane.position[axis] + getNodeDimension(lane, sizeKey) / 2;
3845
+ if (position[axis] < midpoint) return index;
3846
+ }
3847
+ return lanes.length;
3848
+ }
3849
+ function sortBpmnLanes(state, poolId, laneId, index) {
3850
+ const lanes = getBpmnPoolLanes(state, poolId);
3851
+ const currentIndex = lanes.findIndex((lane) => lane.id === laneId);
3852
+ if (currentIndex < 0) return state;
3853
+ const orderedIds = lanes.map((lane) => lane.id);
3854
+ const [moved] = orderedIds.splice(currentIndex, 1);
3855
+ orderedIds.splice(Math.max(0, Math.min(index, orderedIds.length)), 0, moved);
3856
+ const order = new Map(orderedIds.map((id, laneIndex) => [id, laneIndex]));
3857
+ return {
3858
+ ...state,
3859
+ nodes: [...state.nodes].sort((a, b) => {
3860
+ const aOrder = order.get(a.id);
3861
+ const bOrder = order.get(b.id);
3862
+ if (aOrder === void 0 && bOrder === void 0) return 0;
3863
+ if (aOrder === void 0) return -1;
3864
+ if (bOrder === void 0) return 1;
3865
+ return aOrder - bOrder;
3866
+ })
3867
+ };
3868
+ }
3869
+ function layoutBpmnPoolLanes(state, poolId) {
3870
+ const pool = diagramsCore.getNode(state, poolId);
3871
+ if (!pool) return state;
3872
+ const poolSize = getBpmnElementSize("Pool");
3873
+ const direction = resolvePoolLaneDirection(pool);
3874
+ const lanes = getBpmnPoolLanes(state, poolId);
3875
+ let cursor = direction === "vertical" ? BPMN_POOL_LANE_LAYOUT.poolHeaderSize : 0;
3876
+ let next = state;
3877
+ for (const lane of lanes) {
3878
+ const laneSize = getBpmnElementSize("Lane");
3879
+ const width = direction === "vertical" ? Math.max(poolSize.minWidth - BPMN_POOL_LANE_LAYOUT.poolHeaderSize, lane.width ?? laneSize.width) : lane.width ?? laneSize.width;
3880
+ const height = direction === "vertical" ? lane.height ?? laneSize.height : Math.max(poolSize.minHeight - BPMN_POOL_LANE_LAYOUT.poolHeaderSize, lane.height ?? laneSize.height);
3881
+ next = diagramsCore.patchNode(next, lane.id, {
3882
+ position: direction === "vertical" ? { x: BPMN_POOL_LANE_LAYOUT.poolHeaderSize, y: cursor } : { x: cursor, y: BPMN_POOL_LANE_LAYOUT.poolHeaderSize },
3883
+ width,
3884
+ height,
3885
+ data: { orientation: pool.data.orientation ?? "horizontal" }
3886
+ });
3887
+ cursor += (direction === "vertical" ? height : width) + BPMN_POOL_LANE_LAYOUT.laneGap;
3888
+ }
3889
+ const minWidth = direction === "vertical" ? poolSize.minWidth : Math.max(poolSize.minWidth, cursor);
3890
+ const minHeight = direction === "vertical" ? Math.max(poolSize.minHeight, cursor) : poolSize.minHeight;
3891
+ return diagramsCore.resizeNode(next, poolId, { width: minWidth, height: minHeight });
3892
+ }
3893
+ function reorderBpmnLane(state, options) {
3894
+ return layoutBpmnPoolLanes(
3895
+ sortBpmnLanes(state, options.poolId, options.laneId, options.index),
3896
+ options.poolId
3897
+ );
3898
+ }
3899
+ function validateBpmnConnectionForEdgeType(state, edgeType, source, target) {
3900
+ const rule = BPMN_EDGE_CONNECTION_RULES[edgeType];
3901
+ if (!matchesConnectionCategory(source.data.elementType, rule.sourceCategories)) {
3902
+ return `${edgeType} cannot start from ${source.data.elementType}.`;
3903
+ }
3904
+ if (!matchesConnectionCategory(target.data.elementType, rule.targetCategories)) {
3905
+ return `${edgeType} cannot target ${target.data.elementType}.`;
3906
+ }
3907
+ const sameParent = (source.parentId ?? null) === (target.parentId ?? null);
3908
+ if (sameParent && rule.allowSameParent === false) {
3909
+ return `${edgeType} must connect BPMN elements in different participants/scopes.`;
3910
+ }
3911
+ if (!sameParent && rule.allowDifferentParent === false) {
3912
+ return `${edgeType} must stay inside the same BPMN participant/scope.`;
3913
+ }
3914
+ if (edgeType === "sequenceFlow") {
3915
+ if (source.data.elementType === "EndEvent") return "End events cannot have outgoing sequence flows.";
3916
+ if (target.data.elementType === "StartEvent") return "Start events cannot have incoming sequence flows.";
3917
+ return validateEdgeCardinality(state, edgeType, source, target);
3918
+ }
3919
+ return true;
3920
+ }
3606
3921
  function validateEdgeCardinality(state, edgeType, source, target) {
3607
3922
  if (edgeType !== "sequenceFlow") return true;
3608
3923
  const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
@@ -3629,14 +3944,9 @@ var bpmnConnectionValidators = [
3629
3944
  return "Elements without BPMN connection handles cannot be directly connected.";
3630
3945
  }
3631
3946
  if (edgeType === "sequenceFlow") {
3632
- if (!canUseSequenceFlow(source.data.elementType) || !canUseSequenceFlow(target.data.elementType)) {
3633
- return "Sequence flows can only connect BPMN flow nodes.";
3634
- }
3635
- if (source.data.elementType === "EndEvent") return "End events cannot have outgoing sequence flows.";
3636
- if (target.data.elementType === "StartEvent") return "Start events cannot have incoming sequence flows.";
3637
- return validateEdgeCardinality(state, edgeType, source, target);
3947
+ return validateBpmnConnectionForEdgeType(state, edgeType, source, target);
3638
3948
  }
3639
- return true;
3949
+ return validateBpmnConnectionForEdgeType(state, edgeType, source, target);
3640
3950
  }
3641
3951
  ];
3642
3952
  var BPMN_MODELING_RULES = diagramsCore.createModelingRules({
@@ -3661,10 +3971,7 @@ var BPMN_MODELING_RULES = diagramsCore.createModelingRules({
3661
3971
  if (node.data.elementType === "BoundaryEvent") {
3662
3972
  return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be attached to tasks or subprocesses.";
3663
3973
  }
3664
- if (parent.data.elementType === "Pool" || parent.data.elementType === "Lane") {
3665
- return isEventType(node.data.elementType) || node.data.elementType.includes("Task") || node.data.elementType.includes("Gateway") || node.data.elementType.includes("SubProcess") ? true : "Only flow nodes can be dropped into pools or lanes.";
3666
- }
3667
- return true;
3974
+ return canContainBpmnElement(parent.data.elementType, node.data.elementType);
3668
3975
  }
3669
3976
  ],
3670
3977
  reparent: [
@@ -3673,11 +3980,13 @@ var BPMN_MODELING_RULES = diagramsCore.createModelingRules({
3673
3980
  if (node.data.elementType === "BoundaryEvent") {
3674
3981
  return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be reparented to tasks or subprocesses.";
3675
3982
  }
3676
- return true;
3983
+ return canContainBpmnElement(parent?.data.elementType, node.data.elementType);
3677
3984
  }
3678
3985
  ],
3679
3986
  delete: [() => true],
3680
- resize: [() => true]
3987
+ resize: [
3988
+ ({ node }) => !node || isBpmnElementResizable(node.data.elementType) ? true : `${node.data.elementType} is not resizable in BPMN.`
3989
+ ]
3681
3990
  });
3682
3991
  function createBpmnNodeCommand(options) {
3683
3992
  return {
@@ -3692,6 +4001,12 @@ function connectBpmnCommand(options) {
3692
4001
  label: "Connect BPMN elements",
3693
4002
  execute: (state) => {
3694
4003
  const edgeType = options.edgeType ?? inferBpmnEdgeType(state, options.source, options.target);
4004
+ const source = diagramsCore.getNode(state, options.source);
4005
+ const target = diagramsCore.getNode(state, options.target);
4006
+ if (!source) throw new Error(`Source node "${options.source}" does not exist.`);
4007
+ if (!target) throw new Error(`Target node "${options.target}" does not exist.`);
4008
+ const validation = validateBpmnConnectionForEdgeType(state, edgeType, source, target);
4009
+ if (validation !== true) throw new Error(validation);
3695
4010
  return diagramsCore.connectNodes(
3696
4011
  state,
3697
4012
  {
@@ -3707,7 +4022,7 @@ function connectBpmnCommand(options) {
3707
4022
  ...options.data ?? {}
3708
4023
  }
3709
4024
  },
3710
- bpmnConnectionValidators
4025
+ []
3711
4026
  );
3712
4027
  }
3713
4028
  };
@@ -3766,10 +4081,13 @@ function reparentBpmnNodeCommand(options) {
3766
4081
  if (parent && node.data.elementType === "BoundaryEvent" && !acceptsBoundaryEvents(parent.data.elementType)) {
3767
4082
  throw new Error("Boundary events can only be reparented to tasks or subprocesses.");
3768
4083
  }
3769
- return diagramsCore.reparentNode(state, options.id, {
4084
+ const containment = canContainBpmnElement(parent?.data.elementType, node.data.elementType);
4085
+ if (containment !== true) throw new Error(containment);
4086
+ const reparented = diagramsCore.reparentNode(state, options.id, {
3770
4087
  ...options.parentId !== void 0 ? { parentId: options.parentId } : {},
3771
4088
  ...options.position ? { position: options.position } : {}
3772
4089
  });
4090
+ return parent?.data.elementType === "Pool" && node.data.elementType === "Lane" ? layoutBpmnPoolLanes(reparented, parent.id) : reparented;
3773
4091
  }
3774
4092
  };
3775
4093
  }
@@ -3777,7 +4095,63 @@ function resizeBpmnNodeCommand(options) {
3777
4095
  return {
3778
4096
  id: `bpmn.resize.${options.id}`,
3779
4097
  label: "Resize BPMN element",
3780
- execute: (state) => diagramsCore.resizeNode(state, options.id, options)
4098
+ execute: (state) => {
4099
+ const node = diagramsCore.getNode(state, options.id);
4100
+ if (!node) throw new Error(`Element "${options.id}" does not exist.`);
4101
+ const size = getBpmnElementSize(node.data.elementType);
4102
+ if (!size.resizable) {
4103
+ throw new Error(`${node.data.elementType} is not resizable in BPMN.`);
4104
+ }
4105
+ return diagramsCore.resizeNode(state, options.id, {
4106
+ width: options.width === void 0 ? void 0 : Math.max(size.minWidth, options.width),
4107
+ height: options.height === void 0 ? void 0 : Math.max(size.minHeight, options.height)
4108
+ });
4109
+ }
4110
+ };
4111
+ }
4112
+ function reorderBpmnLaneCommand(options) {
4113
+ return {
4114
+ id: `bpmn.reorderLane.${options.poolId}.${options.laneId}`,
4115
+ label: "Reorder BPMN lane",
4116
+ execute: (state) => {
4117
+ const pool = diagramsCore.getNode(state, options.poolId);
4118
+ const lane = diagramsCore.getNode(state, options.laneId);
4119
+ if (!pool || pool.data.elementType !== "Pool") {
4120
+ throw new Error(`Element "${options.poolId}" is not a pool.`);
4121
+ }
4122
+ if (!lane || lane.data.elementType !== "Lane" || lane.parentId !== options.poolId) {
4123
+ throw new Error(`Element "${options.laneId}" is not a lane in pool "${options.poolId}".`);
4124
+ }
4125
+ return reorderBpmnLane(state, options);
4126
+ }
4127
+ };
4128
+ }
4129
+ function moveBpmnLaneCommand(options) {
4130
+ return {
4131
+ id: `bpmn.moveLane.${options.poolId}.${options.laneId}`,
4132
+ label: "Move BPMN lane",
4133
+ execute: (state) => reorderBpmnLane(state, {
4134
+ poolId: options.poolId,
4135
+ laneId: options.laneId,
4136
+ index: getBpmnLaneIndexAtPosition(state, options.poolId, options.position)
4137
+ })
4138
+ };
4139
+ }
4140
+ function routeBpmnEdgeCommand(options) {
4141
+ return {
4142
+ id: `bpmn.routeEdge.${options.id}`,
4143
+ label: "Route BPMN edge",
4144
+ execute: (state) => {
4145
+ const edge = state.edges.find((item) => item.id === options.id);
4146
+ if (!edge) throw new Error(`Edge "${options.id}" does not exist.`);
4147
+ const edgeType = edge.data?.edgeType;
4148
+ if (!edgeType || !isBpmnEdgeRoutingEditable(edgeType)) {
4149
+ throw new Error(`${edgeType ?? "edge"} routing points cannot be edited.`);
4150
+ }
4151
+ return diagramsCore.patchEdge(state, options.id, {
4152
+ data: { routingPoints: options.routingPoints }
4153
+ });
4154
+ }
3781
4155
  };
3782
4156
  }
3783
4157
  function deleteBpmnElementsCommand(ids) {
@@ -3834,12 +4208,237 @@ function runBpmnCommands(stack, commands, options = {}) {
3834
4208
  return diagramsCore.executeCommands(stack, commands, options);
3835
4209
  }
3836
4210
 
4211
+ // src/validation/index.ts
4212
+ function isFlowNode(type) {
4213
+ return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess" || type === "ChoreographyTask" || type === "SubChoreography" || type === "CallChoreography";
4214
+ }
4215
+ function isProcessNode(type) {
4216
+ return isFlowNode(type) && type !== "BoundaryEvent";
4217
+ }
4218
+ function isSubProcess2(type) {
4219
+ return type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
4220
+ }
4221
+ function isCatchTarget(type) {
4222
+ return type === "IntermediateCatchEvent" || type === "ReceiveTask";
4223
+ }
4224
+ function poolAncestor(node, nodeById2) {
4225
+ let current = node;
4226
+ const visited = /* @__PURE__ */ new Set();
4227
+ while (current?.parentId && !visited.has(current.id)) {
4228
+ visited.add(current.id);
4229
+ const parent = nodeById2.get(current.parentId);
4230
+ if (parent?.data.elementType === "Pool") return parent.id;
4231
+ current = parent;
4232
+ }
4233
+ return void 0;
4234
+ }
4235
+ function countSequenceEdges(edges, nodeId, direction) {
4236
+ return edges.filter((edge) => {
4237
+ if (edge.data?.edgeType !== "sequenceFlow") return false;
4238
+ return direction === "in" ? edge.target === nodeId : edge.source === nodeId;
4239
+ }).length;
4240
+ }
4241
+ function sequenceEdges(edges) {
4242
+ return edges.filter((edge) => (edge.data?.edgeType ?? edge.type) === "sequenceFlow");
4243
+ }
4244
+ function sequenceOut(edges, nodeId) {
4245
+ return sequenceEdges(edges).filter((edge) => edge.source === nodeId);
4246
+ }
4247
+ function sequenceIn(edges, nodeId) {
4248
+ return sequenceEdges(edges).filter((edge) => edge.target === nodeId);
4249
+ }
4250
+ function issue(code, severity, message, elementId, relatedElementIds) {
4251
+ return {
4252
+ id: `${code}:${elementId ?? relatedElementIds?.join(",") ?? "diagram"}`,
4253
+ code,
4254
+ severity,
4255
+ message,
4256
+ ...elementId ? { elementId } : {},
4257
+ ...relatedElementIds ? { relatedElementIds } : {}
4258
+ };
4259
+ }
4260
+ function validateBpmnDiagram(nodes, edges, options = {}) {
4261
+ const opts = {
4262
+ requireStartEvent: true,
4263
+ requireEndEvent: true,
4264
+ strictNames: false,
4265
+ ...options
4266
+ };
4267
+ const issues = [];
4268
+ const nodeById2 = new Map(nodes.map((node) => [node.id, node]));
4269
+ const seqEdges = sequenceEdges(edges);
4270
+ const processNodes = nodes.filter((node) => isProcessNode(node.data.elementType));
4271
+ if (opts.requireStartEvent && !processNodes.some((node) => node.data.elementType === "StartEvent")) {
4272
+ issues.push(issue("bpmn/start-event-required", "error", "The diagram must contain at least one start event."));
4273
+ }
4274
+ if (opts.requireEndEvent && !processNodes.some((node) => node.data.elementType === "EndEvent")) {
4275
+ issues.push(issue("bpmn/end-event-required", "error", "The diagram must contain at least one end event."));
4276
+ }
4277
+ for (const edge of edges) {
4278
+ const edgeType = edge.data?.edgeType ?? edge.type;
4279
+ const source = nodeById2.get(edge.source);
4280
+ const target = nodeById2.get(edge.target);
4281
+ if (!source || !target) {
4282
+ issues.push(issue(
4283
+ "bpmn/no-orphan-edges",
4284
+ "error",
4285
+ `Edge "${edge.id}" references a missing ${!source ? "source" : "target"} node.`,
4286
+ edge.id,
4287
+ [edge.source, edge.target]
4288
+ ));
4289
+ continue;
4290
+ }
4291
+ if (edge.source === edge.target) {
4292
+ issues.push(issue("bpmn/no-self-loop", "error", "BPMN edges cannot connect an element to itself.", edge.id, [edge.source]));
4293
+ }
4294
+ if (edgeType === "sequenceFlow") {
4295
+ if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType) || isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
4296
+ issues.push(issue("bpmn/sequence-flow-valid-endpoints", "error", "Sequence flows must connect BPMN flow nodes.", edge.id, [source.id, target.id]));
4297
+ }
4298
+ const sourcePool = poolAncestor(source, nodeById2);
4299
+ const targetPool = poolAncestor(target, nodeById2);
4300
+ if (sourcePool && targetPool && sourcePool !== targetPool) {
4301
+ issues.push(issue("bpmn/sequence-flow-no-cross-pool", "error", "Sequence flows cannot cross pools. Use message flow between participants.", edge.id, [source.id, target.id]));
4302
+ }
4303
+ }
4304
+ if (edgeType === "messageFlow") {
4305
+ const sourcePool = poolAncestor(source, nodeById2);
4306
+ const targetPool = poolAncestor(target, nodeById2);
4307
+ if (!sourcePool || !targetPool || sourcePool === targetPool) {
4308
+ issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect flow nodes in different pools.", edge.id, [source.id, target.id]));
4309
+ }
4310
+ if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType)) {
4311
+ issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect BPMN flow nodes, not containers.", edge.id, [source.id, target.id]));
4312
+ }
4313
+ }
4314
+ if (edgeType === "dataAssociation") {
4315
+ const hasDataEndpoint = isDataType(source.data.elementType) || isDataType(target.data.elementType);
4316
+ const hasFlowEndpoint = isFlowNode(source.data.elementType) || isFlowNode(target.data.elementType);
4317
+ if (!hasDataEndpoint || !hasFlowEndpoint) {
4318
+ issues.push(issue("bpmn/data-association-valid-endpoints", "error", "Data associations must connect data elements with flow nodes.", edge.id, [source.id, target.id]));
4319
+ }
4320
+ }
4321
+ }
4322
+ const duplicateSequenceKeys = /* @__PURE__ */ new Set();
4323
+ const reportedDuplicateKeys = /* @__PURE__ */ new Set();
4324
+ for (const edge of seqEdges) {
4325
+ const key = `${edge.source}->${edge.target}`;
4326
+ if (duplicateSequenceKeys.has(key) && !reportedDuplicateKeys.has(key)) {
4327
+ reportedDuplicateKeys.add(key);
4328
+ issues.push(issue("bpmn/no-duplicate-sequence-flow", "error", "Only one sequence flow is allowed between the same source and target.", edge.id, [edge.source, edge.target]));
4329
+ }
4330
+ duplicateSequenceKeys.add(key);
4331
+ }
4332
+ for (const node of nodes) {
4333
+ const type = node.data.elementType;
4334
+ const incoming = countSequenceEdges(edges, node.id, "in");
4335
+ const outgoing = countSequenceEdges(edges, node.id, "out");
4336
+ const meta = BPMN_ELEMENT_CATALOG[type];
4337
+ if (type === "StartEvent" && incoming > 0) {
4338
+ issues.push(issue("bpmn/start-event-no-incoming", "error", "Start events cannot have incoming sequence flows.", node.id));
4339
+ }
4340
+ if (type === "EndEvent") {
4341
+ if (outgoing > 0) issues.push(issue("bpmn/no-outgoing-from-end-event", "error", "End events cannot have outgoing sequence flows.", node.id));
4342
+ if (incoming === 0) issues.push(issue("bpmn/end-event-has-incoming", "error", "End events should have at least one incoming sequence flow.", node.id));
4343
+ }
4344
+ if ((type === "IntermediateCatchEvent" || type === "IntermediateThrowEvent") && (incoming === 0 || outgoing === 0)) {
4345
+ issues.push(issue("bpmn/intermediate-event-both-flows", "error", "Intermediate events should have both incoming and outgoing sequence flows.", node.id));
4346
+ }
4347
+ if (type === "BoundaryEvent") {
4348
+ const hostId = node.data.attachedToRef ?? node.parentId;
4349
+ const host = hostId ? nodeById2.get(hostId) : void 0;
4350
+ if (!host || !BPMN_ELEMENT_CATALOG[host.data.elementType]?.acceptsBoundaryEvents) {
4351
+ issues.push(issue("bpmn/boundary-event-attached", "error", "Boundary events must be attached to an activity or subprocess.", node.id, hostId ? [hostId] : void 0));
4352
+ }
4353
+ if (sequenceIn(edges, node.id).length > 0) {
4354
+ issues.push(issue("bpmn/boundary-no-incoming", "error", "Boundary events cannot have incoming sequence flows.", node.id));
4355
+ }
4356
+ if (sequenceOut(edges, node.id).length === 0) {
4357
+ issues.push(issue("bpmn/boundary-has-outgoing", "warning", "Boundary events should define an outgoing exception path.", node.id));
4358
+ }
4359
+ }
4360
+ if (isGatewayType(type)) {
4361
+ if (incoming === 0) issues.push(issue("bpmn/gateway-has-incoming", "error", "Gateways should have at least one incoming sequence flow.", node.id));
4362
+ if (outgoing === 0) issues.push(issue("bpmn/gateway-has-outgoing", "error", "Gateways should have at least one outgoing sequence flow.", node.id));
4363
+ }
4364
+ if (type === "ExclusiveGateway" || type === "InclusiveGateway" || type === "ComplexGateway") {
4365
+ const outgoingEdges = sequenceOut(edges, node.id);
4366
+ const defaults = outgoingEdges.filter((edge) => edge.data?.isDefault);
4367
+ if (defaults.length > 1) {
4368
+ issues.push(issue("bpmn/gateway-single-default", "error", "Gateways can have at most one default sequence flow.", node.id, defaults.map((edge) => edge.id)));
4369
+ }
4370
+ if (outgoingEdges.length >= 2) {
4371
+ for (const edge of outgoingEdges) {
4372
+ if (!edge.data?.isDefault && !edge.data?.conditionExpression) {
4373
+ issues.push(issue("bpmn/gateway-condition", "error", "Conditional gateway branches should have a condition or be marked as default.", edge.id, [node.id, edge.target]));
4374
+ }
4375
+ }
4376
+ }
4377
+ }
4378
+ if (type === "EventBasedGateway") {
4379
+ const outgoingEdges = edges.filter((edge) => edge.data?.edgeType === "sequenceFlow" && edge.source === node.id);
4380
+ if (outgoingEdges.length < 2) {
4381
+ issues.push(issue("bpmn/event-based-gateway-min-outgoing", "error", "Event-based gateways should have at least two outgoing sequence flows.", node.id));
4382
+ }
4383
+ for (const edge of outgoingEdges) {
4384
+ const target = nodeById2.get(edge.target);
4385
+ if (target && !isCatchTarget(target.data.elementType)) {
4386
+ issues.push(issue("bpmn/event-based-gateway-valid-targets", "error", "Event-based gateways must target catch events or receive tasks.", edge.id, [node.id, target.id]));
4387
+ }
4388
+ }
4389
+ }
4390
+ if (meta.maxIncoming !== void 0 && incoming > meta.maxIncoming) {
4391
+ issues.push(issue("bpmn/max-incoming", "error", `${type} cannot have more than ${meta.maxIncoming} incoming sequence flow(s).`, node.id));
4392
+ }
4393
+ if (meta.maxOutgoing !== void 0 && outgoing > meta.maxOutgoing) {
4394
+ issues.push(issue("bpmn/max-outgoing", "error", `${type} cannot have more than ${meta.maxOutgoing} outgoing sequence flow(s).`, node.id));
4395
+ }
4396
+ if (opts.strictNames && (type.includes("Task") || isGatewayType(type)) && !node.data.label) {
4397
+ issues.push(issue("bpmn/name-required", "warning", `${type} should have a label.`, node.id));
4398
+ }
4399
+ if (isSubProcess2(type)) {
4400
+ const childNodes = nodes.filter((child) => child.parentId === node.id);
4401
+ if (childNodes.length > 0) {
4402
+ if (!childNodes.some((child) => child.data.elementType === "StartEvent")) {
4403
+ issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain a start event.", node.id));
4404
+ }
4405
+ if (!childNodes.some((child) => child.data.elementType === "EndEvent")) {
4406
+ issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain an end event.", node.id));
4407
+ }
4408
+ }
4409
+ if (type === "EventSubProcess") {
4410
+ const starts = childNodes.filter((child) => child.data.elementType === "StartEvent");
4411
+ for (const start of starts) {
4412
+ if (!start.data.trigger || start.data.trigger === "none") {
4413
+ issues.push(issue("bpmn/event-subprocess-triggered-start", "error", "Event subprocess start events must define an event trigger.", start.id, [node.id]));
4414
+ }
4415
+ }
4416
+ }
4417
+ }
4418
+ if (type === "Lane") {
4419
+ const parent = node.parentId ? nodeById2.get(node.parentId) : void 0;
4420
+ if (parent?.data.elementType !== "Pool") {
4421
+ issues.push(issue("bpmn/lane-parent-pool", "error", "Lanes must be contained by a pool.", node.id));
4422
+ }
4423
+ }
4424
+ }
4425
+ return {
4426
+ valid: issues.every((item) => item.severity !== "error"),
4427
+ issues
4428
+ };
4429
+ }
4430
+
3837
4431
  exports.AnnotationNode = AnnotationNode;
3838
4432
  exports.AssociationEdge = AssociationEdge;
4433
+ exports.BPMN_EDGE_CONNECTION_RULES = BPMN_EDGE_CONNECTION_RULES;
3839
4434
  exports.BPMN_EDGE_TYPES = BPMN_EDGE_TYPES;
3840
4435
  exports.BPMN_ELEMENT_CATALOG = BPMN_ELEMENT_CATALOG;
3841
4436
  exports.BPMN_MODELING_RULES = BPMN_MODELING_RULES;
3842
4437
  exports.BPMN_NODE_TYPES = BPMN_NODE_TYPES;
4438
+ exports.BPMN_POOL_LANE_LAYOUT = BPMN_POOL_LANE_LAYOUT;
4439
+ exports.BPMN_RESIZABLE_ELEMENT_TYPES = BPMN_RESIZABLE_ELEMENT_TYPES;
4440
+ exports.BPMN_ROUTABLE_EDGE_TYPES = BPMN_ROUTABLE_EDGE_TYPES;
4441
+ exports.BPMN_SELECTION_STYLE = BPMN_SELECTION_STYLE;
3843
4442
  exports.BoundaryEventNode = BoundaryEventNode;
3844
4443
  exports.CallChoreographyNode = CallChoreographyNode;
3845
4444
  exports.CallConversationNode = CallConversationNode;
@@ -3870,6 +4469,7 @@ exports.TaskNode = TaskNode;
3870
4469
  exports.acceptsBoundaryEvents = acceptsBoundaryEvents;
3871
4470
  exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
3872
4471
  exports.bpmnConnectionValidators = bpmnConnectionValidators;
4472
+ exports.canContainBpmnElement = canContainBpmnElement;
3873
4473
  exports.connectBpmnCommand = connectBpmnCommand;
3874
4474
  exports.copyBpmnElements = copyBpmnElements;
3875
4475
  exports.createBpmnDiagramDocument = createBpmnDiagramDocument;
@@ -3879,11 +4479,18 @@ exports.createSimulation = createSimulation;
3879
4479
  exports.deleteBpmnElementsCommand = deleteBpmnElementsCommand;
3880
4480
  exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
3881
4481
  exports.fire = fire;
4482
+ exports.getBpmnDragHandleSelector = getBpmnDragHandleSelector;
4483
+ exports.getBpmnElementSize = getBpmnElementSize;
4484
+ exports.getBpmnLaneIndexAtPosition = getBpmnLaneIndexAtPosition;
4485
+ exports.getBpmnPoolLanes = getBpmnPoolLanes;
3882
4486
  exports.getElementMeta = getElementMeta;
3883
4487
  exports.getFireable = getFireable;
3884
4488
  exports.getHandlePolicy = getHandlePolicy;
3885
4489
  exports.getOrientation = getOrientation;
3886
4490
  exports.inferBpmnEdgeType = inferBpmnEdgeType;
4491
+ exports.isBpmnEdgeRoutingEditable = isBpmnEdgeRoutingEditable;
4492
+ exports.isBpmnElementResizable = isBpmnElementResizable;
4493
+ exports.isBpmnProcessNode = isBpmnProcessNode;
3887
4494
  exports.isChoreographyType = isChoreographyType;
3888
4495
  exports.isCompleted = isCompleted;
3889
4496
  exports.isContainerType = isContainerType;
@@ -3892,12 +4499,17 @@ exports.isDataType = isDataType;
3892
4499
  exports.isEventType = isEventType;
3893
4500
  exports.isGatewayType = isGatewayType;
3894
4501
  exports.isTaskType = isTaskType;
4502
+ exports.layoutBpmnPoolLanes = layoutBpmnPoolLanes;
4503
+ exports.moveBpmnLaneCommand = moveBpmnLaneCommand;
3895
4504
  exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
3896
4505
  exports.parseBpmnXml = parseBpmnXml;
3897
4506
  exports.pasteBpmnElementsCommand = pasteBpmnElementsCommand;
4507
+ exports.reorderBpmnLane = reorderBpmnLane;
4508
+ exports.reorderBpmnLaneCommand = reorderBpmnLaneCommand;
3898
4509
  exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
3899
4510
  exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
3900
4511
  exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
4512
+ exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;
3901
4513
  exports.runBpmnCommand = runBpmnCommand;
3902
4514
  exports.runBpmnCommands = runBpmnCommands;
3903
4515
  exports.selectBpmnElementsCommand = selectBpmnElementsCommand;
@@ -3907,5 +4519,7 @@ exports.setVariable = setVariable;
3907
4519
  exports.supportsCollapse = supportsCollapse;
3908
4520
  exports.supportsMarkers = supportsMarkers;
3909
4521
  exports.tick = tick;
4522
+ exports.validateBpmnConnectionForEdgeType = validateBpmnConnectionForEdgeType;
4523
+ exports.validateBpmnDiagram = validateBpmnDiagram;
3910
4524
  //# sourceMappingURL=index.cjs.map
3911
4525
  //# sourceMappingURL=index.cjs.map