@cristianormazabal/triton-core 0.1.0 → 0.1.2

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 (627) hide show
  1. package/dist/contracts/anchors.js +20 -0
  2. package/dist/contracts/anchors.js.map +1 -0
  3. package/dist/contracts/animations.d.ts +5 -0
  4. package/dist/contracts/animations.d.ts.map +1 -0
  5. package/dist/contracts/animations.js +15 -0
  6. package/dist/contracts/animations.js.map +1 -0
  7. package/dist/contracts/crosslink.d.ts +21 -41
  8. package/dist/contracts/crosslink.d.ts.map +1 -1
  9. package/dist/contracts/crosslink.js +17 -0
  10. package/dist/contracts/crosslink.js.map +1 -0
  11. package/dist/contracts/diagram.js +24 -0
  12. package/dist/contracts/diagram.js.map +1 -0
  13. package/dist/contracts/index.d.ts +6 -3
  14. package/dist/contracts/index.d.ts.map +1 -1
  15. package/dist/contracts/index.js +21 -0
  16. package/dist/contracts/index.js.map +1 -0
  17. package/dist/contracts/overlay.js +22 -0
  18. package/dist/contracts/overlay.js.map +1 -0
  19. package/dist/contracts/primitives.js +13 -0
  20. package/dist/contracts/primitives.js.map +1 -0
  21. package/dist/contracts/renderer.js +15 -0
  22. package/dist/contracts/renderer.js.map +1 -0
  23. package/dist/contracts/result.js +26 -0
  24. package/dist/contracts/result.js.map +1 -0
  25. package/dist/contracts/routing.d.ts +4 -0
  26. package/dist/contracts/routing.d.ts.map +1 -1
  27. package/dist/contracts/routing.js +14 -0
  28. package/dist/contracts/routing.js.map +1 -0
  29. package/dist/contracts/scene.d.ts +5 -1
  30. package/dist/contracts/scene.d.ts.map +1 -1
  31. package/dist/contracts/scene.js +18 -0
  32. package/dist/contracts/scene.js.map +1 -0
  33. package/dist/contracts/theme.js +18 -0
  34. package/dist/contracts/theme.js.map +1 -0
  35. package/dist/crosslink/connectors.d.ts +66 -0
  36. package/dist/crosslink/connectors.d.ts.map +1 -0
  37. package/dist/crosslink/connectors.js +130 -0
  38. package/dist/crosslink/connectors.js.map +1 -0
  39. package/dist/crosslink/engine2.d.ts +2 -2
  40. package/dist/crosslink/engine2.d.ts.map +1 -1
  41. package/dist/crosslink/engine2.js +783 -0
  42. package/dist/crosslink/engine2.js.map +1 -0
  43. package/dist/crosslink/engine3.d.ts +2 -2
  44. package/dist/crosslink/engine3.d.ts.map +1 -1
  45. package/dist/crosslink/engine3.js +968 -0
  46. package/dist/crosslink/engine3.js.map +1 -0
  47. package/dist/crosslink/index.d.ts +2 -0
  48. package/dist/crosslink/index.d.ts.map +1 -1
  49. package/dist/crosslink/index.js +4 -0
  50. package/dist/crosslink/index.js.map +1 -0
  51. package/dist/crosslink/render.d.ts +2 -2
  52. package/dist/crosslink/render.d.ts.map +1 -1
  53. package/dist/crosslink/render.js +997 -0
  54. package/dist/crosslink/render.js.map +1 -0
  55. package/dist/crosslink/resolve.js +331 -0
  56. package/dist/crosslink/resolve.js.map +1 -0
  57. package/dist/diagrams/{c4 → mermaid/c4}/index.d.ts +1 -1
  58. package/dist/diagrams/mermaid/c4/index.d.ts.map +1 -0
  59. package/dist/diagrams/mermaid/c4/index.js +14 -0
  60. package/dist/diagrams/mermaid/c4/index.js.map +1 -0
  61. package/dist/diagrams/{c4 → mermaid/c4}/ir.d.ts +1 -1
  62. package/dist/diagrams/mermaid/c4/ir.d.ts.map +1 -0
  63. package/dist/diagrams/mermaid/c4/ir.js +2 -0
  64. package/dist/diagrams/mermaid/c4/ir.js.map +1 -0
  65. package/dist/diagrams/{c4 → mermaid/c4}/layout.d.ts +2 -2
  66. package/dist/diagrams/mermaid/c4/layout.d.ts.map +1 -0
  67. package/dist/diagrams/mermaid/c4/layout.js +110 -0
  68. package/dist/diagrams/mermaid/c4/layout.js.map +1 -0
  69. package/dist/diagrams/{class → mermaid/class}/index.d.ts +1 -1
  70. package/dist/diagrams/mermaid/class/index.d.ts.map +1 -0
  71. package/dist/diagrams/mermaid/class/index.js +14 -0
  72. package/dist/diagrams/mermaid/class/index.js.map +1 -0
  73. package/dist/diagrams/{class → mermaid/class}/ir.d.ts +1 -1
  74. package/dist/diagrams/mermaid/class/ir.d.ts.map +1 -0
  75. package/dist/diagrams/mermaid/class/ir.js +2 -0
  76. package/dist/diagrams/mermaid/class/ir.js.map +1 -0
  77. package/dist/diagrams/{class → mermaid/class}/layout.d.ts +2 -2
  78. package/dist/diagrams/mermaid/class/layout.d.ts.map +1 -0
  79. package/dist/diagrams/mermaid/class/layout.js +877 -0
  80. package/dist/diagrams/mermaid/class/layout.js.map +1 -0
  81. package/dist/diagrams/{er → mermaid/er}/index.d.ts +1 -1
  82. package/dist/diagrams/mermaid/er/index.d.ts.map +1 -0
  83. package/dist/diagrams/mermaid/er/index.js +14 -0
  84. package/dist/diagrams/mermaid/er/index.js.map +1 -0
  85. package/dist/diagrams/{er → mermaid/er}/ir.d.ts +1 -1
  86. package/dist/diagrams/mermaid/er/ir.d.ts.map +1 -0
  87. package/dist/diagrams/mermaid/er/ir.js +2 -0
  88. package/dist/diagrams/mermaid/er/ir.js.map +1 -0
  89. package/dist/diagrams/{er → mermaid/er}/layout.d.ts +2 -2
  90. package/dist/diagrams/mermaid/er/layout.d.ts.map +1 -0
  91. package/dist/diagrams/mermaid/er/layout.js +116 -0
  92. package/dist/diagrams/mermaid/er/layout.js.map +1 -0
  93. package/dist/diagrams/{flowchart → mermaid/flowchart}/index.d.ts +1 -1
  94. package/dist/diagrams/mermaid/flowchart/index.d.ts.map +1 -0
  95. package/dist/diagrams/mermaid/flowchart/index.js +24 -0
  96. package/dist/diagrams/mermaid/flowchart/index.js.map +1 -0
  97. package/dist/diagrams/{flowchart → mermaid/flowchart}/ir.d.ts +7 -1
  98. package/dist/diagrams/mermaid/flowchart/ir.d.ts.map +1 -0
  99. package/dist/diagrams/mermaid/flowchart/ir.js +2 -0
  100. package/dist/diagrams/mermaid/flowchart/ir.js.map +1 -0
  101. package/dist/diagrams/mermaid/flowchart/layout.d.ts +5 -0
  102. package/dist/diagrams/mermaid/flowchart/layout.d.ts.map +1 -0
  103. package/dist/diagrams/mermaid/flowchart/layout.js +652 -0
  104. package/dist/diagrams/mermaid/flowchart/layout.js.map +1 -0
  105. package/dist/diagrams/{gantt → mermaid/gantt}/index.d.ts +1 -1
  106. package/dist/diagrams/mermaid/gantt/index.d.ts.map +1 -0
  107. package/dist/diagrams/mermaid/gantt/index.js +89 -0
  108. package/dist/diagrams/mermaid/gantt/index.js.map +1 -0
  109. package/dist/diagrams/{gantt → mermaid/gantt}/ir.d.ts +1 -1
  110. package/dist/diagrams/mermaid/gantt/ir.d.ts.map +1 -0
  111. package/dist/diagrams/mermaid/gantt/ir.js +2 -0
  112. package/dist/diagrams/mermaid/gantt/ir.js.map +1 -0
  113. package/dist/diagrams/{gantt → mermaid/gantt}/layout.d.ts +2 -2
  114. package/dist/diagrams/mermaid/gantt/layout.d.ts.map +1 -0
  115. package/dist/diagrams/mermaid/gantt/layout.js +95 -0
  116. package/dist/diagrams/mermaid/gantt/layout.js.map +1 -0
  117. package/dist/diagrams/{gitgraph → mermaid/gitgraph}/index.d.ts +1 -1
  118. package/dist/diagrams/mermaid/gitgraph/index.d.ts.map +1 -0
  119. package/dist/diagrams/mermaid/gitgraph/index.js +58 -0
  120. package/dist/diagrams/mermaid/gitgraph/index.js.map +1 -0
  121. package/dist/diagrams/{gitgraph → mermaid/gitgraph}/ir.d.ts +1 -1
  122. package/dist/diagrams/mermaid/gitgraph/ir.d.ts.map +1 -0
  123. package/dist/diagrams/mermaid/gitgraph/ir.js +2 -0
  124. package/dist/diagrams/mermaid/gitgraph/ir.js.map +1 -0
  125. package/dist/diagrams/{gitgraph → mermaid/gitgraph}/layout.d.ts +2 -2
  126. package/dist/diagrams/mermaid/gitgraph/layout.d.ts.map +1 -0
  127. package/dist/diagrams/mermaid/gitgraph/layout.js +89 -0
  128. package/dist/diagrams/mermaid/gitgraph/layout.js.map +1 -0
  129. package/dist/diagrams/{journey → mermaid/journey}/index.d.ts +1 -1
  130. package/dist/diagrams/mermaid/journey/index.d.ts.map +1 -0
  131. package/dist/diagrams/mermaid/journey/index.js +14 -0
  132. package/dist/diagrams/mermaid/journey/index.js.map +1 -0
  133. package/dist/diagrams/{journey → mermaid/journey}/ir.d.ts +1 -1
  134. package/dist/diagrams/mermaid/journey/ir.d.ts.map +1 -0
  135. package/dist/diagrams/mermaid/journey/ir.js +2 -0
  136. package/dist/diagrams/mermaid/journey/ir.js.map +1 -0
  137. package/dist/diagrams/{journey → mermaid/journey}/layout.d.ts +2 -2
  138. package/dist/diagrams/mermaid/journey/layout.d.ts.map +1 -0
  139. package/dist/diagrams/mermaid/journey/layout.js +92 -0
  140. package/dist/diagrams/mermaid/journey/layout.js.map +1 -0
  141. package/dist/diagrams/{kanban → mermaid/kanban}/index.d.ts +1 -1
  142. package/dist/diagrams/mermaid/kanban/index.d.ts.map +1 -0
  143. package/dist/diagrams/mermaid/kanban/index.js +14 -0
  144. package/dist/diagrams/mermaid/kanban/index.js.map +1 -0
  145. package/dist/diagrams/{kanban → mermaid/kanban}/ir.d.ts +1 -1
  146. package/dist/diagrams/mermaid/kanban/ir.d.ts.map +1 -0
  147. package/dist/diagrams/mermaid/kanban/ir.js +2 -0
  148. package/dist/diagrams/mermaid/kanban/ir.js.map +1 -0
  149. package/dist/diagrams/{kanban → mermaid/kanban}/layout.d.ts +2 -2
  150. package/dist/diagrams/mermaid/kanban/layout.d.ts.map +1 -0
  151. package/dist/diagrams/mermaid/kanban/layout.js +68 -0
  152. package/dist/diagrams/mermaid/kanban/layout.js.map +1 -0
  153. package/dist/diagrams/{mindmap → mermaid/mindmap}/index.d.ts +1 -1
  154. package/dist/diagrams/mermaid/mindmap/index.d.ts.map +1 -0
  155. package/dist/diagrams/mermaid/mindmap/index.js +52 -0
  156. package/dist/diagrams/mermaid/mindmap/index.js.map +1 -0
  157. package/dist/diagrams/{mindmap → mermaid/mindmap}/ir.d.ts +1 -1
  158. package/dist/diagrams/mermaid/mindmap/ir.d.ts.map +1 -0
  159. package/dist/diagrams/mermaid/mindmap/ir.js +2 -0
  160. package/dist/diagrams/mermaid/mindmap/ir.js.map +1 -0
  161. package/dist/diagrams/{mindmap → mermaid/mindmap}/layout.d.ts +2 -2
  162. package/dist/diagrams/mermaid/mindmap/layout.d.ts.map +1 -0
  163. package/dist/diagrams/mermaid/mindmap/layout.js +100 -0
  164. package/dist/diagrams/mermaid/mindmap/layout.js.map +1 -0
  165. package/dist/diagrams/{pie → mermaid/pie}/index.d.ts +1 -1
  166. package/dist/diagrams/mermaid/pie/index.d.ts.map +1 -0
  167. package/dist/diagrams/mermaid/pie/index.js +14 -0
  168. package/dist/diagrams/mermaid/pie/index.js.map +1 -0
  169. package/dist/diagrams/{pie → mermaid/pie}/ir.d.ts +1 -1
  170. package/dist/diagrams/mermaid/pie/ir.d.ts.map +1 -0
  171. package/dist/diagrams/mermaid/pie/ir.js +2 -0
  172. package/dist/diagrams/mermaid/pie/ir.js.map +1 -0
  173. package/dist/diagrams/{pie → mermaid/pie}/layout.d.ts +2 -2
  174. package/dist/diagrams/mermaid/pie/layout.d.ts.map +1 -0
  175. package/dist/diagrams/mermaid/pie/layout.js +84 -0
  176. package/dist/diagrams/mermaid/pie/layout.js.map +1 -0
  177. package/dist/diagrams/{quadrant → mermaid/quadrant}/index.d.ts +1 -1
  178. package/dist/diagrams/mermaid/quadrant/index.d.ts.map +1 -0
  179. package/dist/diagrams/mermaid/quadrant/index.js +14 -0
  180. package/dist/diagrams/mermaid/quadrant/index.js.map +1 -0
  181. package/dist/diagrams/{quadrant → mermaid/quadrant}/ir.d.ts +1 -1
  182. package/dist/diagrams/mermaid/quadrant/ir.d.ts.map +1 -0
  183. package/dist/diagrams/mermaid/quadrant/ir.js +2 -0
  184. package/dist/diagrams/mermaid/quadrant/ir.js.map +1 -0
  185. package/dist/diagrams/{quadrant → mermaid/quadrant}/layout.d.ts +2 -2
  186. package/dist/diagrams/mermaid/quadrant/layout.d.ts.map +1 -0
  187. package/dist/diagrams/mermaid/quadrant/layout.js +83 -0
  188. package/dist/diagrams/mermaid/quadrant/layout.js.map +1 -0
  189. package/dist/diagrams/{radar → mermaid/radar}/index.d.ts +1 -1
  190. package/dist/diagrams/mermaid/radar/index.d.ts.map +1 -0
  191. package/dist/diagrams/mermaid/radar/index.js +14 -0
  192. package/dist/diagrams/mermaid/radar/index.js.map +1 -0
  193. package/dist/diagrams/{radar → mermaid/radar}/ir.d.ts +1 -1
  194. package/dist/diagrams/mermaid/radar/ir.d.ts.map +1 -0
  195. package/dist/diagrams/mermaid/radar/ir.js +2 -0
  196. package/dist/diagrams/mermaid/radar/ir.js.map +1 -0
  197. package/dist/diagrams/{radar → mermaid/radar}/layout.d.ts +2 -2
  198. package/dist/diagrams/mermaid/radar/layout.d.ts.map +1 -0
  199. package/dist/diagrams/mermaid/radar/layout.js +91 -0
  200. package/dist/diagrams/mermaid/radar/layout.js.map +1 -0
  201. package/dist/diagrams/{requirement → mermaid/requirement}/index.d.ts +1 -1
  202. package/dist/diagrams/mermaid/requirement/index.d.ts.map +1 -0
  203. package/dist/diagrams/mermaid/requirement/index.js +14 -0
  204. package/dist/diagrams/mermaid/requirement/index.js.map +1 -0
  205. package/dist/diagrams/{requirement → mermaid/requirement}/ir.d.ts +1 -1
  206. package/dist/diagrams/mermaid/requirement/ir.d.ts.map +1 -0
  207. package/dist/diagrams/mermaid/requirement/ir.js +2 -0
  208. package/dist/diagrams/mermaid/requirement/ir.js.map +1 -0
  209. package/dist/diagrams/{requirement → mermaid/requirement}/layout.d.ts +2 -2
  210. package/dist/diagrams/mermaid/requirement/layout.d.ts.map +1 -0
  211. package/dist/diagrams/mermaid/requirement/layout.js +79 -0
  212. package/dist/diagrams/mermaid/requirement/layout.js.map +1 -0
  213. package/dist/diagrams/{sankey → mermaid/sankey}/index.d.ts +1 -1
  214. package/dist/diagrams/mermaid/sankey/index.d.ts.map +1 -0
  215. package/dist/diagrams/mermaid/sankey/index.js +14 -0
  216. package/dist/diagrams/mermaid/sankey/index.js.map +1 -0
  217. package/dist/diagrams/{sankey → mermaid/sankey}/ir.d.ts +1 -1
  218. package/dist/diagrams/mermaid/sankey/ir.d.ts.map +1 -0
  219. package/dist/diagrams/mermaid/sankey/ir.js +2 -0
  220. package/dist/diagrams/mermaid/sankey/ir.js.map +1 -0
  221. package/dist/diagrams/{sankey → mermaid/sankey}/layout.d.ts +2 -2
  222. package/dist/diagrams/mermaid/sankey/layout.d.ts.map +1 -0
  223. package/dist/diagrams/mermaid/sankey/layout.js +124 -0
  224. package/dist/diagrams/mermaid/sankey/layout.js.map +1 -0
  225. package/dist/diagrams/{sequence → mermaid/sequence}/index.d.ts +1 -1
  226. package/dist/diagrams/mermaid/sequence/index.d.ts.map +1 -0
  227. package/dist/diagrams/mermaid/sequence/index.js +14 -0
  228. package/dist/diagrams/mermaid/sequence/index.js.map +1 -0
  229. package/dist/diagrams/{sequence → mermaid/sequence}/ir.d.ts +1 -1
  230. package/dist/diagrams/mermaid/sequence/ir.d.ts.map +1 -0
  231. package/dist/diagrams/mermaid/sequence/ir.js +2 -0
  232. package/dist/diagrams/mermaid/sequence/ir.js.map +1 -0
  233. package/dist/diagrams/{sequence → mermaid/sequence}/layout.d.ts +2 -2
  234. package/dist/diagrams/mermaid/sequence/layout.d.ts.map +1 -0
  235. package/dist/diagrams/mermaid/sequence/layout.js +168 -0
  236. package/dist/diagrams/mermaid/sequence/layout.js.map +1 -0
  237. package/dist/diagrams/{state → mermaid/state}/index.d.ts +1 -1
  238. package/dist/diagrams/mermaid/state/index.d.ts.map +1 -0
  239. package/dist/diagrams/mermaid/state/index.js +14 -0
  240. package/dist/diagrams/mermaid/state/index.js.map +1 -0
  241. package/dist/diagrams/{state → mermaid/state}/ir.d.ts +1 -1
  242. package/dist/diagrams/mermaid/state/ir.d.ts.map +1 -0
  243. package/dist/diagrams/mermaid/state/ir.js +2 -0
  244. package/dist/diagrams/mermaid/state/ir.js.map +1 -0
  245. package/dist/diagrams/{state → mermaid/state}/layout.d.ts +2 -2
  246. package/dist/diagrams/mermaid/state/layout.d.ts.map +1 -0
  247. package/dist/diagrams/mermaid/state/layout.js +172 -0
  248. package/dist/diagrams/mermaid/state/layout.js.map +1 -0
  249. package/dist/diagrams/{timeline → mermaid/timeline}/index.d.ts +1 -1
  250. package/dist/diagrams/mermaid/timeline/index.d.ts.map +1 -0
  251. package/dist/diagrams/mermaid/timeline/index.js +23 -0
  252. package/dist/diagrams/mermaid/timeline/index.js.map +1 -0
  253. package/dist/diagrams/{timeline → mermaid/timeline}/ir.d.ts +1 -1
  254. package/dist/diagrams/mermaid/timeline/ir.d.ts.map +1 -0
  255. package/dist/diagrams/mermaid/timeline/ir.js +2 -0
  256. package/dist/diagrams/mermaid/timeline/ir.js.map +1 -0
  257. package/dist/diagrams/mermaid/timeline/layout.d.ts +5 -0
  258. package/dist/diagrams/mermaid/timeline/layout.d.ts.map +1 -0
  259. package/dist/diagrams/mermaid/timeline/layout.js +228 -0
  260. package/dist/diagrams/mermaid/timeline/layout.js.map +1 -0
  261. package/dist/diagrams/{timeline → mermaid/timeline}/numbered.d.ts +2 -2
  262. package/dist/diagrams/mermaid/timeline/numbered.d.ts.map +1 -0
  263. package/dist/diagrams/mermaid/timeline/numbered.js +112 -0
  264. package/dist/diagrams/mermaid/timeline/numbered.js.map +1 -0
  265. package/dist/diagrams/{timeline → mermaid/timeline}/roadmap.d.ts +2 -2
  266. package/dist/diagrams/mermaid/timeline/roadmap.d.ts.map +1 -0
  267. package/dist/diagrams/mermaid/timeline/roadmap.js +125 -0
  268. package/dist/diagrams/mermaid/timeline/roadmap.js.map +1 -0
  269. package/dist/diagrams/{timeline → mermaid/timeline}/serpentine.d.ts +2 -2
  270. package/dist/diagrams/mermaid/timeline/serpentine.d.ts.map +1 -0
  271. package/dist/diagrams/mermaid/timeline/serpentine.js +152 -0
  272. package/dist/diagrams/mermaid/timeline/serpentine.js.map +1 -0
  273. package/dist/diagrams/{timeline → mermaid/timeline}/shared.d.ts +1 -1
  274. package/dist/diagrams/mermaid/timeline/shared.d.ts.map +1 -0
  275. package/dist/diagrams/mermaid/timeline/shared.js +47 -0
  276. package/dist/diagrams/mermaid/timeline/shared.js.map +1 -0
  277. package/dist/diagrams/{timeline → mermaid/timeline}/timeline-columns.d.ts +2 -2
  278. package/dist/diagrams/mermaid/timeline/timeline-columns.d.ts.map +1 -0
  279. package/dist/diagrams/mermaid/timeline/timeline-columns.js +136 -0
  280. package/dist/diagrams/mermaid/timeline/timeline-columns.js.map +1 -0
  281. package/dist/diagrams/{timeline → mermaid/timeline}/vertical-spine.d.ts +2 -2
  282. package/dist/diagrams/mermaid/timeline/vertical-spine.d.ts.map +1 -0
  283. package/dist/diagrams/mermaid/timeline/vertical-spine.js +136 -0
  284. package/dist/diagrams/mermaid/timeline/vertical-spine.js.map +1 -0
  285. package/dist/diagrams/{xychart → mermaid/xychart}/index.d.ts +1 -1
  286. package/dist/diagrams/mermaid/xychart/index.d.ts.map +1 -0
  287. package/dist/diagrams/mermaid/xychart/index.js +14 -0
  288. package/dist/diagrams/mermaid/xychart/index.js.map +1 -0
  289. package/dist/diagrams/{xychart → mermaid/xychart}/ir.d.ts +1 -1
  290. package/dist/diagrams/mermaid/xychart/ir.d.ts.map +1 -0
  291. package/dist/diagrams/mermaid/xychart/ir.js +2 -0
  292. package/dist/diagrams/mermaid/xychart/ir.js.map +1 -0
  293. package/dist/diagrams/{xychart → mermaid/xychart}/layout.d.ts +2 -2
  294. package/dist/diagrams/mermaid/xychart/layout.d.ts.map +1 -0
  295. package/dist/diagrams/mermaid/xychart/layout.js +120 -0
  296. package/dist/diagrams/mermaid/xychart/layout.js.map +1 -0
  297. package/dist/diagrams/{architecture → triton/architecture}/index.d.ts +1 -1
  298. package/dist/diagrams/triton/architecture/index.d.ts.map +1 -0
  299. package/dist/diagrams/triton/architecture/index.js +14 -0
  300. package/dist/diagrams/triton/architecture/index.js.map +1 -0
  301. package/dist/diagrams/{architecture → triton/architecture}/ir.d.ts +1 -1
  302. package/dist/diagrams/triton/architecture/ir.d.ts.map +1 -0
  303. package/dist/diagrams/triton/architecture/ir.js +2 -0
  304. package/dist/diagrams/triton/architecture/ir.js.map +1 -0
  305. package/dist/diagrams/{architecture → triton/architecture}/layout.d.ts +2 -2
  306. package/dist/diagrams/triton/architecture/layout.d.ts.map +1 -0
  307. package/dist/diagrams/triton/architecture/layout.js +124 -0
  308. package/dist/diagrams/triton/architecture/layout.js.map +1 -0
  309. package/dist/diagrams/{block → triton/block}/index.d.ts +1 -1
  310. package/dist/diagrams/triton/block/index.d.ts.map +1 -0
  311. package/dist/diagrams/triton/block/index.js +14 -0
  312. package/dist/diagrams/triton/block/index.js.map +1 -0
  313. package/dist/diagrams/{block → triton/block}/ir.d.ts +1 -1
  314. package/dist/diagrams/triton/block/ir.d.ts.map +1 -0
  315. package/dist/diagrams/triton/block/ir.js +2 -0
  316. package/dist/diagrams/triton/block/ir.js.map +1 -0
  317. package/dist/diagrams/{block → triton/block}/layout.d.ts +2 -2
  318. package/dist/diagrams/triton/block/layout.d.ts.map +1 -0
  319. package/dist/diagrams/triton/block/layout.js +73 -0
  320. package/dist/diagrams/triton/block/layout.js.map +1 -0
  321. package/dist/diagrams/{ds → triton/ds}/graph/graph.d.ts +1 -1
  322. package/dist/diagrams/triton/ds/graph/graph.d.ts.map +1 -0
  323. package/dist/diagrams/triton/ds/graph/graph.js +140 -0
  324. package/dist/diagrams/triton/ds/graph/graph.js.map +1 -0
  325. package/dist/diagrams/{ds → triton/ds}/hashmap/hashmap.d.ts +1 -1
  326. package/dist/diagrams/triton/ds/hashmap/hashmap.d.ts.map +1 -0
  327. package/dist/diagrams/triton/ds/hashmap/hashmap.js +131 -0
  328. package/dist/diagrams/triton/ds/hashmap/hashmap.js.map +1 -0
  329. package/dist/diagrams/{ds → triton/ds}/matrix/matrix.d.ts +1 -1
  330. package/dist/diagrams/triton/ds/matrix/matrix.d.ts.map +1 -0
  331. package/dist/diagrams/triton/ds/matrix/matrix.js +113 -0
  332. package/dist/diagrams/triton/ds/matrix/matrix.js.map +1 -0
  333. package/dist/diagrams/{ds → triton/ds}/queue/cqueue.d.ts +5 -3
  334. package/dist/diagrams/triton/ds/queue/cqueue.d.ts.map +1 -0
  335. package/dist/diagrams/triton/ds/queue/cqueue.js +195 -0
  336. package/dist/diagrams/triton/ds/queue/cqueue.js.map +1 -0
  337. package/dist/diagrams/{ds → triton/ds}/queue/deque.d.ts +3 -1
  338. package/dist/diagrams/triton/ds/queue/deque.d.ts.map +1 -0
  339. package/dist/diagrams/triton/ds/queue/deque.js +118 -0
  340. package/dist/diagrams/triton/ds/queue/deque.js.map +1 -0
  341. package/dist/diagrams/{ds → triton/ds}/queue/pqueue.d.ts +5 -3
  342. package/dist/diagrams/triton/ds/queue/pqueue.d.ts.map +1 -0
  343. package/dist/diagrams/triton/ds/queue/pqueue.js +129 -0
  344. package/dist/diagrams/triton/ds/queue/pqueue.js.map +1 -0
  345. package/dist/diagrams/{ds → triton/ds}/queue/queue.d.ts +3 -1
  346. package/dist/diagrams/triton/ds/queue/queue.d.ts.map +1 -0
  347. package/dist/diagrams/triton/ds/queue/queue.js +128 -0
  348. package/dist/diagrams/triton/ds/queue/queue.js.map +1 -0
  349. package/dist/diagrams/{ds → triton/ds}/queue/shared.d.ts +18 -2
  350. package/dist/diagrams/triton/ds/queue/shared.d.ts.map +1 -0
  351. package/dist/diagrams/triton/ds/queue/shared.js +186 -0
  352. package/dist/diagrams/triton/ds/queue/shared.js.map +1 -0
  353. package/dist/diagrams/{ds → triton/ds}/stack/stack.d.ts +3 -1
  354. package/dist/diagrams/triton/ds/stack/stack.d.ts.map +1 -0
  355. package/dist/diagrams/triton/ds/stack/stack.js +119 -0
  356. package/dist/diagrams/triton/ds/stack/stack.js.map +1 -0
  357. package/dist/diagrams/triton/ds/struct/array.d.ts +52 -0
  358. package/dist/diagrams/triton/ds/struct/array.d.ts.map +1 -0
  359. package/dist/diagrams/triton/ds/struct/array.js +491 -0
  360. package/dist/diagrams/triton/ds/struct/array.js.map +1 -0
  361. package/dist/diagrams/{ds → triton/ds}/struct/linkedlist.d.ts +1 -1
  362. package/dist/diagrams/triton/ds/struct/linkedlist.d.ts.map +1 -0
  363. package/dist/diagrams/triton/ds/struct/linkedlist.js +99 -0
  364. package/dist/diagrams/triton/ds/struct/linkedlist.js.map +1 -0
  365. package/dist/diagrams/{ds → triton/ds}/struct/memory.d.ts +1 -1
  366. package/dist/diagrams/triton/ds/struct/memory.d.ts.map +1 -0
  367. package/dist/diagrams/triton/ds/struct/memory.js +172 -0
  368. package/dist/diagrams/triton/ds/struct/memory.js.map +1 -0
  369. package/dist/diagrams/{ds → triton/ds}/struct/page.d.ts +1 -1
  370. package/dist/diagrams/triton/ds/struct/page.d.ts.map +1 -0
  371. package/dist/diagrams/triton/ds/struct/page.js +137 -0
  372. package/dist/diagrams/triton/ds/struct/page.js.map +1 -0
  373. package/dist/diagrams/triton/ds/struct/shared.d.ts +17 -0
  374. package/dist/diagrams/triton/ds/struct/shared.d.ts.map +1 -0
  375. package/dist/diagrams/triton/ds/struct/shared.js +60 -0
  376. package/dist/diagrams/triton/ds/struct/shared.js.map +1 -0
  377. package/dist/diagrams/{ds → triton/ds}/tree/avl.d.ts +1 -1
  378. package/dist/diagrams/triton/ds/tree/avl.d.ts.map +1 -0
  379. package/dist/diagrams/triton/ds/tree/avl.js +87 -0
  380. package/dist/diagrams/triton/ds/tree/avl.js.map +1 -0
  381. package/dist/diagrams/{ds → triton/ds}/tree/btree.d.ts +1 -1
  382. package/dist/diagrams/triton/ds/tree/btree.d.ts.map +1 -0
  383. package/dist/diagrams/triton/ds/tree/btree.js +76 -0
  384. package/dist/diagrams/triton/ds/tree/btree.js.map +1 -0
  385. package/dist/diagrams/triton/ds/tree/build.d.ts.map +1 -0
  386. package/dist/diagrams/triton/ds/tree/build.js +51 -0
  387. package/dist/diagrams/triton/ds/tree/build.js.map +1 -0
  388. package/dist/diagrams/{ds → triton/ds}/tree/heap.d.ts +1 -1
  389. package/dist/diagrams/triton/ds/tree/heap.d.ts.map +1 -0
  390. package/dist/diagrams/triton/ds/tree/heap.js +48 -0
  391. package/dist/diagrams/triton/ds/tree/heap.js.map +1 -0
  392. package/dist/diagrams/{ds → triton/ds}/tree/index.d.ts +1 -1
  393. package/dist/diagrams/triton/ds/tree/index.d.ts.map +1 -0
  394. package/dist/diagrams/triton/ds/tree/index.js +20 -0
  395. package/dist/diagrams/triton/ds/tree/index.js.map +1 -0
  396. package/dist/diagrams/{ds → triton/ds}/tree/ir.d.ts +1 -1
  397. package/dist/diagrams/triton/ds/tree/ir.d.ts.map +1 -0
  398. package/dist/diagrams/triton/ds/tree/ir.js +10 -0
  399. package/dist/diagrams/triton/ds/tree/ir.js.map +1 -0
  400. package/dist/diagrams/{ds → triton/ds}/tree/layout.d.ts +1 -1
  401. package/dist/diagrams/triton/ds/tree/layout.d.ts.map +1 -0
  402. package/dist/diagrams/triton/ds/tree/layout.js +281 -0
  403. package/dist/diagrams/triton/ds/tree/layout.js.map +1 -0
  404. package/dist/diagrams/{ds → triton/ds}/tree/plan.d.ts +1 -1
  405. package/dist/diagrams/triton/ds/tree/plan.d.ts.map +1 -0
  406. package/dist/diagrams/triton/ds/tree/plan.js +48 -0
  407. package/dist/diagrams/triton/ds/tree/plan.js.map +1 -0
  408. package/dist/diagrams/{ds → triton/ds}/tree/radix.d.ts +1 -1
  409. package/dist/diagrams/triton/ds/tree/radix.d.ts.map +1 -0
  410. package/dist/diagrams/triton/ds/tree/radix.js +88 -0
  411. package/dist/diagrams/triton/ds/tree/radix.js.map +1 -0
  412. package/dist/diagrams/{ds → triton/ds}/tree/rbtree.d.ts +1 -1
  413. package/dist/diagrams/triton/ds/tree/rbtree.d.ts.map +1 -0
  414. package/dist/diagrams/triton/ds/tree/rbtree.js +78 -0
  415. package/dist/diagrams/triton/ds/tree/rbtree.js.map +1 -0
  416. package/dist/diagrams/{ds → triton/ds}/tree/segtree.d.ts +1 -1
  417. package/dist/diagrams/triton/ds/tree/segtree.d.ts.map +1 -0
  418. package/dist/diagrams/triton/ds/tree/segtree.js +51 -0
  419. package/dist/diagrams/triton/ds/tree/segtree.js.map +1 -0
  420. package/dist/diagrams/{ds → triton/ds}/trie/trie.d.ts +1 -1
  421. package/dist/diagrams/triton/ds/trie/trie.d.ts.map +1 -0
  422. package/dist/diagrams/triton/ds/trie/trie.js +58 -0
  423. package/dist/diagrams/triton/ds/trie/trie.js.map +1 -0
  424. package/dist/diagrams/{ds → triton/ds}/unionfind/unionfind.d.ts +1 -1
  425. package/dist/diagrams/triton/ds/unionfind/unionfind.d.ts.map +1 -0
  426. package/dist/diagrams/triton/ds/unionfind/unionfind.js +110 -0
  427. package/dist/diagrams/triton/ds/unionfind/unionfind.js.map +1 -0
  428. package/dist/diagrams/{packet → triton/packet}/index.d.ts +1 -1
  429. package/dist/diagrams/triton/packet/index.d.ts.map +1 -0
  430. package/dist/diagrams/triton/packet/index.js +14 -0
  431. package/dist/diagrams/triton/packet/index.js.map +1 -0
  432. package/dist/diagrams/{packet → triton/packet}/ir.d.ts +1 -1
  433. package/dist/diagrams/triton/packet/ir.d.ts.map +1 -0
  434. package/dist/diagrams/triton/packet/ir.js +2 -0
  435. package/dist/diagrams/triton/packet/ir.js.map +1 -0
  436. package/dist/diagrams/{packet → triton/packet}/layout.d.ts +2 -2
  437. package/dist/diagrams/triton/packet/layout.d.ts.map +1 -0
  438. package/dist/diagrams/triton/packet/layout.js +69 -0
  439. package/dist/diagrams/triton/packet/layout.js.map +1 -0
  440. package/dist/diagrams/{poster → triton/poster}/index.d.ts +1 -1
  441. package/dist/diagrams/triton/poster/index.d.ts.map +1 -0
  442. package/dist/diagrams/triton/poster/index.js +127 -0
  443. package/dist/diagrams/triton/poster/index.js.map +1 -0
  444. package/dist/diagrams/{poster → triton/poster}/ir.d.ts +1 -3
  445. package/dist/diagrams/{poster → triton/poster}/ir.d.ts.map +1 -1
  446. package/dist/diagrams/triton/poster/ir.js +2 -0
  447. package/dist/diagrams/triton/poster/ir.js.map +1 -0
  448. package/dist/diagrams/{poster → triton/poster}/layout.d.ts +2 -2
  449. package/dist/diagrams/triton/poster/layout.d.ts.map +1 -0
  450. package/dist/diagrams/triton/poster/layout.js +517 -0
  451. package/dist/diagrams/triton/poster/layout.js.map +1 -0
  452. package/dist/diagrams/{topology → triton/topology}/topology.d.ts +2 -2
  453. package/dist/diagrams/triton/topology/topology.d.ts.map +1 -0
  454. package/dist/diagrams/triton/topology/topology.js +198 -0
  455. package/dist/diagrams/triton/topology/topology.js.map +1 -0
  456. package/dist/frontend/detect.js +94 -0
  457. package/dist/frontend/detect.js.map +1 -0
  458. package/dist/frontend/index.d.ts +4 -4
  459. package/dist/frontend/index.d.ts.map +1 -1
  460. package/dist/frontend/index.js +196 -0
  461. package/dist/frontend/index.js.map +1 -0
  462. package/dist/frontend/preprocess.d.ts +28 -0
  463. package/dist/frontend/preprocess.d.ts.map +1 -0
  464. package/dist/frontend/preprocess.js +60 -0
  465. package/dist/frontend/preprocess.js.map +1 -0
  466. package/dist/frontend/registry.js +25 -0
  467. package/dist/frontend/registry.js.map +1 -0
  468. package/dist/graph/connect.js +44 -0
  469. package/dist/graph/connect.js.map +1 -0
  470. package/dist/graph/layered.d.ts +65 -5
  471. package/dist/graph/layered.d.ts.map +1 -1
  472. package/dist/graph/layered.js +936 -0
  473. package/dist/graph/layered.js.map +1 -0
  474. package/dist/graph/tree.js +107 -0
  475. package/dist/graph/tree.js.map +1 -0
  476. package/dist/index.js +4691 -2735
  477. package/dist/index.js.map +4 -4
  478. package/dist/overlay/apply.js +22 -0
  479. package/dist/overlay/apply.js.map +1 -0
  480. package/dist/overlay/compiler.js +48 -0
  481. package/dist/overlay/compiler.js.map +1 -0
  482. package/dist/overlay/layout.js +242 -0
  483. package/dist/overlay/layout.js.map +1 -0
  484. package/dist/palette/categorical.js +21 -0
  485. package/dist/palette/categorical.js.map +1 -0
  486. package/dist/render/registry.js +22 -0
  487. package/dist/render/registry.js.map +1 -0
  488. package/dist/render/svg.d.ts.map +1 -1
  489. package/dist/render/svg.js +287 -0
  490. package/dist/render/svg.js.map +1 -0
  491. package/dist/routing/d3-curves.d.ts +31 -0
  492. package/dist/routing/d3-curves.d.ts.map +1 -0
  493. package/dist/routing/d3-curves.js +58 -0
  494. package/dist/routing/d3-curves.js.map +1 -0
  495. package/dist/routing/registry.js +22 -0
  496. package/dist/routing/registry.js.map +1 -0
  497. package/dist/routing/router.d.ts +3 -0
  498. package/dist/routing/router.d.ts.map +1 -1
  499. package/dist/routing/router.js +849 -0
  500. package/dist/routing/router.js.map +1 -0
  501. package/dist/scene/build.d.ts +3 -1
  502. package/dist/scene/build.d.ts.map +1 -1
  503. package/dist/scene/build.js +57 -0
  504. package/dist/scene/build.js.map +1 -0
  505. package/dist/scene/strip.js +46 -0
  506. package/dist/scene/strip.js.map +1 -0
  507. package/dist/style/cost.js +39 -0
  508. package/dist/style/cost.js.map +1 -0
  509. package/dist/text/metrics.js +62 -0
  510. package/dist/text/metrics.js.map +1 -0
  511. package/dist/text/wrap.js +84 -0
  512. package/dist/text/wrap.js.map +1 -0
  513. package/dist/theme/preset.d.ts +2 -0
  514. package/dist/theme/preset.d.ts.map +1 -1
  515. package/dist/theme/preset.js +295 -0
  516. package/dist/theme/preset.js.map +1 -0
  517. package/dist/theme/resolver.js +15 -0
  518. package/dist/theme/resolver.js.map +1 -0
  519. package/dist/time/dates.js +301 -0
  520. package/dist/time/dates.js.map +1 -0
  521. package/dist/util/round.js +17 -0
  522. package/dist/util/round.js.map +1 -0
  523. package/package.json +1 -1
  524. package/dist/diagrams/architecture/index.d.ts.map +0 -1
  525. package/dist/diagrams/architecture/ir.d.ts.map +0 -1
  526. package/dist/diagrams/architecture/layout.d.ts.map +0 -1
  527. package/dist/diagrams/block/index.d.ts.map +0 -1
  528. package/dist/diagrams/block/ir.d.ts.map +0 -1
  529. package/dist/diagrams/block/layout.d.ts.map +0 -1
  530. package/dist/diagrams/c4/index.d.ts.map +0 -1
  531. package/dist/diagrams/c4/ir.d.ts.map +0 -1
  532. package/dist/diagrams/c4/layout.d.ts.map +0 -1
  533. package/dist/diagrams/class/index.d.ts.map +0 -1
  534. package/dist/diagrams/class/ir.d.ts.map +0 -1
  535. package/dist/diagrams/class/layout.d.ts.map +0 -1
  536. package/dist/diagrams/ds/graph/graph.d.ts.map +0 -1
  537. package/dist/diagrams/ds/hashmap/hashmap.d.ts.map +0 -1
  538. package/dist/diagrams/ds/matrix/matrix.d.ts.map +0 -1
  539. package/dist/diagrams/ds/queue/cqueue.d.ts.map +0 -1
  540. package/dist/diagrams/ds/queue/deque.d.ts.map +0 -1
  541. package/dist/diagrams/ds/queue/pqueue.d.ts.map +0 -1
  542. package/dist/diagrams/ds/queue/queue.d.ts.map +0 -1
  543. package/dist/diagrams/ds/queue/shared.d.ts.map +0 -1
  544. package/dist/diagrams/ds/stack/stack.d.ts.map +0 -1
  545. package/dist/diagrams/ds/struct/array.d.ts +0 -28
  546. package/dist/diagrams/ds/struct/array.d.ts.map +0 -1
  547. package/dist/diagrams/ds/struct/linkedlist.d.ts.map +0 -1
  548. package/dist/diagrams/ds/struct/memory.d.ts.map +0 -1
  549. package/dist/diagrams/ds/struct/page.d.ts.map +0 -1
  550. package/dist/diagrams/ds/struct/shared.d.ts +0 -9
  551. package/dist/diagrams/ds/struct/shared.d.ts.map +0 -1
  552. package/dist/diagrams/ds/tree/avl.d.ts.map +0 -1
  553. package/dist/diagrams/ds/tree/btree.d.ts.map +0 -1
  554. package/dist/diagrams/ds/tree/build.d.ts.map +0 -1
  555. package/dist/diagrams/ds/tree/heap.d.ts.map +0 -1
  556. package/dist/diagrams/ds/tree/index.d.ts.map +0 -1
  557. package/dist/diagrams/ds/tree/ir.d.ts.map +0 -1
  558. package/dist/diagrams/ds/tree/layout.d.ts.map +0 -1
  559. package/dist/diagrams/ds/tree/plan.d.ts.map +0 -1
  560. package/dist/diagrams/ds/tree/radix.d.ts.map +0 -1
  561. package/dist/diagrams/ds/tree/rbtree.d.ts.map +0 -1
  562. package/dist/diagrams/ds/tree/segtree.d.ts.map +0 -1
  563. package/dist/diagrams/ds/trie/trie.d.ts.map +0 -1
  564. package/dist/diagrams/ds/unionfind/unionfind.d.ts.map +0 -1
  565. package/dist/diagrams/er/index.d.ts.map +0 -1
  566. package/dist/diagrams/er/ir.d.ts.map +0 -1
  567. package/dist/diagrams/er/layout.d.ts.map +0 -1
  568. package/dist/diagrams/flowchart/index.d.ts.map +0 -1
  569. package/dist/diagrams/flowchart/ir.d.ts.map +0 -1
  570. package/dist/diagrams/flowchart/layout.d.ts +0 -5
  571. package/dist/diagrams/flowchart/layout.d.ts.map +0 -1
  572. package/dist/diagrams/gantt/index.d.ts.map +0 -1
  573. package/dist/diagrams/gantt/ir.d.ts.map +0 -1
  574. package/dist/diagrams/gantt/layout.d.ts.map +0 -1
  575. package/dist/diagrams/gitgraph/index.d.ts.map +0 -1
  576. package/dist/diagrams/gitgraph/ir.d.ts.map +0 -1
  577. package/dist/diagrams/gitgraph/layout.d.ts.map +0 -1
  578. package/dist/diagrams/journey/index.d.ts.map +0 -1
  579. package/dist/diagrams/journey/ir.d.ts.map +0 -1
  580. package/dist/diagrams/journey/layout.d.ts.map +0 -1
  581. package/dist/diagrams/kanban/index.d.ts.map +0 -1
  582. package/dist/diagrams/kanban/ir.d.ts.map +0 -1
  583. package/dist/diagrams/kanban/layout.d.ts.map +0 -1
  584. package/dist/diagrams/mindmap/index.d.ts.map +0 -1
  585. package/dist/diagrams/mindmap/ir.d.ts.map +0 -1
  586. package/dist/diagrams/mindmap/layout.d.ts.map +0 -1
  587. package/dist/diagrams/packet/index.d.ts.map +0 -1
  588. package/dist/diagrams/packet/ir.d.ts.map +0 -1
  589. package/dist/diagrams/packet/layout.d.ts.map +0 -1
  590. package/dist/diagrams/pie/index.d.ts.map +0 -1
  591. package/dist/diagrams/pie/ir.d.ts.map +0 -1
  592. package/dist/diagrams/pie/layout.d.ts.map +0 -1
  593. package/dist/diagrams/poster/index.d.ts.map +0 -1
  594. package/dist/diagrams/poster/layout.d.ts.map +0 -1
  595. package/dist/diagrams/quadrant/index.d.ts.map +0 -1
  596. package/dist/diagrams/quadrant/ir.d.ts.map +0 -1
  597. package/dist/diagrams/quadrant/layout.d.ts.map +0 -1
  598. package/dist/diagrams/radar/index.d.ts.map +0 -1
  599. package/dist/diagrams/radar/ir.d.ts.map +0 -1
  600. package/dist/diagrams/radar/layout.d.ts.map +0 -1
  601. package/dist/diagrams/requirement/index.d.ts.map +0 -1
  602. package/dist/diagrams/requirement/ir.d.ts.map +0 -1
  603. package/dist/diagrams/requirement/layout.d.ts.map +0 -1
  604. package/dist/diagrams/sankey/index.d.ts.map +0 -1
  605. package/dist/diagrams/sankey/ir.d.ts.map +0 -1
  606. package/dist/diagrams/sankey/layout.d.ts.map +0 -1
  607. package/dist/diagrams/sequence/index.d.ts.map +0 -1
  608. package/dist/diagrams/sequence/ir.d.ts.map +0 -1
  609. package/dist/diagrams/sequence/layout.d.ts.map +0 -1
  610. package/dist/diagrams/state/index.d.ts.map +0 -1
  611. package/dist/diagrams/state/ir.d.ts.map +0 -1
  612. package/dist/diagrams/state/layout.d.ts.map +0 -1
  613. package/dist/diagrams/timeline/index.d.ts.map +0 -1
  614. package/dist/diagrams/timeline/ir.d.ts.map +0 -1
  615. package/dist/diagrams/timeline/layout.d.ts +0 -5
  616. package/dist/diagrams/timeline/layout.d.ts.map +0 -1
  617. package/dist/diagrams/timeline/numbered.d.ts.map +0 -1
  618. package/dist/diagrams/timeline/roadmap.d.ts.map +0 -1
  619. package/dist/diagrams/timeline/serpentine.d.ts.map +0 -1
  620. package/dist/diagrams/timeline/shared.d.ts.map +0 -1
  621. package/dist/diagrams/timeline/timeline-columns.d.ts.map +0 -1
  622. package/dist/diagrams/timeline/vertical-spine.d.ts.map +0 -1
  623. package/dist/diagrams/topology/topology.d.ts.map +0 -1
  624. package/dist/diagrams/xychart/index.d.ts.map +0 -1
  625. package/dist/diagrams/xychart/ir.d.ts.map +0 -1
  626. package/dist/diagrams/xychart/layout.d.ts.map +0 -1
  627. /package/dist/diagrams/{ds → triton/ds}/tree/build.d.ts +0 -0
@@ -0,0 +1,968 @@
1
+ /**
2
+ * Cross-Link Engine v3 — Global Cost-Function Routing
3
+ *
4
+ * Passes:
5
+ * 0. Port assign Global: shared-endpoint t values sorted by angular order
6
+ * 1. Sort Axis-aligned first; longest within group
7
+ * 2. Route Greedy: search collapsed by phase-0 hints for shared ports
8
+ * 3. Repair Find crossing pairs, re-route lower-priority links
9
+ * 4. Channel sep Spread parallel overlapping segments
10
+ * 5. Labels Stagger + de-collision
11
+ * 6. Emit SVG path strings (L for orthogonal, C for bezier)
12
+ *
13
+ * Cost function:
14
+ * W_CROSS × crossings — H/V decomposition for orthogonal pairs
15
+ * W_INTER × cross-link port conflict
16
+ * W_SIDE × wrong-side wall
17
+ * W_INTRA × intra-diagram port conflict (softer — can be overridden)
18
+ * W_BEND × excess bends
19
+ * W_LEN × path length
20
+ * W_ALIGN × short jog segments (orthogonal only)
21
+ *
22
+ * Crossing detection:
23
+ * Orthogonal ↔ orthogonal: H/V decomposition, O(1) per segment pair
24
+ * Mixed/bezier: sampled polyline + AABB prefilter + segment intersection
25
+ */
26
+ import { isRenderedConnectorAnimation } from '../contracts/crosslink.js';
27
+ import { createRouter } from '../routing/router.js';
28
+ // ─── Cost weights ─────────────────────────────────────────────────────────────
29
+ const W_CROSS = 10_000; // per crossing with a committed route
30
+ const W_INTER = 3_000; // port conflict with another cross-link (same wall+pos)
31
+ const W_SIDE = 800; // wrong-side wall (not facing the target)
32
+ const W_INTRA = 500; // port conflict with an intra-diagram edge
33
+ const W_BEND = 50; // per excess bend
34
+ const W_LEN = 1; // per pixel of path length
35
+ const W_ALIGN = 400; // per short jog segment (orthogonal only)
36
+ const SNAP_THRESHOLD = 14; // snap near-aligned E/W (or N/S) port pairs
37
+ const CONFLICT_RADIUS = 28; // pixel radius for port conflict detection
38
+ const CELL_SHRINK = 12; // px to shrink intermediate cell rects
39
+ const CHANNEL_GAP = 12; // gap between overlapping parallel segments
40
+ const ROUTE_PADDING = 12; // obstacle clearance during routing
41
+ /** Fractional wall positions tried per candidate (0 = wall start, 1 = wall end). */
42
+ const WALL_TS = [0.1, 0.25, 0.5, 0.75, 0.9];
43
+ const ARROW_ID = 'triton-crosslink-arrow';
44
+ const BI_ARROW_ID = 'triton-crosslink-arrow-both';
45
+ // ─── Entry point ──────────────────────────────────────────────────────────────
46
+ export function routeAndRenderCrossLinks3(links, theme, anchors, intraPorts, occupiedRects, routingObstacles, cellRects) {
47
+ const { palette, typography, edges: edgeTheme } = theme;
48
+ const elements = [];
49
+ const defs = [];
50
+ // ── Colour assignment ─────────────────────────────────────────────────────
51
+ const PALETTE = [
52
+ '#E11D48', '#16A34A', '#9333EA', '#0891B2',
53
+ '#CA8A04', '#DC2626', '#2563EB', '#7C3AED',
54
+ ];
55
+ let explicitColorIdx = 0;
56
+ const allNodeBounds = Object.values(anchors).map(a => a.bounds);
57
+ const addrKey = (addr) => [...addr.cellPath, addr.nodeId].join('.');
58
+ function centerOf(key) {
59
+ const a = anchors[key];
60
+ return a ? { x: a.bounds.x + a.bounds.width / 2, y: a.bounds.y + a.bounds.height / 2 } : { x: 0, y: 0 };
61
+ }
62
+ // ── Pass 1: Sort links axis-aligned first ─────────────────────────────────
63
+ const resolvable = links.filter(l => anchors[addrKey(l.from)] && anchors[addrKey(l.to)]);
64
+ // ── Pass 0: Pre-assign ports at shared endpoints ─────────────────────────
65
+ // For every (node, wall) that has 2+ links, sort arrivals/departures by the
66
+ // angular position of the other endpoint and assign evenly-spaced t values.
67
+ // This guarantees a non-crossing fan at the shared node before routing starts.
68
+ const portHints = preAssignSharedPorts(resolvable, anchors);
69
+ const sortedLinks = [...resolvable].sort((a, b) => {
70
+ const ca = centerOf(addrKey(a.from)), cb = centerOf(addrKey(a.to));
71
+ const cc = centerOf(addrKey(b.from)), cd = centerOf(addrKey(b.to));
72
+ const axA = Math.abs(cb.x - ca.x), ayA = Math.abs(cb.y - ca.y);
73
+ const axB = Math.abs(cd.x - cc.x), ayB = Math.abs(cd.y - cc.y);
74
+ const sA = Math.min(axA, ayA) / (Math.max(axA, ayA) + 1);
75
+ const sB = Math.min(axB, ayB) / (Math.max(axB, ayB) + 1);
76
+ if (Math.abs(sA - sB) > 0.05)
77
+ return sA - sB;
78
+ return Math.hypot(cb.x - ca.x, cb.y - ca.y) - Math.hypot(cd.x - cc.x, cd.y - cc.y);
79
+ }).reverse();
80
+ // ── Pass 2: Greedy routing ────────────────────────────────────────────────
81
+ const committed = [];
82
+ const workingByOriginalIdx = new Map();
83
+ for (let si = 0; si < sortedLinks.length; si++) {
84
+ const link = sortedLinks[si];
85
+ const rIdx = resolvable.indexOf(link);
86
+ const hint = rIdx >= 0 ? portHints.get(rIdx) : undefined;
87
+ const best = findBestRoute(si, link, anchors, allNodeBounds, cellRects, committed, intraPorts ?? [], hint);
88
+ if (!best)
89
+ continue;
90
+ committed.push(best.committed);
91
+ let color;
92
+ const explicitColor = typeof link.props?.color === 'string' ? link.props.color : undefined;
93
+ if (explicitColor) {
94
+ color = explicitColor;
95
+ }
96
+ else {
97
+ color = PALETTE[explicitColorIdx % PALETTE.length];
98
+ explicitColorIdx++;
99
+ }
100
+ const dash = edgeStyleToDash(link.style);
101
+ const animation = link.animation === 'none' ? undefined :
102
+ isRenderedConnectorAnimation(link.animation) ? link.animation :
103
+ dash ? 'march' : undefined;
104
+ let markerEnd;
105
+ let markerStart;
106
+ if (link.direction === 'directed') {
107
+ markerEnd = ARROW_ID;
108
+ }
109
+ else if (link.direction === 'bidirectional') {
110
+ markerEnd = ARROW_ID;
111
+ markerStart = BI_ARROW_ID;
112
+ }
113
+ const origIdx = links.indexOf(link);
114
+ workingByOriginalIdx.set(origIdx >= 0 ? origIdx : workingByOriginalIdx.size, {
115
+ points: [...best.rawPts],
116
+ ...(best.committed.isBezier ? { isBezier: true } : {}),
117
+ color,
118
+ ...(dash ? { dash } : {}),
119
+ ...(animation ? { animation } : {}),
120
+ ...(markerEnd ? { markerEnd } : {}),
121
+ ...(markerStart ? { markerStart } : {}),
122
+ ...(link.label ? { label: link.label } : {}),
123
+ ...(link.props?.labelPlacement === 'path-midpoint' ? { labelPlacement: 'path-midpoint' } : {}),
124
+ });
125
+ }
126
+ // ── Pass 3: Crossing repair ───────────────────────────────────────────────
127
+ repairCrossings(committed, sortedLinks, anchors, allNodeBounds, cellRects, intraPorts ?? [], workingByOriginalIdx, links, portHints, resolvable);
128
+ // Reconstruct workingRoutes in original link order
129
+ const workingRoutes = [];
130
+ for (let i = 0; i < links.length; i++) {
131
+ const wr = workingByOriginalIdx.get(i);
132
+ if (wr)
133
+ workingRoutes.push(wr);
134
+ }
135
+ // ── Pass 4: Border nudging ────────────────────────────────────────────────
136
+ if (routingObstacles && routingObstacles.length > 0) {
137
+ nudgeOffBorders(workingRoutes, routingObstacles);
138
+ }
139
+ // ── Pass 4b: Channel separation ───────────────────────────────────────────
140
+ separateChannels(workingRoutes);
141
+ // ── Pass 5: Label staggering ──────────────────────────────────────────────
142
+ const CORRIDOR_TOL = 20;
143
+ const labelFractions = new Array(workingRoutes.length).fill(0.5);
144
+ const labeledIdxs = workingRoutes.map((r, i) => r.label ? i : -1).filter(i => i >= 0);
145
+ const staggered = new Set();
146
+ for (const i of labeledIdxs) {
147
+ if (staggered.has(i))
148
+ continue;
149
+ const wrI = workingRoutes[i];
150
+ const ptsI = sampledPts(wrI);
151
+ const infoI = dominantSegment(ptsI);
152
+ const group = [i];
153
+ for (const j of labeledIdxs) {
154
+ if (j === i || staggered.has(j))
155
+ continue;
156
+ const wrJ = workingRoutes[j];
157
+ const ptsJ = sampledPts(wrJ);
158
+ const infoJ = dominantSegment(ptsJ);
159
+ if (infoI.axis === infoJ.axis && Math.abs(infoI.coord - infoJ.coord) < CORRIDOR_TOL) {
160
+ group.push(j);
161
+ }
162
+ }
163
+ if (group.length > 1) {
164
+ group.sort((a, b) => a - b);
165
+ group.forEach((idx, k) => { labelFractions[idx] = (k + 1) / (group.length + 1); });
166
+ group.forEach(idx => staggered.add(idx));
167
+ }
168
+ }
169
+ // ── Pass 6: Emit SVG elements ─────────────────────────────────────────────
170
+ let needsArrow = false;
171
+ let needsBiArrow = false;
172
+ const pendingLabels = [];
173
+ for (let i = 0; i < workingRoutes.length; i++) {
174
+ const wr = workingRoutes[i];
175
+ const path = wr.isBezier
176
+ ? `M ${wr.points[0].x} ${wr.points[0].y} C ${wr.points[1].x} ${wr.points[1].y} ${wr.points[2].x} ${wr.points[2].y} ${wr.points[3].x} ${wr.points[3].y}`
177
+ : wr.points.map((p, pi) => `${pi === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');
178
+ if (wr.markerEnd === ARROW_ID)
179
+ needsArrow = true;
180
+ if (wr.markerStart === BI_ARROW_ID)
181
+ needsBiArrow = true;
182
+ elements.push({
183
+ type: 'path',
184
+ d: path,
185
+ stroke: wr.color,
186
+ strokeWidth: edgeTheme.strokeWidth + 0.5,
187
+ ...(wr.dash ? { strokeDasharray: wr.dash } : {}),
188
+ ...(wr.animation ? { animated: wr.animation } : {}),
189
+ ...(wr.markerEnd ? { markerEnd: wr.markerEnd } : {}),
190
+ ...(wr.markerStart ? { markerStart: wr.markerStart } : {}),
191
+ });
192
+ if (wr.label) {
193
+ const pts = sampledPts(wr);
194
+ // Staggered labels (parallel links sharing a corridor) keep their
195
+ // length-fraction offset so they don't stack. Otherwise anchor the label
196
+ // on the route's longest HORIZONTAL run — labels are horizontal text and
197
+ // read best along a horizontal segment, and this avoids parking them on a
198
+ // short/outboard vertical channel that may sit at the diagram edge.
199
+ const labelPos = staggered.has(i) || wr.isBezier || wr.labelPlacement === 'path-midpoint'
200
+ ? pointAtFrac(pts, labelFractions[i] ?? 0.5)
201
+ : labelAnchor(pts);
202
+ pendingLabels.push({
203
+ content: wr.label,
204
+ x: labelPos.x,
205
+ y: labelPos.y - 6,
206
+ fontSize: edgeTheme.labelFontSize,
207
+ fontFamily: typography.fontFamily,
208
+ fill: wr.color,
209
+ });
210
+ }
211
+ }
212
+ // Label de-collision
213
+ const CHAR_W = 0.65;
214
+ const LABEL_PAD = 4;
215
+ const fixedRects = [...allNodeBounds, ...(occupiedRects ?? [])];
216
+ const labelRects = pendingLabels.map(l => ({
217
+ x: l.x - (l.content.length * l.fontSize * CHAR_W) / 2 - LABEL_PAD,
218
+ y: l.y - l.fontSize,
219
+ width: l.content.length * l.fontSize * CHAR_W + LABEL_PAD * 2,
220
+ height: l.fontSize + LABEL_PAD * 2,
221
+ }));
222
+ deCollideLabels(labelRects, fixedRects);
223
+ for (let i = 0; i < pendingLabels.length; i++) {
224
+ const l = pendingLabels[i];
225
+ const r = labelRects[i];
226
+ elements.push({
227
+ type: 'text',
228
+ content: l.content,
229
+ position: { x: r.x + r.width / 2, y: r.y + r.height - LABEL_PAD },
230
+ fontSize: l.fontSize,
231
+ fontFamily: typography.fontFamily,
232
+ fill: l.fill,
233
+ anchor: 'middle',
234
+ fontWeight: 'bold',
235
+ });
236
+ }
237
+ if (needsArrow) {
238
+ const s = edgeTheme.arrowSize;
239
+ defs.push(`<marker id="${ARROW_ID}" markerWidth="${s}" markerHeight="${s * 0.7}" refX="${s - 1}" refY="${s * 0.35}" orient="auto">` +
240
+ `<polygon points="0 0, ${s} ${s * 0.35}, 0 ${s * 0.7}" fill="currentColor" /></marker>`);
241
+ }
242
+ if (needsBiArrow) {
243
+ const s = edgeTheme.arrowSize;
244
+ defs.push(`<marker id="${BI_ARROW_ID}" markerWidth="${s}" markerHeight="${s * 0.7}" refX="1" refY="${s * 0.35}" orient="auto">` +
245
+ `<polygon points="${s} 0, 0 ${s * 0.35}, ${s} ${s * 0.7}" fill="currentColor" /></marker>`);
246
+ }
247
+ return { defs, elements };
248
+ }
249
+ // ─── Route finding (shared by greedy pass and repair pass) ───────────────────
250
+ function findBestRoute(linkIdx, link, anchors, allNodeBounds, cellRects, committed, intraPorts, portHint) {
251
+ const addrKey = (addr) => [...addr.cellPath, addr.nodeId].join('.');
252
+ const srcKey = addrKey(link.from);
253
+ const dstKey = addrKey(link.to);
254
+ const srcAnchor = anchors[srcKey];
255
+ const dstAnchor = anchors[dstKey];
256
+ if (!srcAnchor || !dstAnchor)
257
+ return null;
258
+ const srcCenter = {
259
+ x: srcAnchor.bounds.x + srcAnchor.bounds.width / 2,
260
+ y: srcAnchor.bounds.y + srcAnchor.bounds.height / 2,
261
+ };
262
+ const dstCenter = {
263
+ x: dstAnchor.bounds.x + dstAnchor.bounds.width / 2,
264
+ y: dstAnchor.bounds.y + dstAnchor.bounds.height / 2,
265
+ };
266
+ // Build per-link obstacle list.
267
+ // Nodes inside the source/dest cells must NOT be obstacles — they are the
268
+ // "interior terrain" of the endpoint cells. Without this exclusion the
269
+ // router sees sibling nodes (e.g. Gateway next to the target Order Service)
270
+ // as hard obstacles and produces large detours to reach the destination port.
271
+ const srcCellId = link.from.cellPath.join('.');
272
+ const dstCellId = link.to.cellPath.join('.');
273
+ const sameSourceCell = (key) => srcCellId.length > 0 && key.startsWith(srcCellId + '.');
274
+ const sameTargetCell = (key) => dstCellId.length > 0 && key.startsWith(dstCellId + '.');
275
+ const linkObstacles = Object.entries(anchors)
276
+ .filter(([key]) => !sameSourceCell(key) &&
277
+ !sameTargetCell(key) &&
278
+ key !== srcKey && key !== dstKey)
279
+ .map(([, a]) => a.bounds);
280
+ if (cellRects) {
281
+ for (const [cellId, r] of cellRects) {
282
+ if (cellId === srcCellId || cellId === dstCellId)
283
+ continue;
284
+ const sw = r.width - 2 * CELL_SHRINK;
285
+ const sh = r.height - 2 * CELL_SHRINK;
286
+ if (sw > 0 && sh > 0) {
287
+ linkObstacles.push({ x: r.x + CELL_SHRINK, y: r.y + CELL_SHRINK, width: sw, height: sh });
288
+ }
289
+ }
290
+ }
291
+ const routeStyle = link.routing ?? 'orthogonal';
292
+ const sides = ['N', 'S', 'E', 'W'];
293
+ // Collapse search dimensions. Precedence: explicit user exit/entry walls win,
294
+ // then phase-0 shared-port fan hints, then full 4-wall search.
295
+ const srcWalls = link.exitWall ? [link.exitWall] : portHint?.srcWall ? [portHint.srcWall] : sides;
296
+ const dstWalls = link.entryWall ? [link.entryWall] : portHint?.dstWall ? [portHint.dstWall] : sides;
297
+ // Honor a phase-0 fan t whenever one was assigned. Pinned walls always get a
298
+ // fan slot (centre when alone, evenly spread when several share the wall), so
299
+ // this is what centres the port on the wall.
300
+ const srcTs = portHint?.srcT !== undefined ? [portHint.srcT] : WALL_TS;
301
+ const dstTs = portHint?.dstT !== undefined ? [portHint.dstT] : WALL_TS;
302
+ let bestScore = Infinity;
303
+ let bestCommitted;
304
+ let bestRawPts;
305
+ for (const ss of srcWalls) {
306
+ for (const ds of dstWalls) {
307
+ for (const srcT of srcTs) {
308
+ for (const dstT of dstTs) {
309
+ let sp = wallPoint(srcAnchor.bounds, ss, srcT);
310
+ let dp = wallPoint(dstAnchor.bounds, ds, dstT);
311
+ // Snap near-aligned pairs to exact alignment (eliminates jog segments)
312
+ const snapped = snapAlignment(ss, sp, ds, dp);
313
+ sp = snapped.srcPort;
314
+ dp = snapped.dstPort;
315
+ const router = createRouter(routeStyle);
316
+ const routePadding = typeof link.props?.routePadding === 'number' ? link.props.routePadding : ROUTE_PADDING;
317
+ const routeObstacles = [
318
+ ...linkObstacles,
319
+ ...forcedAwayEndpointObstacles(link, ss, ds, srcCenter, dstCenter, anchors, cellRects, srcKey, dstKey, srcCellId, dstCellId, sameSourceCell, sameTargetCell),
320
+ ];
321
+ const route = router.route({
322
+ from: sp,
323
+ to: dp,
324
+ style: routeStyle,
325
+ obstacles: routeObstacles,
326
+ padding: routePadding,
327
+ fromDir: ss,
328
+ toDir: ds,
329
+ });
330
+ const rawPts = route.points;
331
+ const isBez = routeStyle === 'bezier' && rawPts.length === 4;
332
+ const pts = isBez
333
+ ? sampleCubicBezier(rawPts[0], rawPts[1], rawPts[2], rawPts[3], 12)
334
+ : rawPts;
335
+ const { hSegs, vSegs } = decomposeHV(pts, routeStyle);
336
+ // ── Unified cost function ─────────────────────────────────────
337
+ const score = sidePenalty(ss, ds, srcCenter, dstCenter) +
338
+ crossingScore(pts, hSegs, vSegs, isBez, committed) +
339
+ portConflictScore(srcKey, ss, sp, srcT, dstKey, ds, dp, dstT, committed, intraPorts, anchors) +
340
+ (isBez ? 0 : Math.max(0, rawPts.length - 2) * W_BEND) +
341
+ pathLen(pts) * W_LEN +
342
+ (isBez ? 0 : alignPenalty(rawPts));
343
+ if (score < bestScore) {
344
+ bestScore = score;
345
+ bestRawPts = rawPts;
346
+ bestCommitted = {
347
+ linkIdx,
348
+ srcKey, dstKey,
349
+ srcWall: ss, srcT, srcPort: sp,
350
+ dstWall: ds, dstT, dstPort: dp,
351
+ points: pts,
352
+ rawPts,
353
+ isBezier: isBez,
354
+ hSegs,
355
+ vSegs,
356
+ };
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+ return bestScore < Infinity ? { committed: bestCommitted, rawPts: bestRawPts } : null;
363
+ }
364
+ function forcedAwayEndpointObstacles(link, srcWall, dstWall, srcCenter, dstCenter, anchors, cellRects, srcKey, dstKey, srcCellId, dstCellId, sameSourceCell, sameTargetCell) {
365
+ const exitAway = link.exitWall !== undefined && wallFacesAway(srcWall, srcCenter, dstCenter);
366
+ const entryAway = link.entryWall !== undefined && wallFacesAway(dstWall, dstCenter, srcCenter);
367
+ const rects = [anchors[srcKey]?.bounds, anchors[dstKey]?.bounds].filter((r) => r !== undefined);
368
+ if (exitAway || entryAway) {
369
+ for (const [key, anchor] of Object.entries(anchors)) {
370
+ if (sameSourceCell(key) || sameTargetCell(key))
371
+ rects.push(anchor.bounds);
372
+ }
373
+ const srcCell = cellRects?.get(srcCellId);
374
+ const dstCell = cellRects?.get(dstCellId);
375
+ if (srcCell)
376
+ rects.push(srcCell);
377
+ if (dstCell)
378
+ rects.push(dstCell);
379
+ }
380
+ return rects;
381
+ }
382
+ function wallFacesAway(wall, fromCenter, toCenter) {
383
+ const nx = wall === 'E' ? 1 : wall === 'W' ? -1 : 0;
384
+ const ny = wall === 'S' ? 1 : wall === 'N' ? -1 : 0;
385
+ const vx = toCenter.x - fromCenter.x;
386
+ const vy = toCenter.y - fromCenter.y;
387
+ return vx * nx + vy * ny < 0;
388
+ }
389
+ // ─── Pass 3: Crossing repair ──────────────────────────────────────────────────
390
+ function repairCrossings(committed, sortedLinks, anchors, allNodeBounds, cellRects, intraPorts, workingByOrigIdx, links, portHints, resolvable) {
391
+ // One repair pass: for each crossing pair (i committed before j), try re-routing j
392
+ for (let j = 1; j < committed.length; j++) {
393
+ const crJ = committed[j];
394
+ // Count crossings between j and any earlier route
395
+ let jCrossings = 0;
396
+ for (let i = 0; i < j; i++) {
397
+ jCrossings += countCrossingsBetween(committed[i], crJ);
398
+ }
399
+ if (jCrossings === 0)
400
+ continue;
401
+ // Attempt re-route of j with all other routes committed except j itself
402
+ const committedWithoutJ = committed.filter((_, k) => k !== j);
403
+ const link = sortedLinks[crJ.linkIdx];
404
+ if (!link)
405
+ continue;
406
+ const rIdx = resolvable.indexOf(link);
407
+ const hint = rIdx >= 0 ? portHints.get(rIdx) : undefined;
408
+ const result = findBestRoute(crJ.linkIdx, link, anchors, allNodeBounds, cellRects, committedWithoutJ, intraPorts, hint);
409
+ if (!result)
410
+ continue;
411
+ // Accept only if new route has fewer crossings with earlier routes
412
+ let newCrossings = 0;
413
+ for (let i = 0; i < j; i++) {
414
+ newCrossings += countCrossingsBetween(committed[i], result.committed);
415
+ }
416
+ if (newCrossings >= jCrossings)
417
+ continue;
418
+ committed[j] = result.committed;
419
+ const origIdx = links.indexOf(link);
420
+ const wr = workingByOrigIdx.get(origIdx >= 0 ? origIdx : -1);
421
+ if (wr) {
422
+ wr.points = [...result.rawPts];
423
+ if (result.committed.isBezier) {
424
+ wr.isBezier = true;
425
+ }
426
+ else {
427
+ delete wr.isBezier;
428
+ }
429
+ }
430
+ }
431
+ }
432
+ // ─── H/V crossing detection ───────────────────────────────────────────────────
433
+ /**
434
+ * Decompose a polyline into horizontal and vertical segments for fast
435
+ * crossing detection. Only meaningful for orthogonal routes.
436
+ */
437
+ function decomposeHV(pts, style) {
438
+ const hSegs = [];
439
+ const vSegs = [];
440
+ if (style !== 'orthogonal')
441
+ return { hSegs, vSegs };
442
+ for (let i = 0; i < pts.length - 1; i++) {
443
+ const a = pts[i], b = pts[i + 1];
444
+ if (Math.abs(b.y - a.y) < 0.5 && Math.abs(b.x - a.x) > 0.5) {
445
+ hSegs.push({ y: (a.y + b.y) / 2, x1: Math.min(a.x, b.x), x2: Math.max(a.x, b.x) });
446
+ }
447
+ else if (Math.abs(b.x - a.x) < 0.5 && Math.abs(b.y - a.y) > 0.5) {
448
+ vSegs.push({ x: (a.x + b.x) / 2, y1: Math.min(a.y, b.y), y2: Math.max(a.y, b.y) });
449
+ }
450
+ }
451
+ return { hSegs, vSegs };
452
+ }
453
+ /** Count H/V crossings between two sets of decomposed segments. */
454
+ function countHVCrossings(aH, aV, bH, bV) {
455
+ let n = 0;
456
+ for (const h of aH)
457
+ for (const v of bV)
458
+ if (hvCross(h, v))
459
+ n++;
460
+ for (const v of aV)
461
+ for (const h of bH)
462
+ if (hvCross(h, v))
463
+ n++;
464
+ return n;
465
+ }
466
+ /** True iff a horizontal and a vertical segment properly intersect (not touch). */
467
+ function hvCross(h, v) {
468
+ return v.x > h.x1 && v.x < h.x2 && h.y > v.y1 && h.y < v.y2;
469
+ }
470
+ /** Count crossings between two polylines using AABB prefilter + proper intersection. */
471
+ function countPolylineCrossings(a, b) {
472
+ let n = 0;
473
+ for (let i = 0; i < a.length - 1; i++) {
474
+ const a1 = a[i], a2 = a[i + 1];
475
+ const axMin = Math.min(a1.x, a2.x), axMax = Math.max(a1.x, a2.x);
476
+ const ayMin = Math.min(a1.y, a2.y), ayMax = Math.max(a1.y, a2.y);
477
+ for (let j = 0; j < b.length - 1; j++) {
478
+ const b1 = b[j], b2 = b[j + 1];
479
+ // AABB prefilter
480
+ if (axMax < Math.min(b1.x, b2.x) || axMin > Math.max(b1.x, b2.x))
481
+ continue;
482
+ if (ayMax < Math.min(b1.y, b2.y) || ayMin > Math.max(b1.y, b2.y))
483
+ continue;
484
+ if (properlyCross(a1, a2, b1, b2))
485
+ n++;
486
+ }
487
+ }
488
+ return n;
489
+ }
490
+ /** Count crossings between a candidate and a single committed route. */
491
+ function countCrossingsBetween(a, b) {
492
+ if (!a.isBezier && !b.isBezier) {
493
+ return countHVCrossings(a.hSegs, a.vSegs, b.hSegs, b.vSegs);
494
+ }
495
+ return countPolylineCrossings(a.points, b.points);
496
+ }
497
+ /** Total crossing score for a candidate against all committed routes. */
498
+ function crossingScore(pts, hSegs, vSegs, isBezier, committed) {
499
+ let crossings = 0;
500
+ for (const cr of committed) {
501
+ if (!isBezier && !cr.isBezier) {
502
+ crossings += countHVCrossings(hSegs, vSegs, cr.hSegs, cr.vSegs);
503
+ }
504
+ else {
505
+ crossings += countPolylineCrossings(pts, cr.points);
506
+ }
507
+ }
508
+ return crossings * W_CROSS;
509
+ }
510
+ // ─── Cost function components ─────────────────────────────────────────────────
511
+ /**
512
+ * Side preference penalty.
513
+ * Ideal source wall faces the target; ideal destination wall faces back.
514
+ * Each step away from ideal costs W_SIDE.
515
+ */
516
+ function sidePenalty(srcWall, dstWall, srcCenter, dstCenter) {
517
+ const dx = dstCenter.x - srcCenter.x;
518
+ const dy = dstCenter.y - srcCenter.y;
519
+ const absX = Math.abs(dx), absY = Math.abs(dy);
520
+ const idealSrc = absX >= absY ? (dx >= 0 ? 'E' : 'W') : (dy >= 0 ? 'S' : 'N');
521
+ const idealDst = absX >= absY ? (dx >= 0 ? 'W' : 'E') : (dy >= 0 ? 'N' : 'S');
522
+ return sideSteps(srcWall, idealSrc) * W_SIDE +
523
+ sideSteps(dstWall, idealDst) * W_SIDE;
524
+ }
525
+ function sideSteps(wall, ideal) {
526
+ if (wall === ideal)
527
+ return 0;
528
+ const opp = { N: 'S', S: 'N', E: 'W', W: 'E' };
529
+ return opp[wall] === ideal ? 2 : 1;
530
+ }
531
+ /**
532
+ * Two-tier port conflict penalty.
533
+ * W_INTER for cross-link vs cross-link conflicts (strongly discouraged).
534
+ * W_INTRA for cross-link vs intra-diagram edge (softer, can be overridden).
535
+ */
536
+ function portConflictScore(srcKey, srcWall, srcPt, _srcT, dstKey, dstWall, dstPt, _dstT, committed, intraPorts, anchors) {
537
+ let penalty = 0;
538
+ // Cross-link vs cross-link (W_INTER)
539
+ for (const cr of committed) {
540
+ for (const [key, wall, pt] of [
541
+ [cr.srcKey, cr.srcWall, cr.srcPort],
542
+ [cr.dstKey, cr.dstWall, cr.dstPort],
543
+ ]) {
544
+ if (key === srcKey && wall === srcWall) {
545
+ const d = Math.hypot(srcPt.x - pt.x, srcPt.y - pt.y);
546
+ if (d < CONFLICT_RADIUS)
547
+ penalty += W_INTER * (1 - d / CONFLICT_RADIUS);
548
+ }
549
+ if (key === dstKey && wall === dstWall) {
550
+ const d = Math.hypot(dstPt.x - pt.x, dstPt.y - pt.y);
551
+ if (d < CONFLICT_RADIUS)
552
+ penalty += W_INTER * (1 - d / CONFLICT_RADIUS);
553
+ }
554
+ }
555
+ }
556
+ // Cross-link vs intra-diagram (W_INTRA)
557
+ for (const ip of intraPorts) {
558
+ const anchor = anchors[ip.nodeKey];
559
+ if (!anchor)
560
+ continue;
561
+ const ipPt = wallPoint(anchor.bounds, ip.wall, ip.t);
562
+ if (ip.nodeKey === srcKey && ip.wall === srcWall) {
563
+ const d = Math.hypot(srcPt.x - ipPt.x, srcPt.y - ipPt.y);
564
+ if (d < CONFLICT_RADIUS)
565
+ penalty += W_INTRA * (1 - d / CONFLICT_RADIUS);
566
+ }
567
+ if (ip.nodeKey === dstKey && ip.wall === dstWall) {
568
+ const d = Math.hypot(dstPt.x - ipPt.x, dstPt.y - ipPt.y);
569
+ if (d < CONFLICT_RADIUS)
570
+ penalty += W_INTRA * (1 - d / CONFLICT_RADIUS);
571
+ }
572
+ }
573
+ return penalty;
574
+ }
575
+ /** Flat penalty per short jog segment (orthogonal only). */
576
+ function alignPenalty(pts) {
577
+ let p = 0;
578
+ for (let i = 0; i < pts.length - 1; i++) {
579
+ const a = pts[i], b = pts[i + 1];
580
+ if (Math.hypot(b.x - a.x, b.y - a.y) < SNAP_THRESHOLD)
581
+ p += W_ALIGN;
582
+ }
583
+ return p;
584
+ }
585
+ // ─── Port alignment snap ──────────────────────────────────────────────────────
586
+ function snapAlignment(ss, sp, ds, dp) {
587
+ const sH = ss === 'E' || ss === 'W', dH = ds === 'E' || ds === 'W';
588
+ if (sH && dH && Math.abs(sp.y - dp.y) < SNAP_THRESHOLD) {
589
+ const avgY = (sp.y + dp.y) / 2;
590
+ return { srcPort: { x: sp.x, y: avgY }, dstPort: { x: dp.x, y: avgY } };
591
+ }
592
+ const sV = ss === 'N' || ss === 'S', dV = ds === 'N' || ds === 'S';
593
+ if (sV && dV && Math.abs(sp.x - dp.x) < SNAP_THRESHOLD) {
594
+ const avgX = (sp.x + dp.x) / 2;
595
+ return { srcPort: { x: avgX, y: sp.y }, dstPort: { x: avgX, y: dp.y } };
596
+ }
597
+ return { srcPort: sp, dstPort: dp };
598
+ }
599
+ // ─── Pass 0: Shared-endpoint port pre-assignment ─────────────────────────────
600
+ /**
601
+ * For every (node, wall) pair that has 2+ cross-links touching it, assign
602
+ * evenly-spaced t values sorted by the angular position of the OTHER endpoint
603
+ * along the wall's tangent direction.
604
+ *
605
+ * Invariant: if two routes share a node wall, their t values are ordered the
606
+ * same way as the spatial positions of their other endpoints — so the routes
607
+ * form a non-crossing fan at the shared node, eliminating the need for repair.
608
+ */
609
+ function preAssignSharedPorts(links, anchors) {
610
+ const key = (addr) => [...addr.cellPath, addr.nodeId].join('.');
611
+ // Step 1: determine ideal wall for each endpoint
612
+ const walls = links.map(link => {
613
+ const sa = anchors[key(link.from)];
614
+ const da = anchors[key(link.to)];
615
+ if (!sa || !da)
616
+ return { srcWall: 'E', dstWall: 'W' };
617
+ const sc = rectCenter(sa.bounds), dc = rectCenter(da.bounds);
618
+ return {
619
+ srcWall: link.exitWall ?? idealSrcWall(sc, dc),
620
+ dstWall: link.entryWall ?? idealDstWall(sc, dc),
621
+ };
622
+ });
623
+ const groups = new Map();
624
+ for (let i = 0; i < links.length; i++) {
625
+ const link = links[i];
626
+ const srcKey = key(link.from);
627
+ const dstKey = key(link.to);
628
+ const sa = anchors[srcKey];
629
+ const da = anchors[dstKey];
630
+ if (!sa || !da)
631
+ continue;
632
+ const { srcWall, dstWall } = walls[i];
633
+ const sc = rectCenter(sa.bounds), dc = rectCenter(da.bounds);
634
+ // tangent key = position of the OTHER endpoint along the wall's tangent axis
635
+ // N/S walls run horizontally → sort by x; E/W walls run vertically → sort by y
636
+ const srcTK = (srcWall === 'N' || srcWall === 'S') ? dc.x : dc.y;
637
+ const dstTK = (dstWall === 'N' || dstWall === 'S') ? sc.x : sc.y;
638
+ const sg = `${srcKey}:${srcWall}`;
639
+ const dg = `${dstKey}:${dstWall}`;
640
+ if (!groups.has(sg))
641
+ groups.set(sg, []);
642
+ if (!groups.has(dg))
643
+ groups.set(dg, []);
644
+ groups.get(sg).push({ linkIdx: i, isSource: true, tangentKey: srcTK });
645
+ groups.get(dg).push({ linkIdx: i, isSource: false, tangentKey: dstTK });
646
+ }
647
+ // Step 3: assign evenly-spaced t values along each wall.
648
+ // - Groups with 2+ members always fan (non-crossing arrival/departure order).
649
+ // - A single link that is USER-PINNED to a wall still gets a slot so it
650
+ // lands at the wall midpoint (1/(1+1)); this is the fan formula degenerating
651
+ // to centre, NOT a hardcoded 0.5. Two pinned links → 1/3, 2/3, and so on.
652
+ // - A single AUTO link keeps its cost-search freedom (no hint emitted).
653
+ const result = new Map();
654
+ for (const [groupKey, members] of groups) {
655
+ const wall = groupKey.split(':').at(-1);
656
+ const pinnedHere = members.filter(m => {
657
+ const l = links[m.linkIdx];
658
+ return m.isSource ? l.exitWall === wall : l.entryWall === wall;
659
+ });
660
+ // Which members actually get fanned on this wall.
661
+ // If any link is pinned here, only the pinned links share the wall slots
662
+ // (auto links keep searching). Otherwise fan the whole group when 2+.
663
+ const fanned = pinnedHere.length > 0 ? pinnedHere : members;
664
+ if (fanned.length < 2 && pinnedHere.length === 0)
665
+ continue;
666
+ fanned.sort((a, b) => a.tangentKey - b.tangentKey);
667
+ const n = fanned.length;
668
+ for (let k = 0; k < n; k++) {
669
+ const { linkIdx, isSource } = fanned[k];
670
+ const t = (k + 1) / (n + 1);
671
+ const ex = result.get(linkIdx) ?? {};
672
+ result.set(linkIdx, isSource
673
+ ? { ...ex, srcWall: wall, srcT: t }
674
+ : { ...ex, dstWall: wall, dstT: t });
675
+ }
676
+ }
677
+ return result;
678
+ }
679
+ /** Centre of a bounding rect. */
680
+ function rectCenter(r) {
681
+ return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
682
+ }
683
+ /** Ideal exit wall on the source node when routing toward dst. */
684
+ function idealSrcWall(sc, dc) {
685
+ const dx = dc.x - sc.x, dy = dc.y - sc.y;
686
+ return Math.abs(dx) >= Math.abs(dy) ? (dx >= 0 ? 'E' : 'W') : (dy >= 0 ? 'S' : 'N');
687
+ }
688
+ /** Ideal entry wall on the destination node (opposite of idealSrcWall). */
689
+ function idealDstWall(sc, dc) {
690
+ const opp = { N: 'S', S: 'N', E: 'W', W: 'E' };
691
+ return opp[idealSrcWall(sc, dc)];
692
+ }
693
+ // ─── Geometry helpers ─────────────────────────────────────────────────────────
694
+ /**
695
+ * Point at fraction t (0=wall start, 1=wall end) along a node wall.
696
+ * N/S: t=0 is left edge, t=1 is right edge.
697
+ * E/W: t=0 is top edge, t=1 is bottom edge.
698
+ */
699
+ function wallPoint(bounds, wall, t) {
700
+ const { x, y, width: w, height: h } = bounds;
701
+ switch (wall) {
702
+ case 'N': return { x: x + w * t, y };
703
+ case 'S': return { x: x + w * t, y: y + h };
704
+ case 'W': return { x, y: y + h * t };
705
+ case 'E': return { x: x + w, y: y + h * t };
706
+ }
707
+ }
708
+ /** Sample n+1 points along a cubic bezier. */
709
+ function sampleCubicBezier(p0, p1, p2, p3, n) {
710
+ const pts = [];
711
+ for (let i = 0; i <= n; i++) {
712
+ const t = i / n, t2 = t * t, t3 = t2 * t;
713
+ const mt = 1 - t, mt2 = mt * mt, mt3 = mt2 * mt;
714
+ pts.push({
715
+ x: mt3 * p0.x + 3 * mt2 * t * p1.x + 3 * mt * t2 * p2.x + t3 * p3.x,
716
+ y: mt3 * p0.y + 3 * mt2 * t * p1.y + 3 * mt * t2 * p2.y + t3 * p3.y,
717
+ });
718
+ }
719
+ return pts;
720
+ }
721
+ /** For bezier WorkingRoute: return sampled curve pts; otherwise return raw pts. */
722
+ function sampledPts(wr) {
723
+ if (wr.isBezier && wr.points.length === 4) {
724
+ return sampleCubicBezier(wr.points[0], wr.points[1], wr.points[2], wr.points[3], 12);
725
+ }
726
+ return wr.points;
727
+ }
728
+ /** True iff two line segments properly cross (not merely touch). */
729
+ function properlyCross(p1, p2, p3, p4) {
730
+ const d1 = cross2(p3, p4, p1), d2 = cross2(p3, p4, p2);
731
+ const d3 = cross2(p1, p2, p3), d4 = cross2(p1, p2, p4);
732
+ return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
733
+ ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0));
734
+ }
735
+ function cross2(a, b, c) {
736
+ return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
737
+ }
738
+ function pathLen(pts) {
739
+ let len = 0;
740
+ for (let i = 0; i < pts.length - 1; i++) {
741
+ const a = pts[i], b = pts[i + 1];
742
+ len += Math.hypot(b.x - a.x, b.y - a.y);
743
+ }
744
+ return len;
745
+ }
746
+ function pointAtFrac(pts, t) {
747
+ if (pts.length === 0)
748
+ return { x: 0, y: 0 };
749
+ if (pts.length === 1)
750
+ return pts[0];
751
+ const lens = [];
752
+ let total = 0;
753
+ for (let i = 0; i < pts.length - 1; i++) {
754
+ const l = Math.hypot(pts[i + 1].x - pts[i].x, pts[i + 1].y - pts[i].y);
755
+ lens.push(l);
756
+ total += l;
757
+ }
758
+ if (total === 0)
759
+ return pts[0];
760
+ let acc = 0;
761
+ const target = total * Math.min(Math.max(t, 0), 1);
762
+ for (let i = 0; i < lens.length; i++) {
763
+ const l = lens[i];
764
+ if (acc + l >= target) {
765
+ const frac = l > 0 ? (target - acc) / l : 0;
766
+ const a = pts[i], b = pts[i + 1];
767
+ return { x: a.x + (b.x - a.x) * frac, y: a.y + (b.y - a.y) * frac };
768
+ }
769
+ acc += l;
770
+ }
771
+ return pts[pts.length - 1];
772
+ }
773
+ function dominantSegment(pts) {
774
+ let bestLen = 0, axis = 'h', coord = 0;
775
+ for (let i = 0; i < pts.length - 1; i++) {
776
+ const a = pts[i], b = pts[i + 1];
777
+ const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
778
+ const len = dx + dy;
779
+ if (len > bestLen) {
780
+ bestLen = len;
781
+ if (dy > dx) {
782
+ axis = 'v';
783
+ coord = (a.x + b.x) / 2;
784
+ }
785
+ else {
786
+ axis = 'h';
787
+ coord = (a.y + b.y) / 2;
788
+ }
789
+ }
790
+ }
791
+ return { axis, coord };
792
+ }
793
+ /**
794
+ * Pick the anchor point for an edge label. Prefers the midpoint of the longest
795
+ * HORIZONTAL segment (labels are horizontal text and read best along a
796
+ * horizontal run), and only falls back to the longest segment overall when the
797
+ * route has no meaningful horizontal segment (e.g. a pure vertical link).
798
+ */
799
+ function labelAnchor(pts) {
800
+ if (pts.length === 0)
801
+ return { x: 0, y: 0 };
802
+ if (pts.length === 1)
803
+ return pts[0];
804
+ let bestH = -1;
805
+ let hMid = null;
806
+ let bestAny = -1;
807
+ let anyMid = pts[0];
808
+ for (let i = 0; i < pts.length - 1; i++) {
809
+ const a = pts[i], b = pts[i + 1];
810
+ const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
811
+ const len = Math.hypot(dx, dy);
812
+ if (len > bestAny) {
813
+ bestAny = len;
814
+ anyMid = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
815
+ }
816
+ if (dx > dy && dx > bestH) {
817
+ bestH = dx;
818
+ hMid = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
819
+ }
820
+ }
821
+ return hMid ?? anyMid;
822
+ }
823
+ function edgeStyleToDash(style) {
824
+ if (style === 'dashed')
825
+ return '8 4';
826
+ if (style === 'dotted')
827
+ return '3 4';
828
+ return undefined;
829
+ }
830
+ // ─── Post-route: border nudging ───────────────────────────────────────────────
831
+ function nudgeOffBorders(routes, borders) {
832
+ const TOLERANCE = 3, NUDGE = 8;
833
+ const hBorderYs = borders.filter(b => b.width > b.height).map(b => b.y + b.height / 2);
834
+ const vBorderXs = borders.filter(b => b.height >= b.width).map(b => b.x + b.width / 2);
835
+ for (const route of routes) {
836
+ if (route.isBezier)
837
+ continue;
838
+ const pts = route.points;
839
+ for (let i = 0; i < pts.length - 1; i++) {
840
+ const a = pts[i], b = pts[i + 1];
841
+ if (Math.abs(b.y - a.y) < 1 && Math.abs(b.x - a.x) > 1) {
842
+ for (const borderY of hBorderYs) {
843
+ if (Math.abs(a.y - borderY) < TOLERANCE) {
844
+ const midY = (Math.min(...pts.map(p => p.y)) + Math.max(...pts.map(p => p.y))) / 2;
845
+ const nd = a.y < midY ? -NUDGE : NUDGE;
846
+ pts[i] = { x: a.x, y: a.y + nd };
847
+ pts[i + 1] = { x: b.x, y: b.y + nd };
848
+ break;
849
+ }
850
+ }
851
+ }
852
+ else if (Math.abs(b.x - a.x) < 1 && Math.abs(b.y - a.y) > 1) {
853
+ for (const borderX of vBorderXs) {
854
+ if (Math.abs(a.x - borderX) < TOLERANCE) {
855
+ const midX = (Math.min(...pts.map(p => p.x)) + Math.max(...pts.map(p => p.x))) / 2;
856
+ const nd = a.x < midX ? -NUDGE : NUDGE;
857
+ pts[i] = { x: a.x + nd, y: a.y };
858
+ pts[i + 1] = { x: b.x + nd, y: b.y };
859
+ break;
860
+ }
861
+ }
862
+ }
863
+ }
864
+ }
865
+ }
866
+ // ─── Post-route: channel separation ──────────────────────────────────────────
867
+ function separateChannels(routes) {
868
+ const segs = [];
869
+ for (let ri = 0; ri < routes.length; ri++) {
870
+ if (routes[ri].isBezier)
871
+ continue;
872
+ const pts = routes[ri].points;
873
+ for (let si = 0; si < pts.length - 1; si++) {
874
+ const a = pts[si], b = pts[si + 1];
875
+ const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
876
+ if (dx < 1 && dy > 1) {
877
+ segs.push({ ri, si, isV: true, coord: (a.x + b.x) / 2, lo: Math.min(a.y, b.y), hi: Math.max(a.y, b.y) });
878
+ }
879
+ else if (dy < 1 && dx > 1) {
880
+ segs.push({ ri, si, isV: false, coord: (a.y + b.y) / 2, lo: Math.min(a.x, b.x), hi: Math.max(a.x, b.x) });
881
+ }
882
+ }
883
+ }
884
+ const COORD_TOL = 10;
885
+ const used = new Set();
886
+ for (let i = 0; i < segs.length; i++) {
887
+ if (used.has(i))
888
+ continue;
889
+ const si = segs[i];
890
+ const group = [i];
891
+ for (let j = i + 1; j < segs.length; j++) {
892
+ if (used.has(j))
893
+ continue;
894
+ const sj = segs[j];
895
+ if (sj.isV !== si.isV)
896
+ continue;
897
+ if (Math.abs(sj.coord - si.coord) > COORD_TOL)
898
+ continue;
899
+ if (sj.hi - si.lo > 8 && si.hi - sj.lo > 8) {
900
+ group.push(j);
901
+ used.add(j);
902
+ }
903
+ }
904
+ used.add(i);
905
+ if (group.length < 2)
906
+ continue;
907
+ const n = group.length;
908
+ for (let k = 0; k < n; k++) {
909
+ const seg = segs[group[k]];
910
+ const offset = (k - (n - 1) / 2) * CHANNEL_GAP;
911
+ const pts = routes[seg.ri].points;
912
+ if (seg.isV) {
913
+ pts[seg.si] = { x: pts[seg.si].x + offset, y: pts[seg.si].y };
914
+ pts[seg.si + 1] = { x: pts[seg.si + 1].x + offset, y: pts[seg.si + 1].y };
915
+ }
916
+ else {
917
+ pts[seg.si] = { x: pts[seg.si].x, y: pts[seg.si].y + offset };
918
+ pts[seg.si + 1] = { x: pts[seg.si + 1].x, y: pts[seg.si + 1].y + offset };
919
+ }
920
+ }
921
+ }
922
+ }
923
+ // ─── Label de-collision ───────────────────────────────────────────────────────
924
+ function deCollideLabels(labelRects, fixedRects) {
925
+ const MAX_PASSES = 20, NUDGE = 2;
926
+ for (let pass = 0; pass < MAX_PASSES; pass++) {
927
+ let moved = false;
928
+ for (const lr of labelRects) {
929
+ for (const fr of fixedRects) {
930
+ if (!rectsOverlap(lr, fr))
931
+ continue;
932
+ const ox = Math.min(lr.x + lr.width, fr.x + fr.width) - Math.max(lr.x, fr.x);
933
+ const oy = Math.min(lr.y + lr.height, fr.y + fr.height) - Math.max(lr.y, fr.y);
934
+ if (ox <= oy) {
935
+ lr.x = (lr.x + lr.width / 2) <= (fr.x + fr.width / 2) ? fr.x - lr.width - NUDGE : fr.x + fr.width + NUDGE;
936
+ }
937
+ else {
938
+ lr.y = (lr.y + lr.height / 2) <= (fr.y + fr.height / 2) ? fr.y - lr.height - NUDGE : fr.y + fr.height + NUDGE;
939
+ }
940
+ moved = true;
941
+ }
942
+ }
943
+ for (let i = 0; i < labelRects.length; i++) {
944
+ for (let j = i + 1; j < labelRects.length; j++) {
945
+ const a = labelRects[i], b = labelRects[j];
946
+ if (!rectsOverlap(a, b))
947
+ continue;
948
+ const oy = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
949
+ if (a.y + a.height / 2 <= b.y + b.height / 2) {
950
+ a.y -= oy / 2 + NUDGE;
951
+ b.y += oy / 2 + NUDGE;
952
+ }
953
+ else {
954
+ a.y += oy / 2 + NUDGE;
955
+ b.y -= oy / 2 + NUDGE;
956
+ }
957
+ moved = true;
958
+ }
959
+ }
960
+ if (!moved)
961
+ break;
962
+ }
963
+ }
964
+ function rectsOverlap(a, b) {
965
+ return a.x < b.x + b.width && a.x + a.width > b.x &&
966
+ a.y < b.y + b.height && a.y + a.height > b.y;
967
+ }
968
+ //# sourceMappingURL=engine3.js.map