@metadev/daga-angular 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/Changelog.md +204 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +67 -0
  4. package/assets/fonts/DMMono-Medium.ttf +0 -0
  5. package/assets/fonts/DMMono-Medium.woff +0 -0
  6. package/assets/fonts/DMMono-Medium.woff2 +0 -0
  7. package/assets/fonts/WonderUnitSans-Medium.ttf +0 -0
  8. package/assets/fonts/WonderUnitSans-Medium.woff +0 -0
  9. package/assets/fonts/WonderUnitSans-Medium.woff2 +0 -0
  10. package/assets/icon/action/drop-down-arrow.svg +8 -0
  11. package/assets/icon/action/drop-horizontal-left.svg +14 -0
  12. package/assets/icon/action/drop-horizontal-none.svg +13 -0
  13. package/assets/icon/action/drop-horizontal-right.svg +14 -0
  14. package/assets/icon/action/drop-vertical-down.svg +14 -0
  15. package/assets/icon/action/drop-vertical-none.svg +13 -0
  16. package/assets/icon/action/drop-vertical-up.svg +14 -0
  17. package/assets/icon/action/filter-clear.png +0 -0
  18. package/assets/icon/buttons/center-hover.svg +10 -0
  19. package/assets/icon/buttons/center.svg +10 -0
  20. package/assets/icon/buttons/copy-hover.svg +6 -0
  21. package/assets/icon/buttons/copy.svg +6 -0
  22. package/assets/icon/buttons/cut-hover.svg +6 -0
  23. package/assets/icon/buttons/cut.svg +6 -0
  24. package/assets/icon/buttons/delete-hover.svg +6 -0
  25. package/assets/icon/buttons/delete.svg +6 -0
  26. package/assets/icon/buttons/ellipsis-hover.svg +7 -0
  27. package/assets/icon/buttons/ellipsis.svg +7 -0
  28. package/assets/icon/buttons/filter-off-hover.svg +5 -0
  29. package/assets/icon/buttons/filter-off.svg +5 -0
  30. package/assets/icon/buttons/filter-on-hover.svg +5 -0
  31. package/assets/icon/buttons/filter-on.svg +5 -0
  32. package/assets/icon/buttons/layout-hover.svg +8 -0
  33. package/assets/icon/buttons/layout.svg +8 -0
  34. package/assets/icon/buttons/multiple-selection-hover.svg +18 -0
  35. package/assets/icon/buttons/multiple-selection.svg +18 -0
  36. package/assets/icon/buttons/paste-hover.svg +6 -0
  37. package/assets/icon/buttons/paste.svg +6 -0
  38. package/assets/icon/buttons/redo-hover.svg +5 -0
  39. package/assets/icon/buttons/redo.svg +5 -0
  40. package/assets/icon/buttons/undo-hover.svg +5 -0
  41. package/assets/icon/buttons/undo.svg +5 -0
  42. package/assets/icon/buttons/zoom-in-hover.svg +8 -0
  43. package/assets/icon/buttons/zoom-in.svg +8 -0
  44. package/assets/icon/buttons/zoom-out-hover.svg +7 -0
  45. package/assets/icon/buttons/zoom-out.svg +7 -0
  46. package/assets/icon/context/context-copy.svg +4 -0
  47. package/assets/icon/context/context-cross.svg +3 -0
  48. package/assets/icon/context/context-cut.svg +4 -0
  49. package/assets/icon/context/context-delete.svg +4 -0
  50. package/assets/icon/context/context-paste.svg +4 -0
  51. package/assets/icon/property/add.svg +23 -0
  52. package/assets/icon/property/close.svg +3 -0
  53. package/assets/icon/property/ellipsis.svg +5 -0
  54. package/assets/icon/property/gear.svg +3 -0
  55. package/assets/icon/property/hide.svg +10 -0
  56. package/assets/icon/property/move.svg +35 -0
  57. package/assets/styles/_collapse-button.scss +37 -0
  58. package/assets/styles/_context-menu.scss +32 -0
  59. package/assets/styles/_diagram-buttons.scss +197 -0
  60. package/assets/styles/_diagram.scss +15 -0
  61. package/assets/styles/_errors.scss +83 -0
  62. package/assets/styles/_palette.scss +20 -0
  63. package/assets/styles/_property-editor.scss +285 -0
  64. package/assets/styles/daga.scss +150 -0
  65. package/fesm2022/metadev-daga-angular.mjs +1861 -0
  66. package/fesm2022/metadev-daga-angular.mjs.map +1 -0
  67. package/index.d.ts +14 -0
  68. package/lib/collapse-button/collapse-button.component.d.ts +22 -0
  69. package/lib/daga.module.d.ts +18 -0
  70. package/lib/diagram/diagram.component.d.ts +43 -0
  71. package/lib/diagram-buttons/diagram-buttons.component.d.ts +46 -0
  72. package/lib/diagram-editor/diagram-editor.component.d.ts +34 -0
  73. package/lib/errors/errors.component.d.ts +24 -0
  74. package/lib/palette/palette.component.d.ts +36 -0
  75. package/lib/property-editor/autocomplete/autocomplete.component.d.ts +39 -0
  76. package/lib/property-editor/object-editor/object-editor.component.d.ts +29 -0
  77. package/lib/property-editor/option-list-editor/option-list-editor.component.d.ts +33 -0
  78. package/lib/property-editor/property-editor.component.d.ts +34 -0
  79. package/lib/property-editor/property-settings/property-settings.component.d.ts +33 -0
  80. package/lib/property-editor/text-list-editor/text-list-editor.component.d.ts +29 -0
  81. package/lib/property-editor/text-map-editor/text-map-editor.component.d.ts +36 -0
  82. package/lib/services/canvas-provider.service.d.ts +30 -0
  83. package/lib/services/daga-configuration.service.d.ts +23 -0
  84. package/package.json +55 -0
@@ -0,0 +1,1861 @@
1
+ import { Side, DiagramCanvas, DiagramActions, layouts, Events, DragEvents, setCursorStyle, CursorStyle, AddNodeAction, generalClosedPath, DIAGRAM_FIELD_DEFAULTS, getLeftMargin, getTopMargin, ClosedShape, Type, Property, isObject, equals, Keys, Corner, DagaImporter, DagaExporter } from '@metadev/daga';
2
+ export { ACTION_STACK_SIZE, ActionStack, AddConnectionAction, AddNodeAction, AdjacencyLayout, BreadthAdjacencyLayout, BreadthLayout, ClosedShape, CollabClient, Corner, DagaExporter, DagaImporter, DiagramActions, DiagramCanvas, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramDecorator, DiagramDecoratorSet, DiagramElement, DiagramElementSet, DiagramEntitySet, DiagramEvent, DiagramField, DiagramFieldSet, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramObject, DiagramObjectSet, DiagramPort, DiagramPortSet, DiagramSection, DiagramSectionSet, EditFieldAction, ForceLayout, HorizontalAlign, HorizontalLayout, LineShape, LineStyle, PriorityLayout, Property, PropertySet, RemoveAction, SetGeometryAction, Side, TreeLayout, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, layouts } from '@metadev/daga';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i0 from '@angular/core';
6
+ import { ElementRef, Component, Input, Injectable, ViewChild, EventEmitter, Output, NgModule } from '@angular/core';
7
+ import * as d3 from 'd3';
8
+ import * as i2 from '@angular/forms';
9
+ import { FormsModule } from '@angular/forms';
10
+ import { merge, delay, map } from 'rxjs';
11
+
12
+ /**
13
+ * Button used to collapse components that implement it.
14
+ * @private
15
+ */
16
+ class CollapseButtonComponent {
17
+ constructor() {
18
+ this.collapsed = false;
19
+ this.disabled = false;
20
+ this.direction = Side.Bottom;
21
+ this.rule = 'visibility';
22
+ this.collapsedValue = 'collapse';
23
+ this.visibleValue = 'visible';
24
+ this.Side = Side;
25
+ }
26
+ toggleCollapse() {
27
+ if (!this.disabled) {
28
+ this.collapsed = !this.collapsed;
29
+ let selection;
30
+ if (this.collapsableSelector instanceof ElementRef) {
31
+ selection = d3.select(this.collapsableSelector.nativeElement);
32
+ if (this.collapsableAdditionalSelector) {
33
+ selection = selection.select(this.collapsableAdditionalSelector);
34
+ }
35
+ }
36
+ else if (this.collapsableSelector instanceof HTMLElement) {
37
+ selection = d3.select(this.collapsableSelector);
38
+ if (this.collapsableAdditionalSelector) {
39
+ selection = selection.select(this.collapsableAdditionalSelector);
40
+ }
41
+ }
42
+ else {
43
+ selection = d3.select(this.collapsableSelector);
44
+ if (this.collapsableAdditionalSelector) {
45
+ selection = selection.select(this.collapsableAdditionalSelector);
46
+ }
47
+ }
48
+ selection.style(this.rule, this.collapsed ? this.collapsedValue : this.visibleValue);
49
+ }
50
+ }
51
+ getClass() {
52
+ switch (this.direction) {
53
+ case Side.Right:
54
+ if (this.disabled) {
55
+ return 'daga-horizontal-none';
56
+ }
57
+ else if (this.collapsed) {
58
+ return 'daga-horizontal-right';
59
+ }
60
+ else {
61
+ return 'daga-horizontal-left';
62
+ }
63
+ case Side.Bottom:
64
+ if (this.disabled) {
65
+ return 'daga-vertical-none';
66
+ }
67
+ else if (this.collapsed) {
68
+ return 'daga-vertical-down';
69
+ }
70
+ else {
71
+ return 'daga-vertical-up';
72
+ }
73
+ case Side.Left:
74
+ if (this.disabled) {
75
+ return 'daga-horizontal-none';
76
+ }
77
+ else if (this.collapsed) {
78
+ return 'daga-horizontal-left';
79
+ }
80
+ else {
81
+ return 'daga-horizontal-right';
82
+ }
83
+ case Side.Top:
84
+ if (this.disabled) {
85
+ return 'daga-vertical-none';
86
+ }
87
+ else if (this.collapsed) {
88
+ return 'daga-vertical-up';
89
+ }
90
+ else {
91
+ return 'daga-vertical-down';
92
+ }
93
+ }
94
+ }
95
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: CollapseButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
96
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: CollapseButtonComponent, isStandalone: true, selector: "daga-collapse-button", inputs: { collapsableSelector: "collapsableSelector", collapsableAdditionalSelector: "collapsableAdditionalSelector", collapsed: "collapsed", disabled: "disabled", direction: "direction", rule: "rule", collapsedValue: "collapsedValue", visibleValue: "visibleValue" }, ngImport: i0, template: "<button\r\n class=\"daga-collapse-button daga-{{ direction }}\"\r\n (click)=\"toggleCollapse()\"\r\n>\r\n <div [class]=\"getClass()\"></div>\r\n</button>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: CollapseButtonComponent, decorators: [{
99
+ type: Component,
100
+ args: [{ standalone: true, selector: 'daga-collapse-button', imports: [CommonModule], template: "<button\r\n class=\"daga-collapse-button daga-{{ direction }}\"\r\n (click)=\"toggleCollapse()\"\r\n>\r\n <div [class]=\"getClass()\"></div>\r\n</button>\r\n" }]
101
+ }], propDecorators: { collapsableSelector: [{
102
+ type: Input
103
+ }], collapsableAdditionalSelector: [{
104
+ type: Input
105
+ }], collapsed: [{
106
+ type: Input
107
+ }], disabled: [{
108
+ type: Input
109
+ }], direction: [{
110
+ type: Input
111
+ }], rule: [{
112
+ type: Input
113
+ }], collapsedValue: [{
114
+ type: Input
115
+ }], visibleValue: [{
116
+ type: Input
117
+ }] } });
118
+
119
+ /**
120
+ * A provider for the {@link Canvas} associated with a {@link DiagramComponent} context.
121
+ * @public
122
+ */
123
+ class CanvasProviderService {
124
+ /**
125
+ * Initialize the diagram canvas object of this context.
126
+ * @private
127
+ * @param parentComponent A diagram editor.
128
+ * @param config A diagram configuration.
129
+ */
130
+ initCanvas(parentComponent, config) {
131
+ this._canvas = new DiagramCanvas(parentComponent, config);
132
+ }
133
+ /**
134
+ * Attach the canvas of this context to an HTML Element to render it there.
135
+ * @private
136
+ * @param appendTo An HTML Element.
137
+ */
138
+ initCanvasView(appendTo) {
139
+ this._canvas.initView(appendTo);
140
+ }
141
+ /**
142
+ * Get the diagram canvas of this context. Should only be called after the view of the {@link DiagramComponent} context has been initialized.
143
+ * @public
144
+ * @returns A diagram canvas.
145
+ */
146
+ getCanvas() {
147
+ return this._canvas;
148
+ }
149
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: CanvasProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
150
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: CanvasProviderService }); }
151
+ }
152
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: CanvasProviderService, decorators: [{
153
+ type: Injectable
154
+ }] });
155
+
156
+ /**
157
+ * Buttons used to trigger diagram functionalities by the user.
158
+ * @private
159
+ */
160
+ class DiagramButtonsComponent {
161
+ get canvas() {
162
+ return this.canvasProvider.getCanvas();
163
+ }
164
+ constructor(canvasProvider) {
165
+ this.canvasProvider = canvasProvider;
166
+ this.enableAction = false;
167
+ this.enableFilter = false;
168
+ this.enableLayout = false;
169
+ this.enableSelection = false;
170
+ this.enableZoom = true;
171
+ this.filterOn = false;
172
+ this.collapsed = true;
173
+ this.animationOngoing = false;
174
+ this.DiagramActions = DiagramActions;
175
+ }
176
+ ngAfterViewInit() {
177
+ switch (this.direction) {
178
+ case Side.Bottom:
179
+ this.sizeAttribute = 'height';
180
+ this.transformFunction = 'scaleY';
181
+ this.transformOrigin = 'top';
182
+ this.marginSide = 'bottom';
183
+ break;
184
+ case Side.Top:
185
+ this.sizeAttribute = 'height';
186
+ this.transformFunction = 'scaleY';
187
+ this.transformOrigin = 'bottom';
188
+ this.marginSide = 'top';
189
+ break;
190
+ case Side.Left:
191
+ this.sizeAttribute = 'width';
192
+ this.transformFunction = 'scaleX';
193
+ this.transformOrigin = 'right';
194
+ this.marginSide = 'left';
195
+ break;
196
+ case Side.Right:
197
+ this.sizeAttribute = 'width';
198
+ this.transformFunction = 'scaleX';
199
+ this.transformOrigin = 'left';
200
+ this.marginSide = 'right';
201
+ break;
202
+ }
203
+ const numberOfCollapsableButtons = d3
204
+ .select(this.collapsableButtons.nativeElement)
205
+ .selectChildren()
206
+ .size();
207
+ this.collapsableButtonsSize = `${4 * numberOfCollapsableButtons}rem`;
208
+ d3.select(this.collapsableButtons.nativeElement)
209
+ .style(`margin-${this.marginSide}`, '-1rem')
210
+ .style(this.sizeAttribute, '0rem')
211
+ .style('transform', `${this.transformFunction}(0)`)
212
+ .style('transform-origin', this.transformOrigin);
213
+ }
214
+ // Collapse functions
215
+ async toggleCollapse() {
216
+ if (!this.animationOngoing) {
217
+ const duration = 500;
218
+ const collapsableButtons = d3.select(this.collapsableButtons.nativeElement);
219
+ if (this.collapsed) {
220
+ this.collapsed = false;
221
+ collapsableButtons
222
+ .transition()
223
+ .duration(duration)
224
+ .ease(d3.easeLinear)
225
+ .style(this.sizeAttribute, this.collapsableButtonsSize)
226
+ .style('transform', `${this.transformFunction}(1)`);
227
+ setTimeout(() => {
228
+ this.animationOngoing = false;
229
+ }, duration);
230
+ }
231
+ else {
232
+ this.collapsed = true;
233
+ collapsableButtons
234
+ .transition()
235
+ .duration(duration)
236
+ .ease(d3.easeLinear)
237
+ .style(this.sizeAttribute, '0rem')
238
+ .style('transform', `${this.transformFunction}(0)`);
239
+ setTimeout(() => {
240
+ this.animationOngoing = false;
241
+ }, duration);
242
+ }
243
+ }
244
+ }
245
+ // Button functions
246
+ zoomIn() {
247
+ this.canvas.zoomBy(this.canvas.zoomFactor);
248
+ }
249
+ zoomOut() {
250
+ this.canvas.zoomBy(1 / this.canvas.zoomFactor);
251
+ }
252
+ center() {
253
+ this.canvas.center();
254
+ }
255
+ layout() {
256
+ if (this.canvas.layoutFormat && this.canvas.layoutFormat in layouts) {
257
+ layouts[this.canvas.layoutFormat].apply(this.canvas.model);
258
+ }
259
+ }
260
+ filter() {
261
+ this.filterOn = !this.filterOn;
262
+ const priorityThresholds = this.canvas.getPriorityThresholdOptions();
263
+ if (priorityThresholds && priorityThresholds.length >= 2) {
264
+ this.canvas.setPriorityThreshold(priorityThresholds[this.filterOn ? 1 : 0]);
265
+ }
266
+ }
267
+ undo() {
268
+ this.canvas.actionStack.undo();
269
+ }
270
+ redo() {
271
+ this.canvas.actionStack.redo();
272
+ }
273
+ copySelection() {
274
+ this.canvas.userSelection.copyToClipboard();
275
+ }
276
+ cutSelection() {
277
+ this.canvas.userSelection.cutToClipboard();
278
+ }
279
+ pasteSelection() {
280
+ this.canvas.userSelection.pasteFromClipboard();
281
+ }
282
+ deleteSelection() {
283
+ this.canvas.userSelection.removeFromModel();
284
+ }
285
+ startMultipleSelection() {
286
+ this.canvas.multipleSelectionOn = true;
287
+ }
288
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramButtonsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
289
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: DiagramButtonsComponent, isStandalone: true, selector: "daga-diagram-buttons", inputs: { location: "location", direction: "direction", enableAction: "enableAction", enableFilter: "enableFilter", enableLayout: "enableLayout", enableSelection: "enableSelection", enableZoom: "enableZoom" }, viewQueries: [{ propertyName: "collapsableButtons", first: true, predicate: ["collapsableButtons"], descendants: true }], ngImport: i0, template: "<div class=\"daga-diagram-buttons daga-{{ location }} daga-{{ direction }}\">\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-zoom-in\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <span class=\"daga-tooltip\">Zoom in</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-zoom-out\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <span class=\"daga-tooltip\">Zoom out</span>\r\n </button>\r\n <div #collapsableButtons class=\"daga-collapsable-buttons daga-collapsed\">\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-center\"\r\n (click)=\"center()\"\r\n >\r\n <span class=\"daga-tooltip\">Fit diagram to screen</span>\r\n </button>\r\n <button *ngIf=\"enableAction\" class=\"daga-undo\" (click)=\"undo()\">\r\n <span class=\"daga-tooltip\">Undo</span>\r\n </button>\r\n <button *ngIf=\"enableAction\" class=\"daga-redo\" (click)=\"redo()\">\r\n <span class=\"daga-tooltip\">Redo</span>\r\n </button>\r\n <button *ngIf=\"enableSelection\" class=\"daga-copy\" (click)=\"copySelection()\">\r\n <span class=\"daga-tooltip\">Copy</span>\r\n </button>\r\n <button *ngIf=\"enableSelection\" class=\"daga-cut\" (click)=\"cutSelection()\">\r\n <span class=\"daga-tooltip\">Cut</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-multiple-selection\"\r\n [class]=\"canvas.multipleSelectionOn ? 'daga-on' : 'daga-off'\"\r\n (click)=\"startMultipleSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Multiple selection</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-paste\"\r\n (click)=\"pasteSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Paste</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-delete\"\r\n (click)=\"deleteSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Delete</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableLayout && canvas.layoutFormat\"\r\n class=\"daga-layout\"\r\n (click)=\"layout()\"\r\n >\r\n <span class=\"daga-tooltip\">Apply layout</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableFilter\"\r\n class=\"daga-filter\"\r\n [class]=\"filterOn ? 'daga-on' : 'daga-off'\"\r\n (click)=\"filter()\"\r\n >\r\n <span class=\"daga-tooltip\">Apply filter</span>\r\n </button>\r\n </div>\r\n <button class=\"daga-more-options\" (click)=\"toggleCollapse()\">\r\n <span *ngIf=\"!collapsed\" class=\"daga-tooltip\">Less options</span>\r\n <span *ngIf=\"collapsed\" class=\"daga-tooltip\">More options</span>\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
290
+ }
291
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramButtonsComponent, decorators: [{
292
+ type: Component,
293
+ args: [{ standalone: true, selector: 'daga-diagram-buttons', imports: [CommonModule], template: "<div class=\"daga-diagram-buttons daga-{{ location }} daga-{{ direction }}\">\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-zoom-in\"\r\n (click)=\"zoomIn()\"\r\n >\r\n <span class=\"daga-tooltip\">Zoom in</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-zoom-out\"\r\n (click)=\"zoomOut()\"\r\n >\r\n <span class=\"daga-tooltip\">Zoom out</span>\r\n </button>\r\n <div #collapsableButtons class=\"daga-collapsable-buttons daga-collapsed\">\r\n <button\r\n *ngIf=\"enableZoom && canvas.canUserPerformAction(DiagramActions.Zoom)\"\r\n class=\"daga-center\"\r\n (click)=\"center()\"\r\n >\r\n <span class=\"daga-tooltip\">Fit diagram to screen</span>\r\n </button>\r\n <button *ngIf=\"enableAction\" class=\"daga-undo\" (click)=\"undo()\">\r\n <span class=\"daga-tooltip\">Undo</span>\r\n </button>\r\n <button *ngIf=\"enableAction\" class=\"daga-redo\" (click)=\"redo()\">\r\n <span class=\"daga-tooltip\">Redo</span>\r\n </button>\r\n <button *ngIf=\"enableSelection\" class=\"daga-copy\" (click)=\"copySelection()\">\r\n <span class=\"daga-tooltip\">Copy</span>\r\n </button>\r\n <button *ngIf=\"enableSelection\" class=\"daga-cut\" (click)=\"cutSelection()\">\r\n <span class=\"daga-tooltip\">Cut</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-multiple-selection\"\r\n [class]=\"canvas.multipleSelectionOn ? 'daga-on' : 'daga-off'\"\r\n (click)=\"startMultipleSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Multiple selection</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-paste\"\r\n (click)=\"pasteSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Paste</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableSelection\"\r\n class=\"daga-delete\"\r\n (click)=\"deleteSelection()\"\r\n >\r\n <span class=\"daga-tooltip\">Delete</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableLayout && canvas.layoutFormat\"\r\n class=\"daga-layout\"\r\n (click)=\"layout()\"\r\n >\r\n <span class=\"daga-tooltip\">Apply layout</span>\r\n </button>\r\n <button\r\n *ngIf=\"enableFilter\"\r\n class=\"daga-filter\"\r\n [class]=\"filterOn ? 'daga-on' : 'daga-off'\"\r\n (click)=\"filter()\"\r\n >\r\n <span class=\"daga-tooltip\">Apply filter</span>\r\n </button>\r\n </div>\r\n <button class=\"daga-more-options\" (click)=\"toggleCollapse()\">\r\n <span *ngIf=\"!collapsed\" class=\"daga-tooltip\">Less options</span>\r\n <span *ngIf=\"collapsed\" class=\"daga-tooltip\">More options</span>\r\n </button>\r\n</div>\r\n" }]
294
+ }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { collapsableButtons: [{
295
+ type: ViewChild,
296
+ args: ['collapsableButtons']
297
+ }], location: [{
298
+ type: Input
299
+ }], direction: [{
300
+ type: Input
301
+ }], enableAction: [{
302
+ type: Input
303
+ }], enableFilter: [{
304
+ type: Input
305
+ }], enableLayout: [{
306
+ type: Input
307
+ }], enableSelection: [{
308
+ type: Input
309
+ }], enableZoom: [{
310
+ type: Input
311
+ }] } });
312
+
313
+ /**
314
+ * Displays the errors detected by a diagram's validators.
315
+ * @private
316
+ * @see DiagramValidator
317
+ */
318
+ class ErrorsComponent {
319
+ get canvas() {
320
+ return this.canvasProvider.getCanvas();
321
+ }
322
+ constructor(canvasProvider) {
323
+ this.canvasProvider = canvasProvider;
324
+ this.errors = [];
325
+ this.Side = Side;
326
+ }
327
+ ngAfterViewInit() {
328
+ merge(this.canvas.validatorChange$, this.canvas.diagramChange$)
329
+ .pipe(
330
+ // delay to avoid errors of variables changing right after checking
331
+ delay(1), map(() => this.validate()))
332
+ .subscribe();
333
+ }
334
+ selectPanel() {
335
+ return d3
336
+ .select(this.errorsContainer.nativeElement)
337
+ .select('.daga-error-panel');
338
+ }
339
+ validate() {
340
+ this.errors = [];
341
+ for (const validator of this.canvas.validators) {
342
+ const newErrors = validator.validate(this.canvas.model);
343
+ this.errors = [...this.errors, ...newErrors];
344
+ }
345
+ }
346
+ showError(error) {
347
+ if (error.elementId &&
348
+ (error.propertyNames === undefined || error.propertyNames.length === 0)) {
349
+ const element = this.canvas.model.nodes.get(error.elementId) ||
350
+ this.canvas.model.connections.get(error.elementId);
351
+ if (element) {
352
+ this.canvas.userHighlight.add(element);
353
+ }
354
+ }
355
+ else if (error.elementId &&
356
+ error.propertyNames !== undefined &&
357
+ error.propertyNames.length > 0) {
358
+ this.canvas.userSelection.openInPropertyEditor(this.canvas.model.nodes.get(error.elementId) ||
359
+ this.canvas.model.connections.get(error.elementId));
360
+ const element = this.canvas.model.nodes.get(error.elementId) ||
361
+ this.canvas.model.connections.get(error.elementId);
362
+ if (element) {
363
+ this.canvas.userHighlight.add(element);
364
+ }
365
+ this.canvas.parentComponent?.propertyEditor?.highlightProperty(...error.propertyNames);
366
+ }
367
+ else if (!error.elementId &&
368
+ error.propertyNames !== undefined &&
369
+ error.propertyNames.length > 0) {
370
+ this.canvas.userSelection.openInPropertyEditor();
371
+ this.canvas.parentComponent?.propertyEditor?.highlightProperty(...error.propertyNames);
372
+ }
373
+ }
374
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: ErrorsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
375
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: ErrorsComponent, isStandalone: true, selector: "daga-errors", viewQueries: [{ propertyName: "errorsContainer", first: true, predicate: ["errors"], descendants: true }], ngImport: i0, template: "<div #errorsContainer class=\"daga-errors\">\r\n <div\r\n *ngIf=\"errors.length === 0\"\r\n class=\"daga-errors-summary daga-no-errors daga-prevent-user-select\"\r\n >\r\n <span>No errors found</span>\r\n </div>\r\n <div\r\n *ngIf=\"errors.length > 0\"\r\n class=\"daga-errors-summary daga-with-errors daga-prevent-user-select\"\r\n >\r\n <span>{{ errors.length }} errors found</span>\r\n <div class=\"daga-collapse-button-container\">\r\n <daga-collapse-button\r\n [collapsableSelector]=\"errorsContainer\"\r\n [collapsableAdditionalSelector]=\"'.daga-error-panel'\"\r\n [direction]=\"Side.Top\"\r\n [rule]=\"'display'\"\r\n [collapsedValue]=\"'none'\"\r\n [visibleValue]=\"'block'\"\r\n />\r\n </div>\r\n </div>\r\n <div *ngIf=\"errors.length > 0\" class=\"daga-error-panel\">\r\n <ol>\r\n <li\r\n *ngFor=\"let error of errors; index as i\"\r\n (click)=\"showError(error)\"\r\n [innerHTML]=\"error.message\"\r\n ></li>\r\n </ol>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
376
+ }
377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: ErrorsComponent, decorators: [{
378
+ type: Component,
379
+ args: [{ standalone: true, selector: 'daga-errors', imports: [CommonModule, CollapseButtonComponent], template: "<div #errorsContainer class=\"daga-errors\">\r\n <div\r\n *ngIf=\"errors.length === 0\"\r\n class=\"daga-errors-summary daga-no-errors daga-prevent-user-select\"\r\n >\r\n <span>No errors found</span>\r\n </div>\r\n <div\r\n *ngIf=\"errors.length > 0\"\r\n class=\"daga-errors-summary daga-with-errors daga-prevent-user-select\"\r\n >\r\n <span>{{ errors.length }} errors found</span>\r\n <div class=\"daga-collapse-button-container\">\r\n <daga-collapse-button\r\n [collapsableSelector]=\"errorsContainer\"\r\n [collapsableAdditionalSelector]=\"'.daga-error-panel'\"\r\n [direction]=\"Side.Top\"\r\n [rule]=\"'display'\"\r\n [collapsedValue]=\"'none'\"\r\n [visibleValue]=\"'block'\"\r\n />\r\n </div>\r\n </div>\r\n <div *ngIf=\"errors.length > 0\" class=\"daga-error-panel\">\r\n <ol>\r\n <li\r\n *ngFor=\"let error of errors; index as i\"\r\n (click)=\"showError(error)\"\r\n [innerHTML]=\"error.message\"\r\n ></li>\r\n </ol>\r\n </div>\r\n</div>\r\n" }]
380
+ }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { errorsContainer: [{
381
+ type: ViewChild,
382
+ args: ['errors']
383
+ }] } });
384
+
385
+ /**
386
+ * Palette that the user can drag and drop nodes from.
387
+ * @private
388
+ * @see DiagramConfig
389
+ * @see DiagramNode
390
+ */
391
+ class PaletteComponent {
392
+ get canvas() {
393
+ return this.canvasProvider.getCanvas();
394
+ }
395
+ constructor(canvasProvider) {
396
+ this.canvasProvider = canvasProvider;
397
+ this.currentCategory = '';
398
+ }
399
+ ngAfterContentInit() {
400
+ // we initialize the currentPalette variable if it hasn't been initalized with a proper value
401
+ // doing this in ngAfterViewInit() would cause an ExpressionChangedAfterItHasBeenCheckedError
402
+ this.currentPalette = this.currentPalette || this.palettes[0];
403
+ }
404
+ ngAfterViewInit() {
405
+ this.refreshPalette();
406
+ switch (this.direction) {
407
+ case Side.Bottom:
408
+ case Side.Top:
409
+ this.selectPanel().style('width', this.width);
410
+ break;
411
+ case Side.Left:
412
+ case Side.Right:
413
+ this.selectPanel().style('height', this.width);
414
+ break;
415
+ }
416
+ }
417
+ refreshPalette() {
418
+ this.switchPalette(this.currentPalette);
419
+ }
420
+ switchPalette(palette) {
421
+ this.currentPalette = palette;
422
+ this.selectPalette().selectAll('*').remove();
423
+ this.priorityThreshold = this.canvas.getPriorityThreshold();
424
+ if (palette.categories) {
425
+ this.appendCategories(palette.categories);
426
+ }
427
+ if (palette.templates) {
428
+ for (const template of palette.templates) {
429
+ this.appendTemplate(template);
430
+ }
431
+ }
432
+ }
433
+ selectPanel() {
434
+ return d3.select(this.panel.nativeElement);
435
+ }
436
+ selectPalette() {
437
+ return this.selectPanel().select('.daga-palette-view');
438
+ }
439
+ appendCategories(categories) {
440
+ const thisComponent = this.selectPalette()
441
+ .append('select')
442
+ .style('width', '100%')
443
+ .style('height', '2rem')
444
+ .style('padding', '0.5rem')
445
+ .style('border-radius', '0.25rem')
446
+ .style('background-color', '#f7f8fc')
447
+ .style('border', `1px solid #e6e6e6`);
448
+ thisComponent.append('option').attr('value', '').text('(None selected)');
449
+ for (const categoryKey in categories) {
450
+ thisComponent
451
+ .append('option')
452
+ .attr('value', categoryKey)
453
+ .text(categoryKey);
454
+ }
455
+ thisComponent.on(Events.Change, () => {
456
+ if (this.currentCategory) {
457
+ this.selectPalette()
458
+ .selectAll(`.daga-template-container.daga-in-category`)
459
+ .remove();
460
+ }
461
+ const selectedKey = thisComponent.property('value');
462
+ this.currentCategory = selectedKey;
463
+ const templatesInCategory = categories[selectedKey] || [];
464
+ for (const template of templatesInCategory) {
465
+ this.appendTemplate(template, 'daga-in-category');
466
+ }
467
+ });
468
+ if (this.currentCategory) {
469
+ // if we had a category already selected, re-select it
470
+ thisComponent.property('value', this.currentCategory);
471
+ thisComponent.dispatch(Events.Change);
472
+ }
473
+ }
474
+ appendTemplate(template, classes) {
475
+ if (template.templateType === 'node') {
476
+ const nodeType = this.canvas.model.nodes.types.get(template.type);
477
+ if (nodeType) {
478
+ this.appendNodeTemplate(nodeType, template, classes);
479
+ }
480
+ else {
481
+ console.error(`Could not find a node type called '${template.type}'`);
482
+ }
483
+ }
484
+ else if (template.templateType === 'connection') {
485
+ {
486
+ const connectionType = this.canvas.model.connections.types.get(template.type);
487
+ if (connectionType) {
488
+ this.appendConnectionTemplate(connectionType, template, classes);
489
+ }
490
+ else {
491
+ console.error(`Could not find a connection type called '${template.type}'`);
492
+ }
493
+ }
494
+ }
495
+ }
496
+ appendNodeTemplate(type, templateConfig, classes) {
497
+ if (this.priorityThreshold !== undefined &&
498
+ type.priority < this.priorityThreshold) {
499
+ return;
500
+ }
501
+ const thisComponent = this.selectPalette()
502
+ .append('div')
503
+ .attr('class', `daga-template-container ${classes !== undefined ? classes : ''}`)
504
+ .style('width', `${type.defaultWidth}px`)
505
+ .style('height', `${type.defaultHeight}px`)
506
+ .call(d3
507
+ .drag()
508
+ .on(DragEvents.Drag, (event) => {
509
+ if (this.canvas.canUserPerformAction(DiagramActions.AddNode)) {
510
+ const pointerCoords = this.canvas.getPointerLocationRelativeToScreen(event);
511
+ if (pointerCoords.length < 2 ||
512
+ isNaN(pointerCoords[0]) ||
513
+ isNaN(pointerCoords[1])) {
514
+ return;
515
+ }
516
+ thisComponent
517
+ .style('position', 'fixed')
518
+ .style('left', `${pointerCoords[0] - type.defaultWidth / 2}px`)
519
+ .style('top', `${pointerCoords[1] - type.defaultHeight / 2}px`)
520
+ .style('z-index', 1);
521
+ }
522
+ })
523
+ .on(DragEvents.Start, (event) => {
524
+ if (this.canvas.canUserPerformAction(DiagramActions.AddNode)) {
525
+ setCursorStyle(CursorStyle.Grabbing);
526
+ const pointerCoords = this.canvas.getPointerLocationRelativeToScreen(event);
527
+ if (pointerCoords.length < 2 ||
528
+ isNaN(pointerCoords[0]) ||
529
+ isNaN(pointerCoords[1])) {
530
+ return;
531
+ }
532
+ thisComponent
533
+ .style('position', 'fixed')
534
+ .style('left', `${pointerCoords[0] - type.defaultWidth / 2}px`)
535
+ .style('top', `${pointerCoords[1] - type.defaultHeight / 2}px`)
536
+ .style('z-index', 1);
537
+ // when trying to place a unique node in a diagram that already has a node of that type, set cursor style to not allowed
538
+ if (type.isUnique &&
539
+ this.canvas.model.nodes.find((n) => !n.removed && n.type.id === type.id) !== undefined) {
540
+ setCursorStyle(CursorStyle.NotAllowed);
541
+ }
542
+ }
543
+ })
544
+ .on(DragEvents.End, (event) => {
545
+ if (this.canvas.canUserPerformAction(DiagramActions.AddNode)) {
546
+ // take node back to its original position
547
+ setCursorStyle(CursorStyle.Auto);
548
+ thisComponent
549
+ .style('position', 'relative')
550
+ .style('left', 0)
551
+ .style('top', 0)
552
+ .style('z-index', 'auto');
553
+ // try to place node
554
+ if (type.isUnique &&
555
+ this.canvas.model.nodes.find((n) => !n.removed && n.type.id === type.id) !== undefined) {
556
+ // can't place, it's unique and that node is already in the model
557
+ return;
558
+ }
559
+ const pointerCoordsRelativeToScreen = this.canvas.getPointerLocationRelativeToScreen(event);
560
+ if (pointerCoordsRelativeToScreen.length < 2 ||
561
+ isNaN(pointerCoordsRelativeToScreen[0]) ||
562
+ isNaN(pointerCoordsRelativeToScreen[1])) {
563
+ // can't place, position is incorrect
564
+ return;
565
+ }
566
+ const element = document.elementFromPoint(pointerCoordsRelativeToScreen[0], pointerCoordsRelativeToScreen[1]);
567
+ if (element &&
568
+ !this.canvas.selectCanvasView().node()?.contains(element)) {
569
+ // can't place, node hasn't been dropped on the canvas
570
+ return;
571
+ }
572
+ const pointerCoords = this.canvas.getPointerLocationRelativeToCanvas(event);
573
+ if (pointerCoords.length < 2 ||
574
+ isNaN(pointerCoords[0]) ||
575
+ isNaN(pointerCoords[1])) {
576
+ // can't place, position is incorrect
577
+ return;
578
+ }
579
+ let newNodeCoords = [
580
+ pointerCoords[0] - type.defaultWidth / 2,
581
+ pointerCoords[1] - type.defaultHeight / 2
582
+ ];
583
+ if (this.canvas.snapToGrid) {
584
+ newNodeCoords = this.canvas.getClosestGridPoint(newNodeCoords);
585
+ }
586
+ const addNodeAction = new AddNodeAction(this.canvas, type, newNodeCoords, templateConfig.label, templateConfig.values);
587
+ addNodeAction.do();
588
+ this.canvas.actionStack.add(addNodeAction);
589
+ // reset cursor
590
+ setCursorStyle();
591
+ }
592
+ }))
593
+ .append('svg')
594
+ .attr('class', `palette-node ${type.id}`)
595
+ .style('position', 'relative')
596
+ .style('left', 0)
597
+ .style('top', 0)
598
+ .style('width', '100%')
599
+ .style('height', '100%');
600
+ switch (type.look.lookType) {
601
+ case 'shaped-look':
602
+ thisComponent
603
+ .append('path')
604
+ .attr('d', generalClosedPath(type.look.shape, 0, 0, type.defaultWidth, type.defaultHeight))
605
+ .attr('fill', type.look.fillColor)
606
+ .attr('stroke', type.look.borderColor)
607
+ .attr('stroke-width', '1px');
608
+ break;
609
+ case 'image-look':
610
+ thisComponent
611
+ .append('image')
612
+ .attr('x', 0)
613
+ .attr('y', 0)
614
+ .attr('width', type.defaultWidth)
615
+ .attr('height', type.defaultHeight)
616
+ .attr('href', type.look.backgroundImage)
617
+ .attr('preserveAspectRatio', 'none');
618
+ break;
619
+ case 'stretchable-image-look':
620
+ thisComponent
621
+ .append('image')
622
+ .attr('x', 0)
623
+ .attr('y', 0)
624
+ .attr('width', type.look.leftMargin)
625
+ .attr('height', type.look.topMargin)
626
+ .attr('href', type.look.backgroundImageTopLeft)
627
+ .attr('preserveAspectRatio', 'none');
628
+ thisComponent
629
+ .append('image')
630
+ .attr('x', type.look.leftMargin)
631
+ .attr('y', 0)
632
+ .attr('width', type.defaultWidth - type.look.rightMargin - type.look.leftMargin)
633
+ .attr('height', type.look.topMargin)
634
+ .attr('href', type.look.backgroundImageTop)
635
+ .attr('preserveAspectRatio', 'none');
636
+ thisComponent
637
+ .append('image')
638
+ .attr('x', type.defaultWidth - type.look.rightMargin)
639
+ .attr('y', 0)
640
+ .attr('width', type.look.rightMargin)
641
+ .attr('height', type.look.topMargin)
642
+ .attr('href', type.look.backgroundImageTopRight)
643
+ .attr('preserveAspectRatio', 'none');
644
+ thisComponent
645
+ .append('image')
646
+ .attr('x', 0)
647
+ .attr('y', type.look.topMargin)
648
+ .attr('width', type.look.leftMargin)
649
+ .attr('height', type.defaultHeight - type.look.bottomMargin - type.look.topMargin)
650
+ .attr('href', type.look.backgroundImageLeft)
651
+ .attr('preserveAspectRatio', 'none');
652
+ thisComponent
653
+ .append('image')
654
+ .attr('x', type.look.leftMargin)
655
+ .attr('y', type.look.topMargin)
656
+ .attr('width', type.defaultWidth - type.look.rightMargin - type.look.leftMargin)
657
+ .attr('height', type.defaultHeight - type.look.bottomMargin - type.look.topMargin)
658
+ .attr('href', type.look.backgroundImageCenter)
659
+ .attr('preserveAspectRatio', 'none');
660
+ thisComponent
661
+ .append('image')
662
+ .attr('x', type.defaultWidth - type.look.rightMargin)
663
+ .attr('y', type.look.topMargin)
664
+ .attr('width', type.look.rightMargin)
665
+ .attr('height', type.defaultHeight - type.look.bottomMargin - type.look.topMargin)
666
+ .attr('href', type.look.backgroundImageRight)
667
+ .attr('preserveAspectRatio', 'none');
668
+ thisComponent
669
+ .append('image')
670
+ .attr('x', 0)
671
+ .attr('y', type.defaultHeight - type.look.bottomMargin)
672
+ .attr('width', type.look.leftMargin)
673
+ .attr('height', type.look.bottomMargin)
674
+ .attr('href', type.look.backgroundImageBottomLeft)
675
+ .attr('preserveAspectRatio', 'none');
676
+ thisComponent
677
+ .append('image')
678
+ .attr('x', type.look.leftMargin)
679
+ .attr('y', type.defaultHeight - type.look.bottomMargin)
680
+ .attr('width', type.defaultWidth - type.look.rightMargin - type.look.leftMargin)
681
+ .attr('height', type.look.bottomMargin)
682
+ .attr('href', type.look.backgroundImageBottom)
683
+ .attr('preserveAspectRatio', 'none');
684
+ thisComponent
685
+ .append('image')
686
+ .attr('x', type.defaultWidth - type.look.rightMargin)
687
+ .attr('y', type.defaultHeight - type.look.bottomMargin)
688
+ .attr('width', type.look.rightMargin)
689
+ .attr('height', type.look.bottomMargin)
690
+ .attr('href', type.look.backgroundImageBottomRight)
691
+ .attr('preserveAspectRatio', 'none');
692
+ }
693
+ if (templateConfig.label) {
694
+ const labelConfig = {
695
+ ...DIAGRAM_FIELD_DEFAULTS,
696
+ ...type.label,
697
+ ...templateConfig.labelLook
698
+ };
699
+ thisComponent
700
+ .append('text')
701
+ .attr('transform', `translate(${(getLeftMargin(labelConfig) + type.defaultWidth) / 2},${(getTopMargin(labelConfig) + type.defaultHeight) / 2})`)
702
+ .attr('x', 0)
703
+ .attr('y', 0)
704
+ .attr('font-size', `${labelConfig.fontSize}px`)
705
+ .attr('text-anchor', 'middle')
706
+ .attr('font-family', labelConfig.fontFamily)
707
+ .attr('font-weight', 400)
708
+ .attr('fill', labelConfig.color)
709
+ .attr('stroke', 'none')
710
+ .style('font-kerning', 'none')
711
+ .style('user-select', 'none')
712
+ .text(templateConfig.label);
713
+ }
714
+ }
715
+ appendConnectionTemplate(type, templateConfig, classes) {
716
+ const thisComponent = this.selectPalette()
717
+ .append('div')
718
+ .attr('class', `daga-template-container ${classes !== undefined ? classes : ''}`)
719
+ .style('width', `${templateConfig.width}px`)
720
+ .style('height', `${templateConfig.height}px`)
721
+ .append('svg')
722
+ .attr('class', `palette-button ${type.id}`)
723
+ .style('position', 'relative')
724
+ .style('left', 0)
725
+ .style('top', 0)
726
+ .style('width', '100%')
727
+ .style('height', '100%')
728
+ .on('click', () => {
729
+ this.canvas.connectionType = type;
730
+ });
731
+ thisComponent
732
+ .append('path')
733
+ .attr('d', generalClosedPath(ClosedShape.Rectangle, 0, 0, templateConfig.width, templateConfig.height))
734
+ .attr('fill', templateConfig.backgroundColor)
735
+ .attr('stroke', 'black')
736
+ .attr('stroke-width', '1px');
737
+ if (templateConfig.icon !== '') {
738
+ thisComponent
739
+ .append('image')
740
+ .attr('x', 0)
741
+ .attr('y', 0)
742
+ .attr('width', templateConfig.width)
743
+ .attr('height', templateConfig.height)
744
+ .attr('href', templateConfig.icon);
745
+ }
746
+ if (templateConfig.label !== '') {
747
+ thisComponent
748
+ .append('text')
749
+ .attr('transform', `translate(${templateConfig.width / 2},${templateConfig.height / 2 + 5})`)
750
+ .attr('x', 0)
751
+ .attr('y', 0)
752
+ .attr('font-size', '20px')
753
+ .attr('text-anchor', 'middle')
754
+ .attr('font-family', "'Wonder Unit Sans', sans-serif")
755
+ .attr('font-weight', 400)
756
+ .attr('fill', '#000000')
757
+ .attr('stroke', 'none')
758
+ .style('font-kerning', 'none')
759
+ .style('user-select', 'none')
760
+ .text(templateConfig.label);
761
+ }
762
+ }
763
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PaletteComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
764
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: PaletteComponent, isStandalone: true, selector: "daga-palette", inputs: { palettes: "palettes", currentPalette: "currentPalette", currentCategory: "currentCategory", location: "location", direction: "direction", width: "width" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div #panel class=\"daga-panel daga-{{ location }} daga-{{ direction }}\">\r\n <daga-collapse-button\r\n #collapseButton\r\n [direction]=\"direction\"\r\n [collapsableSelector]=\"panel\"\r\n collapsableAdditionalSelector=\".daga-panel-content\"\r\n rule=\"display\"\r\n collapsedValue=\"none\"\r\n visibleValue=\"block\"\r\n />\r\n <div class=\"daga-panel-content\">\r\n <div *ngIf=\"palettes.length > 1\" class=\"daga-panel-tabs\">\r\n <div\r\n *ngFor=\"let palette of palettes\"\r\n class=\"daga-panel-tab\"\r\n [class]=\"palette === currentPalette ? 'daga-current-tab' : ''\"\r\n (click)=\"switchPalette(palette)\"\r\n >\r\n {{ palette.name }}\r\n </div>\r\n </div>\r\n <div class=\"daga-palette-view\"></div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
765
+ }
766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PaletteComponent, decorators: [{
767
+ type: Component,
768
+ args: [{ standalone: true, selector: 'daga-palette', imports: [CommonModule, CollapseButtonComponent], template: "<div #panel class=\"daga-panel daga-{{ location }} daga-{{ direction }}\">\r\n <daga-collapse-button\r\n #collapseButton\r\n [direction]=\"direction\"\r\n [collapsableSelector]=\"panel\"\r\n collapsableAdditionalSelector=\".daga-panel-content\"\r\n rule=\"display\"\r\n collapsedValue=\"none\"\r\n visibleValue=\"block\"\r\n />\r\n <div class=\"daga-panel-content\">\r\n <div *ngIf=\"palettes.length > 1\" class=\"daga-panel-tabs\">\r\n <div\r\n *ngFor=\"let palette of palettes\"\r\n class=\"daga-panel-tab\"\r\n [class]=\"palette === currentPalette ? 'daga-current-tab' : ''\"\r\n (click)=\"switchPalette(palette)\"\r\n >\r\n {{ palette.name }}\r\n </div>\r\n </div>\r\n <div class=\"daga-palette-view\"></div>\r\n </div>\r\n</div>\r\n" }]
769
+ }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { panel: [{
770
+ type: ViewChild,
771
+ args: ['panel']
772
+ }], palettes: [{
773
+ type: Input
774
+ }], currentPalette: [{
775
+ type: Input
776
+ }], currentCategory: [{
777
+ type: Input
778
+ }], location: [{
779
+ type: Input
780
+ }], direction: [{
781
+ type: Input
782
+ }], width: [{
783
+ type: Input
784
+ }] } });
785
+
786
+ /**
787
+ * Editor of the settings of a property editor, such as what properties are displayed and hidden and in what order.
788
+ * @private
789
+ * @see PropertyEditor
790
+ * @see ValueSet
791
+ */
792
+ class PropertySettingsComponent {
793
+ get canvas() {
794
+ return this.canvasProvider.getCanvas();
795
+ }
796
+ get valueSet() {
797
+ return this._valueSet;
798
+ }
799
+ set valueSet(valueSet) {
800
+ if (this._valueSet !== valueSet) {
801
+ this._valueSet = valueSet;
802
+ // force value change detection
803
+ this.cdr.detectChanges();
804
+ }
805
+ }
806
+ constructor(element, cdr, canvasProvider) {
807
+ this.element = element;
808
+ this.cdr = cdr;
809
+ this.canvasProvider = canvasProvider;
810
+ /** How many property-settings elements are parents of this property-settings element. @private */
811
+ this.depth = 0;
812
+ // Attributes for the template
813
+ this.Type = Type;
814
+ this.getStyleClassName = getStyleClassName;
815
+ this.asString = asString;
816
+ }
817
+ ngAfterViewInit() {
818
+ this.addListeners();
819
+ }
820
+ addListeners() {
821
+ for (const property of this.valueSet?.displayedProperties || []) {
822
+ let propertyElementWidth = 0;
823
+ let propertyElementHeight = 0;
824
+ let closestDropbarIndex = 0;
825
+ const propertyElement = d3
826
+ .select(this.element.nativeElement)
827
+ .select(`.daga-property.${getStyleClassName(property.name)}.daga-depth-${this.depth}`);
828
+ propertyElement.select('button.daga-move-button').call(d3
829
+ .drag()
830
+ .on(DragEvents.Start, (event) => {
831
+ setCursorStyle(CursorStyle.Grabbing);
832
+ const pointerCoords = this.canvas.getPointerLocationRelativeToScreen(event);
833
+ if (pointerCoords.length < 2 ||
834
+ isNaN(pointerCoords[0]) ||
835
+ isNaN(pointerCoords[1])) {
836
+ return;
837
+ }
838
+ const boundingRect = propertyElement
839
+ .node()
840
+ ?.getBoundingClientRect();
841
+ propertyElementWidth = boundingRect?.width || 0;
842
+ propertyElementHeight = boundingRect?.height || 0;
843
+ propertyElement
844
+ .style('position', 'fixed')
845
+ .style('left', `${pointerCoords[0] - propertyElementWidth / 2}px`)
846
+ .style('top', `${pointerCoords[1] - propertyElementHeight / 2}px`)
847
+ .style('width', `${propertyElementWidth}px`)
848
+ .style('height', `${propertyElementHeight}px`)
849
+ .style('z-index', 1);
850
+ })
851
+ .on(DragEvents.Drag, (event) => {
852
+ setCursorStyle(CursorStyle.Grabbing);
853
+ const pointerCoords = this.canvas.getPointerLocationRelativeToScreen(event);
854
+ if (pointerCoords.length < 2 ||
855
+ isNaN(pointerCoords[0]) ||
856
+ isNaN(pointerCoords[1])) {
857
+ return;
858
+ }
859
+ propertyElement
860
+ .style('position', 'fixed')
861
+ .style('left', `${pointerCoords[0] - propertyElementWidth / 2}px`)
862
+ .style('top', `${pointerCoords[1] - propertyElementHeight / 2}px`)
863
+ .style('width', `${propertyElementWidth}px`)
864
+ .style('height', `${propertyElementHeight}px`)
865
+ .style('z-index', 1);
866
+ d3.select(this.element.nativeElement)
867
+ .select(`.daga-dropbar.daga-index-${closestDropbarIndex}.daga-depth-${this.depth}`)
868
+ .style('visibility', 'hidden')
869
+ .style('height', 0);
870
+ closestDropbarIndex = this.getClosestDropbarIndex(pointerCoords);
871
+ d3.select(this.element.nativeElement)
872
+ .select(`.daga-dropbar.daga-index-${closestDropbarIndex}.daga-depth-${this.depth}`)
873
+ .style('visibility', 'visible')
874
+ .style('height', '0.25rem');
875
+ })
876
+ .on(DragEvents.End, (event) => {
877
+ setCursorStyle(CursorStyle.Auto);
878
+ propertyElement
879
+ .style('position', 'relative')
880
+ .style('left', 0)
881
+ .style('top', 0)
882
+ .style('z-index', 0)
883
+ .style('width', 'unset')
884
+ .style('height', 'unset');
885
+ d3.select(this.element.nativeElement)
886
+ .select(`.daga-dropbar.daga-index-${closestDropbarIndex}.daga-depth-${this.depth}`)
887
+ .style('visibility', 'hidden')
888
+ .style('height', 0);
889
+ const pointerCoords = this.canvas.getPointerLocationRelativeToScreen(event);
890
+ if (pointerCoords.length < 2 ||
891
+ isNaN(pointerCoords[0]) ||
892
+ isNaN(pointerCoords[1])) {
893
+ return;
894
+ }
895
+ closestDropbarIndex = this.getClosestDropbarIndex(pointerCoords);
896
+ this.valueSet?.displayedProperties?.splice(this.valueSet.displayedProperties.indexOf(property), 1);
897
+ this.valueSet?.displayedProperties?.splice(closestDropbarIndex, 0, property);
898
+ }));
899
+ }
900
+ }
901
+ getClosestDropbarIndex(pointerCoords) {
902
+ const propertyList = this.valueSet?.propertySet.propertyList || [];
903
+ // note that this is <= and not < as we are counting the index after the last element as well
904
+ const coordsList = [];
905
+ for (let i = 0; i <= propertyList.length; ++i) {
906
+ const boundingRect = d3
907
+ .select(this.element.nativeElement)
908
+ .select(`.daga-dropbar.daga-index-${i}.daga-depth-${this.depth}`)
909
+ .node()
910
+ ?.getBoundingClientRect();
911
+ if (boundingRect) {
912
+ coordsList.push([
913
+ boundingRect.x + boundingRect.width / 2,
914
+ boundingRect.y + boundingRect.height / 2
915
+ ]);
916
+ }
917
+ }
918
+ if (coordsList.length > 0) {
919
+ // euclidean distance
920
+ const distanceToDropbars = coordsList.map((p) => ((pointerCoords[0] - p[0]) ** 2 + (pointerCoords[1] - p[1]) ** 2) **
921
+ 0.5);
922
+ const indexOfClosestDropbar = distanceToDropbars.indexOf(Math.min(...distanceToDropbars));
923
+ return indexOfClosestDropbar;
924
+ }
925
+ return 0;
926
+ }
927
+ displayProperty(property) {
928
+ if (this.valueSet === undefined) {
929
+ return;
930
+ }
931
+ let selectedProperty;
932
+ if (property instanceof Property) {
933
+ selectedProperty = property;
934
+ }
935
+ else if (property instanceof Event) {
936
+ selectedProperty = this.valueSet?.propertySet.getProperty(property.target?.value || '');
937
+ }
938
+ else {
939
+ selectedProperty = this.valueSet?.propertySet.getProperty(property || '');
940
+ }
941
+ if (selectedProperty) {
942
+ this.valueSet.displayProperty(selectedProperty);
943
+ }
944
+ this.cdr.detectChanges();
945
+ this.addListeners();
946
+ }
947
+ hideProperty(property) {
948
+ if (this.valueSet === undefined) {
949
+ return;
950
+ }
951
+ let selectedProperty;
952
+ if (property instanceof Property) {
953
+ selectedProperty = property;
954
+ }
955
+ else if (property instanceof Event) {
956
+ selectedProperty = this.valueSet?.propertySet.getProperty(property.target?.value || '');
957
+ }
958
+ else {
959
+ selectedProperty = this.valueSet?.propertySet.getProperty(property || '');
960
+ }
961
+ if (selectedProperty) {
962
+ this.valueSet.hideProperty(selectedProperty);
963
+ }
964
+ this.cdr.detectChanges();
965
+ this.addListeners();
966
+ }
967
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PropertySettingsComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
968
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: PropertySettingsComponent, isStandalone: true, selector: "daga-property-settings", inputs: { valueSet: "valueSet", depth: "depth" }, ngImport: i0, template: "<div\r\n class=\"daga-dropbar\"\r\n [class]=\"'daga-index-' + 0 + ' daga-depth-' + depth\"\r\n></div>\r\n<div\r\n *ngFor=\"let property of valueSet?.displayedProperties || []; index as i\"\r\n class=\"daga-property-and-dropbar\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n>\r\n <div\r\n class=\"daga-property\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n >\r\n <div class=\"daga-property-name\">\r\n <span>{{ property.name }}</span>\r\n <div class=\"daga-buttons\">\r\n <button class=\"daga-property-button daga-move-button\">\r\n <div class=\"daga-icon daga-move-icon\"></div>\r\n </button>\r\n <button\r\n class=\"daga-property-button daga-hide-button\"\r\n (click)=\"hideProperty(property.name)\"\r\n >\r\n <div class=\"daga-icon daga-hide-icon\"></div>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"property.type !== Type.Object\" class=\"daga-property-value\">\r\n {{ asString(valueSet?.getValue(property.name)) }}\r\n </div>\r\n <div *ngIf=\"property.type === Type.Object\">\r\n <daga-property-settings\r\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\r\n [depth]=\"depth + 1\"\r\n ></daga-property-settings>\r\n </div>\r\n </div>\r\n <div\r\n class=\"daga-dropbar\"\r\n [class]=\"'daga-index-' + (i + 1) + ' daga-depth-' + depth\"\r\n ></div>\r\n</div>\r\n<div\r\n class=\"daga-property\"\r\n *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\"\r\n>\r\n <p class=\"daga-property-name\">Add property:</p>\r\n <select (change)=\"displayProperty($event)\">\r\n <option value=\"\">Select a property</option>\r\n <option\r\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\r\n [value]=\"property.name\"\r\n >\r\n {{ property.name }}\r\n </option>\r\n </select>\r\n</div>\r\n", dependencies: [{ kind: "component", type: PropertySettingsComponent, selector: "daga-property-settings", inputs: ["valueSet", "depth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }] }); }
969
+ }
970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PropertySettingsComponent, decorators: [{
971
+ type: Component,
972
+ args: [{ standalone: true, selector: 'daga-property-settings', imports: [CommonModule, FormsModule], template: "<div\r\n class=\"daga-dropbar\"\r\n [class]=\"'daga-index-' + 0 + ' daga-depth-' + depth\"\r\n></div>\r\n<div\r\n *ngFor=\"let property of valueSet?.displayedProperties || []; index as i\"\r\n class=\"daga-property-and-dropbar\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n>\r\n <div\r\n class=\"daga-property\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n >\r\n <div class=\"daga-property-name\">\r\n <span>{{ property.name }}</span>\r\n <div class=\"daga-buttons\">\r\n <button class=\"daga-property-button daga-move-button\">\r\n <div class=\"daga-icon daga-move-icon\"></div>\r\n </button>\r\n <button\r\n class=\"daga-property-button daga-hide-button\"\r\n (click)=\"hideProperty(property.name)\"\r\n >\r\n <div class=\"daga-icon daga-hide-icon\"></div>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"property.type !== Type.Object\" class=\"daga-property-value\">\r\n {{ asString(valueSet?.getValue(property.name)) }}\r\n </div>\r\n <div *ngIf=\"property.type === Type.Object\">\r\n <daga-property-settings\r\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\r\n [depth]=\"depth + 1\"\r\n ></daga-property-settings>\r\n </div>\r\n </div>\r\n <div\r\n class=\"daga-dropbar\"\r\n [class]=\"'daga-index-' + (i + 1) + ' daga-depth-' + depth\"\r\n ></div>\r\n</div>\r\n<div\r\n class=\"daga-property\"\r\n *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\"\r\n>\r\n <p class=\"daga-property-name\">Add property:</p>\r\n <select (change)=\"displayProperty($event)\">\r\n <option value=\"\">Select a property</option>\r\n <option\r\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\r\n [value]=\"property.name\"\r\n >\r\n {{ property.name }}\r\n </option>\r\n </select>\r\n</div>\r\n" }]
973
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: CanvasProviderService }], propDecorators: { valueSet: [{
974
+ type: Input
975
+ }], depth: [{
976
+ type: Input
977
+ }] } });
978
+ const asString = (value) => {
979
+ if (Array.isArray(value)) {
980
+ return value.join(', ');
981
+ }
982
+ if (isObject(value)) {
983
+ return Object.entries(value)
984
+ .map((pair) => pair.map((p) => JSON.stringify(p)).join(': '))
985
+ .join(', ');
986
+ }
987
+ if (value instanceof Date) {
988
+ return value.toLocaleString();
989
+ }
990
+ if (value === undefined || value === null) {
991
+ return '';
992
+ }
993
+ return '' + value;
994
+ };
995
+
996
+ const LOST_FOCUS_TIME_WINDOW_MS = 200;
997
+ /**
998
+ * Combobox with autocomplete.
999
+ * @private
1000
+ * @see PropertyEditor
1001
+ * @see ValueSet
1002
+ */
1003
+ class AutocompleteComponent {
1004
+ set value(value) {
1005
+ if (equals(value, this._value)) {
1006
+ return;
1007
+ }
1008
+ this._value = value;
1009
+ this.valueInput = this.getLabelOfValue(value);
1010
+ }
1011
+ get value() {
1012
+ return this._value;
1013
+ }
1014
+ constructor(cdr) {
1015
+ this.cdr = cdr;
1016
+ this.valueInput = '';
1017
+ this.disabled = false;
1018
+ this.showOptions = false;
1019
+ this.valueChange = new EventEmitter();
1020
+ }
1021
+ getLabelOfValue(value) {
1022
+ for (const option of this.options) {
1023
+ if (equals(option.key, value)) {
1024
+ return option.label;
1025
+ }
1026
+ }
1027
+ return asString(value);
1028
+ }
1029
+ onKeyup(event) {
1030
+ if (!this.disabled) {
1031
+ switch (event.key) {
1032
+ case Keys.PageDown:
1033
+ if (this.focusIndex === undefined) {
1034
+ this.focusOnOption(0);
1035
+ this.scrollToOption(0);
1036
+ }
1037
+ else {
1038
+ this.focusOnOption(this.focusIndex + 5);
1039
+ this.scrollToOption(this.focusIndex);
1040
+ }
1041
+ event.preventDefault();
1042
+ break;
1043
+ case Keys.ArrowDown:
1044
+ if (this.focusIndex === undefined) {
1045
+ this.focusOnOption(0);
1046
+ this.scrollToOption(0);
1047
+ }
1048
+ else {
1049
+ this.focusOnOption(this.focusIndex + 1);
1050
+ this.scrollToOption(this.focusIndex);
1051
+ }
1052
+ event.preventDefault();
1053
+ break;
1054
+ case Keys.PageUp:
1055
+ if (this.focusIndex === undefined) {
1056
+ this.focusOnOption(this.options.length - 1);
1057
+ this.scrollToOption(this.options.length - 1);
1058
+ }
1059
+ else {
1060
+ this.focusOnOption(this.focusIndex - 5);
1061
+ this.scrollToOption(this.focusIndex);
1062
+ }
1063
+ event.preventDefault();
1064
+ break;
1065
+ case Keys.ArrowUp:
1066
+ if (this.focusIndex === undefined) {
1067
+ this.focusOnOption(this.options.length - 1);
1068
+ this.scrollToOption(this.options.length - 1);
1069
+ }
1070
+ else {
1071
+ this.focusOnOption(this.focusIndex - 1);
1072
+ this.scrollToOption(this.focusIndex);
1073
+ }
1074
+ event.preventDefault();
1075
+ break;
1076
+ case Keys.Escape:
1077
+ this.closeOptions();
1078
+ event.preventDefault();
1079
+ break;
1080
+ case Keys.Enter:
1081
+ this.complete(this.options[this.focusIndex || 0]);
1082
+ event.preventDefault();
1083
+ break;
1084
+ default:
1085
+ this.openOptions();
1086
+ }
1087
+ }
1088
+ }
1089
+ openOptions() {
1090
+ if (!this.disabled) {
1091
+ const mustContain = normalizeString(this.valueInput.trim());
1092
+ this.currentOptions = [];
1093
+ this.currentLabelStarts = [];
1094
+ this.currentLabelMatches = [];
1095
+ this.currentLabelEnds = [];
1096
+ for (const option of this.options) {
1097
+ const normalizedLabel = normalizeString(option.label);
1098
+ const position = normalizedLabel.indexOf(mustContain);
1099
+ if (position >= 0) {
1100
+ const labelStart = option.label.substring(0, position);
1101
+ const labelMatch = option.label.substring(position, position + mustContain.length);
1102
+ const labelEnd = option.label.substring(position + mustContain.length);
1103
+ this.currentOptions.push(option);
1104
+ this.currentLabelStarts.push(labelStart);
1105
+ this.currentLabelMatches.push(labelMatch);
1106
+ this.currentLabelEnds.push(labelEnd);
1107
+ }
1108
+ }
1109
+ this.showOptions = true;
1110
+ }
1111
+ }
1112
+ closeOptions() {
1113
+ this.showOptions = false;
1114
+ }
1115
+ focusOnOption(index) {
1116
+ if (!this.disabled) {
1117
+ this.focusIndex = index;
1118
+ if (index === undefined) {
1119
+ return;
1120
+ }
1121
+ if (index < 0) {
1122
+ this.focusIndex = 0;
1123
+ }
1124
+ if (index >= this.options.length) {
1125
+ this.focusIndex = this.options.length - 1;
1126
+ }
1127
+ }
1128
+ }
1129
+ onLostFocus() {
1130
+ setTimeout(() => {
1131
+ this.closeOptions();
1132
+ }, LOST_FOCUS_TIME_WINDOW_MS);
1133
+ }
1134
+ scrollToOption(index) {
1135
+ const target = this.mainElement.nativeElement.querySelectorAll('li')[index];
1136
+ if (target) {
1137
+ target.scrollIntoView({ block: 'center' });
1138
+ }
1139
+ }
1140
+ clearInput() {
1141
+ if (!this.disabled) {
1142
+ this.value = undefined;
1143
+ this.valueInput = '';
1144
+ this.showOptions = false;
1145
+ this.focusIndex = undefined;
1146
+ }
1147
+ }
1148
+ complete(option) {
1149
+ if (!this.disabled) {
1150
+ this.value = option;
1151
+ this.valueInput = option.label;
1152
+ this.showOptions = false;
1153
+ this.focusIndex = undefined;
1154
+ this.valueChange.emit(option.key);
1155
+ }
1156
+ }
1157
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: AutocompleteComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1158
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: AutocompleteComponent, isStandalone: true, selector: "daga-autocomplete", inputs: { value: "value", valueInput: "valueInput", options: "options", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "mainElement", first: true, predicate: ["main"], descendants: true, static: true }], ngImport: i0, template: "<div\r\n #main\r\n class=\"daga-autocomplete\"\r\n [class]=\"showOptions ? 'daga-showing-options' : ''\"\r\n (blur)=\"closeOptions()\"\r\n>\r\n <div class=\"daga-autocomplete-input\">\r\n <input\r\n [(ngModel)]=\"valueInput\"\r\n [disabled]=\"disabled\"\r\n (keyup)=\"onKeyup($event)\"\r\n (focus)=\"openOptions()\"\r\n (blur)=\"onLostFocus()\"\r\n />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearInput()\"\r\n ></button>\r\n </div>\r\n <div class=\"daga-autocomplete-options\">\r\n <ul class=\"daga-autocomplete-option-list\">\r\n <li\r\n *ngIf=\"(currentOptions?.length || 0) === 0\"\r\n class=\"daga-autocomplete-option no-options\"\r\n >\r\n (No options)\r\n </li>\r\n <li\r\n *ngFor=\"let option of currentOptions; let index = index\"\r\n class=\"daga-autocomplete-option\"\r\n [class]=\"index === focusIndex ? 'daga-focused' : ''\"\r\n (mousemove)=\"focusOnOption(index)\"\r\n (click)=\"complete(option)\"\r\n >\r\n <span>{{ currentLabelStarts[index] }}</span>\r\n <span class=\"daga-match\">{{ currentLabelMatches[index] }}</span>\r\n <span>{{ currentLabelEnds[index] }}</span>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
1159
+ }
1160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: AutocompleteComponent, decorators: [{
1161
+ type: Component,
1162
+ args: [{ standalone: true, selector: 'daga-autocomplete', imports: [CommonModule, FormsModule], template: "<div\r\n #main\r\n class=\"daga-autocomplete\"\r\n [class]=\"showOptions ? 'daga-showing-options' : ''\"\r\n (blur)=\"closeOptions()\"\r\n>\r\n <div class=\"daga-autocomplete-input\">\r\n <input\r\n [(ngModel)]=\"valueInput\"\r\n [disabled]=\"disabled\"\r\n (keyup)=\"onKeyup($event)\"\r\n (focus)=\"openOptions()\"\r\n (blur)=\"onLostFocus()\"\r\n />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearInput()\"\r\n ></button>\r\n </div>\r\n <div class=\"daga-autocomplete-options\">\r\n <ul class=\"daga-autocomplete-option-list\">\r\n <li\r\n *ngIf=\"(currentOptions?.length || 0) === 0\"\r\n class=\"daga-autocomplete-option no-options\"\r\n >\r\n (No options)\r\n </li>\r\n <li\r\n *ngFor=\"let option of currentOptions; let index = index\"\r\n class=\"daga-autocomplete-option\"\r\n [class]=\"index === focusIndex ? 'daga-focused' : ''\"\r\n (mousemove)=\"focusOnOption(index)\"\r\n (click)=\"complete(option)\"\r\n >\r\n <span>{{ currentLabelStarts[index] }}</span>\r\n <span class=\"daga-match\">{{ currentLabelMatches[index] }}</span>\r\n <span>{{ currentLabelEnds[index] }}</span>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n" }]
1163
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { mainElement: [{
1164
+ type: ViewChild,
1165
+ args: ['main', { static: true }]
1166
+ }], value: [{
1167
+ type: Input
1168
+ }], valueInput: [{
1169
+ type: Input
1170
+ }], options: [{
1171
+ type: Input
1172
+ }], disabled: [{
1173
+ type: Input
1174
+ }], valueChange: [{
1175
+ type: Output
1176
+ }] } });
1177
+ const normalizeString = (a) => (a || '')
1178
+ .toLowerCase()
1179
+ .normalize('NFD')
1180
+ .replace(/[\u0300-\u036f]/g, '');
1181
+
1182
+ /**
1183
+ * Editor of a property of text list type within a property editor.
1184
+ * @private
1185
+ * @see Type.TextList
1186
+ * @see PropertyEditor
1187
+ * @see ValueSet
1188
+ */
1189
+ class OptionListEditorComponent {
1190
+ set value(value) {
1191
+ if (value === this._value) {
1192
+ return;
1193
+ }
1194
+ const initialAndEmpty = value.length === 0 && this._value.length === 0;
1195
+ this._value = value;
1196
+ this.labelsOfValue = [];
1197
+ for (const key of this._value) {
1198
+ this.labelsOfValue.push(this.getLabelOfValue(key));
1199
+ }
1200
+ if (initialAndEmpty) {
1201
+ this.valueChange.emit(this._value);
1202
+ }
1203
+ this.updateOptionsNotPresentInValue();
1204
+ }
1205
+ get value() {
1206
+ return this._value;
1207
+ }
1208
+ constructor(cdr) {
1209
+ this.cdr = cdr;
1210
+ this._value = [];
1211
+ this.labelsOfValue = [];
1212
+ this.options = [];
1213
+ this.valueInput = undefined;
1214
+ this.allowRepeats = true;
1215
+ this.optionsNotPresentInValue = [];
1216
+ this.disabled = false;
1217
+ this.valueChange = new EventEmitter();
1218
+ }
1219
+ getLabelOfValue(value) {
1220
+ for (const option of this.options) {
1221
+ if (option.key === value) {
1222
+ return option.label;
1223
+ }
1224
+ }
1225
+ return `${value}`;
1226
+ }
1227
+ hasValue(value) {
1228
+ for (const item of this._value || []) {
1229
+ if (item === value) {
1230
+ return true;
1231
+ }
1232
+ }
1233
+ return false;
1234
+ }
1235
+ removeFromValue(index) {
1236
+ if (this._value.length > index) {
1237
+ this._value.splice(index, 1);
1238
+ this.labelsOfValue.splice(index, 1);
1239
+ this.valueChange.emit(this._value);
1240
+ this.updateOptionsNotPresentInValue();
1241
+ this.cdr.detectChanges();
1242
+ }
1243
+ }
1244
+ addToValue() {
1245
+ if (this.valueInput !== undefined &&
1246
+ (this.allowRepeats ? true : !this.hasValue(this.valueInput))) {
1247
+ this._value.push(this.valueInput);
1248
+ this.labelsOfValue.push(this.getLabelOfValue(this.valueInput));
1249
+ this.valueChange.emit(this._value);
1250
+ this.clearInput();
1251
+ this.updateOptionsNotPresentInValue();
1252
+ this.cdr.detectChanges();
1253
+ }
1254
+ }
1255
+ clearInput() {
1256
+ this.valueInput = '';
1257
+ }
1258
+ updateOptionsNotPresentInValue() {
1259
+ if (!this.allowRepeats) {
1260
+ const optionsNotPresentInValue = [];
1261
+ for (const option of this.options) {
1262
+ if (!this.hasValue(option.key)) {
1263
+ optionsNotPresentInValue.push(option);
1264
+ }
1265
+ }
1266
+ this.optionsNotPresentInValue = optionsNotPresentInValue;
1267
+ }
1268
+ }
1269
+ onKeyUp(event) {
1270
+ if (event.key === 'Enter') {
1271
+ this.addToValue();
1272
+ }
1273
+ }
1274
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: OptionListEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1275
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: OptionListEditorComponent, isStandalone: true, selector: "daga-option-list-editor", inputs: { value: "value", options: "options", valueInput: "valueInput", allowRepeats: "allowRepeats", optionsNotPresentInValue: "optionsNotPresentInValue", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div\r\n *ngFor=\"let item of value; let index = index\"\r\n class=\"daga-value-item-element\"\r\n>\r\n <span class=\"daga-input\">{{ labelsOfValue[index] }}</span>\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(index)\"\r\n >\r\n <div class=\"daga-icon daga-close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <daga-autocomplete\r\n [disabled]=\"disabled\"\r\n [options]=\"allowRepeats ? options || [] : optionsNotPresentInValue || []\"\r\n [(value)]=\"valueInput\"\r\n />\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "component", type: AutocompleteComponent, selector: "daga-autocomplete", inputs: ["value", "valueInput", "options", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] }); }
1276
+ }
1277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: OptionListEditorComponent, decorators: [{
1278
+ type: Component,
1279
+ args: [{ standalone: true, selector: 'daga-option-list-editor', imports: [AutocompleteComponent, CommonModule, FormsModule], template: "<div\r\n *ngFor=\"let item of value; let index = index\"\r\n class=\"daga-value-item-element\"\r\n>\r\n <span class=\"daga-input\">{{ labelsOfValue[index] }}</span>\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(index)\"\r\n >\r\n <div class=\"daga-icon daga-close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <daga-autocomplete\r\n [disabled]=\"disabled\"\r\n [options]=\"allowRepeats ? options || [] : optionsNotPresentInValue || []\"\r\n [(value)]=\"valueInput\"\r\n />\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n" }]
1280
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
1281
+ type: Input
1282
+ }], options: [{
1283
+ type: Input
1284
+ }], valueInput: [{
1285
+ type: Input
1286
+ }], allowRepeats: [{
1287
+ type: Input
1288
+ }], optionsNotPresentInValue: [{
1289
+ type: Input
1290
+ }], disabled: [{
1291
+ type: Input
1292
+ }], valueChange: [{
1293
+ type: Output
1294
+ }] } });
1295
+
1296
+ /**
1297
+ * Editor of a property of text list type within a property editor.
1298
+ * @private
1299
+ * @see Type.TextList
1300
+ * @see PropertyEditor
1301
+ * @see ValueSet
1302
+ */
1303
+ class TextListEditorComponent {
1304
+ set value(value) {
1305
+ if (value === this._value) {
1306
+ return;
1307
+ }
1308
+ const initialAndEmpty = value.length === 0 && this._value.length === 0;
1309
+ this._value = value;
1310
+ if (initialAndEmpty) {
1311
+ this.valueChange.emit(this._value);
1312
+ }
1313
+ }
1314
+ get value() {
1315
+ return this._value;
1316
+ }
1317
+ constructor(cdr) {
1318
+ this.cdr = cdr;
1319
+ this._value = [];
1320
+ this.valueInput = '';
1321
+ this.allowRepeats = true;
1322
+ this.disabled = false;
1323
+ this.valueChange = new EventEmitter();
1324
+ }
1325
+ getValueFromEvent(event) {
1326
+ return event.target.value;
1327
+ }
1328
+ hasValue(value) {
1329
+ for (const item of this._value || []) {
1330
+ if (item === value) {
1331
+ return true;
1332
+ }
1333
+ }
1334
+ return false;
1335
+ }
1336
+ removeFromValue(index) {
1337
+ if (this._value.length > index) {
1338
+ this._value.splice(index, 1);
1339
+ this.valueChange.emit(this._value);
1340
+ this.cdr.detectChanges();
1341
+ }
1342
+ }
1343
+ editFromValue(item, index) {
1344
+ item = item.trim();
1345
+ if (this._value.length > index && item !== '') {
1346
+ this._value.splice(index, 1, item);
1347
+ this.valueChange.emit(this._value);
1348
+ this.cdr.detectChanges();
1349
+ }
1350
+ }
1351
+ addToValue() {
1352
+ const valueInput = this.valueInput.trim();
1353
+ if (valueInput !== '' &&
1354
+ (this.allowRepeats ? true : !this.hasValue(valueInput))) {
1355
+ this._value.push(valueInput);
1356
+ this.valueChange.emit(this._value);
1357
+ this.clearInput();
1358
+ this.cdr.detectChanges();
1359
+ }
1360
+ }
1361
+ clearInput() {
1362
+ this.valueInput = '';
1363
+ }
1364
+ onKeyUp(event) {
1365
+ if (event.key === 'Enter') {
1366
+ this.addToValue();
1367
+ }
1368
+ }
1369
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: TextListEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1370
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: TextListEditorComponent, isStandalone: true, selector: "daga-text-list-editor", inputs: { value: "value", valueInput: "valueInput", allowRepeats: "allowRepeats", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div\r\n *ngFor=\"let item of value; let index = index\"\r\n class=\"daga-value-item-element\"\r\n>\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item\"\r\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\r\n />\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(index)\"\r\n >\r\n <div class=\"icon close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"valueInput\" />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearInput()\"\r\n ></button>\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
1371
+ }
1372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: TextListEditorComponent, decorators: [{
1373
+ type: Component,
1374
+ args: [{ standalone: true, selector: 'daga-text-list-editor', imports: [CommonModule, FormsModule], template: "<div\r\n *ngFor=\"let item of value; let index = index\"\r\n class=\"daga-value-item-element\"\r\n>\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item\"\r\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\r\n />\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(index)\"\r\n >\r\n <div class=\"icon close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"valueInput\" />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearInput()\"\r\n ></button>\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n" }]
1375
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
1376
+ type: Input
1377
+ }], valueInput: [{
1378
+ type: Input
1379
+ }], allowRepeats: [{
1380
+ type: Input
1381
+ }], disabled: [{
1382
+ type: Input
1383
+ }], valueChange: [{
1384
+ type: Output
1385
+ }] } });
1386
+
1387
+ /**
1388
+ * Editor of a property of text map type within a property editor.
1389
+ * @private
1390
+ * @see Type.TextMap
1391
+ * @see PropertyEditor
1392
+ * @see ValueSet
1393
+ */
1394
+ class TextMapEditorComponent {
1395
+ set value(value) {
1396
+ if (value === this._value) {
1397
+ return;
1398
+ }
1399
+ const initialAndEmpty = Object.keys(value).length === 0 && Object.keys(this._value).length === 0;
1400
+ this._value = value;
1401
+ if (initialAndEmpty) {
1402
+ this.valueChange.emit(this._value);
1403
+ }
1404
+ }
1405
+ get value() {
1406
+ return this._value;
1407
+ }
1408
+ constructor(cdr) {
1409
+ this.cdr = cdr;
1410
+ this._value = {};
1411
+ this.keyInput = '';
1412
+ this.valueInput = '';
1413
+ this.disabled = false;
1414
+ this.valueChange = new EventEmitter();
1415
+ }
1416
+ getValueFromEvent(event) {
1417
+ return event.target.value;
1418
+ }
1419
+ removeFromValue(key) {
1420
+ delete this._value[key];
1421
+ this.cdr.detectChanges();
1422
+ }
1423
+ editKey(oldKey, newKey) {
1424
+ newKey = newKey.trim();
1425
+ if (oldKey !== newKey && newKey !== '') {
1426
+ this._value[newKey] = this._value[oldKey];
1427
+ delete this._value[oldKey];
1428
+ this.cdr.detectChanges();
1429
+ }
1430
+ }
1431
+ editValue(key, value) {
1432
+ value = value.trim();
1433
+ if (value !== '') {
1434
+ this._value[key] = value;
1435
+ this.cdr.detectChanges();
1436
+ }
1437
+ }
1438
+ addToValue() {
1439
+ const keyInput = this.keyInput.trim();
1440
+ const valueInput = this.valueInput.trim();
1441
+ if (keyInput !== '' && valueInput !== '') {
1442
+ this._value[keyInput] = valueInput;
1443
+ this.valueChange.emit(this._value);
1444
+ this.clearKeyInput();
1445
+ this.clearValueInput();
1446
+ this.cdr.detectChanges();
1447
+ }
1448
+ }
1449
+ clearKeyInput() {
1450
+ this.keyInput = '';
1451
+ }
1452
+ clearValueInput() {
1453
+ this.valueInput = '';
1454
+ }
1455
+ onKeyUp(event) {
1456
+ if (event.key === 'Enter') {
1457
+ this.addToValue();
1458
+ }
1459
+ }
1460
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: TextMapEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1461
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: TextMapEditorComponent, isStandalone: true, selector: "daga-text-map-editor", inputs: { value: "value", keyInput: "keyInput", valueInput: "valueInput", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div *ngFor=\"let item of value | keyvalue\" class=\"daga-value-item-element\">\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item.key\"\r\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\r\n />\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item.value\"\r\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\r\n />\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(item.key)\"\r\n >\r\n <div class=\"icon close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"keyInput\" />\r\n <button\r\n *ngIf=\"keyInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearKeyInput()\"\r\n ></button>\r\n </div>\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"valueInput\" />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearValueInput()\"\r\n ></button>\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
1462
+ }
1463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: TextMapEditorComponent, decorators: [{
1464
+ type: Component,
1465
+ args: [{ standalone: true, selector: 'daga-text-map-editor', imports: [CommonModule, FormsModule], template: "<div *ngFor=\"let item of value | keyvalue\" class=\"daga-value-item-element\">\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item.key\"\r\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\r\n />\r\n <input\r\n class=\"daga-input\"\r\n type=\"text\"\r\n [disabled]=\"disabled\"\r\n [value]=\"item.value\"\r\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\r\n />\r\n <button\r\n *ngIf=\"!disabled\"\r\n class=\"daga-property-button\"\r\n (click)=\"removeFromValue(item.key)\"\r\n >\r\n <div class=\"icon close-icon\"></div>\r\n </button>\r\n</div>\r\n<div *ngIf=\"!disabled\" class=\"daga-value-item-input\">\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"keyInput\" />\r\n <button\r\n *ngIf=\"keyInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearKeyInput()\"\r\n ></button>\r\n </div>\r\n <div class=\"daga-input daga-relatively-positioned\">\r\n <input type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"valueInput\" />\r\n <button\r\n *ngIf=\"valueInput !== ''\"\r\n class=\"daga-clear\"\r\n (click)=\"clearValueInput()\"\r\n ></button>\r\n </div>\r\n <button class=\"daga-property-button\" (click)=\"addToValue()\">\r\n <div class=\"daga-icon daga-add-icon\"></div>\r\n </button>\r\n</div>\r\n" }]
1466
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
1467
+ type: Input
1468
+ }], keyInput: [{
1469
+ type: Input
1470
+ }], valueInput: [{
1471
+ type: Input
1472
+ }], disabled: [{
1473
+ type: Input
1474
+ }], valueChange: [{
1475
+ type: Output
1476
+ }] } });
1477
+
1478
+ /**
1479
+ * Editor of a value set within a property editor.
1480
+ * @private
1481
+ * @see PropertyEditor
1482
+ * @see ValueSet
1483
+ */
1484
+ class ObjectEditorComponent {
1485
+ get canvas() {
1486
+ return this.canvasProvider.getCanvas();
1487
+ }
1488
+ get userCanEdit() {
1489
+ return (this.canvas.canUserPerformAction(DiagramActions.UpdateValues) &&
1490
+ this.valueSet?.rootElement?.['removed'] !== true);
1491
+ }
1492
+ get valueSet() {
1493
+ return this._valueSet;
1494
+ }
1495
+ set valueSet(valueSet) {
1496
+ if (this._valueSet !== valueSet) {
1497
+ this._valueSet = valueSet;
1498
+ // force value change detection
1499
+ this.cdr.detectChanges();
1500
+ }
1501
+ }
1502
+ constructor(cdr, canvasProvider) {
1503
+ this.cdr = cdr;
1504
+ this.canvasProvider = canvasProvider;
1505
+ /** How many object-editor elements are parents of this object-editor element. @private */
1506
+ this.depth = 0;
1507
+ // Attributes for the template
1508
+ this.Type = Type;
1509
+ this.getStyleClassName = getStyleClassName;
1510
+ }
1511
+ setValue(property, value) {
1512
+ if (this.valueSet === undefined) {
1513
+ return;
1514
+ }
1515
+ if (property.editable) {
1516
+ if (!equals(this.valueSet.getValue(property.name), value)) {
1517
+ this.valueSet.setValue(property.name, value);
1518
+ // register a diagram change when editing a value
1519
+ this.canvas.diagramChange$?.next();
1520
+ this.canvas.propertyEditorChanges$?.next();
1521
+ }
1522
+ }
1523
+ }
1524
+ dateToLocalDatetimeString(date) {
1525
+ if (typeof date === 'string') {
1526
+ return date;
1527
+ }
1528
+ if (date === null || date === undefined || isNaN(date.valueOf())) {
1529
+ return '';
1530
+ }
1531
+ const offsetDate = new Date(date);
1532
+ const timezoneOffset = offsetDate.getTimezoneOffset();
1533
+ offsetDate.setMinutes(offsetDate.getMinutes() - timezoneOffset);
1534
+ return offsetDate.toISOString().substring(0, 19); // for user friendliness, we trim off the milliseconds
1535
+ }
1536
+ localDatetimeStringToDate(string) {
1537
+ // with no timezone specified, the local time is assumed
1538
+ return new Date(string);
1539
+ }
1540
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: ObjectEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
1541
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: ObjectEditorComponent, isStandalone: true, selector: "daga-object-editor", inputs: { valueSet: "valueSet", depth: "depth" }, ngImport: i0, template: "<div\r\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\r\n class=\"daga-property\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n>\r\n <p class=\"daga-property-name\">\r\n {{ property.name }}\r\n </p>\r\n\r\n <input\r\n *ngIf=\"property.type === Type.Text\"\r\n type=\"daga-text\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <textarea\r\n *ngIf=\"property.type === Type.TextArea\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n ></textarea>\r\n <input\r\n *ngIf=\"property.type === Type.Number\"\r\n type=\"number\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Color\"\r\n type=\"text\"\r\n pattern=\"#\\d{6}\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Datetime\"\r\n type=\"datetime-local\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"dateToLocalDatetimeString(valueSet?.getValue(property.name))\"\r\n (ngModelChange)=\"setValue(property, localDatetimeStringToDate($event))\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Date\"\r\n type=\"date\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Time\"\r\n type=\"time\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Url\"\r\n type=\"url\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <div class=\"daga-radio\" *ngIf=\"property.type === Type.Boolean\">\r\n <label class=\"daga-radio-item daga-radio-start\">\r\n <input\r\n type=\"radio\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [name]=\"property.name\"\r\n value=\"false\"\r\n [checked]=\"valueSet?.getValue(property.name) === false\"\r\n (change)=\"setValue(property, false)\"\r\n />\r\n No\r\n </label>\r\n <label class=\"daga-radio-item daga-radio-end\">\r\n <input\r\n type=\"radio\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [name]=\"property.name\"\r\n value=\"true\"\r\n [checked]=\"valueSet?.getValue(property.name) === true\"\r\n (change)=\"setValue(property, true)\"\r\n />\r\n Yes\r\n </label>\r\n </div>\r\n <div class=\"daga-relatively-positioned\" *ngIf=\"property.type === Type.Option\">\r\n <daga-autocomplete\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [options]=\"property.options || []\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n />\r\n </div>\r\n <daga-option-list-editor\r\n *ngIf=\"\r\n property.type === Type.OptionList || property.type === Type.OptionSet\r\n \"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [allowRepeats]=\"property.type === Type.OptionList\"\r\n [options]=\"property.options || []\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-option-list-editor>\r\n <daga-text-list-editor\r\n *ngIf=\"property.type === Type.TextList || property.type === Type.TextSet\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [allowRepeats]=\"property.type === Type.TextList\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-text-list-editor>\r\n <daga-text-map-editor\r\n *ngIf=\"property.type === Type.TextMap\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-text-map-editor>\r\n <div *ngIf=\"property.type === Type.Object\" class=\"daga-left-bar\">\r\n <daga-object-editor\r\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\r\n [depth]=\"depth + 1\"\r\n ></daga-object-editor>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }, { kind: "component", type: AutocompleteComponent, selector: "daga-autocomplete", inputs: ["value", "valueInput", "options", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: OptionListEditorComponent, selector: "daga-option-list-editor", inputs: ["value", "options", "valueInput", "allowRepeats", "optionsNotPresentInValue", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TextListEditorComponent, selector: "daga-text-list-editor", inputs: ["value", "valueInput", "allowRepeats", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TextMapEditorComponent, selector: "daga-text-map-editor", inputs: ["value", "keyInput", "valueInput", "disabled"], outputs: ["valueChange"] }] }); }
1542
+ }
1543
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: ObjectEditorComponent, decorators: [{
1544
+ type: Component,
1545
+ args: [{ standalone: true, selector: 'daga-object-editor', imports: [
1546
+ AutocompleteComponent,
1547
+ CommonModule,
1548
+ FormsModule,
1549
+ OptionListEditorComponent,
1550
+ TextListEditorComponent,
1551
+ TextMapEditorComponent
1552
+ ], template: "<div\r\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\r\n class=\"daga-property\"\r\n [class]=\"getStyleClassName(property.name) + ' daga-depth-' + depth\"\r\n>\r\n <p class=\"daga-property-name\">\r\n {{ property.name }}\r\n </p>\r\n\r\n <input\r\n *ngIf=\"property.type === Type.Text\"\r\n type=\"daga-text\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <textarea\r\n *ngIf=\"property.type === Type.TextArea\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n ></textarea>\r\n <input\r\n *ngIf=\"property.type === Type.Number\"\r\n type=\"number\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Color\"\r\n type=\"text\"\r\n pattern=\"#\\d{6}\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Datetime\"\r\n type=\"datetime-local\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"dateToLocalDatetimeString(valueSet?.getValue(property.name))\"\r\n (ngModelChange)=\"setValue(property, localDatetimeStringToDate($event))\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Date\"\r\n type=\"date\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Time\"\r\n type=\"time\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <input\r\n *ngIf=\"property.type === Type.Url\"\r\n type=\"url\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [ngModel]=\"valueSet?.getValue(property.name)\"\r\n (ngModelChange)=\"setValue(property, $event)\"\r\n />\r\n <div class=\"daga-radio\" *ngIf=\"property.type === Type.Boolean\">\r\n <label class=\"daga-radio-item daga-radio-start\">\r\n <input\r\n type=\"radio\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [name]=\"property.name\"\r\n value=\"false\"\r\n [checked]=\"valueSet?.getValue(property.name) === false\"\r\n (change)=\"setValue(property, false)\"\r\n />\r\n No\r\n </label>\r\n <label class=\"daga-radio-item daga-radio-end\">\r\n <input\r\n type=\"radio\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [name]=\"property.name\"\r\n value=\"true\"\r\n [checked]=\"valueSet?.getValue(property.name) === true\"\r\n (change)=\"setValue(property, true)\"\r\n />\r\n Yes\r\n </label>\r\n </div>\r\n <div class=\"daga-relatively-positioned\" *ngIf=\"property.type === Type.Option\">\r\n <daga-autocomplete\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [options]=\"property.options || []\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n />\r\n </div>\r\n <daga-option-list-editor\r\n *ngIf=\"\r\n property.type === Type.OptionList || property.type === Type.OptionSet\r\n \"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [allowRepeats]=\"property.type === Type.OptionList\"\r\n [options]=\"property.options || []\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-option-list-editor>\r\n <daga-text-list-editor\r\n *ngIf=\"property.type === Type.TextList || property.type === Type.TextSet\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [allowRepeats]=\"property.type === Type.TextList\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-text-list-editor>\r\n <daga-text-map-editor\r\n *ngIf=\"property.type === Type.TextMap\"\r\n [disabled]=\"!property.editable || !userCanEdit\"\r\n [value]=\"valueSet?.getValue(property.name)\"\r\n (valueChange)=\"setValue(property, $event)\"\r\n ></daga-text-map-editor>\r\n <div *ngIf=\"property.type === Type.Object\" class=\"daga-left-bar\">\r\n <daga-object-editor\r\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\r\n [depth]=\"depth + 1\"\r\n ></daga-object-editor>\r\n </div>\r\n</div>\r\n" }]
1553
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: CanvasProviderService }], propDecorators: { valueSet: [{
1554
+ type: Input
1555
+ }], depth: [{
1556
+ type: Input
1557
+ }] } });
1558
+
1559
+ /**
1560
+ * Duration of the highlight property animation in milliseconds.
1561
+ */
1562
+ const HIGHLIGHT_ANIMATION_DURATION_MS = 1000;
1563
+ /**
1564
+ * Editor of the values of a value set.
1565
+ * @private
1566
+ * @see ValueSet
1567
+ */
1568
+ class PropertyEditorComponent {
1569
+ get valueSet() {
1570
+ return this._valueSet;
1571
+ }
1572
+ set valueSet(valueSet) {
1573
+ if (this._valueSet !== valueSet) {
1574
+ this._valueSet = valueSet;
1575
+ this.settings = undefined;
1576
+ // force value change detection
1577
+ this.cdr.detectChanges();
1578
+ }
1579
+ }
1580
+ constructor(cdr) {
1581
+ this.cdr = cdr;
1582
+ }
1583
+ ngAfterViewInit() {
1584
+ switch (this.direction) {
1585
+ case Side.Bottom:
1586
+ case Side.Top:
1587
+ this.selectPanel().style('width', this.width);
1588
+ break;
1589
+ case Side.Left:
1590
+ case Side.Right:
1591
+ this.selectPanel().style('height', this.width);
1592
+ break;
1593
+ }
1594
+ }
1595
+ selectPanel() {
1596
+ return d3.select(this.panel.nativeElement);
1597
+ }
1598
+ highlightProperty(...propertyNames) {
1599
+ let selector = '';
1600
+ let depth = 0;
1601
+ for (const propertyName of propertyNames) {
1602
+ selector += ` .daga-property.${getStyleClassName(propertyName)}.daga-depth-${depth}`;
1603
+ ++depth;
1604
+ }
1605
+ if (this.valueSet) {
1606
+ d3.select(this.panel.nativeElement)
1607
+ .select(selector)
1608
+ .transition()
1609
+ .duration(HIGHLIGHT_ANIMATION_DURATION_MS)
1610
+ .ease(d3.easeLinear)
1611
+ .styleTween('background-color', () => {
1612
+ const interpolator = d3.interpolate('rgba(255, 0, 0, 0)', 'rgba(255, 0, 0, 0.4)');
1613
+ return (t) => interpolator(t > 0.5 ? 1 - t : t);
1614
+ });
1615
+ }
1616
+ }
1617
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PropertyEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1618
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: PropertyEditorComponent, isStandalone: true, selector: "daga-property-editor", inputs: { location: "location", direction: "direction", width: "width", valueSet: "valueSet" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div\r\n #panel\r\n class=\"daga-panel daga-bottom daga-{{ location }} daga-{{ direction }}\"\r\n>\r\n <daga-collapse-button\r\n #collapse\r\n [disabled]=\"\r\n !valueSet ||\r\n !valueSet.propertySet ||\r\n !valueSet.propertySet.hasProperties()\r\n \"\r\n [direction]=\"direction\"\r\n [collapsableSelector]=\"panel\"\r\n collapsableAdditionalSelector=\".daga-panel-content\"\r\n rule=\"display\"\r\n collapsedValue=\"none\"\r\n visibleValue=\"block\"\r\n />\r\n <div\r\n *ngIf=\"\r\n valueSet &&\r\n valueSet.propertySet &&\r\n valueSet.propertySet.hasProperties() &&\r\n !collapse.collapsed\r\n \"\r\n class=\"daga-panel-content\"\r\n >\r\n <p *ngIf=\"title\" class=\"daga-title\">\r\n {{ title }}\r\n <button class=\"daga-property-button\" (click)=\"settings = !settings\">\r\n <div\r\n class=\"daga-icon daga-settings-icon\"\r\n [class]=\"\r\n settings === undefined\r\n ? ''\r\n : settings\r\n ? 'daga-unrotate'\r\n : 'daga-rotate'\r\n \"\r\n ></div>\r\n </button>\r\n </p>\r\n <daga-object-editor *ngIf=\"!settings\" [valueSet]=\"valueSet\" />\r\n <daga-property-settings *ngIf=\"settings\" [valueSet]=\"valueSet\" />\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }, { kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }, { kind: "component", type: PropertySettingsComponent, selector: "daga-property-settings", inputs: ["valueSet", "depth"] }] }); }
1619
+ }
1620
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: PropertyEditorComponent, decorators: [{
1621
+ type: Component,
1622
+ args: [{ standalone: true, selector: 'daga-property-editor', imports: [
1623
+ CommonModule,
1624
+ CollapseButtonComponent,
1625
+ ObjectEditorComponent,
1626
+ PropertySettingsComponent
1627
+ ], template: "<div\r\n #panel\r\n class=\"daga-panel daga-bottom daga-{{ location }} daga-{{ direction }}\"\r\n>\r\n <daga-collapse-button\r\n #collapse\r\n [disabled]=\"\r\n !valueSet ||\r\n !valueSet.propertySet ||\r\n !valueSet.propertySet.hasProperties()\r\n \"\r\n [direction]=\"direction\"\r\n [collapsableSelector]=\"panel\"\r\n collapsableAdditionalSelector=\".daga-panel-content\"\r\n rule=\"display\"\r\n collapsedValue=\"none\"\r\n visibleValue=\"block\"\r\n />\r\n <div\r\n *ngIf=\"\r\n valueSet &&\r\n valueSet.propertySet &&\r\n valueSet.propertySet.hasProperties() &&\r\n !collapse.collapsed\r\n \"\r\n class=\"daga-panel-content\"\r\n >\r\n <p *ngIf=\"title\" class=\"daga-title\">\r\n {{ title }}\r\n <button class=\"daga-property-button\" (click)=\"settings = !settings\">\r\n <div\r\n class=\"daga-icon daga-settings-icon\"\r\n [class]=\"\r\n settings === undefined\r\n ? ''\r\n : settings\r\n ? 'daga-unrotate'\r\n : 'daga-rotate'\r\n \"\r\n ></div>\r\n </button>\r\n </p>\r\n <daga-object-editor *ngIf=\"!settings\" [valueSet]=\"valueSet\" />\r\n <daga-property-settings *ngIf=\"settings\" [valueSet]=\"valueSet\" />\r\n </div>\r\n</div>\r\n" }]
1628
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { panel: [{
1629
+ type: ViewChild,
1630
+ args: ['panel']
1631
+ }], location: [{
1632
+ type: Input
1633
+ }], direction: [{
1634
+ type: Input
1635
+ }], width: [{
1636
+ type: Input
1637
+ }], valueSet: [{
1638
+ type: Input
1639
+ }] } });
1640
+ const getStyleClassName = (s) => {
1641
+ return 'daga-property-name-' + s.replace(/\s/g, '');
1642
+ };
1643
+
1644
+ /**
1645
+ * A provider for the {@link DiagramConfig} associated with a {@link DiagramComponent} context.
1646
+ * @public
1647
+ */
1648
+ class DagaConfigurationService {
1649
+ /**
1650
+ * Set the diagram configuration of this context.
1651
+ * @private
1652
+ * @param config A diagram configuration.
1653
+ */
1654
+ init(config) {
1655
+ this._config = config;
1656
+ }
1657
+ /**
1658
+ * Get the diagram configuration of this context. Should only be called after the {@link DiagramComponent} context has been initialized.
1659
+ * @public
1660
+ * @returns A diagram configuration.
1661
+ */
1662
+ getConfig() {
1663
+ return this._config;
1664
+ }
1665
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1666
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaConfigurationService }); }
1667
+ }
1668
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaConfigurationService, decorators: [{
1669
+ type: Injectable
1670
+ }] });
1671
+
1672
+ /**
1673
+ * A diagram's user interface editor.
1674
+ * @private
1675
+ */
1676
+ class DiagramEditorComponent {
1677
+ get config() {
1678
+ return this.configurationService.getConfig();
1679
+ }
1680
+ get canvas() {
1681
+ return this.canvasProvider.getCanvas();
1682
+ }
1683
+ constructor(configurationService, canvasProvider) {
1684
+ this.configurationService = configurationService;
1685
+ this.canvasProvider = canvasProvider;
1686
+ /**
1687
+ * Output for user events on the diagram's model.
1688
+ * @public
1689
+ */
1690
+ this.modelEvent = new EventEmitter();
1691
+ this.Corner = Corner;
1692
+ this.Side = Side;
1693
+ }
1694
+ ngOnInit() {
1695
+ this.canvasProvider.initCanvas(this, this.config);
1696
+ }
1697
+ ngAfterViewInit() {
1698
+ this.canvasProvider.initCanvasView(this.appendTo.nativeElement);
1699
+ this.canvas.diagramEvent$.subscribe((e) => {
1700
+ this.modelEvent.emit(e);
1701
+ });
1702
+ }
1703
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramEditorComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
1704
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: DiagramEditorComponent, isStandalone: true, selector: "daga-diagram-editor", outputs: { modelEvent: "modelEvent" }, viewQueries: [{ propertyName: "appendTo", first: true, predicate: ["appendTo"], descendants: true }, { propertyName: "diagramButtons", first: true, predicate: ["diagramButtons"], descendants: true }, { propertyName: "palette", first: true, predicate: ["palette"], descendants: true }, { propertyName: "propertyEditor", first: true, predicate: ["propertyEditor"], descendants: true }], ngImport: i0, template: "<div class=\"daga-append-to\" #appendTo></div>\r\n<daga-diagram-buttons\r\n *ngIf=\"\r\n config.components?.buttons !== undefined &&\r\n config.components?.buttons?.enabled !== false\r\n \"\r\n #diagramButtons\r\n [location]=\"config.components?.buttons?.location || Corner.BottomRight\"\r\n [direction]=\"config.components?.buttons?.direction || Side.Top\"\r\n [enableAction]=\"config.components?.buttons?.enableAction === true\"\r\n [enableFilter]=\"config.components?.buttons?.enableFilter === true\"\r\n [enableLayout]=\"config.components?.buttons?.enableLayout === true\"\r\n [enableSelection]=\"config.components?.buttons?.enableSelection === true\"\r\n [enableZoom]=\"config.components?.buttons?.enableZoom !== false\"\r\n/>\r\n<daga-palette\r\n *ngIf=\"\r\n config.components?.palette !== undefined &&\r\n config.components?.palette?.enabled !== false &&\r\n config.components?.palette?.sections &&\r\n (config.components?.palette?.sections?.length || 0) > 0\r\n \"\r\n #palette\r\n [location]=\"config.components?.palette?.location || Corner.TopLeft\"\r\n [direction]=\"config.components?.palette?.direction || Side.Bottom\"\r\n [width]=\"config.components?.palette?.width || '12rem'\"\r\n [palettes]=\"config.components?.palette?.sections || []\"\r\n/>\r\n<daga-property-editor\r\n *ngIf=\"\r\n config.components?.propertyEditor !== undefined &&\r\n config.components?.propertyEditor?.enabled !== false\r\n \"\r\n #propertyEditor\r\n [location]=\"config.components?.propertyEditor?.location || Corner.TopRight\"\r\n [direction]=\"config.components?.propertyEditor?.direction || Side.Bottom\"\r\n [width]=\"config.components?.propertyEditor?.width || '24rem'\"\r\n/>\r\n<daga-errors\r\n *ngIf=\"\r\n config.components?.errors !== undefined &&\r\n config.components?.errors?.enabled !== false\r\n \"\r\n/>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DiagramButtonsComponent, selector: "daga-diagram-buttons", inputs: ["location", "direction", "enableAction", "enableFilter", "enableLayout", "enableSelection", "enableZoom"] }, { kind: "component", type: PaletteComponent, selector: "daga-palette", inputs: ["palettes", "currentPalette", "currentCategory", "location", "direction", "width"] }, { kind: "component", type: PropertyEditorComponent, selector: "daga-property-editor", inputs: ["location", "direction", "width", "valueSet"] }, { kind: "component", type: ErrorsComponent, selector: "daga-errors" }] }); }
1705
+ }
1706
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramEditorComponent, decorators: [{
1707
+ type: Component,
1708
+ args: [{ standalone: true, selector: 'daga-diagram-editor', imports: [
1709
+ CommonModule,
1710
+ DiagramButtonsComponent,
1711
+ PaletteComponent,
1712
+ PropertyEditorComponent,
1713
+ ErrorsComponent
1714
+ ], template: "<div class=\"daga-append-to\" #appendTo></div>\r\n<daga-diagram-buttons\r\n *ngIf=\"\r\n config.components?.buttons !== undefined &&\r\n config.components?.buttons?.enabled !== false\r\n \"\r\n #diagramButtons\r\n [location]=\"config.components?.buttons?.location || Corner.BottomRight\"\r\n [direction]=\"config.components?.buttons?.direction || Side.Top\"\r\n [enableAction]=\"config.components?.buttons?.enableAction === true\"\r\n [enableFilter]=\"config.components?.buttons?.enableFilter === true\"\r\n [enableLayout]=\"config.components?.buttons?.enableLayout === true\"\r\n [enableSelection]=\"config.components?.buttons?.enableSelection === true\"\r\n [enableZoom]=\"config.components?.buttons?.enableZoom !== false\"\r\n/>\r\n<daga-palette\r\n *ngIf=\"\r\n config.components?.palette !== undefined &&\r\n config.components?.palette?.enabled !== false &&\r\n config.components?.palette?.sections &&\r\n (config.components?.palette?.sections?.length || 0) > 0\r\n \"\r\n #palette\r\n [location]=\"config.components?.palette?.location || Corner.TopLeft\"\r\n [direction]=\"config.components?.palette?.direction || Side.Bottom\"\r\n [width]=\"config.components?.palette?.width || '12rem'\"\r\n [palettes]=\"config.components?.palette?.sections || []\"\r\n/>\r\n<daga-property-editor\r\n *ngIf=\"\r\n config.components?.propertyEditor !== undefined &&\r\n config.components?.propertyEditor?.enabled !== false\r\n \"\r\n #propertyEditor\r\n [location]=\"config.components?.propertyEditor?.location || Corner.TopRight\"\r\n [direction]=\"config.components?.propertyEditor?.direction || Side.Bottom\"\r\n [width]=\"config.components?.propertyEditor?.width || '24rem'\"\r\n/>\r\n<daga-errors\r\n *ngIf=\"\r\n config.components?.errors !== undefined &&\r\n config.components?.errors?.enabled !== false\r\n \"\r\n/>\r\n" }]
1715
+ }], ctorParameters: () => [{ type: DagaConfigurationService }, { type: CanvasProviderService }], propDecorators: { appendTo: [{
1716
+ type: ViewChild,
1717
+ args: ['appendTo']
1718
+ }], diagramButtons: [{
1719
+ type: ViewChild,
1720
+ args: ['diagramButtons']
1721
+ }], palette: [{
1722
+ type: ViewChild,
1723
+ args: ['palette']
1724
+ }], propertyEditor: [{
1725
+ type: ViewChild,
1726
+ args: ['propertyEditor']
1727
+ }], modelEvent: [{
1728
+ type: Output
1729
+ }] } });
1730
+
1731
+ /**
1732
+ * The context of a diagram. Every separate diagram must be contained within its own {@link DiagramComponent} and every {@link DiagramComponent} must contain its own {@link DiagramEditorComponent}.
1733
+ * This component defines a {@link DagaConfigurationService} and a {@link CanvasProviderService}, which is shared by all the components within and allows accessing the configuration and the canvas of this component's diagram, respectively.
1734
+ * @public
1735
+ */
1736
+ class DiagramComponent {
1737
+ /**
1738
+ * Serialized model for the diagram. Used for data binding to the model.
1739
+ * @public
1740
+ */
1741
+ get model() {
1742
+ return this._model;
1743
+ }
1744
+ /**
1745
+ * Serialized model for the diagram. Used for data binding to the model.
1746
+ * @public
1747
+ */
1748
+ set model(model) {
1749
+ if (this._model !== model) {
1750
+ this._model = model;
1751
+ const canvas = this.canvasProvider.getCanvas();
1752
+ if (canvas) {
1753
+ this.importer.import(this.canvasProvider.getCanvas().model, model);
1754
+ }
1755
+ }
1756
+ }
1757
+ constructor(configurationService, canvasProvider) {
1758
+ this.configurationService = configurationService;
1759
+ this.canvasProvider = canvasProvider;
1760
+ this.importer = new DagaImporter();
1761
+ this.exporter = new DagaExporter();
1762
+ /**
1763
+ * Output for changes to the diagram's model.
1764
+ * @public
1765
+ */
1766
+ this.modelChange = new EventEmitter();
1767
+ }
1768
+ ngOnInit() {
1769
+ this.configurationService.init(this.config);
1770
+ }
1771
+ ngAfterContentInit() {
1772
+ this.canvasProvider
1773
+ .getCanvas()
1774
+ .viewInitialized$.pipe(delay(1))
1775
+ .subscribe(() => {
1776
+ if (this.model) {
1777
+ this.importer.import(this.canvasProvider.getCanvas().model, this.model);
1778
+ }
1779
+ });
1780
+ }
1781
+ ngAfterViewInit() {
1782
+ this.canvasProvider.getCanvas().diagramChange$.subscribe(() => {
1783
+ const exportedModel = this.exporter.export(this.canvasProvider.getCanvas().model);
1784
+ this._model = exportedModel;
1785
+ this.modelChange.emit(exportedModel);
1786
+ });
1787
+ }
1788
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
1789
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.2", type: DiagramComponent, isStandalone: true, selector: "daga-diagram", inputs: { config: "config", model: "model" }, outputs: { modelChange: "modelChange" }, providers: [CanvasProviderService, DagaConfigurationService], ngImport: i0, template: `<ng-content />`, isInline: true }); }
1790
+ }
1791
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DiagramComponent, decorators: [{
1792
+ type: Component,
1793
+ args: [{
1794
+ standalone: true,
1795
+ selector: 'daga-diagram',
1796
+ template: `<ng-content />`,
1797
+ providers: [CanvasProviderService, DagaConfigurationService]
1798
+ }]
1799
+ }], ctorParameters: () => [{ type: DagaConfigurationService }, { type: CanvasProviderService }], propDecorators: { config: [{
1800
+ type: Input
1801
+ }], model: [{
1802
+ type: Input
1803
+ }], modelChange: [{
1804
+ type: Output
1805
+ }] } });
1806
+
1807
+ class DagaModule {
1808
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1809
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.2", ngImport: i0, type: DagaModule, imports: [CollapseButtonComponent,
1810
+ DiagramButtonsComponent,
1811
+ DiagramComponent,
1812
+ DiagramEditorComponent,
1813
+ ErrorsComponent,
1814
+ ObjectEditorComponent,
1815
+ PaletteComponent,
1816
+ TextListEditorComponent,
1817
+ TextMapEditorComponent,
1818
+ PropertyEditorComponent,
1819
+ CommonModule,
1820
+ FormsModule], exports: [DiagramComponent, DiagramEditorComponent] }); }
1821
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaModule, providers: [DagaConfigurationService, CanvasProviderService], imports: [CollapseButtonComponent,
1822
+ DiagramButtonsComponent,
1823
+ DiagramEditorComponent,
1824
+ ErrorsComponent,
1825
+ ObjectEditorComponent,
1826
+ PaletteComponent,
1827
+ TextListEditorComponent,
1828
+ TextMapEditorComponent,
1829
+ PropertyEditorComponent,
1830
+ CommonModule,
1831
+ FormsModule] }); }
1832
+ }
1833
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.2", ngImport: i0, type: DagaModule, decorators: [{
1834
+ type: NgModule,
1835
+ args: [{
1836
+ declarations: [],
1837
+ imports: [
1838
+ CollapseButtonComponent,
1839
+ DiagramButtonsComponent,
1840
+ DiagramComponent,
1841
+ DiagramEditorComponent,
1842
+ ErrorsComponent,
1843
+ ObjectEditorComponent,
1844
+ PaletteComponent,
1845
+ TextListEditorComponent,
1846
+ TextMapEditorComponent,
1847
+ PropertyEditorComponent,
1848
+ CommonModule,
1849
+ FormsModule
1850
+ ],
1851
+ exports: [DiagramComponent, DiagramEditorComponent],
1852
+ providers: [DagaConfigurationService, CanvasProviderService]
1853
+ }]
1854
+ }] });
1855
+
1856
+ /**
1857
+ * Generated bundle index. Do not edit.
1858
+ */
1859
+
1860
+ export { CanvasProviderService, CollapseButtonComponent, DagaConfigurationService, DagaModule, DiagramButtonsComponent, DiagramComponent, DiagramEditorComponent, ErrorsComponent, ObjectEditorComponent, PaletteComponent, PropertyEditorComponent, TextListEditorComponent, TextMapEditorComponent };
1861
+ //# sourceMappingURL=metadev-daga-angular.mjs.map