@peter.prib/renderengine 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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/REFERENCE.md +2198 -0
  4. package/dist/renderengine-workspace.umd.js +46905 -0
  5. package/dist/renderengine.umd.js +42223 -0
  6. package/examples/archimate.html +66 -0
  7. package/examples/diagram-editor.html +51 -0
  8. package/package.json +65 -4
  9. package/src/BaseRenderer.js +57 -0
  10. package/src/CanvasRenderer.js +194 -0
  11. package/src/Mat4.js +111 -0
  12. package/src/OrbitCamera.js +57 -0
  13. package/src/RendererFactory.js +50 -0
  14. package/src/SVGRenderer.js +439 -0
  15. package/src/archimate.js +723 -0
  16. package/src/archimateArchiFormat.js +1693 -0
  17. package/src/archimateArchiTypes.js +72 -0
  18. package/src/archimateArchive.js +140 -0
  19. package/src/archimateCSV.js +127 -0
  20. package/src/archimateDrawio.js +182 -0
  21. package/src/archimateExchangeFormat.js +546 -0
  22. package/src/archimateRelationshipTable.js +93 -0
  23. package/src/archimateSpecializations.js +161 -0
  24. package/src/chartCatalog.js +589 -0
  25. package/src/charting/ArchimateDiagramEditor.js +1624 -0
  26. package/src/charting/ArchimateSpecializationSelector.js +134 -0
  27. package/src/charting/Axis.js +68 -0
  28. package/src/charting/CameraSeeder.js +30 -0
  29. package/src/charting/CatalogDialog.js +92 -0
  30. package/src/charting/Chart.js +37 -0
  31. package/src/charting/Chart3D.js +99 -0
  32. package/src/charting/ChartBox.js +80 -0
  33. package/src/charting/ChartData.js +27 -0
  34. package/src/charting/ChartRegistry.js +76 -0
  35. package/src/charting/CheckboxTreeSelector.js +304 -0
  36. package/src/charting/ColorField.js +107 -0
  37. package/src/charting/ColorPalette.js +88 -0
  38. package/src/charting/CommandHistory.js +176 -0
  39. package/src/charting/DataFilter.js +52 -0
  40. package/src/charting/Diagram.js +36 -0
  41. package/src/charting/Diagram3D.js +29 -0
  42. package/src/charting/DiagramClipboard.js +31 -0
  43. package/src/charting/DiagramEditor.js +3330 -0
  44. package/src/charting/DiagramEditorCommand.js +110 -0
  45. package/src/charting/DiagramEditorCommands.js +237 -0
  46. package/src/charting/DiagramEditorEdgeCommands.js +142 -0
  47. package/src/charting/DiagramEditorState.js +98 -0
  48. package/src/charting/DiagramRegistry.js +86 -0
  49. package/src/charting/DiagramTypeRegistry.js +326 -0
  50. package/src/charting/DiagramViewPropertiesDialog.js +46 -0
  51. package/src/charting/Edge.js +113 -0
  52. package/src/charting/ErrorBars.js +37 -0
  53. package/src/charting/FilterSystem.js +285 -0
  54. package/src/charting/FindReplaceDialog.js +139 -0
  55. package/src/charting/FormDialog.js +385 -0
  56. package/src/charting/Gauge.js +58 -0
  57. package/src/charting/Hierarchy.js +175 -0
  58. package/src/charting/HintPanel.js +86 -0
  59. package/src/charting/ImageSelector.js +148 -0
  60. package/src/charting/InteractionManager.js +725 -0
  61. package/src/charting/Legend.js +58 -0
  62. package/src/charting/MenuBar.js +62 -0
  63. package/src/charting/ModelFileFormat.js +115 -0
  64. package/src/charting/OrbitControls.js +77 -0
  65. package/src/charting/Palette.js +119 -0
  66. package/src/charting/PopupMenu.js +117 -0
  67. package/src/charting/PropertiesPanel.js +155 -0
  68. package/src/charting/PropertyListEditor.js +96 -0
  69. package/src/charting/PropertyLog.js +92 -0
  70. package/src/charting/SettingsCascade.js +93 -0
  71. package/src/charting/SettingsDialog.js +53 -0
  72. package/src/charting/SettingsManager.js +179 -0
  73. package/src/charting/SettingsViewPropertiesDialog.js +58 -0
  74. package/src/charting/ShapePaths.js +27 -0
  75. package/src/charting/Statistics.js +134 -0
  76. package/src/charting/TemplateCatalog.js +59 -0
  77. package/src/charting/TemplateLibrary.js +103 -0
  78. package/src/charting/TextStyle.js +168 -0
  79. package/src/charting/ViewFit.js +55 -0
  80. package/src/charting/ViewMenu.js +70 -0
  81. package/src/charting/ViewPropertiesDialog.js +77 -0
  82. package/src/charting/ViewTabStrip.js +81 -0
  83. package/src/charting/archimate/ArchiFileFormat.js +32 -0
  84. package/src/charting/archimate/ArchimateCanvasEditor.js +815 -0
  85. package/src/charting/archimate/ArchimateCsvFileFormat.js +35 -0
  86. package/src/charting/archimate/ArchimateEdge.js +137 -0
  87. package/src/charting/archimate/ArchimateElementTemplate.js +195 -0
  88. package/src/charting/archimate/ArchimatePalette.js +102 -0
  89. package/src/charting/archimate/CsvImportDialog.js +105 -0
  90. package/src/charting/archimate/CustomViewpoints.js +74 -0
  91. package/src/charting/archimate/DerivedEdge.js +29 -0
  92. package/src/charting/archimate/DrawioFileFormat.js +24 -0
  93. package/src/charting/archimate/ElementFilterRule.js +21 -0
  94. package/src/charting/archimate/ExchangeFileFormat.js +28 -0
  95. package/src/charting/archimate/ViewGroupTemplate.js +137 -0
  96. package/src/charting/archimate/ViewLineEdge.js +84 -0
  97. package/src/charting/archimate/ViewpointRule.js +45 -0
  98. package/src/charting/archimate/archimateFileFormats.js +12 -0
  99. package/src/charting/archimate/archimateNames.js +5 -0
  100. package/src/charting/archimate/csvMapping.js +122 -0
  101. package/src/charting/archimate/elementMenuItems.js +32 -0
  102. package/src/charting/archimate/elementProperties.js +146 -0
  103. package/src/charting/archimate/elementTypeChoices.js +7 -0
  104. package/src/charting/archimate/elementTypeGroups.js +19 -0
  105. package/src/charting/archimate/index.js +17 -0
  106. package/src/charting/archimate/specializationCatalogDialog.js +64 -0
  107. package/src/charting/archimate/typeGlyph.js +29 -0
  108. package/src/charting/arrangement/Arrangement.js +112 -0
  109. package/src/charting/arrangement/ArrangementCommand.js +29 -0
  110. package/src/charting/arrangement/BackgroundCommand.js +41 -0
  111. package/src/charting/arrangement/BackgroundGroup.js +18 -0
  112. package/src/charting/arrangement/GroupCommand.js +46 -0
  113. package/src/charting/arrangement/ItemGroup.js +62 -0
  114. package/src/charting/arrangement/LockCommand.js +32 -0
  115. package/src/charting/arrangement/UngroupCommand.js +27 -0
  116. package/src/charting/arrangement/alignment.js +88 -0
  117. package/src/charting/arrangement/arrangeMenuItems.js +25 -0
  118. package/src/charting/arrangement/index.js +11 -0
  119. package/src/charting/arrangement/layouts.js +233 -0
  120. package/src/charting/canvas/ArchiHint.js +78 -0
  121. package/src/charting/canvas/CanvasBoxKind.js +39 -0
  122. package/src/charting/canvas/CanvasPalette.js +49 -0
  123. package/src/charting/canvas/CanvasTemplateLibrary.js +61 -0
  124. package/src/charting/canvas/CanvasTemplateMenu.js +151 -0
  125. package/src/charting/canvas/EditHintCommand.js +28 -0
  126. package/src/charting/canvas/canvasBoxKinds.js +27 -0
  127. package/src/charting/canvas/canvasBoxMenuItems.js +40 -0
  128. package/src/charting/canvas/defaultCanvasTemplates.js +186 -0
  129. package/src/charting/canvas/diagramBoxKinds.js +12 -0
  130. package/src/charting/canvas/hintMenuItems.js +49 -0
  131. package/src/charting/charts/ArcGauge.js +55 -0
  132. package/src/charting/charts/AreaChart.js +71 -0
  133. package/src/charting/charts/BarChart.js +80 -0
  134. package/src/charting/charts/BarChart3D.js +56 -0
  135. package/src/charting/charts/BarChart3DOrbit.js +53 -0
  136. package/src/charting/charts/BarChartBase.js +70 -0
  137. package/src/charting/charts/BarGauge.js +42 -0
  138. package/src/charting/charts/BoxPlotChart.js +41 -0
  139. package/src/charting/charts/BubbleChart.js +99 -0
  140. package/src/charting/charts/BubbleChart3D.js +78 -0
  141. package/src/charting/charts/BulletGauge.js +87 -0
  142. package/src/charting/charts/CalendarHeatmapChart.js +204 -0
  143. package/src/charting/charts/CandlestickChart.js +54 -0
  144. package/src/charting/charts/ChordDiagram.js +130 -0
  145. package/src/charting/charts/DensityChart.js +73 -0
  146. package/src/charting/charts/DialGauge.js +65 -0
  147. package/src/charting/charts/DonutChart.js +15 -0
  148. package/src/charting/charts/FunnelChart.js +47 -0
  149. package/src/charting/charts/GanttChart.js +201 -0
  150. package/src/charting/charts/GaugeChart.js +175 -0
  151. package/src/charting/charts/GeoMapChart.js +146 -0
  152. package/src/charting/charts/GroupedBarChart.js +88 -0
  153. package/src/charting/charts/GroupedDistributionChart.js +70 -0
  154. package/src/charting/charts/HeatmapChart.js +80 -0
  155. package/src/charting/charts/HierarchyChart.js +39 -0
  156. package/src/charting/charts/HistogramChart.js +45 -0
  157. package/src/charting/charts/KpiTile.js +72 -0
  158. package/src/charting/charts/LagPlotChart.js +41 -0
  159. package/src/charting/charts/LineChart.js +124 -0
  160. package/src/charting/charts/MultiRingGauge.js +54 -0
  161. package/src/charting/charts/OutlineChart.js +95 -0
  162. package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
  163. package/src/charting/charts/PieChart.js +56 -0
  164. package/src/charting/charts/PipeChart.js +88 -0
  165. package/src/charting/charts/PopulationPyramidChart.js +106 -0
  166. package/src/charting/charts/QQPlotChart.js +64 -0
  167. package/src/charting/charts/RadarChart.js +76 -0
  168. package/src/charting/charts/RadialBarChart.js +96 -0
  169. package/src/charting/charts/RingGauge.js +23 -0
  170. package/src/charting/charts/SankeyDiagram.js +174 -0
  171. package/src/charting/charts/ScatterChart.js +104 -0
  172. package/src/charting/charts/StackedAreaChart.js +15 -0
  173. package/src/charting/charts/StackedBarChart.js +33 -0
  174. package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
  175. package/src/charting/charts/StreamGraphChart.js +131 -0
  176. package/src/charting/charts/SunburstChart.js +57 -0
  177. package/src/charting/charts/ThermometerGauge.js +43 -0
  178. package/src/charting/charts/TreemapChart.js +54 -0
  179. package/src/charting/charts/ViolinChart.js +37 -0
  180. package/src/charting/charts/WaterfallChart.js +66 -0
  181. package/src/charting/charts/WordCloudChart.js +104 -0
  182. package/src/charting/diagramModel/AddViewCommand.js +33 -0
  183. package/src/charting/diagramModel/DiagramModel.js +39 -0
  184. package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
  185. package/src/charting/diagramModel/DiagramView.js +50 -0
  186. package/src/charting/diagramModel/ModelHistory.js +43 -0
  187. package/src/charting/diagramModel/ModelReport.js +153 -0
  188. package/src/charting/diagramModel/ModelSearch.js +223 -0
  189. package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
  190. package/src/charting/diagramModel/RenameViewCommand.js +21 -0
  191. package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
  192. package/src/charting/diagramModel/ViewSetChecker.js +34 -0
  193. package/src/charting/diagramModel/ViewSetModel.js +243 -0
  194. package/src/charting/diagramModel/index.js +6 -0
  195. package/src/charting/diagramModel/nameTransforms.js +29 -0
  196. package/src/charting/diagrams/ArchimateCommands.js +141 -0
  197. package/src/charting/diagrams/ArchimateDiagram.js +263 -0
  198. package/src/charting/diagrams/ArchimateModel.js +1155 -0
  199. package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
  200. package/src/charting/diagrams/ArchimateModelReport.js +128 -0
  201. package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
  202. package/src/charting/diagrams/ArchimateValidator.js +357 -0
  203. package/src/charting/diagrams/CanvasView.js +112 -0
  204. package/src/charting/diagrams/ContextMenu.js +37 -0
  205. package/src/charting/diagrams/DataModelDiagram.js +86 -0
  206. package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
  207. package/src/charting/diagrams/DerivedRelationships.js +102 -0
  208. package/src/charting/diagrams/EbnfDiagram.js +39 -0
  209. package/src/charting/diagrams/EdgeGeometry.js +553 -0
  210. package/src/charting/diagrams/EditViewItemCommand.js +128 -0
  211. package/src/charting/diagrams/ElementInstance.js +157 -0
  212. package/src/charting/diagrams/GraphDiagram.js +1340 -0
  213. package/src/charting/diagrams/GraphDiagram3D.js +152 -0
  214. package/src/charting/diagrams/GraphMetrics.js +81 -0
  215. package/src/charting/diagrams/GridOverlay.js +137 -0
  216. package/src/charting/diagrams/ImportRowsCommand.js +62 -0
  217. package/src/charting/diagrams/LabelHelper.js +108 -0
  218. package/src/charting/diagrams/MergeElementsCommand.js +101 -0
  219. package/src/charting/diagrams/NestInstanceCommand.js +34 -0
  220. package/src/charting/diagrams/NodeGeometry.js +158 -0
  221. package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
  222. package/src/charting/diagrams/RadialLayout.js +101 -0
  223. package/src/charting/diagrams/RelationshipInstance.js +93 -0
  224. package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
  225. package/src/charting/diagrams/RemoveLineCommand.js +27 -0
  226. package/src/charting/diagrams/ShowElementCommand.js +43 -0
  227. package/src/charting/diagrams/SvgCoordinate.js +17 -0
  228. package/src/charting/diagrams/SvgZoom.js +127 -0
  229. package/src/charting/diagrams/Tooltip.js +62 -0
  230. package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
  231. package/src/charting/diagrams/ViewObjectInstance.js +56 -0
  232. package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
  233. package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
  234. package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
  235. package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
  236. package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
  237. package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
  238. package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
  239. package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
  240. package/src/charting/diagrams/commands/GraphCommand.js +65 -0
  241. package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
  242. package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
  243. package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
  244. package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
  245. package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
  246. package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
  247. package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
  248. package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
  249. package/src/charting/diagrams/commands/index.js +17 -0
  250. package/src/charting/diagrams/duplicates.js +49 -0
  251. package/src/charting/diagrams/nesting.js +30 -0
  252. package/src/charting/diagrams/roadmap.js +77 -0
  253. package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
  254. package/src/charting/edgeMarkers/CircleMarker.js +13 -0
  255. package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
  256. package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
  257. package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
  258. package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
  259. package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
  260. package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
  261. package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
  262. package/src/charting/edgeMarkers/index.js +27 -0
  263. package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
  264. package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
  265. package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
  266. package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
  267. package/src/charting/edgeStyle/index.js +4 -0
  268. package/src/charting/emphasis/EmphasisRule.js +42 -0
  269. package/src/charting/emphasis/HighlightRule.js +24 -0
  270. package/src/charting/gauges/ArcTrack.js +51 -0
  271. package/src/charting/gauges/GaugeAnimation.js +51 -0
  272. package/src/charting/gauges/GaugeBands.js +48 -0
  273. package/src/charting/gauges/GaugeScale.js +87 -0
  274. package/src/charting/gauges/GaugeTrack.js +44 -0
  275. package/src/charting/gauges/GaugeValue.js +61 -0
  276. package/src/charting/gauges/HorizontalTrack.js +14 -0
  277. package/src/charting/gauges/LinearTrack.js +29 -0
  278. package/src/charting/gauges/Sparkline.js +42 -0
  279. package/src/charting/gauges/VerticalTrack.js +17 -0
  280. package/src/charting/glyphs/ArrowGlyph.js +21 -0
  281. package/src/charting/glyphs/BatteryGlyph.js +18 -0
  282. package/src/charting/glyphs/ChevronGlyph.js +18 -0
  283. package/src/charting/glyphs/CircleGlyph.js +15 -0
  284. package/src/charting/glyphs/CloudGlyph.js +19 -0
  285. package/src/charting/glyphs/ComponentGlyph.js +18 -0
  286. package/src/charting/glyphs/ConstraintGlyph.js +24 -0
  287. package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
  288. package/src/charting/glyphs/CubeGlyph.js +19 -0
  289. package/src/charting/glyphs/CylinderGlyph.js +19 -0
  290. package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
  291. package/src/charting/glyphs/DeviceGlyph.js +17 -0
  292. package/src/charting/glyphs/DiamondGlyph.js +17 -0
  293. package/src/charting/glyphs/DocumentGlyph.js +17 -0
  294. package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
  295. package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
  296. package/src/charting/glyphs/EllipseGlyph.js +18 -0
  297. package/src/charting/glyphs/FactoryGlyph.js +20 -0
  298. package/src/charting/glyphs/FlagGlyph.js +16 -0
  299. package/src/charting/glyphs/GapCircleGlyph.js +17 -0
  300. package/src/charting/glyphs/GearGlyph.js +37 -0
  301. package/src/charting/glyphs/Glyph.js +98 -0
  302. package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
  303. package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
  304. package/src/charting/glyphs/HexagonGlyph.js +28 -0
  305. package/src/charting/glyphs/IconGlyph.js +22 -0
  306. package/src/charting/glyphs/ImageGlyph.js +16 -0
  307. package/src/charting/glyphs/JunctionGlyph.js +17 -0
  308. package/src/charting/glyphs/LollipopGlyph.js +22 -0
  309. package/src/charting/glyphs/MagnifierGlyph.js +17 -0
  310. package/src/charting/glyphs/NoteGlyph.js +33 -0
  311. package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
  312. package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
  313. package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
  314. package/src/charting/glyphs/PersonGlyph.js +23 -0
  315. package/src/charting/glyphs/PillGlyph.js +23 -0
  316. package/src/charting/glyphs/PinGlyph.js +18 -0
  317. package/src/charting/glyphs/PrincipleGlyph.js +23 -0
  318. package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
  319. package/src/charting/glyphs/RectGlyph.js +15 -0
  320. package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
  321. package/src/charting/glyphs/StackGlyph.js +14 -0
  322. package/src/charting/glyphs/StepsGlyph.js +20 -0
  323. package/src/charting/glyphs/StickFigureGlyph.js +32 -0
  324. package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
  325. package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
  326. package/src/charting/glyphs/TargetGlyph.js +23 -0
  327. package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
  328. package/src/charting/glyphs/WheelGlyph.js +28 -0
  329. package/src/charting/glyphs/drawGlyph.js +28 -0
  330. package/src/charting/glyphs/glyphSvg.js +55 -0
  331. package/src/charting/glyphs/index.js +109 -0
  332. package/src/charting/modelTree/AnalysisPanel.js +159 -0
  333. package/src/charting/modelTree/DiagramTabs.js +217 -0
  334. package/src/charting/modelTree/ModelTree.js +164 -0
  335. package/src/charting/modelTree/ModelTreePanel.js +914 -0
  336. package/src/charting/modelTree/TreeBuilder.js +238 -0
  337. package/src/charting/modelTree/TreeModeRegistry.js +51 -0
  338. package/src/charting/modelTree/TreeViewMode.js +110 -0
  339. package/src/charting/modelTree/buildFilterTrees.js +138 -0
  340. package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
  341. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
  342. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
  343. package/src/charting/modelTree/treeLayers.js +11 -0
  344. package/src/charting/report/reportHtml.js +82 -0
  345. package/src/charting/report/reportViewer.js +118 -0
  346. package/src/charting/shapes/CircleShape.js +19 -0
  347. package/src/charting/shapes/PathShape.js +17 -0
  348. package/src/charting/shapes/RectShape.js +20 -0
  349. package/src/charting/shapes/Shape.js +20 -0
  350. package/src/charting/shapes/ShapeFactory.js +23 -0
  351. package/src/charting/storage/LocalJsonStore.js +43 -0
  352. package/src/charting/templates/ActorTemplate.js +36 -0
  353. package/src/charting/templates/BoxTemplate.js +27 -0
  354. package/src/charting/templates/CircleTemplate.js +18 -0
  355. package/src/charting/templates/ClassTemplate.js +20 -0
  356. package/src/charting/templates/CloudTemplate.js +43 -0
  357. package/src/charting/templates/ComponentTemplate.js +19 -0
  358. package/src/charting/templates/CylinderTemplate.js +30 -0
  359. package/src/charting/templates/DataStoreTemplate.js +16 -0
  360. package/src/charting/templates/DiamondTemplate.js +10 -0
  361. package/src/charting/templates/DocumentTemplate.js +32 -0
  362. package/src/charting/templates/EllipseTemplate.js +15 -0
  363. package/src/charting/templates/FinalStateTemplate.js +12 -0
  364. package/src/charting/templates/GlyphTemplate.js +47 -0
  365. package/src/charting/templates/HexagonTemplate.js +17 -0
  366. package/src/charting/templates/LifelineTemplate.js +20 -0
  367. package/src/charting/templates/ManualInputTemplate.js +12 -0
  368. package/src/charting/templates/NoteTemplate.js +23 -0
  369. package/src/charting/templates/OctagonTemplate.js +7 -0
  370. package/src/charting/templates/PackageTemplate.js +25 -0
  371. package/src/charting/templates/ParallelogramTemplate.js +11 -0
  372. package/src/charting/templates/PentagonTemplate.js +5 -0
  373. package/src/charting/templates/PolygonTemplate.js +18 -0
  374. package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
  375. package/src/charting/templates/RectangleTemplate.js +28 -0
  376. package/src/charting/templates/RegularPolygonTemplate.js +21 -0
  377. package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
  378. package/src/charting/templates/StadiumTemplate.js +8 -0
  379. package/src/charting/templates/StarTemplate.js +17 -0
  380. package/src/charting/templates/SwimlaneTemplate.js +18 -0
  381. package/src/charting/templates/Template.js +208 -0
  382. package/src/charting/templates/TrapezoidTemplate.js +11 -0
  383. package/src/charting/templates/TriangleTemplate.js +12 -0
  384. package/src/charting/templates/index.js +31 -0
  385. package/src/charting/templates/outline.js +59 -0
  386. package/src/charting/templates/svg.js +19 -0
  387. package/src/charting/textToShapes.js +61 -0
  388. package/src/charting/toolbar/ToolbarButton.js +38 -0
  389. package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
  390. package/src/charting/toolbar/ToolbarItem.js +19 -0
  391. package/src/charting/toolbar/ToolbarMenu.js +36 -0
  392. package/src/charting/toolbar/ToolbarSelect.js +38 -0
  393. package/src/charting/toolbar/ToolbarSeparator.js +7 -0
  394. package/src/charting/toolbar/ToolbarText.js +22 -0
  395. package/src/charting/toolbar/index.js +8 -0
  396. package/src/charting/toolbar/pickFile.js +14 -0
  397. package/src/charting/viewDecorations.js +85 -0
  398. package/src/charting/zOrder.js +57 -0
  399. package/src/csvTable.js +61 -0
  400. package/src/datamodel.js +122 -0
  401. package/src/datawindow/BoundedWindow.js +36 -0
  402. package/src/datawindow/FlatDataWindow.js +34 -0
  403. package/src/datawindow/GraphDataWindow.js +40 -0
  404. package/src/datawindow/GroupedSampleDataWindow.js +16 -0
  405. package/src/datawindow/SeriesDataWindow.js +42 -0
  406. package/src/datawindow/index.js +31 -0
  407. package/src/diagramCatalog.js +30 -0
  408. package/src/ebnfDiagram.js +57 -0
  409. package/src/ebnfParser.js +129 -0
  410. package/src/exportImage.js +233 -0
  411. package/src/index.js +2636 -0
  412. package/src/itIcons.js +84 -0
  413. package/src/kernelExpr.js +243 -0
  414. package/src/propertiesDialog.js +463 -0
  415. package/src/railroadDiagram.js +571 -0
  416. package/src/treeModeCatalog.js +16 -0
  417. package/src/workspace/ContextBus.js +79 -0
  418. package/src/workspace/EditorShell.js +67 -0
  419. package/src/workspace/Part.js +163 -0
  420. package/src/workspace/PartFactory.js +49 -0
  421. package/src/workspace/PartRegistry.js +86 -0
  422. package/src/workspace/Workspace.js +321 -0
  423. package/src/workspace/archimateServices.js +33 -0
  424. package/src/workspace/dom.js +120 -0
  425. package/src/workspace/index.js +75 -0
  426. package/src/workspace/layout/GridNode.js +280 -0
  427. package/src/workspace/layout/LayoutNode.js +89 -0
  428. package/src/workspace/layout/PartNode.js +77 -0
  429. package/src/workspace/layout/SplitNode.js +114 -0
  430. package/src/workspace/layout/TabsNode.js +191 -0
  431. package/src/workspace/layout/index.js +24 -0
  432. package/src/workspace/parts/AdapterPart.js +33 -0
  433. package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
  434. package/src/workspace/parts/ArchimateEditorPart.js +79 -0
  435. package/src/workspace/parts/ChartPart.js +115 -0
  436. package/src/workspace/parts/ContentPart.js +34 -0
  437. package/src/workspace/parts/DetailPart.js +46 -0
  438. package/src/workspace/parts/DiagramEditorPart.js +135 -0
  439. package/src/workspace/parts/EditorPart.js +388 -0
  440. package/src/workspace/parts/HtmlPart.js +25 -0
  441. package/src/workspace/parts/ListPart.js +57 -0
  442. package/src/workspace/parts/ModelFile.js +187 -0
  443. package/src/workspace/parts/ModelsPart.js +135 -0
  444. package/src/workspace/styles.js +258 -0
  445. package/src/workspace/themes.js +96 -0
  446. package/src/workspace/workArea.js +413 -0
  447. package/src/workspace/workAreaModel.js +197 -0
  448. package/src/workspace.js +16 -0
  449. package/src/zip/ZipArchive.js +160 -0
  450. package/src/zip/crc32.js +25 -0
  451. package/src/zip/inflate.js +159 -0
@@ -0,0 +1,725 @@
1
+ import { ContextMenu } from './diagrams/ContextMenu.js';
2
+ import { Tooltip } from './diagrams/Tooltip.js';
3
+ import { SvgZoom } from './diagrams/SvgZoom.js';
4
+ import { OrbitControls } from './OrbitControls.js';
5
+ import { CompositeCommand } from './CommandHistory.js';
6
+ import {
7
+ MoveNodeCommand, ResizeNodeCommand, NODE_SIZE_KEYS, nodeSize,
8
+ AddEdgeCommand, DeleteWaypointCommand, MoveWaypointCommand, UpdateEdgeSideCommand,
9
+ } from './diagrams/commands/index.js';
10
+
11
+ /**
12
+ * InteractionManager — owns all DOM event-listener wiring for a RenderEngine.
13
+ *
14
+ * Moving listener registration here shrinks the RenderEngine constructor and
15
+ * keeps interaction concerns in one place. State that other RenderEngine
16
+ * methods rely on (e.g. `_svgZoom`, `_orbitControls`) is still stored on the
17
+ * engine instance so existing call sites continue to work.
18
+ */
19
+ export class InteractionManager {
20
+ constructor(engine) {
21
+ this._engine = engine;
22
+ }
23
+
24
+ attach() {
25
+ if (!this._engine.container) return;
26
+ this._addDragListeners();
27
+ this._addMarqueeListeners();
28
+ this._addTooltipListeners();
29
+ this._addZoomListeners();
30
+ this._addClickListeners();
31
+ this._addContextMenuListeners();
32
+ this._addOrbit3DListeners();
33
+ this._addEdgeCreationListeners();
34
+ this._addResizeListeners();
35
+ this._addKeyboardListeners();
36
+ }
37
+
38
+ _addDragListeners() {
39
+ const engine = this._engine;
40
+ if (!engine.container) return;
41
+
42
+ const DRAG_THRESHOLD = 4;
43
+ let selectedNode = null;
44
+ /** The rest of the dragged node's group: [{id, from}]. */
45
+ let companions = [];
46
+ let selectedWaypoint = null;
47
+ let selectedEndpoint = null;
48
+ let offset = { x: 0, y: 0 };
49
+ let downScreenPos = null;
50
+ let dragStarted = false;
51
+ let dragStartState = null;
52
+
53
+ const getMousePosition = (event) => engine._clientToSvgPoint(event.clientX, event.clientY);
54
+
55
+ const onMouseDown = (event) => {
56
+ const pos = getMousePosition(event);
57
+ const hitShape = engine.hitTest(event.clientX, event.clientY);
58
+ if (!engine._graphDiagram?._graph || !hitShape || !hitShape.draggable) return;
59
+
60
+ if (hitShape.isEndpoint) {
61
+ selectedEndpoint = { edge: hitShape.edge, type: hitShape.endpointType };
62
+ dragStartState = { sourceSide: hitShape.edge.sourceSide, targetSide: hitShape.edge.targetSide };
63
+ downScreenPos = { x: event.clientX, y: event.clientY };
64
+ dragStarted = false;
65
+ return;
66
+ }
67
+
68
+ if (hitShape.isWaypoint) {
69
+ const wp = hitShape.edge.waypoints[hitShape.waypointIndex];
70
+ selectedWaypoint = { edge: hitShape.edge, index: hitShape.waypointIndex };
71
+ dragStartState = { x: wp.x, y: wp.y };
72
+ downScreenPos = { x: event.clientX, y: event.clientY };
73
+ dragStarted = false;
74
+ offset.x = pos.x - wp.x;
75
+ offset.y = pos.y - wp.y;
76
+ return;
77
+ }
78
+
79
+ const nodeId = hitShape.nodeId;
80
+ const graphNode = engine._graphDiagram?._graph.nodes?.find(n => n.id === nodeId);
81
+ // A locked node stays where it is.
82
+ if (graphNode?.locked) return;
83
+ selectedNode = { id: nodeId, el: engine._graphDiagram?._graph.nodeEls.find(el => el.getAttribute('nodeId') === nodeId) };
84
+ // The rest of its group comes along, from where each one is now.
85
+ const posOf = (id) => engine._graphDiagram?._graph.pos.get(id);
86
+ const graph = engine._graphDiagram;
87
+ // A node of the selection drags the rest of it; another node drops the selection.
88
+ const selection = graph?.selectedNodeIds ?? new Set();
89
+ if (!selection.has(nodeId) && selection.size && !(event.ctrlKey || event.metaKey)) graph.selectNodes([]);
90
+ const together = selection.has(nodeId) ? [...selection] : [nodeId];
91
+ const nodeOf = (id) => graph?._graph.nodes?.find(n => n.id === id);
92
+ if (together.some(id => nodeOf(id)?.locked)) { selectedNode = null; return; }
93
+ const ids = new Set(together.flatMap(id => [id, ...(nodeOf(id)?.moveWith ?? [])]));
94
+ companions = [...ids].filter(id => id !== nodeId && posOf(id)).map(id => ({ id, from: { ...posOf(id) } }));
95
+ downScreenPos = { x: event.clientX, y: event.clientY };
96
+ dragStarted = false;
97
+ if (selectedNode) {
98
+ const p = engine._graphDiagram?._graph.pos.get(nodeId);
99
+ dragStartState = p ? { x: p.x, y: p.y } : null;
100
+ offset.x = pos.x - p.x;
101
+ offset.y = pos.y - p.y;
102
+ }
103
+ };
104
+
105
+ const onMouseMove = (event) => {
106
+ if (selectedEndpoint) {
107
+ if (!dragStarted) {
108
+ const dx = event.clientX - downScreenPos.x, dy = event.clientY - downScreenPos.y;
109
+ if (Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
110
+ dragStarted = true;
111
+ }
112
+ event.preventDefault();
113
+ const pos = getMousePosition(event);
114
+ const edge = selectedEndpoint.edge;
115
+ const nodeId = selectedEndpoint.type === 'source' ? edge.source : edge.target;
116
+ const nodePos = engine._graphDiagram?._graph.pos.get(nodeId);
117
+
118
+ if (nodePos) {
119
+ // Determine which side (top/right/bottom/left) the drag point is closest to
120
+ const dx = pos.x - nodePos.x;
121
+ const dy = pos.y - nodePos.y;
122
+ const absDx = Math.abs(dx);
123
+ const absDy = Math.abs(dy);
124
+
125
+ let newSide;
126
+ if (absDx > absDy) {
127
+ newSide = dx > 0 ? 'right' : 'left';
128
+ } else {
129
+ newSide = dy > 0 ? 'bottom' : 'top';
130
+ }
131
+
132
+ if (selectedEndpoint.type === 'source') {
133
+ edge.sourceSide = newSide;
134
+ } else {
135
+ edge.targetSide = newSide;
136
+ }
137
+ engine._graphDiagram?._rerenderGraph();
138
+ engine._graphDiagram?._updateGraphLayout();
139
+ }
140
+ return;
141
+ }
142
+
143
+ if (selectedWaypoint) {
144
+ if (!dragStarted) {
145
+ const dx = event.clientX - downScreenPos.x, dy = event.clientY - downScreenPos.y;
146
+ if (Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
147
+ dragStarted = true;
148
+ }
149
+ event.preventDefault();
150
+ const pos = getMousePosition(event);
151
+ const wp = selectedWaypoint.edge.waypoints[selectedWaypoint.index];
152
+ wp.x = pos.x - offset.x;
153
+ wp.y = pos.y - offset.y;
154
+ engine._graphDiagram?._rerenderGraph();
155
+ engine._graphDiagram?._updateGraphLayout();
156
+ return;
157
+ }
158
+
159
+ if (!selectedNode) return;
160
+ if (!dragStarted) {
161
+ const dx = event.clientX - downScreenPos.x, dy = event.clientY - downScreenPos.y;
162
+ if (Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
163
+ dragStarted = true;
164
+ engine._graphDiagram?._graphFixedPos.add(selectedNode.id);
165
+ if (selectedNode.el && selectedNode.el.parentElement) {
166
+ selectedNode.el.parentElement.appendChild(selectedNode.el);
167
+ }
168
+ }
169
+ event.preventDefault();
170
+ const pos = getMousePosition(event);
171
+ const p = engine._graphDiagram?._graph.pos.get(selectedNode.id);
172
+ const rawX = pos.x - offset.x, rawY = pos.y - offset.y;
173
+ const gridSize = engine._chartState?.options?.gridSize ?? 0;
174
+ const GraphDiagram = engine._graphDiagram?.constructor;
175
+ p.x = GraphDiagram?.snapToGrid ? GraphDiagram.snapToGrid(rawX, gridSize) : rawX;
176
+ p.y = GraphDiagram?.snapToGrid ? GraphDiagram.snapToGrid(rawY, gridSize) : rawY;
177
+ if (dragStartState) {
178
+ for (const c of companions) {
179
+ const q = engine._graphDiagram?._graph.pos.get(c.id);
180
+ if (q) { q.x = c.from.x + (p.x - dragStartState.x); q.y = c.from.y + (p.y - dragStartState.y); }
181
+ }
182
+ }
183
+
184
+ // Highlight folder under cursor
185
+ const folders = engine._chartState?.folders || [];
186
+ if (folders.length > 0) {
187
+ const foldersHit = folders.filter(f =>
188
+ p.x > f.x && p.x < f.x + (f.width || 200) &&
189
+ p.y > f.y && p.y < f.y + (f.height || 150)
190
+ );
191
+ engine._graphDiagram._dragOverFolderId = foldersHit.length > 0 ? foldersHit[0].id : null;
192
+ }
193
+
194
+ engine._graphDiagram?._rerenderGraph();
195
+ engine._graphDiagram?._updateGraphLayout();
196
+ };
197
+
198
+ const onMouseUp = () => {
199
+ if (selectedEndpoint && dragStarted) {
200
+ const edge = selectedEndpoint.edge;
201
+ const type = selectedEndpoint.type;
202
+ const currentSide = type === 'source' ? edge.sourceSide : edge.targetSide;
203
+ const oldSide = type === 'source' ? dragStartState.sourceSide : dragStartState.targetSide;
204
+
205
+ if (currentSide !== oldSide) {
206
+ // The drag already moved the side; the command needs where it started.
207
+ engine._graphDiagram?.history?.execute(new UpdateEdgeSideCommand(
208
+ edge, type, currentSide, { diagram: engine._graphDiagram, oldSide }
209
+ ));
210
+ }
211
+ }
212
+ selectedEndpoint = null;
213
+
214
+ if (selectedWaypoint && dragStarted) {
215
+ const wp = selectedWaypoint.edge.waypoints[selectedWaypoint.index];
216
+ const end = { x: wp.x, y: wp.y };
217
+ if (dragStartState && (end.x !== dragStartState.x || end.y !== dragStartState.y)) {
218
+ engine._graphDiagram?.history?.execute(new MoveWaypointCommand(
219
+ selectedWaypoint.edge, selectedWaypoint.index, dragStartState, end, { diagram: engine._graphDiagram }
220
+ ));
221
+ }
222
+ }
223
+ selectedWaypoint = null;
224
+
225
+ if (selectedNode && dragStarted) {
226
+ engine._graphDiagram?._graphFixedPos?.delete(selectedNode.id);
227
+ const finalPos = engine._graphDiagram?._graph?.pos?.get(selectedNode.id);
228
+ if (dragStartState && finalPos && (finalPos.x !== dragStartState.x || finalPos.y !== dragStartState.y)) {
229
+ const diagram = engine._graphDiagram;
230
+ const move = new MoveNodeCommand(selectedNode.id, dragStartState, { x: finalPos.x, y: finalPos.y }, { diagram });
231
+ // With its group: one undo step for them all.
232
+ const moves = companions.map(c => {
233
+ const to = diagram?._graph?.pos?.get(c.id);
234
+ return new MoveNodeCommand(c.id, c.from, { x: to.x, y: to.y }, { diagram });
235
+ });
236
+ diagram?.history?.execute(moves.length ? new CompositeCommand(diagram.selectedNodeIds.has(selectedNode.id) ? 'Move selection' : 'Move group', [move, ...moves]) : move);
237
+ }
238
+
239
+ // Check if node was dropped onto a folder
240
+ const folders = engine._chartState?.folders || [];
241
+ if (finalPos && folders.length > 0) {
242
+ const foldersHit = folders.filter(f =>
243
+ finalPos.x > f.x && finalPos.x < f.x + (f.width || 200) &&
244
+ finalPos.y > f.y && finalPos.y < f.y + (f.height || 150)
245
+ );
246
+ if (foldersHit.length > 0) {
247
+ const targetFolder = foldersHit[0];
248
+ const elementFolderMap = engine._chartState?.options?.elementFolderMap;
249
+ if (elementFolderMap) {
250
+ const oldFolder = elementFolderMap.get(selectedNode.id);
251
+ if (oldFolder !== targetFolder.id) {
252
+ elementFolderMap.set(selectedNode.id, targetFolder.id);
253
+ engine._graphDiagram?._rerenderGraph();
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ }
260
+ selectedNode = null;
261
+ companions = [];
262
+ dragStartState = null;
263
+ downScreenPos = null;
264
+ dragStarted = false;
265
+ };
266
+
267
+ const onDblClick = (event) => {
268
+ if (!engine._graphDiagram?._graph) return;
269
+ const hit = engine.hitTest(event.clientX, event.clientY);
270
+
271
+ if (hit?.isWaypoint) {
272
+ if (!engine._graphDiagram?._graph.editable) return;
273
+ event.preventDefault();
274
+ const { edge, waypointIndex } = hit;
275
+ // Keep edge selected so endpoints remain visible after waypoint deletion
276
+ engine._graphDiagram._selectedEdge = edge;
277
+ engine._graphDiagram?.history?.execute(new DeleteWaypointCommand(edge, waypointIndex, { diagram: engine._graphDiagram }));
278
+ return;
279
+ }
280
+
281
+ const { onNodeDoubleClick, onEdgeDoubleClick, onCanvasDoubleClick } = engine._chartState?.options || {};
282
+
283
+ if (hit?.draggable && hit.nodeId != null) {
284
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === hit.nodeId);
285
+ if (node && onNodeDoubleClick) { event.preventDefault(); onNodeDoubleClick(node); }
286
+ return;
287
+ }
288
+
289
+ if (hit?.isEdge) {
290
+ if (onEdgeDoubleClick) { event.preventDefault(); onEdgeDoubleClick(hit.edge); }
291
+ return;
292
+ }
293
+
294
+ if (!hit && onCanvasDoubleClick) {
295
+ event.preventDefault();
296
+ onCanvasDoubleClick(engine._clientToSvgPoint(event.clientX, event.clientY));
297
+ }
298
+ };
299
+
300
+ engine.container.addEventListener('mousedown', onMouseDown);
301
+ engine.container.addEventListener('mousemove', onMouseMove);
302
+ engine.container.addEventListener('mouseup', onMouseUp);
303
+ engine.container.addEventListener('mouseleave', onMouseUp);
304
+ engine.container.addEventListener('dblclick', onDblClick);
305
+ }
306
+
307
+ _addContextMenuListeners() {
308
+ const engine = this._engine;
309
+ if (!engine.container) return;
310
+
311
+ const contextMenu = new ContextMenu(engine.container);
312
+ engine.container.addEventListener('click', () => contextMenu.remove());
313
+
314
+ engine._buildAndShowContextMenu = (event, menuItems, subject) => {
315
+ contextMenu.show(event, menuItems, subject, engine._clientToSvgPoint.bind(engine), engine);
316
+ };
317
+
318
+ const onContextMenu = (event) => {
319
+ contextMenu.remove();
320
+ if (!engine._graphDiagram?._graph) return;
321
+
322
+ const hitShape = engine.hitTest(event.clientX, event.clientY);
323
+
324
+ if (hitShape && hitShape.draggable && hitShape.nodeId != null) {
325
+ event.preventDefault();
326
+ engine._graphDiagram?._showNodeContextMenu(event, hitShape.nodeId);
327
+ } else if (engine._graphDiagram?._graph.editable && hitShape && hitShape.isEdge) {
328
+ event.preventDefault();
329
+ engine._graphDiagram?._showEdgeContextMenu(event, hitShape.edge);
330
+ } else if ((engine._graphDiagram?._graph.editable || engine._graphDiagram?._graph.canvasContextMenuItems) && !(hitShape && hitShape.legendItem)) {
331
+ event.preventDefault();
332
+ engine._graphDiagram?._showCanvasContextMenu(event);
333
+ }
334
+ };
335
+
336
+ engine.container.addEventListener('contextmenu', onContextMenu);
337
+ }
338
+
339
+ _addEdgeCreationListeners() {
340
+ const engine = this._engine;
341
+ if (!engine.renderer || !engine.renderer.svg) return;
342
+
343
+ const HANDLE_OFFSET = -3;
344
+ const HANDLE_R = 8;
345
+ const DRAG_THRESHOLD = 4;
346
+
347
+ let handleEl = null;
348
+ let hoveredNodeId = null;
349
+ let pendingSource = null;
350
+ let downScreenPos = null;
351
+ let rubberBandEl = null;
352
+ let lastHoverTarget = null;
353
+
354
+ const ensureHandle = () => {
355
+ if (handleEl) return;
356
+ handleEl = document.createElement('div');
357
+ handleEl.style.cssText = `
358
+ position: absolute;
359
+ width: ${HANDLE_R * 2}px;
360
+ height: ${HANDLE_R * 2}px;
361
+ border-radius: 50%;
362
+ background: #4f8ef7;
363
+ border: 2px solid #fff;
364
+ box-shadow: 0 0 2px rgba(0,0,0,0.4);
365
+ cursor: crosshair;
366
+ z-index: 998;
367
+ display: none;
368
+ `;
369
+ handleEl.addEventListener('mousedown', onHandleMouseDown);
370
+ engine.container.appendChild(handleEl);
371
+ };
372
+
373
+ const positionHandleForNode = (nodeId) => {
374
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === nodeId);
375
+ const p = engine._graphDiagram?._graph.pos.get(nodeId);
376
+ const CTM = engine.renderer.svg.getScreenCTM();
377
+ if (!node || !p || !CTM) return;
378
+ const size = engine._nodeSize(node, engine._graphDiagram?._graph.nodeRadius, engine._graphDiagram?._graph.sizeDomain, engine._graphDiagram?._graph.sizeOptions);
379
+ const svgX = p.x + size.w / 2 + HANDLE_OFFSET;
380
+ const svgY = p.y + size.h / 2 + HANDLE_OFFSET;
381
+ const screenX = svgX * CTM.a + CTM.e;
382
+ const screenY = svgY * CTM.d + CTM.f;
383
+ const containerRect = engine.container.getBoundingClientRect();
384
+ handleEl.style.left = `${screenX - containerRect.left - HANDLE_R}px`;
385
+ handleEl.style.top = `${screenY - containerRect.top - HANDLE_R}px`;
386
+ };
387
+
388
+ const clearHoverTarget = () => {
389
+ if (lastHoverTarget) { engine.leaveState(lastHoverTarget, 'hover'); lastHoverTarget = null; }
390
+ };
391
+
392
+ const onHandleMouseDown = (event) => {
393
+ event.stopPropagation();
394
+ event.preventDefault();
395
+ if (!engine._graphDiagram?._graph?.editable || !hoveredNodeId) return;
396
+ downScreenPos = { x: event.clientX, y: event.clientY };
397
+ pendingSource = { nodeId: hoveredNodeId };
398
+ const sourcePos = engine._graphDiagram?._graph.pos.get(pendingSource.nodeId);
399
+ rubberBandEl = engine.renderer.path(`M${sourcePos.x},${sourcePos.y} L${sourcePos.x},${sourcePos.y}`, 'none', { color: '#4f8ef7', width: 1.5 });
400
+ rubberBandEl.setAttribute('stroke-dasharray', '4 3');
401
+ rubberBandEl.style.pointerEvents = 'none';
402
+ };
403
+
404
+ const onMouseMove = (event) => {
405
+ if (!engine._graphDiagram?._graph?.editable) {
406
+ if (handleEl) handleEl.style.display = 'none';
407
+ return;
408
+ }
409
+
410
+ if (pendingSource) {
411
+ const svgPt = engine._clientToSvgPoint(event.clientX, event.clientY);
412
+ const sourcePos = engine._graphDiagram?._graph.pos.get(pendingSource.nodeId);
413
+ if (rubberBandEl && sourcePos) rubberBandEl.setAttribute('d', `M${sourcePos.x},${sourcePos.y} L${svgPt.x},${svgPt.y}`);
414
+
415
+ const hit = engine.hitTest(event.clientX, event.clientY);
416
+ const validTarget = (hit?.draggable && hit.nodeId != null && hit.nodeId !== pendingSource.nodeId) ? hit : null;
417
+ if (lastHoverTarget && lastHoverTarget !== validTarget) clearHoverTarget();
418
+ if (validTarget && !lastHoverTarget) { engine.enterState(validTarget, 'hover'); lastHoverTarget = validTarget; }
419
+ return;
420
+ }
421
+
422
+ if (event.target === handleEl) return;
423
+
424
+ const hit = engine.hitTest(event.clientX, event.clientY);
425
+ if (hit?.draggable && hit.nodeId != null) {
426
+ hoveredNodeId = hit.nodeId;
427
+ ensureHandle();
428
+ positionHandleForNode(hoveredNodeId);
429
+ handleEl.style.display = 'block';
430
+ } else {
431
+ hoveredNodeId = null;
432
+ if (handleEl) handleEl.style.display = 'none';
433
+ }
434
+ };
435
+
436
+ const onMouseUp = (event) => {
437
+ if (!pendingSource) return;
438
+ const dx = event.clientX - downScreenPos.x, dy = event.clientY - downScreenPos.y;
439
+ if (Math.hypot(dx, dy) >= DRAG_THRESHOLD) {
440
+ const hit = engine.hitTest(event.clientX, event.clientY);
441
+ if (hit?.draggable && hit.nodeId != null && hit.nodeId !== pendingSource.nodeId) {
442
+ const newEdge = { source: pendingSource.nodeId, target: hit.nodeId };
443
+ const Validator = engine.constructor.ArchimateValidator;
444
+ const Notation = engine.constructor.ArchimateNotation;
445
+ const archimateVersion = engine._archimateOptions?.archimateVersion || '4';
446
+ if (Validator && Notation && engine._archimateOptions) {
447
+ const sourceNode = engine._chartState.nodes.find(n => n.id === newEdge.source);
448
+ const targetNode = engine._chartState.nodes.find(n => n.id === newEdge.target);
449
+ const allowed = Validator.allowedKinds(sourceNode, targetNode, archimateVersion);
450
+ if (allowed.length) {
451
+ newEdge.kind = allowed[0];
452
+ const style = Notation.relationshipType(newEdge.kind);
453
+ newEdge.lineStyle = style.lineStyle;
454
+ newEdge.arrowhead = style.arrowhead || 'none';
455
+ newEdge.arrowheadStart = style.arrowheadStart;
456
+ }
457
+ }
458
+ engine._graphDiagram?.history?.execute(new AddEdgeCommand(
459
+ newEdge,
460
+ { diagram: engine._graphDiagram, onAdd: engine._chartState?.options?.onEdgeAdd }
461
+ ));
462
+ }
463
+ }
464
+ clearHoverTarget();
465
+ rubberBandEl?.remove();
466
+ rubberBandEl = null;
467
+ pendingSource = null;
468
+ downScreenPos = null;
469
+ hoveredNodeId = null;
470
+ if (handleEl) handleEl.style.display = 'none';
471
+ };
472
+
473
+ engine.container.addEventListener('mousemove', onMouseMove);
474
+ engine.container.addEventListener('mouseup', onMouseUp);
475
+ engine.container.addEventListener('mouseleave', onMouseUp);
476
+ }
477
+
478
+ _addResizeListeners() {
479
+ const engine = this._engine;
480
+ if (!engine.renderer || !engine.renderer.svg) return;
481
+
482
+ const HANDLE_SIZE = 10;
483
+ const DRAG_THRESHOLD = 3;
484
+
485
+ let handleEl = null;
486
+ let hoveredNodeId = null;
487
+ let resizing = null;
488
+ let downScreenPos = null;
489
+ let resizeStartState = null;
490
+
491
+ const isResizable = (node) => node?.resizable ?? engine._graphDiagram?._graph?.resizableDefault ?? false;
492
+ const cornerFor = (node) => engine._nodeResizeCorner(node, engine._graphDiagram?._graph?.resizeCornerByShape, engine._graphDiagram?._graph?.resizeCorner || 'top-right');
493
+
494
+ const ensureHandle = () => {
495
+ if (handleEl) return;
496
+ handleEl = document.createElement('div');
497
+ handleEl.style.cssText = `
498
+ position: absolute;
499
+ width: ${HANDLE_SIZE}px;
500
+ height: ${HANDLE_SIZE}px;
501
+ background: #fff;
502
+ border: 2px solid #4f8ef7;
503
+ box-shadow: 0 0 2px rgba(0,0,0,0.4);
504
+ z-index: 998;
505
+ display: none;
506
+ `;
507
+ handleEl.addEventListener('mousedown', onHandleMouseDown);
508
+ engine.container.appendChild(handleEl);
509
+ };
510
+
511
+ const positionHandle = (nodeId) => {
512
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === nodeId);
513
+ const p = engine._graphDiagram?._graph.pos.get(nodeId);
514
+ const CTM = engine.renderer.svg.getScreenCTM();
515
+ if (!node || !p || !CTM) return;
516
+ const size = engine._nodeSize(node, engine._graphDiagram?._graph.nodeRadius, engine._graphDiagram?._graph.sizeDomain, engine._graphDiagram?._graph.sizeOptions);
517
+ const corner = cornerFor(node);
518
+ const cp = engine._cornerPoint(p, size, corner);
519
+ const screenX = cp.x * CTM.a + CTM.e, screenY = cp.y * CTM.d + CTM.f;
520
+ const containerRect = engine.container.getBoundingClientRect();
521
+ handleEl.style.left = `${screenX - containerRect.left - HANDLE_SIZE / 2}px`;
522
+ handleEl.style.top = `${screenY - containerRect.top - HANDLE_SIZE / 2}px`;
523
+ handleEl.style.cursor = (corner === 'top-right' || corner === 'bottom-left') ? 'nesw-resize' : 'nwse-resize';
524
+ };
525
+
526
+ const onHandleMouseDown = (event) => {
527
+ event.stopPropagation();
528
+ event.preventDefault();
529
+ if (!hoveredNodeId) return;
530
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === hoveredNodeId);
531
+ if (!node || !isResizable(node)) return;
532
+ downScreenPos = { x: event.clientX, y: event.clientY };
533
+ resizeStartState = nodeSize(node);
534
+ resizing = { nodeId: hoveredNodeId, corner: cornerFor(node) };
535
+ };
536
+
537
+ const onMouseMove = (event) => {
538
+ if (!engine._graphDiagram?._graph) { if (handleEl) handleEl.style.display = 'none'; return; }
539
+
540
+ if (resizing) {
541
+ event.preventDefault();
542
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === resizing.nodeId);
543
+ const p = engine._graphDiagram?._graph.pos.get(resizing.nodeId);
544
+ if (!node || !p) return;
545
+ const mouseSvg = engine._clientToSvgPoint(event.clientX, event.clientY);
546
+ Object.assign(node, engine._resizedNodeValue(node, resizing.corner, p, mouseSvg));
547
+ engine._graphDiagram?._rerenderGraph();
548
+ if (handleEl) { positionHandle(resizing.nodeId); handleEl.style.display = 'block'; }
549
+ return;
550
+ }
551
+
552
+ if (event.target === handleEl) return;
553
+ const hit = engine.hitTest(event.clientX, event.clientY);
554
+ const node = hit?.draggable && hit.nodeId != null ? engine._graphDiagram?._graph.nodes.find(n => n.id === hit.nodeId) : null;
555
+ if (node && isResizable(node)) {
556
+ hoveredNodeId = node.id;
557
+ ensureHandle();
558
+ positionHandle(hoveredNodeId);
559
+ handleEl.style.display = 'block';
560
+ } else {
561
+ hoveredNodeId = null;
562
+ if (handleEl) handleEl.style.display = 'none';
563
+ }
564
+ };
565
+
566
+ const onMouseUp = (event) => {
567
+ if (resizing) {
568
+ const dx = event.clientX - downScreenPos.x, dy = event.clientY - downScreenPos.y;
569
+ const node = engine._graphDiagram?._graph.nodes.find(n => n.id === resizing.nodeId);
570
+ if (Math.hypot(dx, dy) >= DRAG_THRESHOLD) {
571
+ const end = nodeSize(node);
572
+ if (resizeStartState && NODE_SIZE_KEYS.some(key => end[key] !== resizeStartState[key])) {
573
+ engine._graphDiagram?.history?.execute(new ResizeNodeCommand(
574
+ resizing.nodeId, resizeStartState, end, { diagram: engine._graphDiagram }
575
+ ));
576
+ }
577
+ }
578
+ }
579
+ resizing = null;
580
+ resizeStartState = null;
581
+ downScreenPos = null;
582
+ };
583
+
584
+ engine.container.addEventListener('mousemove', onMouseMove);
585
+ engine.container.addEventListener('mouseup', onMouseUp);
586
+ engine.container.addEventListener('mouseleave', onMouseUp);
587
+ }
588
+
589
+ _addTooltipListeners() {
590
+ const engine = this._engine;
591
+ if (!engine.container) return;
592
+
593
+ const tooltip = new Tooltip(engine.container);
594
+
595
+ const onMouseMove = (event) => {
596
+ const hitShape = engine.hitTest(event.clientX, event.clientY);
597
+ if (hitShape && hitShape.tooltip) {
598
+ tooltip.show(hitShape.tooltip, event.clientX, event.clientY);
599
+ } else {
600
+ tooltip.hide();
601
+ }
602
+ };
603
+
604
+ const onMouseOut = () => tooltip.hide();
605
+
606
+ engine.container.addEventListener('mousemove', onMouseMove);
607
+ engine.container.addEventListener('mouseout', onMouseOut);
608
+ }
609
+
610
+ _addClickListeners() {
611
+ const engine = this._engine;
612
+ if (!engine.container) return;
613
+
614
+ const onClick = (event) => {
615
+ const hitShape = engine.hitTest(event.clientX, event.clientY);
616
+ engine._activeChart?.onClick?.(event, hitShape);
617
+ engine._activeDiagram?.onClick?.(event, hitShape);
618
+ };
619
+
620
+ engine.container.addEventListener('click', onClick);
621
+ }
622
+
623
+ _addZoomListeners() {
624
+ const engine = this._engine;
625
+ if (!engine.renderer || !engine.renderer.svg) return;
626
+ if (!engine.renderer.supportsSceneGraph) return;
627
+
628
+ engine._svgZoom = new SvgZoom(engine.container, engine.renderer.svg, {
629
+ clientToSvgPoint: (clientX, clientY) => engine._clientToSvgPoint(clientX, clientY),
630
+ hitTest: (clientX, clientY) => engine.hitTest(clientX, clientY),
631
+ is3D: () => engine._chart3D,
632
+ });
633
+ engine._initialViewBox = engine._svgZoom.initialViewBox;
634
+ }
635
+
636
+ _addOrbit3DListeners() {
637
+ const engine = this._engine;
638
+ if (!engine.container) return;
639
+ engine._orbitControls = new OrbitControls(
640
+ engine.container,
641
+ () => engine._camera3D,
642
+ () => engine._chart3DRedraw?.(),
643
+ () => engine.resetView(),
644
+ () => engine._chart3D,
645
+ );
646
+ }
647
+
648
+ /**
649
+ * A left drag on empty space draws a selection box; on release the nodes
650
+ * wholly inside it are selected (added with Ctrl or Cmd). A press without
651
+ * a drag clears the selection. (The right button pans: SvgZoom.)
652
+ */
653
+ _addMarqueeListeners() {
654
+ const engine = this._engine;
655
+ const container = engine.container;
656
+ const doc = container.ownerDocument;
657
+ const onDown = (event) => {
658
+ if (event.button !== 0 || event.altKey || !engine._graphDiagram?._graph?.editable) return;
659
+ const hit = engine.hitTest(event.clientX, event.clientY);
660
+ if (hit?.draggable || hit?.edge || event.target.closest?.('[nodeId], [edgeId], path[stroke-width]')?.getAttribute?.('edgeId')) return;
661
+ if (event.target.closest?.('[nodeId]')) return;
662
+ event.preventDefault();
663
+ const start = { x: event.clientX, y: event.clientY };
664
+ const extend = event.ctrlKey || event.metaKey;
665
+ let box = null;
666
+ const rect = (e) => ({ left: Math.min(start.x, e.clientX), top: Math.min(start.y, e.clientY), right: Math.max(start.x, e.clientX), bottom: Math.max(start.y, e.clientY) });
667
+ const onMove = (e) => {
668
+ if (!box && Math.hypot(e.clientX - start.x, e.clientY - start.y) < 4) return;
669
+ if (!box) {
670
+ box = doc.createElement('div');
671
+ box.className = 'marquee';
672
+ Object.assign(box.style, { position: 'fixed', border: '1px dashed #0066cc', background: 'rgba(0, 102, 204, 0.08)', pointerEvents: 'none', zIndex: '1000' });
673
+ doc.body.appendChild(box);
674
+ }
675
+ const r = rect(e);
676
+ Object.assign(box.style, { left: `${r.left}px`, top: `${r.top}px`, width: `${r.right - r.left}px`, height: `${r.bottom - r.top}px` });
677
+ };
678
+ const onUp = (e) => {
679
+ doc.removeEventListener('mousemove', onMove);
680
+ doc.removeEventListener('mouseup', onUp);
681
+ const graph = engine._graphDiagram;
682
+ if (!graph?._graph) return;
683
+ if (!box) { if (!extend) graph.selectNodes([]); return; }
684
+ box.remove();
685
+ const r = rect(e);
686
+ const inside = graph._graph.nodeEls.filter(el => {
687
+ if (!el || el.getAttribute('visibility') === 'hidden') return false;
688
+ const b = el.getBoundingClientRect();
689
+ return b.width && b.left >= r.left && b.right <= r.right && b.top >= r.top && b.bottom <= r.bottom;
690
+ }).map(el => el.getAttribute('nodeId'));
691
+ graph.selectNodes(inside, { extend });
692
+ };
693
+ doc.addEventListener('mousemove', onMove);
694
+ doc.addEventListener('mouseup', onUp);
695
+ };
696
+ container.addEventListener('mousedown', onDown);
697
+ }
698
+
699
+ _addKeyboardListeners() {
700
+ const engine = this._engine;
701
+ if (!engine.container) return;
702
+
703
+ const onKeyDown = (event) => {
704
+ const graph = engine._graphDiagram;
705
+ if (!graph?.history || graph.hostOwnsHistory) return;
706
+ if (!graph._graph?.editable) return;
707
+
708
+ const isUndo = (event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'z' && !event.shiftKey;
709
+ const isRedo = (event.ctrlKey || event.metaKey) && (event.key.toLowerCase() === 'y' || (event.key.toLowerCase() === 'z' && event.shiftKey));
710
+
711
+ if (isUndo) {
712
+ event.preventDefault();
713
+ graph.history.undo();
714
+ return;
715
+ }
716
+ if (isRedo) {
717
+ event.preventDefault();
718
+ graph.history.redo();
719
+ }
720
+ };
721
+
722
+ engine.container.tabIndex = engine.container.tabIndex ?? 0;
723
+ engine.container.addEventListener('keydown', onKeyDown);
724
+ }
725
+ }