@bpmn-ld/bpmn-ld 0.0.0-stage → 0.2.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 (339) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +125 -2
  3. package/contexts/combined.jsonld +3 -0
  4. package/contexts/core.jsonld +170 -0
  5. package/contexts/di.jsonld +37 -0
  6. package/dist/analyze/analyze.d.ts +3 -0
  7. package/dist/analyze/analyze.js +11 -0
  8. package/dist/analyze/findings.d.ts +8 -0
  9. package/dist/analyze/findings.js +1 -0
  10. package/dist/analyze/report.d.ts +3 -0
  11. package/dist/analyze/report.js +9 -0
  12. package/dist/analyze/rules/ad-hoc-completion-condition.d.ts +2 -0
  13. package/dist/analyze/rules/ad-hoc-completion-condition.js +7 -0
  14. package/dist/analyze/rules/cannot-reach-end.d.ts +2 -0
  15. package/dist/analyze/rules/cannot-reach-end.js +28 -0
  16. package/dist/analyze/rules/compensation-association.d.ts +2 -0
  17. package/dist/analyze/rules/compensation-association.js +13 -0
  18. package/dist/analyze/rules/dead-end.d.ts +2 -0
  19. package/dist/analyze/rules/dead-end.js +13 -0
  20. package/dist/analyze/rules/end-event.d.ts +2 -0
  21. package/dist/analyze/rules/end-event.js +8 -0
  22. package/dist/analyze/rules/error-catch.d.ts +2 -0
  23. package/dist/analyze/rules/error-catch.js +14 -0
  24. package/dist/analyze/rules/escalation-catch.d.ts +2 -0
  25. package/dist/analyze/rules/escalation-catch.js +14 -0
  26. package/dist/analyze/rules/gateway-cardinality.d.ts +3 -0
  27. package/dist/analyze/rules/gateway-cardinality.js +17 -0
  28. package/dist/analyze/rules/index.d.ts +4 -0
  29. package/dist/analyze/rules/index.js +21 -0
  30. package/dist/analyze/rules/instantiating-gateway.d.ts +2 -0
  31. package/dist/analyze/rules/instantiating-gateway.js +14 -0
  32. package/dist/analyze/rules/non-interrupting-start.d.ts +2 -0
  33. package/dist/analyze/rules/non-interrupting-start.js +14 -0
  34. package/dist/analyze/rules/reachability.d.ts +2 -0
  35. package/dist/analyze/rules/reachability.js +25 -0
  36. package/dist/analyze/rules/rule.d.ts +7 -0
  37. package/dist/analyze/rules/rule.js +1 -0
  38. package/dist/analyze/rules/signal-catch.d.ts +2 -0
  39. package/dist/analyze/rules/signal-catch.js +12 -0
  40. package/dist/analyze/rules/split-join-pairing.d.ts +3 -0
  41. package/dist/analyze/rules/split-join-pairing.js +50 -0
  42. package/dist/analyze/rules/start-event.d.ts +2 -0
  43. package/dist/analyze/rules/start-event.js +8 -0
  44. package/dist/analyze/rules/task-message-flow.d.ts +2 -0
  45. package/dist/analyze/rules/task-message-flow.js +19 -0
  46. package/dist/analyze/scope-graph.d.ts +56 -0
  47. package/dist/analyze/scope-graph.js +89 -0
  48. package/dist/analyze-cli.d.ts +1 -0
  49. package/dist/analyze-cli.js +5 -0
  50. package/dist/analyze-run.d.ts +12 -0
  51. package/dist/analyze-run.js +85 -0
  52. package/dist/bpmn-ld-cli.d.ts +2 -0
  53. package/dist/bpmn-ld-cli.js +97 -0
  54. package/dist/build-cli.d.ts +1 -0
  55. package/dist/build-cli.js +2 -0
  56. package/dist/build.d.ts +3 -0
  57. package/dist/build.js +38 -0
  58. package/dist/cheat-sheet-catalog.d.ts +10 -0
  59. package/dist/cheat-sheet-catalog.js +72 -0
  60. package/dist/cheat-sheet-cli.d.ts +1 -0
  61. package/dist/cheat-sheet-cli.js +7 -0
  62. package/dist/cheat-sheet-compose.d.ts +13 -0
  63. package/dist/cheat-sheet-compose.js +107 -0
  64. package/dist/cheat-sheet-run.d.ts +11 -0
  65. package/dist/cheat-sheet-run.js +65 -0
  66. package/dist/cheat-sheet-svg.d.ts +2 -0
  67. package/dist/cheat-sheet-svg.js +2 -0
  68. package/dist/cheat-sheet.d.ts +2 -0
  69. package/dist/cheat-sheet.js +2 -0
  70. package/dist/check-xml/check.d.ts +3 -0
  71. package/dist/check-xml/check.js +11 -0
  72. package/dist/check-xml/lint.d.ts +2 -0
  73. package/dist/check-xml/lint.js +47 -0
  74. package/dist/check-xml/moddle.d.ts +6 -0
  75. package/dist/check-xml/moddle.js +23 -0
  76. package/dist/check-xml/types.d.ts +20 -0
  77. package/dist/check-xml/types.js +1 -0
  78. package/dist/check-xml/xsd.d.ts +2 -0
  79. package/dist/check-xml/xsd.js +25 -0
  80. package/dist/check-xml-cli.d.ts +1 -0
  81. package/dist/check-xml-cli.js +5 -0
  82. package/dist/check-xml-run.d.ts +10 -0
  83. package/dist/check-xml-run.js +77 -0
  84. package/dist/convert/analyze-output.d.ts +3 -0
  85. package/dist/convert/analyze-output.js +8 -0
  86. package/dist/convert/convert.d.ts +19 -0
  87. package/dist/convert/convert.js +96 -0
  88. package/dist/convert/errors.d.ts +5 -0
  89. package/dist/convert/errors.js +8 -0
  90. package/dist/convert/extensions.d.ts +23 -0
  91. package/dist/convert/extensions.js +103 -0
  92. package/dist/convert/mapping-check.d.ts +15 -0
  93. package/dist/convert/mapping-check.js +66 -0
  94. package/dist/convert/mapping.d.ts +52 -0
  95. package/dist/convert/mapping.js +273 -0
  96. package/dist/convert/namespaces.d.ts +2 -0
  97. package/dist/convert/namespaces.js +19 -0
  98. package/dist/convert/validate-output.d.ts +2 -0
  99. package/dist/convert/validate-output.js +28 -0
  100. package/dist/convert/warnings.d.ts +9 -0
  101. package/dist/convert/warnings.js +67 -0
  102. package/dist/convert/xml-reader.d.ts +11 -0
  103. package/dist/convert/xml-reader.js +84 -0
  104. package/dist/convert-cli.d.ts +1 -0
  105. package/dist/convert-cli.js +5 -0
  106. package/dist/convert-run.d.ts +10 -0
  107. package/dist/convert-run.js +125 -0
  108. package/dist/coverage-cli.d.ts +1 -0
  109. package/dist/coverage-cli.js +8 -0
  110. package/dist/coverage-mappings.d.ts +3 -0
  111. package/dist/coverage-mappings.js +34 -0
  112. package/dist/coverage-scope.d.ts +11 -0
  113. package/dist/coverage-scope.js +187 -0
  114. package/dist/coverage-xsd.d.ts +15 -0
  115. package/dist/coverage-xsd.js +55 -0
  116. package/dist/coverage.d.ts +35 -0
  117. package/dist/coverage.js +152 -0
  118. package/dist/docs-cli.d.ts +1 -0
  119. package/dist/docs-cli.js +18 -0
  120. package/dist/docs.d.ts +8 -0
  121. package/dist/docs.js +136 -0
  122. package/dist/eval/checks.d.ts +19 -0
  123. package/dist/eval/checks.js +252 -0
  124. package/dist/eval/regenerate.d.ts +10 -0
  125. package/dist/eval/regenerate.js +48 -0
  126. package/dist/eval-regenerate-cli.d.ts +1 -0
  127. package/dist/eval-regenerate-cli.js +16 -0
  128. package/dist/export/data.d.ts +10 -0
  129. package/dist/export/data.js +127 -0
  130. package/dist/export/diagram.d.ts +8 -0
  131. package/dist/export/diagram.js +112 -0
  132. package/dist/export/element.d.ts +27 -0
  133. package/dist/export/element.js +175 -0
  134. package/dist/export/export.d.ts +22 -0
  135. package/dist/export/export.js +124 -0
  136. package/dist/export/extensions.d.ts +18 -0
  137. package/dist/export/extensions.js +122 -0
  138. package/dist/export/layout-export.d.ts +4 -0
  139. package/dist/export/layout-export.js +25 -0
  140. package/dist/export/mapping-check.d.ts +39 -0
  141. package/dist/export/mapping-check.js +175 -0
  142. package/dist/export/normalize.d.ts +3 -0
  143. package/dist/export/normalize.js +67 -0
  144. package/dist/export-cli.d.ts +1 -0
  145. package/dist/export-cli.js +5 -0
  146. package/dist/export-run.d.ts +10 -0
  147. package/dist/export-run.js +157 -0
  148. package/dist/index.d.ts +10 -0
  149. package/dist/index.js +10 -0
  150. package/dist/install-skill-run.d.ts +8 -0
  151. package/dist/install-skill-run.js +30 -0
  152. package/dist/install-skill.d.ts +23 -0
  153. package/dist/install-skill.js +76 -0
  154. package/dist/layout/collaboration.d.ts +36 -0
  155. package/dist/layout/collaboration.js +152 -0
  156. package/dist/layout/di.d.ts +15 -0
  157. package/dist/layout/di.js +52 -0
  158. package/dist/layout/extract.d.ts +2 -0
  159. package/dist/layout/extract.js +99 -0
  160. package/dist/layout/lanes.d.ts +30 -0
  161. package/dist/layout/lanes.js +112 -0
  162. package/dist/layout/layering.d.ts +7 -0
  163. package/dist/layout/layering.js +53 -0
  164. package/dist/layout/layout.d.ts +12 -0
  165. package/dist/layout/layout.js +299 -0
  166. package/dist/layout/model.d.ts +52 -0
  167. package/dist/layout/model.js +10 -0
  168. package/dist/layout/placement.d.ts +25 -0
  169. package/dist/layout/placement.js +256 -0
  170. package/dist/layout/standalone.d.ts +8 -0
  171. package/dist/layout/standalone.js +50 -0
  172. package/dist/layout-cli.d.ts +1 -0
  173. package/dist/layout-cli.js +5 -0
  174. package/dist/layout-run.d.ts +9 -0
  175. package/dist/layout-run.js +105 -0
  176. package/dist/loader.d.ts +5 -0
  177. package/dist/loader.js +7 -0
  178. package/dist/namespace.d.ts +5 -0
  179. package/dist/namespace.js +5 -0
  180. package/dist/ontology.d.ts +19 -0
  181. package/dist/ontology.js +94 -0
  182. package/dist/paths.d.ts +1 -0
  183. package/dist/paths.js +2 -0
  184. package/dist/render/geometry.d.ts +40 -0
  185. package/dist/render/geometry.js +81 -0
  186. package/dist/render/renderer.d.ts +31 -0
  187. package/dist/render/renderer.js +369 -0
  188. package/dist/render/symbols.d.ts +10 -0
  189. package/dist/render/symbols.js +26 -0
  190. package/dist/render/text.d.ts +20 -0
  191. package/dist/render/text.js +28 -0
  192. package/dist/render-cli.d.ts +1 -0
  193. package/dist/render-cli.js +7 -0
  194. package/dist/render-run.d.ts +9 -0
  195. package/dist/render-run.js +161 -0
  196. package/dist/render.d.ts +4 -0
  197. package/dist/render.js +4 -0
  198. package/dist/schema-overrides.d.ts +14 -0
  199. package/dist/schema-overrides.js +36 -0
  200. package/dist/schema-validate.d.ts +5 -0
  201. package/dist/schema-validate.js +8 -0
  202. package/dist/schema.d.ts +6 -0
  203. package/dist/schema.js +114 -0
  204. package/dist/shacl.d.ts +15 -0
  205. package/dist/shacl.js +37 -0
  206. package/dist/validate-cli.d.ts +1 -0
  207. package/dist/validate-cli.js +5 -0
  208. package/dist/validate-run.d.ts +8 -0
  209. package/dist/validate-run.js +58 -0
  210. package/dist/validate.d.ts +11 -0
  211. package/dist/validate.js +94 -0
  212. package/dist/versioning-cli.d.ts +1 -0
  213. package/dist/versioning-cli.js +18 -0
  214. package/dist/versioning.d.ts +17 -0
  215. package/dist/versioning.js +45 -0
  216. package/ontology/core.ttl +993 -0
  217. package/ontology/di.ttl +167 -0
  218. package/package.json +77 -4
  219. package/reference/bpmn-xsd/BPMN20.xsd +37 -0
  220. package/reference/bpmn-xsd/BPMNDI.xsd +100 -0
  221. package/reference/bpmn-xsd/DC.xsd +29 -0
  222. package/reference/bpmn-xsd/DI.xsd +100 -0
  223. package/reference/bpmn-xsd/Semantic.xsd +1562 -0
  224. package/reference/rospocher/ATTRIBUTION.md +22 -0
  225. package/reference/rospocher/BPMNOntology.owl +8937 -0
  226. package/reference/rospocher-verified.json +221 -0
  227. package/schema/bpmn-ld.schema.json +15230 -0
  228. package/shapes/core.shapes.ttl +398 -0
  229. package/skills/bpmn-ld/SKILL.md +154 -0
  230. package/skills/bpmn-ld/evals/models/order-approval-di.jsonld +296 -0
  231. package/skills/bpmn-ld/evals/models/refund-di.bpmn +82 -0
  232. package/skills/bpmn-ld/evals/models/refund.bpmn +18 -0
  233. package/skills/bpmn-ld/evals/outputs/explain-collaboration.md +22 -0
  234. package/skills/bpmn-ld/evals/outputs/explain-order-approval.md +24 -0
  235. package/skills/bpmn-ld/evals/outputs/explain-refund.md +17 -0
  236. package/skills/bpmn-ld/evals/outputs/generate-activity-compensation.jsonld +39 -0
  237. package/skills/bpmn-ld/evals/outputs/generate-ad-hoc-sub-process.jsonld +52 -0
  238. package/skills/bpmn-ld/evals/outputs/generate-boundary-event.jsonld +27 -0
  239. package/skills/bpmn-ld/evals/outputs/generate-collaboration.jsonld +49 -0
  240. package/skills/bpmn-ld/evals/outputs/generate-conditions.jsonld +93 -0
  241. package/skills/bpmn-ld/evals/outputs/generate-diagram-properties.jsonld +340 -0
  242. package/skills/bpmn-ld/evals/outputs/generate-error.jsonld +217 -0
  243. package/skills/bpmn-ld/evals/outputs/generate-escalation.jsonld +231 -0
  244. package/skills/bpmn-ld/evals/outputs/generate-event-definition-ref.jsonld +67 -0
  245. package/skills/bpmn-ld/evals/outputs/generate-event-sub-process.jsonld +54 -0
  246. package/skills/bpmn-ld/evals/outputs/generate-exclusive-choice.jsonld +32 -0
  247. package/skills/bpmn-ld/evals/outputs/generate-instantiating-gateway.jsonld +24 -0
  248. package/skills/bpmn-ld/evals/outputs/generate-lane-partition.jsonld +46 -0
  249. package/skills/bpmn-ld/evals/outputs/generate-link-event.expect.json +11 -0
  250. package/skills/bpmn-ld/evals/outputs/generate-link-event.jsonld +57 -0
  251. package/skills/bpmn-ld/evals/outputs/generate-loop.jsonld +30 -0
  252. package/skills/bpmn-ld/evals/outputs/generate-message.jsonld +61 -0
  253. package/skills/bpmn-ld/evals/outputs/generate-parallel-branches.jsonld +25 -0
  254. package/skills/bpmn-ld/evals/outputs/generate-process-attributes.jsonld +49 -0
  255. package/skills/bpmn-ld/evals/outputs/generate-script-task.jsonld +18 -0
  256. package/skills/bpmn-ld/evals/outputs/generate-signal.jsonld +178 -0
  257. package/skills/bpmn-ld/evals/outputs/generate-sub-process.jsonld +31 -0
  258. package/skills/bpmn-ld/evals/outputs/generate-targeted-compensation.jsonld +40 -0
  259. package/skills/bpmn-ld/evals/outputs/generate-task-implementation.jsonld +18 -0
  260. package/skills/bpmn-ld/evals/outputs/generate-task-message-references.jsonld +49 -0
  261. package/skills/bpmn-ld/evals/outputs/generate-transaction.jsonld +48 -0
  262. package/skills/bpmn-ld/evals/outputs/modify-order-approval.jsonld +376 -0
  263. package/skills/bpmn-ld/evals/outputs/modify-refund.jsonld +373 -0
  264. package/skills/bpmn-ld/evals/outputs/order-approval.jsonld +29 -0
  265. package/skills/bpmn-ld/evals/outputs/refine-order-approval.jsonld +377 -0
  266. package/skills/bpmn-ld/evals/prompts/explain-collaboration.md +3 -0
  267. package/skills/bpmn-ld/evals/prompts/explain-order-approval.md +3 -0
  268. package/skills/bpmn-ld/evals/prompts/explain-refund.md +3 -0
  269. package/skills/bpmn-ld/evals/prompts/generate-activity-compensation.md +1 -0
  270. package/skills/bpmn-ld/evals/prompts/generate-ad-hoc-sub-process.md +1 -0
  271. package/skills/bpmn-ld/evals/prompts/generate-boundary-event.md +1 -0
  272. package/skills/bpmn-ld/evals/prompts/generate-collaboration.md +1 -0
  273. package/skills/bpmn-ld/evals/prompts/generate-conditions.md +1 -0
  274. package/skills/bpmn-ld/evals/prompts/generate-diagram-properties.md +1 -0
  275. package/skills/bpmn-ld/evals/prompts/generate-error.md +1 -0
  276. package/skills/bpmn-ld/evals/prompts/generate-escalation.md +1 -0
  277. package/skills/bpmn-ld/evals/prompts/generate-event-definition-ref.md +1 -0
  278. package/skills/bpmn-ld/evals/prompts/generate-event-sub-process.md +1 -0
  279. package/skills/bpmn-ld/evals/prompts/generate-exclusive-choice.md +1 -0
  280. package/skills/bpmn-ld/evals/prompts/generate-instantiating-gateway.md +1 -0
  281. package/skills/bpmn-ld/evals/prompts/generate-lane-partition.md +1 -0
  282. package/skills/bpmn-ld/evals/prompts/generate-link-event.md +1 -0
  283. package/skills/bpmn-ld/evals/prompts/generate-loop.md +1 -0
  284. package/skills/bpmn-ld/evals/prompts/generate-message.md +1 -0
  285. package/skills/bpmn-ld/evals/prompts/generate-parallel-branches.md +1 -0
  286. package/skills/bpmn-ld/evals/prompts/generate-process-attributes.md +1 -0
  287. package/skills/bpmn-ld/evals/prompts/generate-script-task.md +1 -0
  288. package/skills/bpmn-ld/evals/prompts/generate-signal.md +1 -0
  289. package/skills/bpmn-ld/evals/prompts/generate-sub-process.md +1 -0
  290. package/skills/bpmn-ld/evals/prompts/generate-targeted-compensation.md +1 -0
  291. package/skills/bpmn-ld/evals/prompts/generate-task-implementation.md +1 -0
  292. package/skills/bpmn-ld/evals/prompts/generate-task-message-references.md +1 -0
  293. package/skills/bpmn-ld/evals/prompts/generate-transaction.md +1 -0
  294. package/skills/bpmn-ld/evals/prompts/modify-order-approval.md +4 -0
  295. package/skills/bpmn-ld/evals/prompts/modify-refund.md +4 -0
  296. package/skills/bpmn-ld/evals/prompts/order-approval.md +1 -0
  297. package/skills/bpmn-ld/evals/prompts/refine-order-approval.md +8 -0
  298. package/skills/bpmn-ld/examples/positive/activity-compensation.jsonld +39 -0
  299. package/skills/bpmn-ld/examples/positive/ad-hoc-sub-process.jsonld +52 -0
  300. package/skills/bpmn-ld/examples/positive/boundary-event.jsonld +27 -0
  301. package/skills/bpmn-ld/examples/positive/collaboration.jsonld +49 -0
  302. package/skills/bpmn-ld/examples/positive/conditions.jsonld +93 -0
  303. package/skills/bpmn-ld/examples/positive/diagram-properties.jsonld +340 -0
  304. package/skills/bpmn-ld/examples/positive/error.jsonld +208 -0
  305. package/skills/bpmn-ld/examples/positive/escalation.jsonld +231 -0
  306. package/skills/bpmn-ld/examples/positive/event-definition-ref.jsonld +142 -0
  307. package/skills/bpmn-ld/examples/positive/event-sub-process.jsonld +54 -0
  308. package/skills/bpmn-ld/examples/positive/exclusive-choice.jsonld +32 -0
  309. package/skills/bpmn-ld/examples/positive/instantiating-gateway.jsonld +24 -0
  310. package/skills/bpmn-ld/examples/positive/lane-partition.jsonld +46 -0
  311. package/skills/bpmn-ld/examples/positive/link-event.expect.json +10 -0
  312. package/skills/bpmn-ld/examples/positive/link-event.jsonld +138 -0
  313. package/skills/bpmn-ld/examples/positive/loop.jsonld +30 -0
  314. package/skills/bpmn-ld/examples/positive/message.jsonld +60 -0
  315. package/skills/bpmn-ld/examples/positive/order-approval.jsonld +29 -0
  316. package/skills/bpmn-ld/examples/positive/parallel-branches.jsonld +25 -0
  317. package/skills/bpmn-ld/examples/positive/process-attributes.jsonld +49 -0
  318. package/skills/bpmn-ld/examples/positive/script-task.jsonld +18 -0
  319. package/skills/bpmn-ld/examples/positive/signal.jsonld +150 -0
  320. package/skills/bpmn-ld/examples/positive/sub-process.jsonld +31 -0
  321. package/skills/bpmn-ld/examples/positive/targeted-compensation.jsonld +40 -0
  322. package/skills/bpmn-ld/examples/positive/task-implementation.jsonld +18 -0
  323. package/skills/bpmn-ld/examples/positive/task-message-references.jsonld +151 -0
  324. package/skills/bpmn-ld/examples/positive/transaction.jsonld +48 -0
  325. package/skills/bpmn-ld/references/clarification-and-refinement.md +60 -0
  326. package/skills/bpmn-ld/references/common-mistakes.md +110 -0
  327. package/skills/bpmn-ld/references/explain-and-document.md +36 -0
  328. package/skills/bpmn-ld/references/modify-existing-model.md +49 -0
  329. package/skills/bpmn-ld/references/patterns.md +292 -0
  330. package/skills/bpmn-ld/references/render-output.md +1 -0
  331. package/skills/bpmn-ld/references/rule-catalogue.md +183 -0
  332. package/skills/bpmn-ld/references/vocabulary-summary.md +65 -0
  333. package/skills/bpmn-ld/template.jsonld +14 -0
  334. package/templates/combined.jsonld +3 -0
  335. package/templates/core.jsonld +170 -0
  336. package/templates/core.shapes.ttl +398 -0
  337. package/templates/core.ttl +993 -0
  338. package/templates/di.jsonld +37 -0
  339. package/templates/di.ttl +167 -0
@@ -0,0 +1,369 @@
1
+ import { geometryDiagrams } from "./geometry.js";
2
+ import { escapeXml, wrapText } from "./text.js";
3
+ import { eventCircle, taskRect, gatewayDiamond, doubleRect, thickRect, poolRect, laneRect, dataObject, dataStore, } from "./symbols.js";
4
+ const unwarn = (shape, message, warnings) => {
5
+ warnings.push({ kind: "unsupported", code: "undrawable-element", construct: String(shape.element?.type ?? "unknown"), location: `/${shape.id}`, node: shape.bpmnElement, message });
6
+ };
7
+ const shapeType = (shape) => String(shape.element?.type ?? "");
8
+ const isCatchEvent = (t) => t === "StartEvent" || t === "BoundaryEvent" || t === "IntermediateCatchEvent" || t === "IntermediateEvent";
9
+ const isThrowEvent = (t) => t === "IntermediateThrowEvent" || t === "EndEvent";
10
+ const eventMarker = (element, cx, cy, r, isCatch) => {
11
+ const defs = Array.isArray(element?.eventDefinitions) ? element.eventDefinitions : [];
12
+ const def = defs.length > 0 ? String(defs[0]?.type ?? "") : "";
13
+ const fill = isCatch ? "none" : "black";
14
+ const parts = [];
15
+ const mr = r * 0.45;
16
+ switch (def) {
17
+ case "TimerEventDefinition": {
18
+ parts.push(`<circle cx="${cx}" cy="${cy}" r="${mr}" fill="none" stroke="black" stroke-width="1.2"/>`);
19
+ parts.push(`<line x1="${cx}" y1="${cy}" x2="${cx}" y2="${cy - mr + 3}" stroke="black" stroke-width="1.2"/>`);
20
+ parts.push(`<line x1="${cx}" y1="${cy}" x2="${cx + mr - 3}" y2="${cy}" stroke="black" stroke-width="1.2"/>`);
21
+ break;
22
+ }
23
+ case "MessageEventDefinition": {
24
+ const w = mr * 1.6;
25
+ const h = mr * 1.1;
26
+ parts.push(`<rect x="${cx - w / 2}" y="${cy - h / 2}" width="${w}" height="${h}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
27
+ if (isCatch) {
28
+ parts.push(`<polyline points="${cx - w / 2},${cy - h / 2} ${cx},${cy + h / 4} ${cx + w / 2},${cy - h / 2}" fill="none" stroke="black" stroke-width="1.2"/>`);
29
+ }
30
+ break;
31
+ }
32
+ case "ErrorEventDefinition": {
33
+ const size = mr;
34
+ parts.push(`<polygon points="${cx},${cy - size} ${cx + size * 0.6},${cy + size * 0.4} ${cx - size * 0.6},${cy + size * 0.4}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
35
+ break;
36
+ }
37
+ case "EscalationEventDefinition": {
38
+ const size = mr;
39
+ parts.push(`<polygon points="${cx},${cy - size} ${cx + size * 0.7},${cy + size} ${cx - size * 0.7},${cy + size}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
40
+ break;
41
+ }
42
+ case "SignalEventDefinition": {
43
+ const size = mr;
44
+ parts.push(`<polygon points="${cx},${cy - size} ${cx + size},${cy + size * 0.6} ${cx - size},${cy + size * 0.6}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
45
+ break;
46
+ }
47
+ case "ConditionalEventDefinition": {
48
+ parts.push(`<rect x="${cx - mr}" y="${cy - mr}" width="${mr * 2}" height="${mr * 2}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
49
+ break;
50
+ }
51
+ case "LinkEventDefinition": {
52
+ parts.push(`<circle cx="${cx}" cy="${cy}" r="${mr}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
53
+ parts.push(`<polygon points="${cx + mr * 0.2},${cy - mr * 0.5} ${cx + mr * 0.8},${cy} ${cx + mr * 0.2},${cy + mr * 0.5}" fill="${isCatch ? "black" : "white"}" stroke="black" stroke-width="1"/>`);
54
+ break;
55
+ }
56
+ case "CompensateEventDefinition": {
57
+ parts.push(`<polygon points="${cx - mr},${cy - mr * 0.6} ${cx},${cy - mr * 0.6} ${cx - mr * 0.5},${cy + mr * 0.6} ${cx + mr * 0.5},${cy + mr * 0.6}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
58
+ break;
59
+ }
60
+ case "CancelEventDefinition": {
61
+ parts.push(`<line x1="${cx - mr}" y1="${cy - mr}" x2="${cx + mr}" y2="${cy + mr}" stroke="black" stroke-width="1.5"/>`);
62
+ parts.push(`<line x1="${cx + mr}" y1="${cy - mr}" x2="${cx - mr}" y2="${cy + mr}" stroke="black" stroke-width="1.5"/>`);
63
+ break;
64
+ }
65
+ case "TerminateEventDefinition": {
66
+ parts.push(`<circle cx="${cx}" cy="${cy}" r="${mr}" fill="black" stroke="black" stroke-width="1.2"/>`);
67
+ break;
68
+ }
69
+ case "MultipleEventDefinition": {
70
+ parts.push(`<polygon points="${cx},${cy - mr} ${cx + mr * 0.95},${cy - mr * 0.3} ${cx + mr * 0.6},${cy + mr * 0.8} ${cx - mr * 0.6},${cy + mr * 0.8} ${cx - mr * 0.95},${cy - mr * 0.3}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
71
+ break;
72
+ }
73
+ case "ParallelMultipleEventDefinition": {
74
+ parts.push(`<line x1="${cx - mr}" y1="${cy}" x2="${cx + mr}" y2="${cy}" stroke="black" stroke-width="1.2"/>`);
75
+ parts.push(`<line x1="${cx}" y1="${cy - mr}" x2="${cx}" y2="${cy + mr}" stroke="black" stroke-width="1.2"/>`);
76
+ parts.push(`<circle cx="${cx}" cy="${cy}" r="${mr * 0.35}" fill="${fill}" stroke="black" stroke-width="1.2"/>`);
77
+ break;
78
+ }
79
+ default: {
80
+ break;
81
+ }
82
+ }
83
+ return parts.join("");
84
+ };
85
+ const drawEvent = (shape, b, warnings, isThrowOverride) => {
86
+ const t = shapeType(shape);
87
+ const el = shape.element;
88
+ const r = Math.min(b.width, b.height) / 2;
89
+ const cx = b.x + r;
90
+ const cy = b.y + r;
91
+ const isInterrupting = el?.cancelActivity !== false;
92
+ const dashed = (t === "BoundaryEvent" || t === "StartEvent" || t === "IntermediateCatchEvent") && el?.cancelActivity === false;
93
+ const isCatch = isCatchEvent(t) && !isThrowOverride;
94
+ const stroke = (t === "EndEvent") ? 3 : 1.5;
95
+ const parts = [eventCircle(cx, cy, r - (t === "IntermediateCatchEvent" || t === "IntermediateThrowEvent" ? 2 : 0), stroke, dashed)];
96
+ if (t === "IntermediateCatchEvent" || t === "IntermediateThrowEvent") {
97
+ parts.push(eventCircle(cx, cy, r - (t === "IntermediateThrowEvent" ? 6 : 6), 1.2, false));
98
+ }
99
+ parts.push(eventMarker(el, cx, cy, r - 6, isCatch));
100
+ return parts.join("");
101
+ };
102
+ const taskIcon = (type, x, y) => {
103
+ const s = 14;
104
+ switch (type) {
105
+ case "UserTask": return `<circle cx="${x + s / 2}" cy="${y + s / 2}" r="${s / 3}" fill="none" stroke="black" stroke-width="1.2"/><line x1="${x + s / 2}" y1="${y + s * 0.83}" x2="${x + s / 2}" y2="${y + s}" stroke="black" stroke-width="1.2"/>`;
106
+ case "ServiceTask": return `<path d="M ${x + s / 2} ${y} l 3 4 4 1 -4 1 -3 4 -3 -4 -4 -1 4 -1 z" fill="none" stroke="black" stroke-width="1.2"/>`;
107
+ case "ScriptTask": return `<rect x="${x}" y="${y + 2}" width="${s}" height="${s - 4}" fill="none" stroke="black" stroke-width="1.2"/><line x1="${x + 2}" y1="${y + 5}" x2="${x + s - 2}" y2="${y + 5}" stroke="black" stroke-width="1"/><line x1="${x + 2}" y1="${y + 8}" x2="${x + s - 2}" y2="${y + 8}" stroke="black" stroke-width="1"/>`;
108
+ case "SendTask": return `<polygon points="${x},${y + s / 2} ${x + s},${y} ${x + s},${y + s}" fill="none" stroke="black" stroke-width="1.2"/>`;
109
+ case "ReceiveTask": return `<polygon points="${x},${y} ${x + s},${y + s / 2} ${x},${y + s}" fill="none" stroke="black" stroke-width="1.2"/>`;
110
+ case "ManualTask": return `<path d="M ${x + 2} ${y + s} V ${y + s / 2} M ${x + 6} ${y + s} V ${y + s / 3} M ${x + 10} ${y + s} V ${y + s / 3}" stroke="black" stroke-width="1.2" fill="none"/>`;
111
+ case "BusinessRuleTask": return `<rect x="${x + 2}" y="${y + 2}" width="${s - 4}" height="${s - 4}" fill="none" stroke="black" stroke-width="1.2"/><line x1="${x + 2}" y1="${y + s / 2}" x2="${x + s - 2}" y2="${y + s / 2}" stroke="black" stroke-width="1"/><line x1="${x + s / 2}" y1="${y + 2}" x2="${x + s / 2}" y2="${y + s - 2}" stroke="black" stroke-width="1"/>`;
112
+ default: return "";
113
+ }
114
+ };
115
+ const activityMarkers = (el, x, y) => {
116
+ const parts = [];
117
+ if (el?.standardLoopCharacteristics) {
118
+ parts.push(`<path d="M ${x + 18} ${y} a 6 6 0 1 1 -6 6" fill="none" stroke="black" stroke-width="1.2"/>`);
119
+ }
120
+ if (el?.multiInstanceLoopCharacteristics) {
121
+ const seq = el.multiInstanceLoopCharacteristics.isSequential === true;
122
+ if (seq) {
123
+ parts.push(`<line x1="${x + 10}" y1="${y - 4}" x2="${x + 10}" y2="${y + 4}" stroke="black" stroke-width="1.2"/>`);
124
+ parts.push(`<line x1="${x + 14}" y1="${y - 4}" x2="${x + 14}" y2="${y + 4}" stroke="black" stroke-width="1.2"/>`);
125
+ parts.push(`<line x1="${x + 18}" y1="${y - 4}" x2="${x + 18}" y2="${y + 4}" stroke="black" stroke-width="1.2"/>`);
126
+ }
127
+ else {
128
+ parts.push(`<line x1="${x + 10}" y1="${y}" x2="${x + 18}" y2="${y - 6}" stroke="black" stroke-width="1.2"/>`);
129
+ parts.push(`<line x1="${x + 10}" y1="${y}" x2="${x + 18}" y2="${y}" stroke="black" stroke-width="1.2"/>`);
130
+ parts.push(`<line x1="${x + 10}" y1="${y}" x2="${x + 18}" y2="${y + 6}" stroke="black" stroke-width="1.2"/>`);
131
+ }
132
+ }
133
+ if (el?.isForCompensation === true) {
134
+ parts.push(`<polygon points="${x + 6},${y} ${x + 2},${y + 4} ${x + 6},${y + 8}" fill="black" stroke="black" stroke-width="1"/>`);
135
+ parts.push(`<polygon points="${x + 12},${y} ${x + 8},${y + 4} ${x + 12},${y + 8}" fill="black" stroke="black" stroke-width="1"/>`);
136
+ }
137
+ return parts.join("");
138
+ };
139
+ const drawShape = (shape, warnings) => {
140
+ const t = shapeType(shape);
141
+ const b = shape.bounds;
142
+ const el = shape.element;
143
+ if (t.endsWith("Event")) {
144
+ return drawEvent(shape, b, warnings);
145
+ }
146
+ if (t.endsWith("Gateway")) {
147
+ const cx = b.x + b.width / 2;
148
+ const cy = b.y + b.height / 2;
149
+ const size = Math.min(b.width, b.height) / 2;
150
+ const core = gatewayDiamond(cx, cy, size);
151
+ const r = size * 0.35;
152
+ let marker = "";
153
+ if (t === "ExclusiveGateway")
154
+ marker = `<line x1="${cx - r}" y1="${cy - r}" x2="${cx + r}" y2="${cy + r}" stroke="black" stroke-width="1.5"/><line x1="${cx + r}" y1="${cy - r}" x2="${cx - r}" y2="${cy + r}" stroke="black" stroke-width="1.5"/>`;
155
+ else if (t === "InclusiveGateway")
156
+ marker = `<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="black" stroke-width="1.5"/>`;
157
+ else if (t === "ParallelGateway")
158
+ marker = `<line x1="${cx - r}" y1="${cy}" x2="${cx + r}" y2="${cy}" stroke="black" stroke-width="1.5"/><line x1="${cx}" y1="${cy - r}" x2="${cx}" y2="${cy + r}" stroke="black" stroke-width="1.5"/>`;
159
+ else if (t === "EventBasedGateway")
160
+ marker = `<polygon points="${cx},${cy - r} ${cx + r},${cy} ${cx},${cy + r} ${cx - r},${cy}" fill="none" stroke="black" stroke-width="1.5"/>`;
161
+ else if (t === "ComplexGateway")
162
+ marker = `<text x="${cx}" y="${cy + 4}" text-anchor="middle" font-family="sans-serif" font-size="12" fill="black">*</text>`;
163
+ return core + marker;
164
+ }
165
+ if (t === "Participant") {
166
+ const process = !!el?.processRef;
167
+ const horizontal = shape.isHorizontal !== false;
168
+ return poolRect(b.x, b.y, b.width, b.height, horizontal, process);
169
+ }
170
+ if (t === "Lane") {
171
+ const horizontal = shape.isHorizontal !== false;
172
+ return laneRect(b.x, b.y, b.width, b.height, horizontal);
173
+ }
174
+ if (t === "DataObjectReference")
175
+ return dataObject(b.x, b.y, b.width, b.height);
176
+ if (t === "DataStoreReference")
177
+ return dataStore(b.x, b.y, b.width, b.height);
178
+ if (t === "Transaction" || t === "SubProcess" || t === "AdHocSubProcess" || t === "CallActivity") {
179
+ let core;
180
+ if (t === "Transaction")
181
+ core = doubleRect(b.x, b.y, b.width, b.height);
182
+ else if (t === "CallActivity")
183
+ core = thickRect(b.x, b.y, b.width, b.height);
184
+ else
185
+ core = taskRect(b.x, b.y, b.width, b.height);
186
+ const parts = [core];
187
+ if (t === "AdHocSubProcess")
188
+ parts.push(`<text x="${b.x + 10}" y="${b.y + 14}" font-family="sans-serif" font-size="14" fill="black">~</text>`);
189
+ if (shape.isExpanded !== true && t !== "CallActivity" && t !== "Transaction") {
190
+ const cx = b.x + b.width / 2;
191
+ const cy = b.y + b.height / 2;
192
+ parts.push(`<line x1="${cx - 8}" y1="${cy}" x2="${cx + 8}" y2="${cy}" stroke="black" stroke-width="1.5"/>`);
193
+ parts.push(`<line x1="${cx}" y1="${cy - 8}" x2="${cx}" y2="${cy + 8}" stroke="black" stroke-width="1.5"/>`);
194
+ }
195
+ const markers = activityMarkers(el, b.x + 12, b.y + b.height - 10);
196
+ if (markers)
197
+ parts.push(markers);
198
+ const icon = taskIcon(t === "SubProcess" ? "" : "", b.x + 8, b.y + 8);
199
+ if (icon)
200
+ parts.push(icon);
201
+ return parts.join("");
202
+ }
203
+ if (t.endsWith("Task")) {
204
+ const parts = [taskRect(b.x, b.y, b.width, b.height)];
205
+ const icon = taskIcon(t, b.x + 8, b.y + 8);
206
+ if (icon)
207
+ parts.push(icon);
208
+ const markers = activityMarkers(el, b.x + b.width / 2, b.y + b.height - 10);
209
+ if (markers)
210
+ parts.push(markers);
211
+ const comp = el?.isForCompensation === true ? activityMarkers({ isForCompensation: true }, b.x + b.width - 20, b.y + 8) : "";
212
+ if (comp)
213
+ parts.push(comp);
214
+ return parts.join("");
215
+ }
216
+ if (t === "TextAnnotation" || t === "Group") {
217
+ return `<rect x="${b.x}" y="${b.y}" width="${b.width}" height="${b.height}" fill="none" stroke="black" stroke-width="1" stroke-dasharray="4 3"/>`;
218
+ }
219
+ unwarn(shape, "element type not specifically supported", warnings);
220
+ return taskRect(b.x, b.y, b.width, b.height);
221
+ };
222
+ const drawLabel = (text, bounds) => {
223
+ const lines = wrapText(text, bounds.width || 80);
224
+ const x = bounds.x + (bounds.width || 0) / 2;
225
+ let y = bounds.y + 12;
226
+ return lines.map((line, index) => `<text x="${x}" y="${y + index * 12}" text-anchor="middle" font-family="sans-serif" font-size="11" fill="black">${escapeXml(line)}</text>`).join("");
227
+ };
228
+ const edgeStyle = (type) => {
229
+ if (type === "MessageFlow")
230
+ return { dashed: true, dotted: false, marker: "openarrow", startMarker: "circle" };
231
+ if (type === "Association" || type === "DataAssociation")
232
+ return { dashed: false, dotted: true, marker: (type === "Association" && false) ? "arrow" : "none" };
233
+ return { dashed: false, dotted: false, marker: "arrow" };
234
+ };
235
+ export const renderDiagramSvg = (diagram) => {
236
+ const warnings = [];
237
+ let minX = Infinity;
238
+ let minY = Infinity;
239
+ let maxX = -Infinity;
240
+ let maxY = -Infinity;
241
+ const touch = (x, y) => {
242
+ minX = Math.min(minX, x);
243
+ minY = Math.min(minY, y);
244
+ maxX = Math.max(maxX, x);
245
+ maxY = Math.max(maxY, y);
246
+ };
247
+ for (const shape of diagram.shapes) {
248
+ touch(shape.bounds.x, shape.bounds.y);
249
+ touch(shape.bounds.x + shape.bounds.width, shape.bounds.y + shape.bounds.height);
250
+ if (shape.label?.bounds) {
251
+ const lb = shape.label.bounds;
252
+ touch(lb.x, lb.y);
253
+ touch(lb.x + lb.width, lb.y + lb.height);
254
+ }
255
+ else {
256
+ touch(shape.bounds.x - 20, shape.bounds.y + shape.bounds.height + 2);
257
+ touch(shape.bounds.x + shape.bounds.width + 20, shape.bounds.y + shape.bounds.height + 14);
258
+ }
259
+ }
260
+ for (const edge of diagram.edges)
261
+ for (const point of edge.waypoints)
262
+ touch(point.x, point.y);
263
+ const hasDrawable = diagram.shapes.length > 0 || diagram.edges.length > 0;
264
+ const margin = 20;
265
+ if (!hasDrawable) {
266
+ minX = 0;
267
+ minY = 0;
268
+ maxX = 100;
269
+ maxY = 100;
270
+ }
271
+ const width = Math.ceil((maxX - minX + margin * 2));
272
+ const height = Math.ceil((maxY - minY + margin * 2));
273
+ const offX = -minX + margin;
274
+ const offY = -minY + margin;
275
+ const parts = [];
276
+ const shifted = (x, y) => `${x + offX},${y + offY}`;
277
+ parts.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`);
278
+ parts.push(`<defs><marker id="arrow" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polygon points="0 0, 10 3.5, 0 7" fill="black"/></marker><marker id="openarrow" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polyline points="0 0, 10 3.5, 0 7" fill="none" stroke="black" stroke-width="1.2"/></marker></defs>`);
279
+ for (const edge of diagram.edges) {
280
+ const el = edge.element;
281
+ const t = String(el?.type ?? "SequenceFlow");
282
+ const style = edgeStyle(t);
283
+ const pts = edge.waypoints.map((p) => shifted(p.x, p.y)).join(" ");
284
+ const dash = style.dashed ? ' stroke-dasharray="6 4"' : style.dotted ? ' stroke-dasharray="2 2"' : "";
285
+ const markerEnd = style.marker === "arrow" ? ' marker-end="url(#arrow)"' : style.marker === "openarrow" ? ' marker-end="url(#openarrow)"' : "";
286
+ let edgeSvg = `<polyline points="${pts}" fill="none" stroke="black" stroke-width="1.5"${dash}${markerEnd}/>`;
287
+ if (style.startMarker === "circle") {
288
+ const sp = edge.waypoints[0];
289
+ edgeSvg = `<circle cx="${sp.x + offX}" cy="${sp.y + offY}" r="4" fill="white" stroke="black" stroke-width="1.2"/>` + edgeSvg;
290
+ }
291
+ if (t === "SequenceFlow" && el?.isDefault === true) {
292
+ const sp = edge.waypoints[0];
293
+ edgeSvg += `<line x1="${sp.x + offX - 6}" y1="${sp.y + offY + 6}" x2="${sp.x + offX + 6}" y2="${sp.y + offY - 6}" stroke="black" stroke-width="1.2"/>`;
294
+ }
295
+ if (t === "SequenceFlow" && el?.conditionExpression) {
296
+ const sp = edge.waypoints[0];
297
+ const d = 4;
298
+ edgeSvg += `<polygon points="${sp.x + offX},${sp.y + offY - d} ${sp.x + offX + d},${sp.y + offY} ${sp.x + offX},${sp.y + offY + d} ${sp.x + offX - d},${sp.y + offY}" fill="white" stroke="black" stroke-width="1.2"/>`;
299
+ }
300
+ parts.push(edgeSvg);
301
+ const name = String(el?.name ?? "");
302
+ if (name !== "" && edge.label?.bounds) {
303
+ const lb = edge.label.bounds;
304
+ const bnds = { x: lb.x + offX, y: lb.y + offY, width: lb.width, height: lb.height };
305
+ parts.push(drawLabel(name, bnds));
306
+ }
307
+ }
308
+ const renderShape = (shape) => {
309
+ const b = shape.bounds;
310
+ const sx = b.x + offX;
311
+ const sy = b.y + offY;
312
+ const shiftedBounds = { x: sx, y: sy, width: b.width, height: b.height };
313
+ const drawn = drawShape({ ...shape, bounds: shiftedBounds }, warnings);
314
+ const res = [drawn];
315
+ const el = shape.element;
316
+ const t = shapeType(shape);
317
+ let labelBounds;
318
+ if (shape.label?.bounds) {
319
+ const lb = shape.label.bounds;
320
+ labelBounds = { x: lb.x + offX, y: lb.y + offY, width: lb.width, height: lb.height };
321
+ }
322
+ else if (t.endsWith("Task") || t === "SubProcess" || t === "Transaction" || t === "AdHocSubProcess" || t === "CallActivity" || t === "Participant" || t === "Lane" || t === "DataObjectReference" || t === "DataStoreReference") {
323
+ labelBounds = { x: shiftedBounds.x + 4, y: shiftedBounds.y + shiftedBounds.height / 2 - 6, width: shiftedBounds.width - 8, height: 12 };
324
+ }
325
+ else {
326
+ labelBounds = { x: shiftedBounds.x - 20, y: shiftedBounds.y + shiftedBounds.height + 2, width: shiftedBounds.width + 40, height: 12 };
327
+ }
328
+ const name = String(el?.name ?? el?.id ?? "");
329
+ if (name !== "") {
330
+ if (t === "Participant" || t === "Lane") {
331
+ const horizontal = shape.isHorizontal !== false;
332
+ const headerBounds = horizontal
333
+ ? { x: shiftedBounds.x, y: shiftedBounds.y, width: 30, height: shiftedBounds.height }
334
+ : { x: shiftedBounds.x, y: shiftedBounds.y, width: shiftedBounds.width, height: 30 };
335
+ const nameBounds = shape.label?.bounds ? labelBounds : { x: headerBounds.x, y: headerBounds.y, width: headerBounds.width, height: headerBounds.height };
336
+ res.push(drawLabel(name, nameBounds));
337
+ }
338
+ else {
339
+ res.push(drawLabel(name, labelBounds));
340
+ }
341
+ }
342
+ return res.join("");
343
+ };
344
+ for (const shape of diagram.shapes) {
345
+ parts.push(renderShape(shape));
346
+ }
347
+ parts.push(`</svg>`);
348
+ return { svg: parts.join(""), warnings };
349
+ };
350
+ export const renderDocument = (document) => {
351
+ const diagrams = geometryDiagrams(document);
352
+ const rendered = [];
353
+ const warnings = [];
354
+ const errors = [];
355
+ const drawables = diagrams.flatMap((diagram) => (diagram.shapes.length > 0 || diagram.edges.length > 0 ? [diagram] : []));
356
+ for (const diagram of diagrams) {
357
+ const out = renderDiagramSvg(diagram);
358
+ rendered.push({ id: diagram.id, name: diagram.name, svg: out.svg, warnings: out.warnings, errors: [] });
359
+ warnings.push(...out.warnings.map((w) => ({ ...w, location: `/${diagram.id}${w.location}` })));
360
+ if (diagram.shapes.length === 0 && diagram.edges.length === 0) {
361
+ const warning = { kind: "unsupported", code: "undrawable-element", construct: "diagram", location: `/${diagram.id}`, node: diagram.bpmnElement, message: "diagram has nothing drawable" };
362
+ warnings.push(warning);
363
+ rendered[rendered.length - 1].warnings.push(warning);
364
+ }
365
+ }
366
+ if (drawables.length === 0)
367
+ errors.push({ code: "nothing-drawable", message: "model has nothing drawable" });
368
+ return { diagrams: rendered, warnings, errors };
369
+ };
@@ -0,0 +1,10 @@
1
+ export declare const eventCircle: (cx: number, cy: number, r: number, strokeWidth?: number, dashed?: boolean) => string;
2
+ export declare const taskRect: (x: number, y: number, width: number, height: number, strokeWidth?: number) => string;
3
+ export declare const gatewayDiamond: (cx: number, cy: number, size: number) => string;
4
+ export declare const doubleRect: (x: number, y: number, width: number, height: number) => string;
5
+ export declare const thickRect: (x: number, y: number, width: number, height: number) => string;
6
+ export declare const poolRect: (x: number, y: number, width: number, height: number, horizontal: boolean, process: boolean) => string;
7
+ export declare const laneRect: (x: number, y: number, width: number, height: number, horizontal: boolean) => string;
8
+ export declare const dataObject: (x: number, y: number, width: number, height: number) => string;
9
+ export declare const dataStore: (x: number, y: number, width: number, height: number) => string;
10
+ export declare const modelName: (element: any) => string;
@@ -0,0 +1,26 @@
1
+ import { escapeXml } from "./text.js";
2
+ export const eventCircle = (cx, cy, r, strokeWidth = 1.5, dashed = false) => `<circle cx="${cx}" cy="${cy}" r="${r}" fill="white" stroke="black" stroke-width="${strokeWidth}"${dashed ? ' stroke-dasharray="4 3"' : ""}/>`;
3
+ export const taskRect = (x, y, width, height, strokeWidth = 1.5) => `<rect x="${x}" y="${y}" width="${width}" height="${height}" rx="10" ry="10" fill="white" stroke="black" stroke-width="${strokeWidth}"/>`;
4
+ export const gatewayDiamond = (cx, cy, size) => `<polygon points="${cx},${cy - size} ${cx + size},${cy} ${cx},${cy + size} ${cx - size},${cy}" fill="white" stroke="black" stroke-width="1.5"/>`;
5
+ export const doubleRect = (x, y, width, height) => `${taskRect(x, y, width, height)}<rect x="${x + 4}" y="${y + 4}" width="${width - 8}" height="${height - 8}" rx="8" ry="8" fill="none" stroke="black" stroke-width="1.5"/>`;
6
+ export const thickRect = (x, y, width, height) => taskRect(x, y, width, height, 3);
7
+ export const poolRect = (x, y, width, height, horizontal, process) => {
8
+ if (!process)
9
+ return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="black" stroke="black" stroke-width="1.5"/>`;
10
+ if (horizontal) {
11
+ return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="white" stroke="black" stroke-width="1.5"/><rect x="${x}" y="${y}" width="30" height="${height}" fill="white" stroke="black" stroke-width="1.5"/>`;
12
+ }
13
+ return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="white" stroke="black" stroke-width="1.5"/><rect x="${x}" y="${y}" width="${width}" height="30" fill="white" stroke="black" stroke-width="1.5"/>`;
14
+ };
15
+ export const laneRect = (x, y, width, height, horizontal) => {
16
+ if (horizontal) {
17
+ return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="white" stroke="black" stroke-width="1.5"/><rect x="${x}" y="${y}" width="30" height="${height}" fill="white" stroke="black" stroke-width="1.5"/>`;
18
+ }
19
+ return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="white" stroke="black" stroke-width="1.5"/><rect x="${x}" y="${y}" width="${width}" height="30" fill="white" stroke="black" stroke-width="1.5"/>`;
20
+ };
21
+ export const dataObject = (x, y, width, height) => `<path d="M ${x + 6} ${y} L ${x + width - 6} ${y} L ${x + width} ${y + 6} L ${x + width} ${y + height} L ${x} ${y + height} L ${x} ${y} Z M ${x + width - 6} ${y} L ${x + width - 6} ${y + 6} L ${x + width} ${y + 6}" fill="white" stroke="black" stroke-width="1.5"/>`;
22
+ export const dataStore = (x, y, width, height) => `<ellipse cx="${x + width / 2}" cy="${y + 6}" rx="${width / 2}" ry="6" fill="white" stroke="black" stroke-width="1.5"/><rect x="${x}" y="${y + 6}" width="${width}" height="${height - 12}" fill="white" stroke="none"/><line x1="${x}" y1="${y + 6}" x2="${x}" y2="${y + height - 6}" stroke="black" stroke-width="1.5"/><line x1="${x + width}" y1="${y + 6}" x2="${x + width}" y2="${y + height - 6}" stroke="black" stroke-width="1.5"/><ellipse cx="${x + width / 2}" cy="${y + height - 6}" rx="${width / 2}" ry="6" fill="white" stroke="black" stroke-width="1.5"/>`;
23
+ export const modelName = (element) => {
24
+ const raw = element?.name ?? element?.id ?? "";
25
+ return escapeXml(raw);
26
+ };
@@ -0,0 +1,20 @@
1
+ export declare const escapeXml: (value: unknown) => string;
2
+ export declare const wrapText: (value: unknown, maxWidth: number) => string[];
3
+ export declare const labelPosition: (label: {
4
+ bounds?: {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ };
10
+ } | undefined, fallback: {
11
+ x: number;
12
+ y: number;
13
+ width: number;
14
+ height: number;
15
+ }) => {
16
+ x: number;
17
+ y: number;
18
+ width: number;
19
+ height: number;
20
+ };
@@ -0,0 +1,28 @@
1
+ const ESCAPE = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
2
+ export const escapeXml = (value) => String(value).replace(/[&<>"']/g, (char) => ESCAPE[char]);
3
+ export const wrapText = (value, maxWidth) => {
4
+ const text = String(value ?? "");
5
+ if (text === "")
6
+ return [];
7
+ const words = text.split(/\s+/);
8
+ const lines = [];
9
+ let current = "";
10
+ for (const word of words) {
11
+ const candidate = current === "" ? word : `${current} ${word}`;
12
+ if (current !== "" && candidate.length * 7 > maxWidth) {
13
+ lines.push(current);
14
+ current = word;
15
+ }
16
+ else {
17
+ current = candidate;
18
+ }
19
+ }
20
+ if (current !== "")
21
+ lines.push(current);
22
+ return lines;
23
+ };
24
+ export const labelPosition = (label, fallback) => {
25
+ if (label?.bounds)
26
+ return label.bounds;
27
+ return { x: fallback.x, y: fallback.y + fallback.height + 2, width: fallback.width, height: 12 };
28
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { runRender } from "./render-run.js";
2
+ const result = runRender(process.argv.slice(2));
3
+ if (result.stdout)
4
+ process.stdout.write(result.stdout);
5
+ if (result.stderr)
6
+ process.stderr.write(result.stderr);
7
+ process.exitCode = result.exitCode;
@@ -0,0 +1,9 @@
1
+ export declare const EXIT_OK = 0;
2
+ export declare const EXIT_BAD_INPUT = 2;
3
+ export interface CliResult {
4
+ exitCode: number;
5
+ stdout: string;
6
+ stderr: string;
7
+ }
8
+ export declare const USAGE = "Usage: render <input> [options]\n\nRenders a BPMN-LD document or BPMN XML file to SVG.\n\nOptions:\n -o, --output <file> Write SVG to <file> (one per diagram)\n --force Recompute all diagram layout\n --json Print { warnings, errors }\n -h, --help Show this help\n\nExit codes:\n 0 Rendered successfully\n 2 Usage error or unusable input\n";
9
+ export declare const runRender: (argv: string[]) => CliResult;
@@ -0,0 +1,161 @@
1
+ import { readFileSync, writeFileSync } from "node:fs";
2
+ import { pathToFileURL } from "node:url";
3
+ import { resolve } from "node:path";
4
+ import { layoutDocument, LayoutInputError } from "./layout/layout.js";
5
+ import { convert } from "./convert/convert.js";
6
+ import { ConversionError } from "./convert/errors.js";
7
+ import { renderDocument } from "./render/renderer.js";
8
+ export const EXIT_OK = 0;
9
+ export const EXIT_BAD_INPUT = 2;
10
+ export const USAGE = `Usage: render <input> [options]
11
+
12
+ Renders a BPMN-LD document or BPMN XML file to SVG.
13
+
14
+ Options:
15
+ -o, --output <file> Write SVG to <file> (one per diagram)
16
+ --force Recompute all diagram layout
17
+ --json Print { warnings, errors }
18
+ -h, --help Show this help
19
+
20
+ Exit codes:
21
+ 0 Rendered successfully
22
+ 2 Usage error or unusable input
23
+ `;
24
+ class UsageError extends Error {
25
+ }
26
+ const parseArgs = (argv) => {
27
+ let input;
28
+ const options = { input: "", force: false, json: false };
29
+ for (let i = 0; i < argv.length; i++) {
30
+ const arg = argv[i];
31
+ if (arg === "-h" || arg === "--help")
32
+ return "help";
33
+ else if (arg === "-o" || arg === "--output") {
34
+ const value = argv[++i];
35
+ if (value === undefined || value.startsWith("-"))
36
+ throw new UsageError(`${arg} requires a value`);
37
+ options.output = value;
38
+ }
39
+ else if (arg === "--force")
40
+ options.force = true;
41
+ else if (arg === "--json")
42
+ options.json = true;
43
+ else if (arg.startsWith("-"))
44
+ throw new UsageError(`unknown option ${arg}`);
45
+ else if (input !== undefined)
46
+ throw new UsageError(`unexpected extra argument ${arg}`);
47
+ else
48
+ input = arg;
49
+ }
50
+ if (input === undefined)
51
+ throw new UsageError("missing input file");
52
+ options.input = input;
53
+ return options;
54
+ };
55
+ const failure = (stderr) => ({ exitCode: EXIT_BAD_INPUT, stdout: "", stderr });
56
+ const readText = (path) => {
57
+ try {
58
+ return readFileSync(path, "utf8");
59
+ }
60
+ catch (error) {
61
+ const reason = error.code === "ENOENT" ? "no such file" : (error.message ?? "cannot read");
62
+ throw new UsageError(`cannot read ${path}: ${reason}`);
63
+ }
64
+ };
65
+ const fileName = (path) => path.split(/[\\/]/).pop() ?? path;
66
+ const suffixPath = (output, index) => {
67
+ if (index === 0)
68
+ return output;
69
+ const dot = output.lastIndexOf(".");
70
+ if (dot > output.lastIndexOf("/") && dot > output.lastIndexOf("\\") && dot > 0) {
71
+ return `${output.slice(0, dot)}-${index + 1}${output.slice(dot)}`;
72
+ }
73
+ return `${output}-${index + 1}`;
74
+ };
75
+ export const runRender = (argv) => {
76
+ let options;
77
+ try {
78
+ options = parseArgs(argv);
79
+ }
80
+ catch (error) {
81
+ if (error instanceof UsageError)
82
+ return failure(`error: ${error.message}\n\n${USAGE}`);
83
+ throw error;
84
+ }
85
+ if (options === "help")
86
+ return { exitCode: EXIT_OK, stdout: USAGE, stderr: "" };
87
+ let document;
88
+ try {
89
+ const text = readText(options.input);
90
+ let parsed;
91
+ let isJson = false;
92
+ try {
93
+ parsed = JSON.parse(text);
94
+ isJson = true;
95
+ }
96
+ catch {
97
+ isJson = false;
98
+ }
99
+ if (isJson) {
100
+ document = parsed;
101
+ }
102
+ else {
103
+ const result = convert(text, { fileName: options.input });
104
+ document = result.document;
105
+ }
106
+ }
107
+ catch (error) {
108
+ if (error instanceof UsageError || error instanceof ConversionError) {
109
+ const message = error instanceof UsageError ? error.message : `${options.input}: ${error.message}`;
110
+ if (options.json)
111
+ return { exitCode: EXIT_BAD_INPUT, stdout: `${JSON.stringify({ warnings: [], errors: [{ code: "bad-input", message }] }, null, 2)}\n`, stderr: "" };
112
+ return failure(`error: ${message}\n`);
113
+ }
114
+ throw error;
115
+ }
116
+ let rendered;
117
+ try {
118
+ rendered = renderDocument(layoutDocument(document, { force: options.force }).document);
119
+ }
120
+ catch (error) {
121
+ if (!(error instanceof LayoutInputError))
122
+ throw error;
123
+ const errors = error.errors.map((message) => ({ code: "invalid-input", message }));
124
+ if (options.json)
125
+ return { exitCode: EXIT_BAD_INPUT, stdout: `${JSON.stringify({ warnings: [], errors }, null, 2)}\n`, stderr: "" };
126
+ return failure(error.errors.map((message) => `error: ${options.input}: invalid BPMN-LD: ${message}`).join("\n") + "\n");
127
+ }
128
+ const warnings = rendered.warnings;
129
+ const errors = rendered.errors;
130
+ const aggregateErrors = errors;
131
+ if (options.output !== undefined) {
132
+ if (aggregateErrors.length > 0) {
133
+ if (options.json)
134
+ return { exitCode: EXIT_BAD_INPUT, stdout: `${JSON.stringify({ warnings, errors: aggregateErrors }, null, 2)}\n`, stderr: "" };
135
+ return failure([...warnings.map((w) => `warning: ${w.message ?? w.code}`), ...aggregateErrors.map((e) => `error: ${e.message}`)].join("\n") + "\n");
136
+ }
137
+ try {
138
+ rendered.diagrams.forEach((diagram, index) => {
139
+ writeFileSync(suffixPath(options.output, index), diagram.svg);
140
+ });
141
+ }
142
+ catch (error) {
143
+ const message = `cannot write ${options.output}: ${error.message}`;
144
+ if (options.json)
145
+ return { exitCode: EXIT_BAD_INPUT, stdout: `${JSON.stringify({ warnings, errors: [...aggregateErrors, { code: "cannot-write", message }] }, null, 2)}\n`, stderr: "" };
146
+ return failure(`error: ${message}\n`);
147
+ }
148
+ if (options.json)
149
+ return { exitCode: EXIT_OK, stdout: `${JSON.stringify({ warnings, errors: [] }, null, 2)}\n`, stderr: "" };
150
+ return { exitCode: EXIT_OK, stdout: "", stderr: warnings.length ? `${warnings.map((w) => `warning: ${w.message ?? w.code}`).join("\n")}\n` : "" };
151
+ }
152
+ if (aggregateErrors.length > 0) {
153
+ if (options.json)
154
+ return { exitCode: EXIT_BAD_INPUT, stdout: `${JSON.stringify({ warnings, errors: aggregateErrors }, null, 2)}\n`, stderr: "" };
155
+ return failure([...warnings.map((w) => `warning: ${w.message ?? w.code}`), ...aggregateErrors.map((e) => `error: ${e.message}`)].join("\n") + "\n");
156
+ }
157
+ const stdout = rendered.diagrams.length === 1 ? `${rendered.diagrams[0].svg}\n` : `${rendered.diagrams.map((d) => d.svg).join("\n")}\n`;
158
+ if (options.json)
159
+ return { exitCode: EXIT_OK, stdout: `${JSON.stringify({ warnings, errors: [] }, null, 2)}\n`, stderr: "" };
160
+ return { exitCode: EXIT_OK, stdout, stderr: warnings.length ? `${warnings.map((w) => `warning: ${w.message ?? w.code}`).join("\n")}\n` : "" };
161
+ };