@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,88 @@
1
+ /**
2
+ * Align, distribute and match size: where shapes go, worked out from their
3
+ * boxes alone (`{id, left, top, width, height}`), so every editor lines
4
+ * shapes up the same way and carries the result out with its own commands.
5
+ * Each function returns only the boxes that change, with their new values.
6
+ *
7
+ * As in Archi, the reference for align and match size is one of the shapes
8
+ * (the editor passes its primary selection); distribute keeps the first and
9
+ * last shapes where they are and spaces the others evenly between them.
10
+ */
11
+
12
+ /** The ways to align, in menu order: [key, label]. */
13
+ export const ALIGNMENTS = Object.freeze([
14
+ ['left', 'Left'], ['centre', 'Centre'], ['right', 'Right'],
15
+ ['top', 'Top'], ['middle', 'Middle'], ['bottom', 'Bottom'],
16
+ ]);
17
+
18
+ /** The ways to distribute: [key, label]. */
19
+ export const DISTRIBUTIONS = Object.freeze([['horizontal', 'Horizontally'], ['vertical', 'Vertically']]);
20
+
21
+ /** The sizes to match: [key, label]. */
22
+ export const SIZE_MATCHES = Object.freeze([['width', 'Width'], ['height', 'Height'], ['both', 'Width and height']]);
23
+
24
+ /** For each alignment: the axis it moves along and where on a box it lines up (0 start, 0.5 middle, 1 end). */
25
+ const LINE = {
26
+ left: ['x', 0], centre: ['x', 0.5], right: ['x', 1],
27
+ top: ['y', 0], middle: ['y', 0.5], bottom: ['y', 1],
28
+ };
29
+ const AXIS = { x: ['left', 'width'], y: ['top', 'height'] };
30
+
31
+ /**
32
+ * Line boxes up with `reference`'s edge or middle.
33
+ * @param {Array<Object>} boxes
34
+ * @param {'left'|'centre'|'right'|'top'|'middle'|'bottom'} edge
35
+ * @param {Object} reference - One of the boxes (default the last)
36
+ * @returns {Array<{id, left, top}>} the boxes that move, at their new place
37
+ */
38
+ export function align(boxes, edge, reference = boxes.at(-1)) {
39
+ const line = LINE[edge];
40
+ if (!line) throw new RangeError(`No such alignment: ${edge}`);
41
+ const [axis, at] = line;
42
+ const [start, size] = AXIS[axis];
43
+ const target = reference[start] + reference[size] * at;
44
+ return boxes
45
+ .map(b => ({ ...b, [start]: target - b[size] * at }))
46
+ .filter((b, i) => b[start] !== boxes[i][start])
47
+ .map(({ id, left, top }) => ({ id, left, top }));
48
+ }
49
+
50
+ /**
51
+ * Space boxes evenly along an axis: the first and last (by where they start)
52
+ * stay, and the gaps between neighbours become equal. Fewer than three: nothing.
53
+ * @param {Array<Object>} boxes
54
+ * @param {'horizontal'|'vertical'} direction
55
+ * @returns {Array<{id, left, top}>}
56
+ */
57
+ export function distribute(boxes, direction) {
58
+ const axis = { horizontal: 'x', vertical: 'y' }[direction];
59
+ if (!axis) throw new RangeError(`No such direction: ${direction}`);
60
+ if (boxes.length < 3) return [];
61
+ const [start, size] = AXIS[axis];
62
+ const sorted = [...boxes].sort((a, b) => a[start] - b[start] || a[size] - b[size]);
63
+ const first = sorted[0], last = sorted.at(-1);
64
+ const used = sorted.reduce((sum, b) => sum + b[size], 0);
65
+ const gap = (last[start] + last[size] - first[start] - used) / (sorted.length - 1);
66
+ const moved = [];
67
+ let next = first[start] + first[size] + gap;
68
+ for (const box of sorted.slice(1, -1)) {
69
+ if (box[start] !== next) moved.push({ id: box.id, left: box.left, top: box.top, [start]: next });
70
+ next += box[size] + gap;
71
+ }
72
+ return moved;
73
+ }
74
+
75
+ /**
76
+ * Give boxes `reference`'s width, height or both; each keeps its top-left corner.
77
+ * @param {Array<Object>} boxes
78
+ * @param {'width'|'height'|'both'} dimension
79
+ * @param {Object} reference - One of the boxes (default the last)
80
+ * @returns {Array<{id, width, height}>}
81
+ */
82
+ export function matchSize(boxes, dimension, reference = boxes.at(-1)) {
83
+ const keys = { width: ['width'], height: ['height'], both: ['width', 'height'] }[dimension];
84
+ if (!keys) throw new RangeError(`No such size: ${dimension}`);
85
+ return boxes
86
+ .filter(b => keys.some(k => b[k] !== reference[k]))
87
+ .map(b => ({ id: b.id, width: keys.includes('width') ? reference.width : b.width, height: keys.includes('height') ? reference.height : b.height }));
88
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The Group / Ungroup / Lock / Unlock menu items for some items of a view:
3
+ * one definition for every editor (the template editor, the ArchiMate canvas
4
+ * and graph editors), each supplying how it carries the change out.
5
+ * @param {Arrangement} arrangement
6
+ * @param {Array<string>} ids - The items the menu is for (the clicked one first)
7
+ * @param {Object} act
8
+ * @param {(ids: string[]) => void} [act.group] - Group them (left out: no Group item)
9
+ * @param {(id: string) => void} act.ungroup
10
+ * @param {(ids: string[], locked: boolean) => void} act.setLocked
11
+ * @returns {Array<{label, action}>}
12
+ */
13
+ export function arrangeMenuItems(arrangement, ids, { group = null, ungroup, setLocked }) {
14
+ const [first] = ids;
15
+ const itemGroup = arrangement.groupOf(first);
16
+ const locked = ids.every(id => arrangement.isLocked(id));
17
+ const together = arrangement.movers(ids);
18
+ const what = itemGroup?.pinnedToBack ? ' background' : '';
19
+ return [
20
+ ...(group && together.size > 1 && (!itemGroup || ids.some(id => !itemGroup.has(id)))
21
+ ? [{ label: '⛓ Group', action: () => group(ids) }] : []),
22
+ ...(itemGroup && !locked ? [{ label: `⛓ Ungroup${what}`, action: () => ungroup(first) }] : []),
23
+ { label: locked ? `🔓 Unlock${what}` : `🔒 Lock${what}`, action: () => setLocked(ids, !locked) },
24
+ ];
25
+ }
@@ -0,0 +1,11 @@
1
+ export { ItemGroup } from './ItemGroup.js';
2
+ export { BackgroundGroup } from './BackgroundGroup.js';
3
+ export { BackgroundCommand } from './BackgroundCommand.js';
4
+ export { arrangeMenuItems } from './arrangeMenuItems.js';
5
+ export { Arrangement } from './Arrangement.js';
6
+ export { ArrangementCommand } from './ArrangementCommand.js';
7
+ export { GroupCommand } from './GroupCommand.js';
8
+ export { UngroupCommand } from './UngroupCommand.js';
9
+ export { LockCommand } from './LockCommand.js';
10
+ export { align, distribute, matchSize, ALIGNMENTS, DISTRIBUTIONS, SIZE_MATCHES } from './alignment.js';
11
+ export { layout, nestLayout, LAYOUTS } from './layouts.js';
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Automatic layouts: where shapes go, worked out from their boxes
3
+ * (`{id, left, top, width, height}`) and the lines between them
4
+ * (`{source, target}`, by box id) alone, as alignment.js does for align and
5
+ * distribute. Every editor carries the result out with its own commands.
6
+ * The laid-out boxes keep the top-left corner of the area they took before,
7
+ * so a layout rearranges shapes where they are.
8
+ *
9
+ * `layout(kind, boxes, options)` returns `[{id, left, top}]` for every box.
10
+ * `nestLayout(...)` plans a shape with its parts drawn inside it.
11
+ */
12
+
13
+ /** The layouts, in menu order: [key, label]. */
14
+ export const LAYOUTS = Object.freeze([
15
+ ['grid', 'Grid'],
16
+ ['circle', 'Circle'],
17
+ ['tree-down', 'Tree, top down'],
18
+ ['tree-right', 'Tree, left to right'],
19
+ ['force', 'Force-directed'],
20
+ ['category', 'By kind, a row each'],
21
+ ]);
22
+
23
+ /**
24
+ * Lay boxes out.
25
+ * @param {string} kind - One of LAYOUTS' keys
26
+ * @param {Array<Object>} boxes - `{id, left, top, width, height}`
27
+ * @param {Object} [options]
28
+ * @param {Array<{source: string, target: string}>} [options.edges] - Lines between the boxes (tree, force)
29
+ * @param {(box) => string} [options.categoryOf] - A box's kind (category layout); rows in order of first appearance
30
+ * @param {number} [options.gap] - Space between boxes
31
+ * @returns {Array<{id, left, top}>}
32
+ */
33
+ export function layout(kind, boxes, { edges = [], categoryOf = () => '', gap = 40 } = {}) {
34
+ const fn = LAYOUT_FUNCTIONS[kind];
35
+ if (!fn) throw new RangeError(`No such layout: ${kind}`);
36
+ if (!boxes.length) return [];
37
+ const ids = new Set(boxes.map(b => b.id));
38
+ const lines = edges.filter(e => ids.has(e.source) && ids.has(e.target) && e.source !== e.target);
39
+ const placed = fn(readingOrder(boxes), { edges: lines, categoryOf, gap });
40
+ return keepCorner(boxes, placed);
41
+ }
42
+
43
+ const LAYOUT_FUNCTIONS = {
44
+ grid: (boxes, { gap }) => {
45
+ const columns = Math.ceil(Math.sqrt(boxes.length));
46
+ const cellW = Math.max(...boxes.map(b => b.width)) + gap;
47
+ const cellH = Math.max(...boxes.map(b => b.height)) + gap;
48
+ return boxes.map((b, i) => ({ id: b.id, left: (i % columns) * cellW, top: Math.floor(i / columns) * cellH }));
49
+ },
50
+
51
+ circle: (boxes, { gap }) => {
52
+ const size = Math.max(...boxes.map(b => Math.max(b.width, b.height))) + gap;
53
+ const radius = Math.max(size, (boxes.length * size) / (2 * Math.PI));
54
+ return boxes.map((b, i) => {
55
+ const angle = -Math.PI / 2 + (2 * Math.PI * i) / boxes.length;
56
+ return { id: b.id, left: radius + radius * Math.cos(angle) - b.width / 2, top: radius + radius * Math.sin(angle) - b.height / 2 };
57
+ });
58
+ },
59
+
60
+ 'tree-down': (boxes, options) => tree(boxes, options, 'down'),
61
+ 'tree-right': (boxes, options) => tree(boxes, options, 'right'),
62
+
63
+ force: (boxes, { edges, gap }) => forceDirected(boxes, edges, gap),
64
+
65
+ category: (boxes, { categoryOf, gap }) => {
66
+ const rows = new Map();
67
+ for (const b of boxes) {
68
+ const key = categoryOf(b) ?? '';
69
+ if (!rows.has(key)) rows.set(key, []);
70
+ rows.get(key).push(b);
71
+ }
72
+ const placed = [];
73
+ let top = 0;
74
+ for (const row of rows.values()) {
75
+ let left = 0;
76
+ for (const b of row) { placed.push({ id: b.id, left, top }); left += b.width + gap; }
77
+ top += Math.max(...row.map(b => b.height)) + gap;
78
+ }
79
+ return placed;
80
+ },
81
+ };
82
+
83
+ /** Boxes in reading order: top to bottom, then left to right (rows by half a box). */
84
+ function readingOrder(boxes) {
85
+ const rowOf = (b) => Math.round(b.top / Math.max(1, b.height / 2));
86
+ return [...boxes].sort((a, b) => rowOf(a) - rowOf(b) || a.left - b.left);
87
+ }
88
+
89
+ /** Move a layout's result so its top-left is where the boxes' was. */
90
+ function keepCorner(boxes, placed) {
91
+ const left0 = Math.min(...boxes.map(b => b.left)), top0 = Math.min(...boxes.map(b => b.top));
92
+ const left1 = Math.min(...placed.map(p => p.left)), top1 = Math.min(...placed.map(p => p.top));
93
+ return placed.map(p => ({ id: p.id, left: Math.round(p.left - left1 + left0), top: Math.round(p.top - top1 + top0) }));
94
+ }
95
+
96
+ /**
97
+ * A tidy tree along the lines (source above target): each box centred over
98
+ * its children, siblings side by side; a box no line reaches is a root, and
99
+ * one reached twice stays under the first that reached it.
100
+ */
101
+ function tree(boxes, { edges, gap }, direction) {
102
+ const byId = new Map(boxes.map(b => [b.id, b]));
103
+ const children = new Map(boxes.map(b => [b.id, []]));
104
+ const reached = new Set(edges.map(e => e.target));
105
+ const parentOf = new Map();
106
+ const roots = boxes.filter(b => !reached.has(b.id)).map(b => b.id);
107
+ const seen = new Set(roots);
108
+ const queue = [...roots];
109
+ while (queue.length) {
110
+ const id = queue.shift();
111
+ for (const e of edges.filter(x => x.source === id)) {
112
+ if (seen.has(e.target)) continue;
113
+ seen.add(e.target);
114
+ parentOf.set(e.target, id);
115
+ children.get(id).push(e.target);
116
+ queue.push(e.target);
117
+ }
118
+ }
119
+ // What the walk did not reach (all in cycles, or a cycle no root leads to) starts its own tree.
120
+ for (const b of boxes) if (!seen.has(b.id)) { roots.push(b.id); seen.add(b.id); }
121
+
122
+ // Along the tree, "breadth" is across (x when down) and "depth" is along it.
123
+ const across = direction === 'down' ? 'width' : 'height';
124
+ const along = direction === 'down' ? 'height' : 'width';
125
+ const span = new Map();
126
+ const measure = (id) => {
127
+ const own = byId.get(id)[across];
128
+ const kids = children.get(id);
129
+ const kidsSpan = kids.reduce((sum, k) => sum + measure(k), 0) + gap * Math.max(0, kids.length - 1);
130
+ const s = Math.max(own, kidsSpan);
131
+ span.set(id, s);
132
+ return s;
133
+ };
134
+ const levelDepth = [];
135
+ const depthOf = (id, d = 0) => { levelDepth[d] = Math.max(levelDepth[d] ?? 0, byId.get(id)[along]); children.get(id).forEach(k => depthOf(k, d + 1)); };
136
+ roots.forEach(r => { measure(r); depthOf(r); });
137
+ const levelStart = [];
138
+ levelDepth.reduce((at, size, d) => { levelStart[d] = at; return at + size + gap * 1.5; }, 0);
139
+
140
+ const placed = [];
141
+ const place = (id, start, d) => {
142
+ const box = byId.get(id);
143
+ const centre = start + span.get(id) / 2;
144
+ const a = centre - box[across] / 2, l = levelStart[d];
145
+ placed.push(direction === 'down' ? { id, left: a, top: l } : { id, left: l, top: a });
146
+ let at = start + (span.get(id) - (children.get(id).reduce((s, k) => s + span.get(k), 0) + gap * Math.max(0, children.get(id).length - 1))) / 2;
147
+ for (const k of children.get(id)) { place(k, at, d + 1); at += span.get(k) + gap; }
148
+ };
149
+ let start = 0;
150
+ for (const r of roots) { place(r, start, 0); start += span.get(r) + gap; }
151
+ return placed;
152
+ }
153
+
154
+ /**
155
+ * Fruchterman–Reingold: lines pull their ends together, every pair of boxes
156
+ * pushes apart, cooling over the iterations. Deterministic: it starts from
157
+ * where the boxes are (boxes on one spot are spread round it first).
158
+ */
159
+ function forceDirected(boxes, edges, gap) {
160
+ const size = Math.max(...boxes.map(b => Math.max(b.width, b.height))) + gap;
161
+ const k = size * 1.2;
162
+ const pos = boxes.map((b, i) => ({ x: b.left + b.width / 2 + (i % 3) * 0.5, y: b.top + b.height / 2 + Math.floor(i / 3) * 0.5 }));
163
+ const index = new Map(boxes.map((b, i) => [b.id, i]));
164
+ let temperature = size * 2;
165
+ for (let iteration = 0; iteration < 120; iteration++) {
166
+ const shift = pos.map(() => ({ x: 0, y: 0 }));
167
+ for (let i = 0; i < pos.length; i++) {
168
+ for (let j = i + 1; j < pos.length; j++) {
169
+ let dx = pos[i].x - pos[j].x, dy = pos[i].y - pos[j].y;
170
+ if (dx === 0 && dy === 0) { dx = 0.1 * (j - i); dy = 0.1; }
171
+ const d = Math.max(1, Math.hypot(dx, dy));
172
+ const push = (k * k) / d;
173
+ shift[i].x += (dx / d) * push; shift[i].y += (dy / d) * push;
174
+ shift[j].x -= (dx / d) * push; shift[j].y -= (dy / d) * push;
175
+ }
176
+ }
177
+ for (const e of edges) {
178
+ const i = index.get(e.source), j = index.get(e.target);
179
+ const dx = pos[i].x - pos[j].x, dy = pos[i].y - pos[j].y;
180
+ const d = Math.max(1, Math.hypot(dx, dy));
181
+ const pull = (d * d) / k;
182
+ shift[i].x -= (dx / d) * pull; shift[i].y -= (dy / d) * pull;
183
+ shift[j].x += (dx / d) * pull; shift[j].y += (dy / d) * pull;
184
+ }
185
+ for (let i = 0; i < pos.length; i++) {
186
+ const d = Math.max(1e-9, Math.hypot(shift[i].x, shift[i].y));
187
+ const step = Math.min(d, temperature);
188
+ pos[i].x += (shift[i].x / d) * step;
189
+ pos[i].y += (shift[i].y / d) * step;
190
+ }
191
+ temperature *= 0.95;
192
+ }
193
+ return boxes.map((b, i) => ({ id: b.id, left: pos[i].x - b.width / 2, top: pos[i].y - b.height / 2 }));
194
+ }
195
+
196
+ /**
197
+ * A shape with its parts drawn inside it, theirs inside them, however deep:
198
+ * each shape's parts in a grid below its label, and the shape grown to hold
199
+ * them (never shrunk). The top shape keeps its top-left corner.
200
+ * @param {string} rootId
201
+ * @param {(id: string) => Array<string>} partsOf - A shape's parts (each placed once)
202
+ * @param {(id: string) => {left, top, width, height}} boxOf
203
+ * @param {{padding?: number, gap?: number, header?: number}} [options]
204
+ * @returns {Map<string, {left, top, width, height, parentId}>} every shape's new box (the root's included,
205
+ * its parentId null) and the shape it goes inside
206
+ */
207
+ export function nestLayout(rootId, partsOf, boxOf, { padding = 15, gap = 12, header = 30 } = {}) {
208
+ const plan = new Map();
209
+ const seen = new Set([rootId]);
210
+ // Sizes bottom-up, relative positions of the parts within their parent.
211
+ const size = (id) => {
212
+ const own = boxOf(id);
213
+ const parts = partsOf(id).filter(p => !seen.has(p) && seen.add(p));
214
+ if (!parts.length) return { width: own.width, height: own.height, parts: [] };
215
+ const sized = parts.map(p => ({ id: p, ...size(p) }));
216
+ const columns = Math.ceil(Math.sqrt(sized.length));
217
+ const cellW = Math.max(...sized.map(s => s.width)), cellH = Math.max(...sized.map(s => s.height));
218
+ const placed = sized.map((s, i) => ({ ...s, dx: padding + (i % columns) * (cellW + gap), dy: header + Math.floor(i / columns) * (cellH + gap) }));
219
+ const rows = Math.ceil(sized.length / columns);
220
+ return {
221
+ width: Math.max(own.width, padding * 2 + columns * cellW + (columns - 1) * gap),
222
+ height: Math.max(own.height, header + rows * cellH + (rows - 1) * gap + padding),
223
+ parts: placed,
224
+ };
225
+ };
226
+ const place = (id, left, top, sized, parentId = null) => {
227
+ plan.set(id, { left, top, width: sized.width, height: sized.height, parentId });
228
+ for (const p of sized.parts) place(p.id, left + p.dx, top + p.dy, p, id);
229
+ };
230
+ const root = boxOf(rootId);
231
+ place(rootId, root.left, root.top, size(rootId));
232
+ return plan;
233
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * ArchiHint — the hint Archi keeps on a canvas and its boxes (Archi's Hints
3
+ * view): a title (the `hintTitle` attribute) and content (a `hintContent`
4
+ * element, HTML). Both live in what an Archi file said that the model does
5
+ * not use (an `archi` record), so this reads them from any record: a view's
6
+ * or a box's.
7
+ *
8
+ * The content is HTML from a file: it is never inserted as HTML. `text()`
9
+ * turns it into plain text (paragraphs and line breaks kept, tags dropped,
10
+ * entities decoded), safe to show as text.
11
+ */
12
+ export class ArchiHint {
13
+ /**
14
+ * The hint in an `archi` record, or null when there is none.
15
+ * @param {Object|null} archi
16
+ * @returns {{title: string, content: string, text: string}|null}
17
+ */
18
+ static of(archi) {
19
+ const title = archi?.attributes?.hintTitle ?? '';
20
+ const content = archi?.elements?.find(e => e.tag === 'hintContent')?.text ?? '';
21
+ if (!title && !content) return null;
22
+ return { title, content, text: ArchiHint.text(content) };
23
+ }
24
+
25
+ /**
26
+ * A copy of an `archi` record with its hint set (or, with no title and no
27
+ * text, removed): the title as \`hintTitle\`, the text as \`hintContent\` HTML.
28
+ * @param {Object|null} archi
29
+ * @param {{title?: string, text?: string}} hint
30
+ * @returns {Object} the new record
31
+ */
32
+ static write(archi, { title = '', text = '' } = {}) {
33
+ const record = archi ?? {};
34
+ const attributes = { ...(record.attributes ?? {}) };
35
+ const elements = (record.elements ?? []).filter(e => e.tag !== 'hintContent');
36
+ if (title.trim()) attributes.hintTitle = title.trim();
37
+ else delete attributes.hintTitle;
38
+ if (text.trim()) elements.push({ tag: 'hintContent', text: ArchiHint.html(text), attributes: {} });
39
+ return { ...record, attributes, elements };
40
+ }
41
+
42
+ /**
43
+ * Plain text as hint HTML: a blank line starts a paragraph, a single line
44
+ * break is a <br>; the text is escaped (what is typed shows as typed).
45
+ * @param {string} text
46
+ */
47
+ static html(text = '') {
48
+ const escape = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
49
+ return String(text).replace(/\r\n?/g, '\n').trim().split(/\n\s*\n/)
50
+ .map(paragraph => `<p>${paragraph.split('\n').map(line => escape(line.trim())).join('<br>')}</p>`)
51
+ .join('');
52
+ }
53
+
54
+ /**
55
+ * HTML as plain text: a paragraph, list item, heading or <br> ends a line,
56
+ * every other tag goes, entities are decoded, runs of blank lines collapse.
57
+ * @param {string} html
58
+ */
59
+ static text(html = '') {
60
+ const entities = { amp: '&', lt: '<', gt: '>', quot: '"', apos: "'", nbsp: ' ' };
61
+ return String(html)
62
+ .replace(/\r\n?/g, '\n')
63
+ .replace(/<\s*br\s*\/?>/gi, '\n')
64
+ .replace(/<\/\s*(p|div|li|h[1-6]|tr)\s*>/gi, '\n')
65
+ .replace(/<\s*li[^>]*>/gi, '• ')
66
+ .replace(/<[^>]*>/g, '')
67
+ .replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (match, name) => {
68
+ if (name[0] === '#') {
69
+ const code = name[1] === 'x' || name[1] === 'X' ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10);
70
+ return Number.isFinite(code) ? String.fromCodePoint(code) : match;
71
+ }
72
+ return entities[name.toLowerCase()] ?? match;
73
+ })
74
+ .split('\n').map(line => line.trim()).join('\n')
75
+ .replace(/\n{3,}/g, '\n\n')
76
+ .trim();
77
+ }
78
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * CanvasBoxKind — one kind of box a view adds besides elements: a canvas's
3
+ * Block, Sticky and Image, an ArchiMate view's Note and Image (each view
4
+ * class lists its own, ArchimateView.BOX_KINDS). Its Archi class (when it
5
+ * has one of its own), size and look. A box is a view object
6
+ * (ViewObjectInstance); the kind makes its content and appearance.
7
+ */
8
+ export class CanvasBoxKind {
9
+ /**
10
+ * @param {Object} spec
11
+ * @param {string} spec.key - 'block', 'sticky', 'image'
12
+ * @param {string} spec.label - As the palette shows it
13
+ * @param {string} [spec.archiVisualType] - Archi's class ('canvas-model-block', ...); none for a note or picture
14
+ * @param {number} spec.width
15
+ * @param {number} spec.height
16
+ * @param {Object} [spec.appearance] - Fill, line, text position... (an instance's appearance)
17
+ * @param {string} [spec.shape] - The renderer's shape ('rect', or 'image' for a picture)
18
+ * @param {string} [spec.icon] - A glyph for menus and palettes
19
+ */
20
+ constructor({ key, label, archiVisualType, width, height, appearance = {}, shape = 'rect', icon = '' }) {
21
+ Object.assign(this, { key, label, archiVisualType, width, height, appearance: Object.freeze({ ...appearance }), shape, icon });
22
+ Object.freeze(this);
23
+ }
24
+
25
+ /**
26
+ * A new box's content (ViewObjectInstance content).
27
+ * @param {string} id
28
+ * @param {Object} [options]
29
+ * @param {string} [options.name] - Its text (default: the kind's label)
30
+ * @param {string} [options.iconUrl] - Its picture (an image's, or a block's)
31
+ */
32
+ content(id, { name = this.label, iconUrl } = {}) {
33
+ return {
34
+ id, name, label: this.shape === 'image' ? '' : name, shape: this.shape,
35
+ ...(this.archiVisualType && { archiVisualType: this.archiVisualType }), width: this.width, height: this.height,
36
+ ...(iconUrl && { iconUrl }),
37
+ };
38
+ }
39
+ }
@@ -0,0 +1,49 @@
1
+ import { ArchimatePalette } from '../archimate/ArchimatePalette.js';
2
+ import { CANVAS_BOX_KINDS } from './canvasBoxKinds.js';
3
+
4
+ /** The data type a dragged canvas palette tile carries: a CanvasBoxKind's key. */
5
+ export const CANVAS_BOX_MIME = 'application/x-canvas-box';
6
+
7
+ /**
8
+ * CanvasPalette — the side palette for a canvas: Archi's Block, Sticky and
9
+ * Image (CANVAS_BOX_KINDS) instead of ArchiMate's element types. A tile is
10
+ * clicked (onPick gets the kind's key) or dragged onto the canvas
11
+ * (CANVAS_BOX_MIME). The layout is ArchimatePalette's.
12
+ */
13
+ export class CanvasPalette extends ArchimatePalette {
14
+ paletteGroups() {
15
+ return [{ key: 'canvas', label: 'Canvas', types: [...CANVAS_BOX_KINDS] }];
16
+ }
17
+
18
+ get dragType() {
19
+ return CANVAS_BOX_MIME;
20
+ }
21
+
22
+ itemKey(kind) {
23
+ return kind.key;
24
+ }
25
+
26
+ itemTitle(kind) {
27
+ return kind.label;
28
+ }
29
+
30
+ /** A small picture of a kind: a box in its fill and line (an image: its icon). */
31
+ preview(kind, size = this.constructor.TILE.icon) {
32
+ const { fillColor = '#ffffff', strokeColor = '#555555' } = kind.appearance;
33
+ const doc = this.doc;
34
+ const svg = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
35
+ svg.setAttribute('width', String(size * 1.4));
36
+ svg.setAttribute('height', String(size + 4));
37
+ if (kind.shape === 'image') {
38
+ const t = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
39
+ for (const [k, v] of Object.entries({ x: size * 0.7, y: size / 2 + 8, 'text-anchor': 'middle', 'font-size': size * 0.7 })) t.setAttribute(k, String(v));
40
+ t.textContent = kind.icon;
41
+ svg.appendChild(t);
42
+ return svg;
43
+ }
44
+ const r = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
45
+ for (const [k, v] of Object.entries({ x: 2, y: 2, width: size * 1.4 - 4, height: size, fill: fillColor, stroke: strokeColor === 'none' ? '#d8c97a' : strokeColor })) r.setAttribute(k, String(v));
46
+ svg.appendChild(r);
47
+ return svg;
48
+ }
49
+ }
@@ -0,0 +1,61 @@
1
+ import { TemplateLibrary } from '../TemplateLibrary.js';
2
+ import { ZipArchive } from '../../zip/ZipArchive.js';
3
+ import { parseArchiFile, archivedFileUrl } from '../../archimateArchive.js';
4
+ import { parseXML, toArchimateModel } from '../../archimateArchiFormat.js';
5
+ import { DEFAULT_CANVAS_TEMPLATES } from './defaultCanvasTemplates.js';
6
+
7
+ /** The archive entry of an Archi template that holds its model. */
8
+ export const ARCHI_TEMPLATE_MODEL_ENTRY = 'model.archimate';
9
+ /** The archive entry of an Archi template that describes it. */
10
+ export const ARCHI_TEMPLATE_MANIFEST_ENTRY = 'manifest.xml';
11
+
12
+ /**
13
+ * CanvasTemplateLibrary — the TemplateLibrary of canvases: entries' views are
14
+ * CanvasView JSON (a canvas is made from one with
15
+ * `model.newCanvasFromTemplate(entry.view, name)`), it starts with the
16
+ * built-in canvases (DEFAULT_CANVAS_TEMPLATES), and it imports Archi's own
17
+ * template files.
18
+ */
19
+ export class CanvasTemplateLibrary extends TemplateLibrary {
20
+ static STORAGE_KEY = 'renderengine.canvasTemplates';
21
+ static DEFAULTS = DEFAULT_CANVAS_TEMPLATES;
22
+
23
+ /**
24
+ * Add the canvases of an Archi template (`.archicanvas`, `.architemplate`):
25
+ * a zip of a manifest (name, description, thumbnail) and the template's
26
+ * model, itself an Archi file. Every canvas in it becomes an entry; a
27
+ * template with one canvas takes the manifest's name.
28
+ * @param {Uint8Array|ArrayBuffer} bytes
29
+ * @returns {Array<Object>} the entries added
30
+ */
31
+ importArchiTemplate(bytes) {
32
+ const data = bytes instanceof ArrayBuffer ? new Uint8Array(bytes) : bytes;
33
+ if (!ZipArchive.isZip(data)) throw new Error('Not an Archi template: it is not a zip archive');
34
+ const zip = ZipArchive.read(data);
35
+ const modelBytes = zip.get(ARCHI_TEMPLATE_MODEL_ENTRY);
36
+ if (!modelBytes) throw new Error(`Not an Archi template: it has no ${ARCHI_TEMPLATE_MODEL_ENTRY}`);
37
+ const manifest = CanvasTemplateLibrary._readManifest(zip);
38
+
39
+ const model = toArchimateModel(parseArchiFile(modelBytes));
40
+ const canvases = model.views().filter(v => v.constructor.kind === 'canvas');
41
+ if (!canvases.length) throw new Error('The Archi template has no canvas');
42
+ const thumbnailBytes = manifest.thumbnail ? zip.get(manifest.thumbnail) : null;
43
+ const thumbnail = thumbnailBytes ? archivedFileUrl(thumbnailBytes, manifest.thumbnail) : null;
44
+ const single = canvases.length === 1;
45
+ return canvases.map(view => this.add({
46
+ view: view.toJSON(),
47
+ name: (single && manifest.name) || view.name,
48
+ description: (single && manifest.description) || view.documentation || '',
49
+ thumbnail: single ? thumbnail : null,
50
+ }));
51
+ }
52
+
53
+ /** An Archi template's manifest: name, description and key thumbnail's path. @private */
54
+ static _readManifest(zip) {
55
+ const bytes = zip.get(ARCHI_TEMPLATE_MANIFEST_ENTRY);
56
+ if (!bytes) return {};
57
+ const root = parseXML(new TextDecoder().decode(bytes));
58
+ const text = (tag) => root.children.find(c => c.tagName === tag)?.textContent?.replace(/\r\n?/g, '\n').trim() || '';
59
+ return { name: text('name'), description: text('description'), thumbnail: text('key-thumbnail') || null };
60
+ }
61
+ }