ngx-vflow 1.0.1 → 1.0.4

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 (139) hide show
  1. package/README.md +10 -10
  2. package/esm2022/lib/vflow/components/background/background.component.mjs +6 -10
  3. package/esm2022/lib/vflow/components/connection/connection.component.mjs +8 -10
  4. package/esm2022/lib/vflow/components/custom-node-base/custom-node-base.component.mjs +2 -2
  5. package/esm2022/lib/vflow/components/default-node/default-node.component.mjs +4 -4
  6. package/esm2022/lib/vflow/components/defs/defs.component.mjs +3 -3
  7. package/esm2022/lib/vflow/components/edge/edge.component.mjs +3 -3
  8. package/esm2022/lib/vflow/components/edge-label/edge-label.component.mjs +5 -7
  9. package/esm2022/lib/vflow/components/node/node.component.mjs +8 -8
  10. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +5 -8
  11. package/esm2022/lib/vflow/decorators/microtask.decorator.mjs +1 -1
  12. package/esm2022/lib/vflow/decorators/run-in-injection-context.decorator.mjs +2 -2
  13. package/esm2022/lib/vflow/directives/changes-controller.directive.mjs +64 -22
  14. package/esm2022/lib/vflow/directives/connection-controller.directive.mjs +6 -3
  15. package/esm2022/lib/vflow/directives/drag-handle.directive.mjs +3 -3
  16. package/esm2022/lib/vflow/directives/flow-size-controller.directive.mjs +6 -4
  17. package/esm2022/lib/vflow/directives/handle-size-controller.directive.mjs +2 -2
  18. package/esm2022/lib/vflow/directives/map-context.directive.mjs +16 -14
  19. package/esm2022/lib/vflow/directives/pointer.directive.mjs +2 -2
  20. package/esm2022/lib/vflow/directives/reference.directive.mjs +1 -1
  21. package/esm2022/lib/vflow/directives/root-pointer.directive.mjs +7 -11
  22. package/esm2022/lib/vflow/directives/root-svg-context.directive.mjs +1 -1
  23. package/esm2022/lib/vflow/directives/selectable.directive.mjs +1 -1
  24. package/esm2022/lib/vflow/directives/space-point-context.directive.mjs +2 -2
  25. package/esm2022/lib/vflow/directives/template.directive.mjs +6 -6
  26. package/esm2022/lib/vflow/interfaces/box.mjs +1 -1
  27. package/esm2022/lib/vflow/interfaces/component-node-event.interface.mjs +1 -1
  28. package/esm2022/lib/vflow/interfaces/connection-settings.interface.mjs +1 -1
  29. package/esm2022/lib/vflow/interfaces/connection.interface.mjs +1 -1
  30. package/esm2022/lib/vflow/interfaces/connection.internal.interface.mjs +1 -1
  31. package/esm2022/lib/vflow/interfaces/edge-label.interface.mjs +1 -1
  32. package/esm2022/lib/vflow/interfaces/edge.interface.mjs +1 -1
  33. package/esm2022/lib/vflow/interfaces/fit-view-options.interface.mjs +1 -1
  34. package/esm2022/lib/vflow/interfaces/flow-entity.interface.mjs +1 -1
  35. package/esm2022/lib/vflow/interfaces/marker.interface.mjs +1 -1
  36. package/esm2022/lib/vflow/interfaces/node.interface.mjs +5 -5
  37. package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +1 -1
  38. package/esm2022/lib/vflow/interfaces/path-data.interface.mjs +1 -1
  39. package/esm2022/lib/vflow/interfaces/point.interface.mjs +1 -1
  40. package/esm2022/lib/vflow/interfaces/rect.mjs +1 -1
  41. package/esm2022/lib/vflow/interfaces/template-context.interface.mjs +1 -1
  42. package/esm2022/lib/vflow/interfaces/viewport.interface.mjs +1 -1
  43. package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +4 -10
  44. package/esm2022/lib/vflow/math/edge-path/smooth-step-path.mjs +3 -3
  45. package/esm2022/lib/vflow/math/edge-path/straigh-path.mjs +6 -6
  46. package/esm2022/lib/vflow/math/point-on-line-by-ratio.mjs +1 -1
  47. package/esm2022/lib/vflow/models/connection.model.mjs +1 -1
  48. package/esm2022/lib/vflow/models/edge-label.model.mjs +2 -2
  49. package/esm2022/lib/vflow/models/edge.model.mjs +25 -25
  50. package/esm2022/lib/vflow/models/handle.model.mjs +41 -37
  51. package/esm2022/lib/vflow/models/minimap.model.mjs +2 -2
  52. package/esm2022/lib/vflow/models/node.model.mjs +9 -14
  53. package/esm2022/lib/vflow/models/toolbar.model.mjs +6 -6
  54. package/esm2022/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.mjs +3 -3
  55. package/esm2022/lib/vflow/public-components/custom-node/custom-node.component.mjs +3 -3
  56. package/esm2022/lib/vflow/public-components/handle/handle.component.mjs +2 -2
  57. package/esm2022/lib/vflow/public-components/minimap/minimap.component.mjs +8 -16
  58. package/esm2022/lib/vflow/public-components/node-toolbar/node-toolbar.component.mjs +3 -3
  59. package/esm2022/lib/vflow/public-components/resizable/resizable.component.mjs +11 -17
  60. package/esm2022/lib/vflow/services/component-event-bus.service.mjs +1 -1
  61. package/esm2022/lib/vflow/services/draggable.service.mjs +10 -12
  62. package/esm2022/lib/vflow/services/edge-changes.service.mjs +14 -20
  63. package/esm2022/lib/vflow/services/flow-entities.service.mjs +7 -10
  64. package/esm2022/lib/vflow/services/flow-settings.service.mjs +1 -1
  65. package/esm2022/lib/vflow/services/flow-status.service.mjs +2 -2
  66. package/esm2022/lib/vflow/services/handle.service.mjs +3 -3
  67. package/esm2022/lib/vflow/services/keyboard.service.mjs +8 -6
  68. package/esm2022/lib/vflow/services/node-accessor.service.mjs +1 -1
  69. package/esm2022/lib/vflow/services/node-changes.service.mjs +13 -21
  70. package/esm2022/lib/vflow/services/node-rendering.service.mjs +6 -7
  71. package/esm2022/lib/vflow/services/overlays.service.mjs +2 -2
  72. package/esm2022/lib/vflow/services/selection.service.mjs +6 -4
  73. package/esm2022/lib/vflow/services/viewport.service.mjs +13 -11
  74. package/esm2022/lib/vflow/testing-utils/provide-custom-node-mocks.mjs +25 -25
  75. package/esm2022/lib/vflow/types/background.type.mjs +1 -1
  76. package/esm2022/lib/vflow/types/connection-mode.type.mjs +1 -1
  77. package/esm2022/lib/vflow/types/edge-change.type.mjs +1 -1
  78. package/esm2022/lib/vflow/types/handle-type.type.mjs +1 -1
  79. package/esm2022/lib/vflow/types/keyboard-action.type.mjs +1 -1
  80. package/esm2022/lib/vflow/types/node-change.type.mjs +1 -1
  81. package/esm2022/lib/vflow/types/position.type.mjs +1 -1
  82. package/esm2022/lib/vflow/types/using-points.type.mjs +1 -1
  83. package/esm2022/lib/vflow/types/viewport-change-type.type.mjs +1 -1
  84. package/esm2022/lib/vflow/utils/add-nodes-to-edges.mjs +2 -2
  85. package/esm2022/lib/vflow/utils/adjust-direction.mjs +1 -1
  86. package/esm2022/lib/vflow/utils/get-os.mjs +6 -6
  87. package/esm2022/lib/vflow/utils/hash.mjs +2 -2
  88. package/esm2022/lib/vflow/utils/id.mjs +1 -1
  89. package/esm2022/lib/vflow/utils/is-defined.mjs +1 -1
  90. package/esm2022/lib/vflow/utils/is-group-node.mjs +1 -1
  91. package/esm2022/lib/vflow/utils/nodes.mjs +2 -2
  92. package/esm2022/lib/vflow/utils/reference-keeper.mjs +7 -7
  93. package/esm2022/lib/vflow/utils/resizable.mjs +4 -4
  94. package/esm2022/lib/vflow/utils/round.mjs +1 -1
  95. package/esm2022/lib/vflow/utils/transform-background.mjs +2 -4
  96. package/esm2022/lib/vflow/utils/viewport.mjs +1 -1
  97. package/esm2022/lib/vflow/vflow.mjs +10 -10
  98. package/esm2022/public-api.mjs +1 -1
  99. package/fesm2022/ngx-vflow.mjs +320 -322
  100. package/fesm2022/ngx-vflow.mjs.map +1 -1
  101. package/lib/vflow/components/node/node.component.d.ts +1 -1
  102. package/lib/vflow/components/vflow/vflow.component.d.ts +1 -1
  103. package/lib/vflow/decorators/run-in-injection-context.decorator.d.ts +1 -1
  104. package/lib/vflow/directives/changes-controller.directive.d.ts +29 -29
  105. package/lib/vflow/directives/connection-controller.directive.d.ts +4 -2
  106. package/lib/vflow/directives/pointer.directive.d.ts +4 -4
  107. package/lib/vflow/interfaces/component-node-event.interface.d.ts +5 -5
  108. package/lib/vflow/interfaces/connection-settings.interface.d.ts +4 -4
  109. package/lib/vflow/interfaces/connection.internal.interface.d.ts +2 -2
  110. package/lib/vflow/interfaces/edge.interface.d.ts +3 -3
  111. package/lib/vflow/interfaces/flow-entity.interface.d.ts +1 -1
  112. package/lib/vflow/interfaces/node.interface.d.ts +4 -4
  113. package/lib/vflow/interfaces/path-data.interface.d.ts +2 -2
  114. package/lib/vflow/interfaces/template-context.interface.d.ts +2 -2
  115. package/lib/vflow/interfaces/viewport.interface.d.ts +2 -2
  116. package/lib/vflow/math/edge-path/straigh-path.d.ts +3 -3
  117. package/lib/vflow/math/point-on-line-by-ratio.d.ts +1 -1
  118. package/lib/vflow/models/connection.model.d.ts +3 -3
  119. package/lib/vflow/models/edge-label.model.d.ts +1 -1
  120. package/lib/vflow/models/edge.model.d.ts +8 -9
  121. package/lib/vflow/models/handle.model.d.ts +2 -2
  122. package/lib/vflow/models/minimap.model.d.ts +1 -1
  123. package/lib/vflow/models/toolbar.model.d.ts +3 -3
  124. package/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.d.ts +2 -2
  125. package/lib/vflow/public-components/custom-node/custom-node.component.d.ts +2 -2
  126. package/lib/vflow/services/flow-status.service.d.ts +1 -1
  127. package/lib/vflow/testing-utils/provide-custom-node-mocks.d.ts +1 -1
  128. package/lib/vflow/types/node-change.type.d.ts +1 -1
  129. package/lib/vflow/types/viewport-change-type.type.d.ts +1 -3
  130. package/lib/vflow/utils/add-nodes-to-edges.d.ts +2 -2
  131. package/lib/vflow/utils/adjust-direction.d.ts +1 -1
  132. package/lib/vflow/utils/is-group-node.d.ts +1 -1
  133. package/lib/vflow/utils/nodes.d.ts +2 -2
  134. package/lib/vflow/utils/reference-keeper.d.ts +3 -3
  135. package/lib/vflow/utils/resizable.d.ts +2 -2
  136. package/lib/vflow/utils/transform-background.d.ts +1 -1
  137. package/lib/vflow/utils/viewport.d.ts +2 -2
  138. package/lib/vflow/vflow.d.ts +8 -8
  139. package/package.json +2 -2
@@ -13,7 +13,7 @@ function getNodesBounds(nodes) {
13
13
  return { x: 0, y: 0, width: 0, height: 0 };
14
14
  }
15
15
  let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
16
- nodes.forEach(node => {
16
+ nodes.forEach((node) => {
17
17
  const nodeBox = nodeToBox(node);
18
18
  box = getBoundsOfBoxes(box, nodeBox);
19
19
  });
@@ -77,7 +77,7 @@ const hasSourceAndTargetHandleValidator = (connection) => {
77
77
 
78
78
  function hashCode(str) {
79
79
  return str.split('').reduce((a, b) => {
80
- a = ((a << 5) - a) + b.charCodeAt(0);
80
+ a = (a << 5) - a + b.charCodeAt(0);
81
81
  return a & a;
82
82
  }, 0);
83
83
  }
@@ -86,20 +86,20 @@ class FlowEntitiesService {
86
86
  constructor() {
87
87
  this.nodes = signal([], {
88
88
  // empty arrays considered equal, other arrays may not be equal
89
- equal: (a, b) => !a.length && !b.length ? true : a === b
89
+ equal: (a, b) => (!a.length && !b.length ? true : a === b),
90
90
  });
91
91
  this.edges = signal([], {
92
92
  // empty arrays considered equal, other arrays may not be equal
93
- equal: (a, b) => !a.length && !b.length ? true : a === b
93
+ equal: (a, b) => (!a.length && !b.length ? true : a === b),
94
94
  });
95
95
  this.validEdges = computed(() => {
96
96
  const nodes = this.nodes();
97
- return this.edges().filter(e => nodes.includes(e.source()) && nodes.includes(e.target()));
97
+ return this.edges().filter((e) => nodes.includes(e.source()) && nodes.includes(e.target()));
98
98
  });
99
99
  this.connection = signal(new ConnectionModel({}));
100
100
  this.markers = computed(() => {
101
101
  const markersMap = new Map();
102
- this.validEdges().forEach(e => {
102
+ this.validEdges().forEach((e) => {
103
103
  if (e.edge.markers?.start) {
104
104
  const hash = hashCode(JSON.stringify(e.edge.markers.start));
105
105
  markersMap.set(hash, e.edge.markers.start);
@@ -116,17 +116,14 @@ class FlowEntitiesService {
116
116
  }
117
117
  return markersMap;
118
118
  });
119
- this.entities = computed(() => [
120
- ...this.nodes(),
121
- ...this.edges()
122
- ]);
119
+ this.entities = computed(() => [...this.nodes(), ...this.edges()]);
123
120
  this.minimap = signal(null);
124
121
  }
125
122
  getNode(id) {
126
123
  return this.nodes().find(({ node }) => node.id === id);
127
124
  }
128
125
  getDetachedEdges() {
129
- return this.edges().filter(e => e.detached());
126
+ return this.edges().filter((e) => e.detached());
130
127
  }
131
128
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
132
129
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService }); }
@@ -187,7 +184,7 @@ class ViewportService {
187
184
  this.writableViewport = signal({
188
185
  changeType: 'initial',
189
186
  state: ViewportService.getDefaultViewport(),
190
- duration: 0
187
+ duration: 0,
191
188
  });
192
189
  /**
193
190
  * Public signal with viewport state. User can directly read from this signal. It's updated by:
@@ -201,22 +198,24 @@ class ViewportService {
201
198
  *
202
199
  * @returns default viewport value
203
200
  */
204
- static getDefaultViewport() { return { zoom: 1, x: 0, y: 0 }; }
201
+ static getDefaultViewport() {
202
+ return { zoom: 1, x: 0, y: 0 };
203
+ }
205
204
  // TODO: add writableViewportWithConstraints (to apply min zoom/max zoom values)
206
- fitView(options = { padding: .1, duration: 0, nodes: [] }) {
205
+ fitView(options = { padding: 0.1, duration: 0, nodes: [] }) {
207
206
  const nodes = this.getBoundsNodes(options.nodes ?? []);
208
- const state = getViewportForBounds(getNodesBounds(nodes), this.flowSettingsService.computedFlowWidth(), this.flowSettingsService.computedFlowHeight(), this.flowSettingsService.minZoom(), this.flowSettingsService.maxZoom(), options.padding ?? .1);
207
+ const state = getViewportForBounds(getNodesBounds(nodes), this.flowSettingsService.computedFlowWidth(), this.flowSettingsService.computedFlowHeight(), this.flowSettingsService.minZoom(), this.flowSettingsService.maxZoom(), options.padding ?? 0.1);
209
208
  const duration = options.duration ?? 0;
210
209
  this.writableViewport.set({ changeType: 'absolute', state, duration });
211
210
  }
212
211
  getBoundsNodes(nodeIds) {
213
212
  return !nodeIds?.length
214
- // If nodes option not passed or the list is empty, then get fit the whole view
215
- ? this.entitiesService.nodes()
216
- // Otherwise fit to specific nodes
217
- : nodeIds
218
- .map(nodeId => this.entitiesService.nodes().find(({ node }) => node.id === nodeId))
219
- .filter((node) => !!node);
213
+ ? // If nodes option not passed or the list is empty, then get fit the whole view
214
+ this.entitiesService.nodes()
215
+ : // Otherwise fit to specific nodes
216
+ nodeIds
217
+ .map((nodeId) => this.entitiesService.nodes().find(({ node }) => node.id === nodeId))
218
+ .filter((node) => !!node);
220
219
  }
221
220
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
222
221
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService }); }
@@ -251,19 +250,19 @@ function getOS() {
251
250
  const iosPlatforms = /(iphone|ipad|ipod)/i;
252
251
  let os = null;
253
252
  if (macosPlatforms.test(userAgent)) {
254
- os = "macos";
253
+ os = 'macos';
255
254
  }
256
255
  else if (iosPlatforms.test(userAgent)) {
257
- os = "ios";
256
+ os = 'ios';
258
257
  }
259
258
  else if (windowsPlatforms.test(userAgent)) {
260
- os = "windows";
259
+ os = 'windows';
261
260
  }
262
261
  else if (/android/.test(userAgent)) {
263
- os = "android";
262
+ os = 'android';
264
263
  }
265
264
  else if (!os && /linux/.test(userAgent)) {
266
- os = "linux";
265
+ os = 'linux';
267
266
  }
268
267
  return os;
269
268
  }
@@ -274,26 +273,28 @@ class KeyboardService {
274
273
  multiSelection: [
275
274
  getOS() === 'macos' ? 'MetaLeft' : 'ControlLeft',
276
275
  getOS() === 'macos' ? 'MetaRight' : 'ControlRight',
277
- ]
276
+ ],
278
277
  });
279
278
  this.actionsActive = {
280
- multiSelection: false
279
+ multiSelection: false,
281
280
  };
282
- toObservable(this.actions).pipe(switchMap(() => merge(fromEvent(document, 'keydown').pipe(tap(event => {
281
+ toObservable(this.actions)
282
+ .pipe(switchMap(() => merge(fromEvent(document, 'keydown').pipe(tap((event) => {
283
283
  for (const action in this.actions()) {
284
284
  const keyCodes = this.actions()[action] ?? [];
285
285
  if (keyCodes.includes(event.code)) {
286
286
  this.actionsActive[action] = true;
287
287
  }
288
288
  }
289
- })), fromEvent(document, 'keyup').pipe(tap(event => {
289
+ })), fromEvent(document, 'keyup').pipe(tap((event) => {
290
290
  for (const action in this.actions()) {
291
291
  const keyCodes = this.actions()[action] ?? [];
292
292
  if (keyCodes.includes(event.code)) {
293
293
  this.actionsActive[action] = false;
294
294
  }
295
295
  }
296
- })))), takeUntilDestroyed()).subscribe();
296
+ })))), takeUntilDestroyed())
297
+ .subscribe();
297
298
  }
298
299
  setShortcuts(newActions) {
299
300
  this.actions.update((actions) => ({ ...actions, ...newActions }));
@@ -313,7 +314,8 @@ class SelectionService {
313
314
  this.flowEntitiesService = inject(FlowEntitiesService);
314
315
  this.keyboardService = inject(KeyboardService);
315
316
  this.viewport$ = new Subject();
316
- this.resetSelection = this.viewport$.pipe(tap(({ start, end, target }) => {
317
+ this.resetSelection = this.viewport$
318
+ .pipe(tap(({ start, end, target }) => {
317
319
  if (start && end && target) {
318
320
  const delta = SelectionService.delta;
319
321
  const diffX = Math.abs(end.x - start.x);
@@ -326,7 +328,8 @@ class SelectionService {
326
328
  this.select(null);
327
329
  }
328
330
  }
329
- }), takeUntilDestroyed()).subscribe();
331
+ }), takeUntilDestroyed())
332
+ .subscribe();
330
333
  }
331
334
  static { this.delta = 6; }
332
335
  setViewport(viewport) {
@@ -340,7 +343,7 @@ class SelectionService {
340
343
  }
341
344
  if (!this.keyboardService.isActiveAction('multiSelection')) {
342
345
  // undo select for previously selected nodes
343
- this.flowEntitiesService.entities().forEach(n => n.selected.set(false));
346
+ this.flowEntitiesService.entities().forEach((n) => n.selected.set(false));
344
347
  }
345
348
  if (entity) {
346
349
  // select passed entity
@@ -372,25 +375,25 @@ class MapContextDirective {
372
375
  return;
373
376
  }
374
377
  // If only zoom provided
375
- if (isDefined(state.zoom) && (!isDefined(state.x) && !isDefined(state.y))) {
376
- this.rootSvgSelection
377
- .transition().duration(viewport.duration)
378
- .call(this.zoomBehavior.scaleTo, state.zoom);
378
+ if (isDefined(state.zoom) && !isDefined(state.x) && !isDefined(state.y)) {
379
+ this.rootSvgSelection.transition().duration(viewport.duration).call(this.zoomBehavior.scaleTo, state.zoom);
379
380
  return;
380
381
  }
381
382
  // If only pan provided
382
- if ((isDefined(state.x) && isDefined(state.y)) && !isDefined(state.zoom)) {
383
+ if (isDefined(state.x) && isDefined(state.y) && !isDefined(state.zoom)) {
383
384
  // remain same zoom value
384
385
  const zoom = untracked(this.viewportService.readableViewport).zoom;
385
386
  this.rootSvgSelection
386
- .transition().duration(viewport.duration)
387
+ .transition()
388
+ .duration(viewport.duration)
387
389
  .call(this.zoomBehavior.transform, zoomIdentity.translate(state.x, state.y).scale(zoom));
388
390
  return;
389
391
  }
390
392
  // If whole viewort state provided
391
393
  if (isDefined(state.x) && isDefined(state.y) && isDefined(state.zoom)) {
392
394
  this.rootSvgSelection
393
- .transition().duration(viewport.duration)
395
+ .transition()
396
+ .duration(viewport.duration)
394
397
  .call(this.zoomBehavior.transform, zoomIdentity.translate(state.x, state.y).scale(state.zoom));
395
398
  return;
396
399
  }
@@ -402,14 +405,14 @@ class MapContextDirective {
402
405
  };
403
406
  this.handleZoomStart = ({ transform }) => {
404
407
  this.viewportForSelection = {
405
- start: mapTransformToViewportState(transform)
408
+ start: mapTransformToViewportState(transform),
406
409
  };
407
410
  };
408
411
  this.handleZoomEnd = ({ transform, sourceEvent }) => {
409
412
  this.viewportForSelection = {
410
413
  ...this.viewportForSelection,
411
414
  end: mapTransformToViewportState(transform),
412
- target: evTarget(sourceEvent)
415
+ target: evTarget(sourceEvent),
413
416
  };
414
417
  this.selectionService.setViewport(this.viewportForSelection);
415
418
  };
@@ -427,9 +430,7 @@ class MapContextDirective {
427
430
  .on('start', this.handleZoomStart)
428
431
  .on('zoom', this.handleZoom)
429
432
  .on('end', this.handleZoomEnd);
430
- this.rootSvgSelection
431
- .call(this.zoomBehavior)
432
- .on('dblclick.zoom', null);
433
+ this.rootSvgSelection.call(this.zoomBehavior).on('dblclick.zoom', null);
433
434
  }
434
435
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
435
436
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: MapContextDirective, isStandalone: true, selector: "g[mapContext]", ngImport: i0 }); }
@@ -441,7 +442,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
441
442
  selector: 'g[mapContext]',
442
443
  }]
443
444
  }] });
444
- const mapTransformToViewportState = (transform) => ({ zoom: transform.k, x: transform.x, y: transform.y });
445
+ const mapTransformToViewportState = (transform) => ({
446
+ zoom: transform.k,
447
+ x: transform.x,
448
+ y: transform.y,
449
+ });
445
450
  const evTarget = (anyEvent) => {
446
451
  if (anyEvent instanceof Event && anyEvent.target instanceof Element) {
447
452
  return anyEvent.target;
@@ -462,8 +467,7 @@ class DraggableService {
462
467
  * @param model model with data for this element
463
468
  */
464
469
  enable(element, model) {
465
- select(element)
466
- .call(this.getDragBehavior(model));
470
+ select(element).call(this.getDragBehavior(model));
467
471
  }
468
472
  /**
469
473
  * Disable draggable behavior for element.
@@ -472,8 +476,7 @@ class DraggableService {
472
476
  * @param model model with data for this element
473
477
  */
474
478
  disable(element) {
475
- select(element)
476
- .call(drag().on('drag', null));
479
+ select(element).call(drag().on('drag', null));
477
480
  }
478
481
  /**
479
482
  * TODO: not shure if this work, need to check
@@ -503,16 +506,16 @@ class DraggableService {
503
506
  .filter(filterCondition)
504
507
  .on('start', (event) => {
505
508
  dragNodes = this.getDragNodes(model);
506
- initialPositions = dragNodes.map(node => ({
509
+ initialPositions = dragNodes.map((node) => ({
507
510
  x: node.point().x - event.x,
508
- y: node.point().y - event.y
511
+ y: node.point().y - event.y,
509
512
  }));
510
513
  })
511
514
  .on('drag', (event) => {
512
515
  dragNodes.forEach((model, index) => {
513
- let point = {
516
+ const point = {
514
517
  x: round(event.x + initialPositions[index].x),
515
- y: round(event.y + initialPositions[index].y)
518
+ y: round(event.y + initialPositions[index].y),
516
519
  };
517
520
  moveNode(model, point);
518
521
  });
@@ -523,9 +526,9 @@ class DraggableService {
523
526
  ? this.entitiesService
524
527
  .nodes()
525
528
  // selected draggable nodes (with current node)
526
- .filter(node => node.selected() && node.draggable())
527
- // we only can move current node if it's not selected
528
- : [model];
529
+ .filter((node) => node.selected() && node.draggable())
530
+ : // we only can move current node if it's not selected
531
+ [model];
529
532
  }
530
533
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
531
534
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService }); }
@@ -570,7 +573,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
570
573
  type: Directive,
571
574
  args: [{
572
575
  standalone: true,
573
- selector: 'ng-template[connection]'
576
+ selector: 'ng-template[connection]',
574
577
  }]
575
578
  }] });
576
579
  class EdgeLabelHtmlTemplateDirective {
@@ -584,7 +587,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
584
587
  type: Directive,
585
588
  args: [{
586
589
  standalone: true,
587
- selector: 'ng-template[edgeLabelHtml]'
590
+ selector: 'ng-template[edgeLabelHtml]',
588
591
  }]
589
592
  }] });
590
593
  class NodeHtmlTemplateDirective {
@@ -598,7 +601,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
598
601
  type: Directive,
599
602
  args: [{
600
603
  standalone: true,
601
- selector: 'ng-template[nodeHtml]'
604
+ selector: 'ng-template[nodeHtml]',
602
605
  }]
603
606
  }] });
604
607
  class GroupNodeTemplateDirective {
@@ -612,7 +615,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
612
615
  type: Directive,
613
616
  args: [{
614
617
  standalone: true,
615
- selector: 'ng-template[groupNode]'
618
+ selector: 'ng-template[groupNode]',
616
619
  }]
617
620
  }] });
618
621
  class HandleTemplateDirective {
@@ -626,7 +629,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
626
629
  type: Directive,
627
630
  args: [{
628
631
  standalone: true,
629
- selector: 'ng-template[handle]'
632
+ selector: 'ng-template[handle]',
630
633
  }]
631
634
  }] });
632
635
 
@@ -635,7 +638,7 @@ function addNodesToEdges(nodes, edges) {
635
638
  acc[n.node.id] = n;
636
639
  return acc;
637
640
  }, {});
638
- edges.forEach(e => {
641
+ edges.forEach((e) => {
639
642
  e.source.set(nodesById[e.edge.source]);
640
643
  e.target.set(nodesById[e.edge.target]);
641
644
  });
@@ -674,7 +677,7 @@ function batchStatusChanges(...changes) {
674
677
  // first change is sync
675
678
  firstChange();
676
679
  // without timer, subscribed effects/comuted signals only get latest value
677
- restChanges.forEach(change => setTimeout(() => change()));
680
+ restChanges.forEach((change) => setTimeout(() => change()));
678
681
  }
679
682
  }
680
683
 
@@ -717,7 +720,10 @@ class ConnectionControllerDirective {
717
720
  *
718
721
  * Also it's important to note, that this event only fires when connection is valid by validator function in `ConnectionSettings`,
719
722
  * by default without passing the validator every connection concidered valid.
723
+ *
724
+ * @todo add connect event and deprecate onConnect
720
725
  */
726
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix
721
727
  this.onConnect = output();
722
728
  this.statusService = inject(FlowStatusService);
723
729
  this.flowEntitiesService = inject(FlowEntitiesService);
@@ -803,7 +809,7 @@ class ConnectionControllerDirective {
803
809
  this.statusService.setConnectionStartStatus(status.payload.source, status.payload.sourceHandle);
804
810
  }
805
811
  }
806
- endConnection(handle) {
812
+ endConnection() {
807
813
  const status = this.statusService.status();
808
814
  if (status.state === 'connection-validation') {
809
815
  const source = status.payload.source;
@@ -958,10 +964,10 @@ function isDynamicNode(node) {
958
964
  return typeof node.point === 'function';
959
965
  }
960
966
  function isComponentStaticNode(node) {
961
- return CustomNodeComponent.isPrototypeOf(node.type);
967
+ return Object.prototype.isPrototypeOf.call(CustomNodeComponent, node.type);
962
968
  }
963
969
  function isComponentDynamicNode(node) {
964
- return CustomDynamicNodeComponent.isPrototypeOf(node.type);
970
+ return Object.prototype.isPrototypeOf.call(CustomDynamicNodeComponent, node.type);
965
971
  }
966
972
  function isTemplateStaticNode(node) {
967
973
  return node.type === 'html-template';
@@ -1001,7 +1007,7 @@ class NodeModel {
1001
1007
  this.throttledPoint$ = toObservable(this.internalPoint).pipe(observeOn(animationFrameScheduler));
1002
1008
  this.notThrottledPoint$ = new Subject();
1003
1009
  this.point = toSignal(merge(this.throttledPoint$, this.notThrottledPoint$), {
1004
- initialValue: this.internalPoint()
1010
+ initialValue: this.internalPoint(),
1005
1011
  });
1006
1012
  this.point$ = this.throttledPoint$;
1007
1013
  this.size = signal({ width: 0, height: 0 });
@@ -1030,16 +1036,15 @@ class NodeModel {
1030
1036
  // disabled for configuration for now
1031
1037
  this.magnetRadius = 20;
1032
1038
  // TODO: not sure if we need to statically store it
1033
- this.isComponentType = CustomNodeComponent.isPrototypeOf(this.node.type) ||
1034
- CustomDynamicNodeComponent.isPrototypeOf(this.node.type);
1039
+ this.isComponentType = isComponentStaticNode(this.node) || isComponentDynamicNode(this.node);
1035
1040
  // Default node specific thing
1036
1041
  this.text = this.createTextSignal();
1037
1042
  // Component node specific thing
1038
1043
  this.componentTypeInputs = {
1039
1044
  node: this.node,
1040
1045
  };
1041
- this.parent = computed(() => this.entitiesService.nodes().find(n => n.node.id === this.parentId()) ?? null);
1042
- this.children = computed(() => this.entitiesService.nodes().filter(n => n.parentId() === this.node.id));
1046
+ this.parent = computed(() => this.entitiesService.nodes().find((n) => n.node.id === this.parentId()) ?? null);
1047
+ this.children = computed(() => this.entitiesService.nodes().filter((n) => n.parentId() === this.node.id));
1043
1048
  this.color = signal(NodeModel.defaultColor);
1044
1049
  this.resizable = signal(false);
1045
1050
  this.resizing = signal(false);
@@ -1106,7 +1111,7 @@ class NodeModel {
1106
1111
  else {
1107
1112
  this.size.set({
1108
1113
  width: node.width ?? NodeModel.defaultWidth,
1109
- height: node.height ?? NodeModel.defaultHeight
1114
+ height: node.height ?? NodeModel.defaultHeight,
1110
1115
  });
1111
1116
  }
1112
1117
  }
@@ -1142,9 +1147,7 @@ class NodeModel {
1142
1147
  return signal('');
1143
1148
  }
1144
1149
  createInternalPointSignal() {
1145
- return isDynamicNode(this.node)
1146
- ? this.node.point
1147
- : signal({ x: this.node.point.x, y: this.node.point.y });
1150
+ return isDynamicNode(this.node) ? this.node.point : signal({ x: this.node.point.x, y: this.node.point.y });
1148
1151
  }
1149
1152
  }
1150
1153
 
@@ -1173,10 +1176,10 @@ function straightPath(source, target, usingPoints = [false, false, false]) {
1173
1176
  return {
1174
1177
  path: `M ${source.x},${source.y}L ${target.x},${target.y}`,
1175
1178
  points: {
1176
- start: start ? getPointOnLineByRatio(source, target, .15) : nullPoint,
1177
- center: center ? getPointOnLineByRatio(source, target, .50) : nullPoint,
1178
- end: end ? getPointOnLineByRatio(source, target, .85) : nullPoint,
1179
- }
1179
+ start: start ? getPointOnLineByRatio(source, target, 0.15) : nullPoint,
1180
+ center: center ? getPointOnLineByRatio(source, target, 0.5) : nullPoint,
1181
+ end: end ? getPointOnLineByRatio(source, target, 0.85) : nullPoint,
1182
+ },
1180
1183
  };
1181
1184
  }
1182
1185
 
@@ -1231,15 +1234,9 @@ function getPathData(path, source, target, sourceControl, targetControl, usingPo
1231
1234
  return {
1232
1235
  path,
1233
1236
  points: {
1234
- start: start
1235
- ? getPointOnBezier(source, target, sourceControl, targetControl, 0.1)
1236
- : nullPoint,
1237
- center: center
1238
- ? getPointOnBezier(source, target, sourceControl, targetControl, 0.5)
1239
- : nullPoint,
1240
- end: end
1241
- ? getPointOnBezier(source, target, sourceControl, targetControl, 0.9)
1242
- : nullPoint,
1237
+ start: start ? getPointOnBezier(source, target, sourceControl, targetControl, 0.1) : nullPoint,
1238
+ center: center ? getPointOnBezier(source, target, sourceControl, targetControl, 0.5) : nullPoint,
1239
+ end: end ? getPointOnBezier(source, target, sourceControl, targetControl, 0.9) : nullPoint,
1243
1240
  },
1244
1241
  };
1245
1242
  }
@@ -1399,7 +1396,7 @@ function smoothStepPath(source, target, sourcePosition, targetPosition, borderRa
1399
1396
  sourcePosition,
1400
1397
  target,
1401
1398
  targetPosition,
1402
- offset: 20
1399
+ offset: 20,
1403
1400
  });
1404
1401
  const path = points.reduce((res, p, i) => {
1405
1402
  let segment = '';
@@ -1419,7 +1416,7 @@ function smoothStepPath(source, target, sourcePosition, targetPosition, borderRa
1419
1416
  start: { x: labelX, y: labelY },
1420
1417
  center: { x: labelX, y: labelY },
1421
1418
  end: { x: labelX, y: labelY },
1422
- }
1419
+ },
1423
1420
  };
1424
1421
  }
1425
1422
 
@@ -1439,20 +1436,16 @@ class EdgeModel {
1439
1436
  let existsSourceHandle = false;
1440
1437
  let existsTargetHandle = false;
1441
1438
  if (this.edge.sourceHandle) {
1442
- existsSourceHandle = !!source.handles()
1443
- .find(handle => handle.rawHandle.id === this.edge.sourceHandle);
1439
+ existsSourceHandle = !!source.handles().find((handle) => handle.rawHandle.id === this.edge.sourceHandle);
1444
1440
  }
1445
1441
  else {
1446
- existsSourceHandle = !!source.handles()
1447
- .find(handle => handle.rawHandle.type === 'source');
1442
+ existsSourceHandle = !!source.handles().find((handle) => handle.rawHandle.type === 'source');
1448
1443
  }
1449
1444
  if (this.edge.targetHandle) {
1450
- existsTargetHandle = !!target.handles()
1451
- .find(handle => handle.rawHandle.id === this.edge.targetHandle);
1445
+ existsTargetHandle = !!target.handles().find((handle) => handle.rawHandle.id === this.edge.targetHandle);
1452
1446
  }
1453
1447
  else {
1454
- existsTargetHandle = !!target.handles()
1455
- .find(handle => handle.rawHandle.type === 'target');
1448
+ existsTargetHandle = !!target.handles().find((handle) => handle.rawHandle.type === 'target');
1456
1449
  }
1457
1450
  return !existsSourceHandle || !existsTargetHandle;
1458
1451
  });
@@ -1460,21 +1453,25 @@ class EdgeModel {
1460
1453
  this.path = computed(() => {
1461
1454
  let source;
1462
1455
  if (this.edge.sourceHandle) {
1463
- source = this.source()?.handles()
1464
- .find(handle => handle.rawHandle.id === this.edge.sourceHandle);
1456
+ source = this.source()
1457
+ ?.handles()
1458
+ .find((handle) => handle.rawHandle.id === this.edge.sourceHandle);
1465
1459
  }
1466
1460
  else {
1467
- source = this.source()?.handles()
1468
- .find(handle => handle.rawHandle.type === 'source');
1461
+ source = this.source()
1462
+ ?.handles()
1463
+ .find((handle) => handle.rawHandle.type === 'source');
1469
1464
  }
1470
1465
  let target;
1471
1466
  if (this.edge.targetHandle) {
1472
- target = this.target()?.handles()
1473
- .find(handle => handle.rawHandle.id === this.edge.targetHandle);
1467
+ target = this.target()
1468
+ ?.handles()
1469
+ .find((handle) => handle.rawHandle.id === this.edge.targetHandle);
1474
1470
  }
1475
1471
  else {
1476
- target = this.target()?.handles()
1477
- .find(handle => handle.rawHandle.type === 'target');
1472
+ target = this.target()
1473
+ ?.handles()
1474
+ .find((handle) => handle.rawHandle.type === 'target');
1478
1475
  }
1479
1476
  // TODO: don't like this
1480
1477
  if (!source || !target) {
@@ -1483,8 +1480,8 @@ class EdgeModel {
1483
1480
  points: {
1484
1481
  start: { x: 0, y: 0 },
1485
1482
  center: { x: 0, y: 0 },
1486
- end: { x: 0, y: 0 }
1487
- }
1483
+ end: { x: 0, y: 0 },
1484
+ },
1488
1485
  };
1489
1486
  }
1490
1487
  switch (this.curve) {
@@ -1517,8 +1514,8 @@ class ReferenceKeeper {
1517
1514
  */
1518
1515
  static nodes(newNodes, oldNodeModels) {
1519
1516
  const oldNodesMap = new Map();
1520
- oldNodeModels.forEach(model => oldNodesMap.set(model.node, model));
1521
- return newNodes.map(newNode => {
1517
+ oldNodeModels.forEach((model) => oldNodesMap.set(model.node, model));
1518
+ return newNodes.map((newNode) => {
1522
1519
  if (oldNodesMap.has(newNode))
1523
1520
  return oldNodesMap.get(newNode);
1524
1521
  else
@@ -1530,8 +1527,8 @@ class ReferenceKeeper {
1530
1527
  */
1531
1528
  static edges(newEdges, oldEdgeModels) {
1532
1529
  const oldEdgesMap = new Map();
1533
- oldEdgeModels.forEach(model => oldEdgesMap.set(model.edge, model));
1534
- return newEdges.map(newEdge => {
1530
+ oldEdgeModels.forEach((model) => oldEdgesMap.set(model.edge, model));
1531
+ return newEdges.map((newEdge) => {
1535
1532
  if (oldEdgesMap.has(newEdge))
1536
1533
  return oldEdgesMap.get(newEdge);
1537
1534
  else
@@ -1546,28 +1543,20 @@ const DELAY_FOR_SCHEDULER = 25;
1546
1543
  class NodesChangeService {
1547
1544
  constructor() {
1548
1545
  this.entitiesService = inject(FlowEntitiesService);
1549
- this.nodesPositionChange$ = toObservable(this.entitiesService.nodes)
1550
- .pipe(
1546
+ this.nodesPositionChange$ = toObservable(this.entitiesService.nodes).pipe(
1551
1547
  // Check for nodes list change and watch for specific node from this list change its position
1552
- switchMap((nodes) => merge(...nodes.map(node => node.point$.pipe(
1548
+ switchMap((nodes) => merge(...nodes.map((node) => node.point$.pipe(
1553
1549
  // skip initial position from signal
1554
1550
  skip(1), map(() => node))))), map((changedNode) => {
1555
- return this.entitiesService.nodes()
1556
- .filter(node => node === changedNode || node.selected())
1557
- .map(node => ({ type: 'position', id: node.node.id, point: node.point() }));
1551
+ return this.entitiesService
1552
+ .nodes()
1553
+ .filter((node) => node === changedNode || node.selected())
1554
+ .map((node) => ({ type: 'position', id: node.node.id, point: node.point() }));
1558
1555
  }));
1559
- this.nodeSizeChange$ = toObservable(this.entitiesService.nodes)
1560
- .pipe(switchMap((nodes) => merge(...nodes.map(node => node.size$.pipe(skip(1), map(() => node))))), map(changedNode => [
1561
- { type: 'size', id: changedNode.node.id, size: changedNode.size() }
1562
- ]));
1563
- this.nodeAddChange$ = toObservable(this.entitiesService.nodes)
1564
- .pipe(pairwise(), map(([oldList, newList]) => newList.filter(node => !oldList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map(node => ({ type: 'add', id: node.node.id }))));
1565
- this.nodeRemoveChange$ = toObservable(this.entitiesService.nodes)
1566
- .pipe(pairwise(), map(([oldList, newList]) => oldList.filter(node => !newList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map(node => ({ type: 'remove', id: node.node.id }))));
1567
- this.nodeSelectedChange$ = toObservable(this.entitiesService.nodes)
1568
- .pipe(switchMap((nodes) => merge(...nodes.map(node => node.selected$.pipe(distinctUntilChanged(), skip(1), map(() => node))))), map((changedNode) => [
1569
- { type: 'select', id: changedNode.node.id, selected: changedNode.selected() }
1570
- ]));
1556
+ this.nodeSizeChange$ = toObservable(this.entitiesService.nodes).pipe(switchMap((nodes) => merge(...nodes.map((node) => node.size$.pipe(skip(1), map(() => node))))), map((changedNode) => [{ type: 'size', id: changedNode.node.id, size: changedNode.size() }]));
1557
+ this.nodeAddChange$ = toObservable(this.entitiesService.nodes).pipe(pairwise(), map(([oldList, newList]) => newList.filter((node) => !oldList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map((node) => ({ type: 'add', id: node.node.id }))));
1558
+ this.nodeRemoveChange$ = toObservable(this.entitiesService.nodes).pipe(pairwise(), map(([oldList, newList]) => oldList.filter((node) => !newList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map((node) => ({ type: 'remove', id: node.node.id }))));
1559
+ this.nodeSelectedChange$ = toObservable(this.entitiesService.nodes).pipe(switchMap((nodes) => merge(...nodes.map((node) => node.selected$.pipe(distinctUntilChanged(), skip(1), map(() => node))))), map((changedNode) => [{ type: 'select', id: changedNode.node.id, selected: changedNode.selected() }]));
1571
1560
  this.changes$ = merge(this.nodesPositionChange$, this.nodeSizeChange$, this.nodeAddChange$, this.nodeRemoveChange$, this.nodeSelectedChange$).pipe(
1572
1561
  // this fixes a bug when on fire node event change,
1573
1562
  // you can't get valid list of detached edges
@@ -1581,7 +1570,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1581
1570
  }] });
1582
1571
 
1583
1572
  const haveSameContents = (a, b) => a.length === b.length &&
1584
- [...new Set([...a, ...b])].every(v => a.filter(e => e === v).length === b.filter(e => e === v).length);
1573
+ [...new Set([...a, ...b])].every((v) => a.filter((e) => e === v).length === b.filter((e) => e === v).length);
1585
1574
  class EdgeChangesService {
1586
1575
  constructor() {
1587
1576
  this.entitiesService = inject(FlowEntitiesService);
@@ -1590,27 +1579,21 @@ class EdgeChangesService {
1590
1579
  const edges = untracked(this.entitiesService.edges);
1591
1580
  return edges.filter(({ source, target }) => !nodes.includes(source()) || !nodes.includes(target()));
1592
1581
  })), toObservable(this.entitiesService.edges).pipe(switchMap((edges) => {
1593
- return zip(...edges.map(e => e.detached$.pipe(map(() => e))));
1594
- }), map((edges) => edges.filter(e => e.detached())),
1582
+ return zip(...edges.map((e) => e.detached$.pipe(map(() => e))));
1583
+ }), map((edges) => edges.filter((e) => e.detached())),
1595
1584
  // TODO check why there are 2 emits
1596
1585
  skip(2))).pipe(
1597
1586
  // here we check if 2 approaches to detect detached edges emits same
1598
1587
  // and same values (this may happen on node delete)
1599
- distinctUntilChanged(haveSameContents), filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'detached', id: edge.id }))));
1600
- this.edgeAddChange$ = toObservable(this.entitiesService.edges)
1601
- .pipe(pairwise(), map(([oldList, newList]) => {
1602
- return newList.filter(edge => !oldList.includes(edge));
1603
- }), filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'add', id: edge.id }))));
1604
- this.edgeRemoveChange$ = toObservable(this.entitiesService.edges)
1605
- .pipe(pairwise(), map(([oldList, newList]) => {
1606
- return oldList.filter(edge => !newList.includes(edge));
1607
- }), filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'remove', id: edge.id }))));
1608
- this.edgeSelectChange$ = toObservable(this.entitiesService.edges)
1609
- .pipe(switchMap((edges) => merge(...edges.map(edge => edge.selected$.pipe(distinctUntilChanged(), skip(1), map(() => edge))))), map((changedEdge) => [
1610
- { type: 'select', id: changedEdge.edge.id, selected: changedEdge.selected() }
1611
- ]));
1612
- this.changes$ = merge(this.edgeDetachedChange$, this.edgeAddChange$, this.edgeRemoveChange$, this.edgeSelectChange$)
1613
- .pipe(
1588
+ distinctUntilChanged(haveSameContents), filter((edges) => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'detached', id: edge.id }))));
1589
+ this.edgeAddChange$ = toObservable(this.entitiesService.edges).pipe(pairwise(), map(([oldList, newList]) => {
1590
+ return newList.filter((edge) => !oldList.includes(edge));
1591
+ }), filter((edges) => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'add', id: edge.id }))));
1592
+ this.edgeRemoveChange$ = toObservable(this.entitiesService.edges).pipe(pairwise(), map(([oldList, newList]) => {
1593
+ return oldList.filter((edge) => !newList.includes(edge));
1594
+ }), filter((edges) => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'remove', id: edge.id }))));
1595
+ this.edgeSelectChange$ = toObservable(this.entitiesService.edges).pipe(switchMap((edges) => merge(...edges.map((edge) => edge.selected$.pipe(distinctUntilChanged(), skip(1), map(() => edge))))), map((changedEdge) => [{ type: 'select', id: changedEdge.edge.id, selected: changedEdge.selected() }]));
1596
+ this.changes$ = merge(this.edgeDetachedChange$, this.edgeAddChange$, this.edgeRemoveChange$, this.edgeSelectChange$).pipe(
1614
1597
  // this fixes the case when user gets 'deteched' changes
1615
1598
  // and tries to delete these edges inside stream
1616
1599
  // angular may ignore this change because [edges] input changed
@@ -1632,37 +1615,79 @@ class ChangesControllerDirective {
1632
1615
  * Watch nodes change
1633
1616
  */
1634
1617
  this.onNodesChange = outputFromObservable(this.nodesChangeService.changes$);
1635
- this.onNodesChangePosition = outputFromObservable(this.nodeChangesOfType('position'), { alias: 'onNodesChange.position' });
1618
+ this.onNodesChangePosition = outputFromObservable(this.nodeChangesOfType('position'), {
1619
+ alias: 'onNodesChange.position',
1620
+ });
1636
1621
  this.onNodesChangePositionSignle = outputFromObservable(this.singleChange(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.single' });
1637
1622
  this.onNodesChangePositionMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.many' });
1638
- this.onNodesChangeSize = outputFromObservable(this.nodeChangesOfType('size'), { alias: 'onNodesChange.size' });
1639
- this.onNodesChangeSizeSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.single' });
1640
- this.onNodesChangeSizeMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.many' });
1641
- this.onNodesChangeAdd = outputFromObservable(this.nodeChangesOfType('add'), { alias: 'onNodesChange.add' });
1642
- this.onNodesChangeAddSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.single' });
1643
- this.onNodesChangeAddMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.many' });
1644
- this.onNodesChangeRemove = outputFromObservable(this.nodeChangesOfType('remove'), { alias: 'onNodesChange.remove' });
1623
+ this.onNodesChangeSize = outputFromObservable(this.nodeChangesOfType('size'), {
1624
+ alias: 'onNodesChange.size',
1625
+ });
1626
+ this.onNodesChangeSizeSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('size')), {
1627
+ alias: 'onNodesChange.size.single',
1628
+ });
1629
+ this.onNodesChangeSizeMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('size')), {
1630
+ alias: 'onNodesChange.size.many',
1631
+ });
1632
+ this.onNodesChangeAdd = outputFromObservable(this.nodeChangesOfType('add'), {
1633
+ alias: 'onNodesChange.add',
1634
+ });
1635
+ this.onNodesChangeAddSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('add')), {
1636
+ alias: 'onNodesChange.add.single',
1637
+ });
1638
+ this.onNodesChangeAddMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('add')), {
1639
+ alias: 'onNodesChange.add.many',
1640
+ });
1641
+ this.onNodesChangeRemove = outputFromObservable(this.nodeChangesOfType('remove'), {
1642
+ alias: 'onNodesChange.remove',
1643
+ });
1645
1644
  this.onNodesChangeRemoveSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.single' });
1646
- this.onNodesChangeRemoveMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.many' });
1647
- this.onNodesChangeSelect = outputFromObservable(this.nodeChangesOfType('select'), { alias: 'onNodesChange.select' });
1645
+ this.onNodesChangeRemoveMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('remove')), {
1646
+ alias: 'onNodesChange.remove.many',
1647
+ });
1648
+ this.onNodesChangeSelect = outputFromObservable(this.nodeChangesOfType('select'), {
1649
+ alias: 'onNodesChange.select',
1650
+ });
1648
1651
  this.onNodesChangeSelectSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.single' });
1649
- this.onNodesChangeSelectMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.many' });
1652
+ this.onNodesChangeSelectMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('select')), {
1653
+ alias: 'onNodesChange.select.many',
1654
+ });
1650
1655
  /**
1651
1656
  * Watch edges change
1652
1657
  */
1653
1658
  this.onEdgesChange = outputFromObservable(this.edgesChangeService.changes$);
1654
- this.onNodesChangeDetached = outputFromObservable(this.edgeChangesOfType('detached'), { alias: 'onEdgesChange.detached' });
1659
+ this.onNodesChangeDetached = outputFromObservable(this.edgeChangesOfType('detached'), {
1660
+ alias: 'onEdgesChange.detached',
1661
+ });
1655
1662
  this.onNodesChangeDetachedSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.single' });
1656
1663
  this.onNodesChangeDetachedMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.many' });
1657
- this.onEdgesChangeAdd = outputFromObservable(this.edgeChangesOfType('add'), { alias: 'onEdgesChange.add' });
1658
- this.onEdgeChangeAddSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.single' });
1659
- this.onEdgeChangeAddMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.many' });
1660
- this.onEdgeChangeRemove = outputFromObservable(this.edgeChangesOfType('remove'), { alias: 'onEdgesChange.remove' });
1661
- this.onEdgeChangeRemoveSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.single' });
1662
- this.onEdgeChangeRemoveMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.many' });
1663
- this.onEdgeChangeSelect = outputFromObservable(this.edgeChangesOfType('select'), { alias: 'onEdgesChange.select' });
1664
- this.onEdgeChangeSelectSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.single' });
1665
- this.onEdgeChangeSelectMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.many' });
1664
+ this.onEdgesChangeAdd = outputFromObservable(this.edgeChangesOfType('add'), {
1665
+ alias: 'onEdgesChange.add',
1666
+ });
1667
+ this.onEdgeChangeAddSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('add')), {
1668
+ alias: 'onEdgesChange.add.single',
1669
+ });
1670
+ this.onEdgeChangeAddMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('add')), {
1671
+ alias: 'onEdgesChange.add.many',
1672
+ });
1673
+ this.onEdgeChangeRemove = outputFromObservable(this.edgeChangesOfType('remove'), {
1674
+ alias: 'onEdgesChange.remove',
1675
+ });
1676
+ this.onEdgeChangeRemoveSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('remove')), {
1677
+ alias: 'onEdgesChange.remove.single',
1678
+ });
1679
+ this.onEdgeChangeRemoveMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('remove')), {
1680
+ alias: 'onEdgesChange.remove.many',
1681
+ });
1682
+ this.onEdgeChangeSelect = outputFromObservable(this.edgeChangesOfType('select'), {
1683
+ alias: 'onEdgesChange.select',
1684
+ });
1685
+ this.onEdgeChangeSelectSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('select')), {
1686
+ alias: 'onEdgesChange.select.single',
1687
+ });
1688
+ this.onEdgeChangeSelectMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('select')), {
1689
+ alias: 'onEdgesChange.select.many',
1690
+ });
1666
1691
  }
1667
1692
  nodeChangesOfType(type) {
1668
1693
  return this.nodesChangeService.changes$.pipe(map((changes) => changes.filter((c) => c.type === type)), filter((changes) => !!changes.length));
@@ -1695,14 +1720,13 @@ class NodeRenderingService {
1695
1720
  constructor() {
1696
1721
  this.flowEntitiesService = inject(FlowEntitiesService);
1697
1722
  this.nodes = computed(() => {
1698
- return this.flowEntitiesService.nodes()
1699
- .sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
1723
+ return this.flowEntitiesService.nodes().sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
1700
1724
  });
1701
1725
  this.groups = computed(() => {
1702
- return this.nodes().filter(n => isGroupNode(n));
1726
+ return this.nodes().filter((n) => isGroupNode(n));
1703
1727
  });
1704
1728
  this.nonGroups = computed(() => {
1705
- return this.nodes().filter(n => !isGroupNode(n));
1729
+ return this.nodes().filter((n) => !isGroupNode(n));
1706
1730
  });
1707
1731
  this.maxOrder = computed(() => {
1708
1732
  return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
@@ -1715,8 +1739,8 @@ class NodeRenderingService {
1715
1739
  // pull children
1716
1740
  this.flowEntitiesService
1717
1741
  .nodes()
1718
- .filter(n => n.parent() === node)
1719
- .forEach(n => this.pullNode(n));
1742
+ .filter((n) => n.parent() === node)
1743
+ .forEach((n) => this.pullNode(n));
1720
1744
  }
1721
1745
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1722
1746
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService }); }
@@ -1731,33 +1755,29 @@ class RootPointerDirective {
1731
1755
  this.initialTouch$ = new Subject();
1732
1756
  this.prevTouchEvent = null;
1733
1757
  // TODO: do not emit if mouse not down
1734
- this.mouseMovement$ = fromEvent(this.host, 'mousemove').pipe(map(event => ({
1758
+ this.mouseMovement$ = fromEvent(this.host, 'mousemove').pipe(map((event) => ({
1735
1759
  x: event.clientX,
1736
1760
  y: event.clientY,
1737
1761
  movementX: event.movementX,
1738
1762
  movementY: event.movementY,
1739
1763
  target: event.target,
1740
- originalEvent: event
1764
+ originalEvent: event,
1741
1765
  })), observeOn(animationFrameScheduler), share());
1742
1766
  this.touchMovement$ = merge(this.initialTouch$, fromEvent(this.host, 'touchmove')).pipe(tap((event) => event.preventDefault()), map((originalEvent) => {
1743
1767
  const x = originalEvent.touches[0]?.clientX ?? 0;
1744
1768
  const y = originalEvent.touches[0]?.clientY ?? 0;
1745
- const movementX = this.prevTouchEvent
1746
- ? originalEvent.touches[0].pageX - this.prevTouchEvent.touches[0].pageX
1747
- : 0;
1748
- const movementY = this.prevTouchEvent
1749
- ? originalEvent.touches[0].pageY - this.prevTouchEvent.touches[0].pageY
1750
- : 0;
1769
+ const movementX = this.prevTouchEvent ? originalEvent.touches[0].pageX - this.prevTouchEvent.touches[0].pageX : 0;
1770
+ const movementY = this.prevTouchEvent ? originalEvent.touches[0].pageY - this.prevTouchEvent.touches[0].pageY : 0;
1751
1771
  const target = document.elementFromPoint(x, y);
1752
1772
  return { x, y, movementX, movementY, target, originalEvent };
1753
- }), tap((event) => this.prevTouchEvent = event.originalEvent), observeOn(animationFrameScheduler), share());
1773
+ }), tap((event) => (this.prevTouchEvent = event.originalEvent)), observeOn(animationFrameScheduler), share());
1754
1774
  this.pointerMovement$ = merge(this.mouseMovement$, this.touchMovement$);
1755
1775
  this.touchEnd$ = fromEvent(this.host, 'touchend').pipe(map((originalEvent) => {
1756
1776
  const x = originalEvent.changedTouches[0]?.clientX ?? 0;
1757
1777
  const y = originalEvent.changedTouches[0]?.clientY ?? 0;
1758
1778
  const target = document.elementFromPoint(x, y);
1759
1779
  return { x, y, target, originalEvent };
1760
- }), tap(() => this.prevTouchEvent = null), share());
1780
+ }), tap(() => (this.prevTouchEvent = null)), share());
1761
1781
  this.mouseUp$ = fromEvent(this.host, 'mouseup').pipe(map((originalEvent) => {
1762
1782
  const x = originalEvent.clientX;
1763
1783
  const y = originalEvent.clientY;
@@ -1799,7 +1819,7 @@ class SpacePointContextDirective {
1799
1819
  }
1800
1820
  return this.documentPointToFlowPoint({
1801
1821
  x: movement.x,
1802
- y: movement.y
1822
+ y: movement.y,
1803
1823
  });
1804
1824
  });
1805
1825
  this.pointerMovement = toSignal(this.pointerMovementDirective.pointerMovement$);
@@ -1822,9 +1842,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1822
1842
  }] });
1823
1843
 
1824
1844
  function transformBackground(background) {
1825
- return typeof background === 'string'
1826
- ? { type: 'solid', color: background }
1827
- : background;
1845
+ return typeof background === 'string' ? { type: 'solid', color: background } : background;
1828
1846
  }
1829
1847
 
1830
1848
  function Microtask(target, key, descriptor) {
@@ -1853,7 +1871,7 @@ class OverlaysService {
1853
1871
  this.toolbars.update((toolbars) => [...toolbars, toolbar]);
1854
1872
  }
1855
1873
  removeToolbar(toolbar) {
1856
- this.toolbars.update((toolbars) => toolbars.filter(t => t !== toolbar));
1874
+ this.toolbars.update((toolbars) => toolbars.filter((t) => t !== toolbar));
1857
1875
  }
1858
1876
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1859
1877
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService }); }
@@ -1894,10 +1912,8 @@ class EdgeLabelComponent {
1894
1912
  // this is a fix for visual artifact in chrome that for some reason adresses only for edge label.
1895
1913
  // the bug reproduces if edgeLabelWrapperRef size fully matched the size of parent foreignObject
1896
1914
  const MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME = 2;
1897
- const width = this.edgeLabelWrapperRef().nativeElement.clientWidth +
1898
- MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1899
- const height = this.edgeLabelWrapperRef().nativeElement.clientHeight +
1900
- MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1915
+ const width = this.edgeLabelWrapperRef().nativeElement.clientWidth + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1916
+ const height = this.edgeLabelWrapperRef().nativeElement.clientHeight + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
1901
1917
  this.model().size.set({ width, height });
1902
1918
  }
1903
1919
  getLabelContext() {
@@ -1909,14 +1925,14 @@ class EdgeLabelComponent {
1909
1925
  };
1910
1926
  }
1911
1927
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1912
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeLabelComponent, isStandalone: true, selector: "g[edgeLabel]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeModel: { classPropertyName: "edgeModel", publicName: "edgeModel", isSignal: true, isRequired: true, transformFunction: null }, point: { classPropertyName: "point", publicName: "point", isSignal: true, isRequired: false, transformFunction: null }, htmlTemplate: { classPropertyName: "htmlTemplate", publicName: "htmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (model().edgeLabel.type === \"html-template\" && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeLabelComponent, isStandalone: true, selector: "g[edgeLabel]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeModel: { classPropertyName: "edgeModel", publicName: "edgeModel", isSignal: true, isRequired: true, transformFunction: null }, point: { classPropertyName: "point", publicName: "point", isSignal: true, isRequired: false, transformFunction: null }, htmlTemplate: { classPropertyName: "htmlTemplate", publicName: "htmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (model().edgeLabel.type === 'html-template' && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\">\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\" />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1913
1929
  }
1914
1930
  __decorate([
1915
1931
  Microtask
1916
1932
  ], EdgeLabelComponent.prototype, "ngAfterViewInit", null);
1917
1933
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, decorators: [{
1918
1934
  type: Component,
1919
- args: [{ standalone: true, selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "@if (model().edgeLabel.type === \"html-template\" && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
1935
+ args: [{ standalone: true, selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "@if (model().edgeLabel.type === 'html-template' && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\">\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\" />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
1920
1936
  }], propDecorators: { ngAfterViewInit: [] } });
1921
1937
 
1922
1938
  class EdgeComponent {
@@ -1954,13 +1970,13 @@ class EdgeComponent {
1954
1970
  }
1955
1971
  }
1956
1972
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1957
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === \"default\") {\n <svg:path\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\n}\n\n@if (model().type === \"template\" && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1973
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\"\n (mousedown)=\"onEdgeMouseDown()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1958
1974
  }
1959
1975
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
1960
1976
  type: Component,
1961
1977
  args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
1962
1978
  class: 'selectable',
1963
- }, imports: [NgTemplateOutlet, EdgeLabelComponent], template: "@if (model().type === \"default\") {\n <svg:path\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\n}\n\n@if (model().type === \"template\" && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\"\n />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
1979
+ }, imports: [NgTemplateOutlet, EdgeLabelComponent], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\"\n (mousedown)=\"onEdgeMouseDown()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
1964
1980
  }] });
1965
1981
 
1966
1982
  class HandleService {
@@ -1970,13 +1986,13 @@ class HandleService {
1970
1986
  createHandle(newHandle) {
1971
1987
  const node = this.node();
1972
1988
  if (node) {
1973
- node.handles.update(handles => [...handles, newHandle]);
1989
+ node.handles.update((handles) => [...handles, newHandle]);
1974
1990
  }
1975
1991
  }
1976
1992
  destroyHandle(handleToDestoy) {
1977
1993
  const node = this.node();
1978
1994
  if (node) {
1979
- node.handles.update(handles => handles.filter(handle => handle !== handleToDestoy));
1995
+ node.handles.update((handles) => handles.filter((handle) => handle !== handleToDestoy));
1980
1996
  }
1981
1997
  }
1982
1998
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -1991,10 +2007,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1991
2007
 
1992
2008
  function resizable(elems, zone) {
1993
2009
  return new Observable((subscriber) => {
1994
- let ro = new ResizeObserver((entries) => {
2010
+ const ro = new ResizeObserver((entries) => {
1995
2011
  zone.run(() => subscriber.next(entries));
1996
2012
  });
1997
- elems.forEach(e => ro.observe(e));
2013
+ elems.forEach((e) => ro.observe(e));
1998
2014
  return () => ro.disconnect();
1999
2015
  });
2000
2016
  }
@@ -2060,13 +2076,13 @@ class DefaultNodeComponent {
2060
2076
  this.selected = input(false);
2061
2077
  }
2062
2078
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2063
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: DefaultNodeComponent, isStandalone: true, selector: "default-node", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.selected": "selected()" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }); }
2079
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: DefaultNodeComponent, isStandalone: true, selector: "default-node", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.selected": "selected()" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2064
2080
  }
2065
2081
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
2066
2082
  type: Component,
2067
2083
  args: [{ standalone: true, selector: 'default-node', host: {
2068
2084
  '[class.selected]': 'selected()',
2069
- }, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
2085
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
2070
2086
  }] });
2071
2087
 
2072
2088
  class PointerDirective {
@@ -2188,10 +2204,8 @@ class ResizableComponent {
2188
2204
  this.model.resizerTemplate.set(this.resizer());
2189
2205
  }
2190
2206
  ngAfterViewInit() {
2191
- this.minWidth =
2192
- +getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
2193
- this.minHeight =
2194
- +getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
2207
+ this.minWidth = +getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
2208
+ this.minHeight = +getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
2195
2209
  }
2196
2210
  startResize(side, event) {
2197
2211
  event.stopPropagation();
@@ -2212,15 +2226,13 @@ class ResizableComponent {
2212
2226
  this.resizeSide = null;
2213
2227
  this.model.resizing.set(false);
2214
2228
  }
2215
- isResizeConstrained({ x, y, movementX, movementY, }) {
2229
+ isResizeConstrained({ x, y, movementX, movementY }) {
2216
2230
  const flowPoint = this.spacePointContext.documentPointToFlowPoint({ x, y });
2217
2231
  if (this.resizeSide?.includes('right')) {
2218
- if (movementX > 0 &&
2219
- flowPoint.x < this.model.point().x + this.model.size().width) {
2232
+ if (movementX > 0 && flowPoint.x < this.model.point().x + this.model.size().width) {
2220
2233
  return true;
2221
2234
  }
2222
- if (movementX < 0 &&
2223
- flowPoint.x > this.model.point().x + this.model.size().width) {
2235
+ if (movementX < 0 && flowPoint.x > this.model.point().x + this.model.size().width) {
2224
2236
  return true;
2225
2237
  }
2226
2238
  }
@@ -2233,12 +2245,10 @@ class ResizableComponent {
2233
2245
  }
2234
2246
  }
2235
2247
  if (this.resizeSide?.includes('bottom')) {
2236
- if (movementY > 0 &&
2237
- flowPoint.y < this.model.point().y + this.model.size().height) {
2248
+ if (movementY > 0 && flowPoint.y < this.model.point().y + this.model.size().height) {
2238
2249
  return true;
2239
2250
  }
2240
- if (movementY < 0 &&
2241
- flowPoint.y > this.model.point().y + this.model.size().height) {
2251
+ if (movementY < 0 && flowPoint.y > this.model.point().y + this.model.size().height) {
2242
2252
  return true;
2243
2253
  }
2244
2254
  }
@@ -2253,14 +2263,14 @@ class ResizableComponent {
2253
2263
  return false;
2254
2264
  }
2255
2265
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2256
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: ResizableComponent, isStandalone: true, selector: "[resizable]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizerColor: { classPropertyName: "resizerColor", publicName: "resizerColor", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }] }); }
2266
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: ResizableComponent, isStandalone: true, selector: "[resizable]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizerColor: { classPropertyName: "resizerColor", publicName: "resizerColor", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n stroke-width=\"2\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('top', $event)\" />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n stroke-width=\"2\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('left', $event)\" />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n stroke-width=\"2\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom', $event)\" />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n stroke-width=\"2\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('right', $event)\" />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\" />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\" />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\" />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\" />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2257
2267
  }
2258
2268
  __decorate([
2259
2269
  Microtask
2260
2270
  ], ResizableComponent.prototype, "ngAfterViewInit", null);
2261
2271
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, decorators: [{
2262
2272
  type: Component,
2263
- args: [{ standalone: true, selector: '[resizable]', imports: [PointerDirective], template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
2273
+ args: [{ standalone: true, selector: '[resizable]', imports: [PointerDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n stroke-width=\"2\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('top', $event)\" />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n stroke-width=\"2\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('left', $event)\" />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n stroke-width=\"2\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom', $event)\" />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n stroke-width=\"2\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n (pointerStart)=\"startResize('right', $event)\" />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\" />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\" />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\" />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\" />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
2264
2274
  }], ctorParameters: () => [], propDecorators: { ngAfterViewInit: [] } });
2265
2275
  function calcOffset(movementX, movementY, zoom) {
2266
2276
  return {
@@ -2368,35 +2378,43 @@ class HandleModel {
2368
2378
  * for custom handles
2369
2379
  */
2370
2380
  this.size = signal({
2371
- width: 10 + (2 * this.strokeWidth),
2372
- height: 10 + (2 * this.strokeWidth)
2381
+ width: 10 + 2 * this.strokeWidth,
2382
+ height: 10 + 2 * this.strokeWidth,
2373
2383
  });
2374
2384
  this.offset = computed(() => {
2375
2385
  switch (this.rawHandle.position) {
2376
- case 'left': return {
2377
- x: 0,
2378
- y: this.parentPosition().y + (this.parentSize().height / 2)
2379
- };
2380
- case 'right': return {
2381
- x: this.parentNode.size().width,
2382
- y: this.parentPosition().y + (this.parentSize().height / 2)
2383
- };
2384
- case 'top': return {
2385
- x: this.parentPosition().x + (this.parentSize().width / 2),
2386
- y: 0
2387
- };
2388
- case 'bottom': return {
2389
- x: this.parentPosition().x + this.parentSize().width / 2,
2390
- y: this.parentNode.size().height
2391
- };
2386
+ case 'left':
2387
+ return {
2388
+ x: 0,
2389
+ y: this.parentPosition().y + this.parentSize().height / 2,
2390
+ };
2391
+ case 'right':
2392
+ return {
2393
+ x: this.parentNode.size().width,
2394
+ y: this.parentPosition().y + this.parentSize().height / 2,
2395
+ };
2396
+ case 'top':
2397
+ return {
2398
+ x: this.parentPosition().x + this.parentSize().width / 2,
2399
+ y: 0,
2400
+ };
2401
+ case 'bottom':
2402
+ return {
2403
+ x: this.parentPosition().x + this.parentSize().width / 2,
2404
+ y: this.parentNode.size().height,
2405
+ };
2392
2406
  }
2393
2407
  });
2394
2408
  this.sizeOffset = computed(() => {
2395
2409
  switch (this.rawHandle.position) {
2396
- case 'left': return { x: -(this.size().width / 2), y: 0 };
2397
- case 'right': return { x: this.size().width / 2, y: 0 };
2398
- case 'top': return { x: 0, y: -(this.size().height / 2) };
2399
- case 'bottom': return { x: 0, y: this.size().height / 2 };
2410
+ case 'left':
2411
+ return { x: -(this.size().width / 2), y: 0 };
2412
+ case 'right':
2413
+ return { x: this.size().width / 2, y: 0 };
2414
+ case 'top':
2415
+ return { x: 0, y: -(this.size().height / 2) };
2416
+ case 'bottom':
2417
+ return { x: 0, y: this.size().height / 2 };
2400
2418
  }
2401
2419
  });
2402
2420
  this.pointAbsolute = computed(() => {
@@ -2408,17 +2426,13 @@ class HandleModel {
2408
2426
  this.state = signal('idle');
2409
2427
  this.updateParentSizeAndPosition$ = new Subject();
2410
2428
  this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
2411
- initialValue: { width: 0, height: 0 }
2429
+ initialValue: { width: 0, height: 0 },
2412
2430
  });
2413
2431
  this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
2414
- x: this.parentReference instanceof HTMLElement
2415
- ? this.parentReference.offsetLeft
2416
- : 0, // for now just 0 for group nodes
2417
- y: this.parentReference instanceof HTMLElement
2418
- ? this.parentReference.offsetTop
2419
- : 0 // for now just 0 for group nodes
2432
+ x: this.parentReference instanceof HTMLElement ? this.parentReference.offsetLeft : 0, // for now just 0 for group nodes
2433
+ y: this.parentReference instanceof HTMLElement ? this.parentReference.offsetTop : 0, // for now just 0 for group nodes
2420
2434
  }))), {
2421
- initialValue: { x: 0, y: 0 }
2435
+ initialValue: { x: 0, y: 0 },
2422
2436
  });
2423
2437
  this.parentReference = this.rawHandle.parentReference;
2424
2438
  this.template = this.rawHandle.template;
@@ -2426,8 +2440,8 @@ class HandleModel {
2426
2440
  $implicit: {
2427
2441
  point: this.offset,
2428
2442
  state: this.state,
2429
- node: this.parentNode.node
2430
- }
2443
+ node: this.parentNode.node,
2444
+ },
2431
2445
  };
2432
2446
  }
2433
2447
  updateParent() {
@@ -2437,7 +2451,7 @@ class HandleModel {
2437
2451
  if (this.parentReference instanceof HTMLElement) {
2438
2452
  return {
2439
2453
  width: this.parentReference.offsetWidth,
2440
- height: this.parentReference.offsetHeight
2454
+ height: this.parentReference.offsetHeight,
2441
2455
  };
2442
2456
  }
2443
2457
  else if (this.parentReference instanceof SVGGraphicsElement) {
@@ -2537,8 +2551,7 @@ class NodeComponent {
2537
2551
  }
2538
2552
  ngAfterViewInit() {
2539
2553
  this.nodeModel().linkDefaultNodeSizeWithModelSize();
2540
- if (this.nodeModel().node.type === 'html-template' ||
2541
- this.nodeModel().isComponentType) {
2554
+ if (this.nodeModel().node.type === 'html-template' || this.nodeModel().isComponentType) {
2542
2555
  resizable([this.htmlWrapperRef().nativeElement], this.zone)
2543
2556
  .pipe(startWith(null), tap(() => this.nodeModel()
2544
2557
  .handles()
@@ -2564,8 +2577,8 @@ class NodeComponent {
2564
2577
  resetValidateConnection(targetHandle) {
2565
2578
  this.connectionController.resetValidateConnection(targetHandle);
2566
2579
  }
2567
- endConnection(handle) {
2568
- this.connectionController.endConnection(handle);
2580
+ endConnection() {
2581
+ this.connectionController.endConnection();
2569
2582
  }
2570
2583
  pullNode() {
2571
2584
  this.nodeRenderingService.pullNode(this.nodeModel());
@@ -2576,7 +2589,7 @@ class NodeComponent {
2576
2589
  }
2577
2590
  }
2578
2591
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2579
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { nodeModel: { classPropertyName: "nodeModel", publicName: "nodeModel", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], viewQueries: [{ propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n >\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2592
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { nodeModel: { classPropertyName: "nodeModel", publicName: "nodeModel", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], viewQueries: [{ propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Default node -->\n@if (nodeModel().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\">\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\">\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\">\n <div #htmlWrapper class=\"wrapper\" [style.width]=\"styleWidth()\" [style.height]=\"styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\">\n <div #htmlWrapper class=\"wrapper\" [style.width]=\"styleWidth()\" [style.height]=\"styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\">\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\">\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }, { kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }, { kind: "component", type: HandleComponent, selector: "handle", inputs: ["position", "type", "id", "template"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: ResizableComponent, selector: "[resizable]", inputs: ["resizable", "resizerColor", "gap"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2580
2593
  }
2581
2594
  __decorate([
2582
2595
  InjectionContext
@@ -2596,7 +2609,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
2596
2609
  NgComponentOutlet,
2597
2610
  ResizableComponent,
2598
2611
  HandleSizeControllerDirective,
2599
- ], template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\"\n >\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
2612
+ ], template: "<!-- Default node -->\n@if (nodeModel().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\">\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\">\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\">\n <div #htmlWrapper class=\"wrapper\" [style.width]=\"styleWidth()\" [style.height]=\"styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\">\n <div #htmlWrapper class=\"wrapper\" [style.width]=\"styleWidth()\" [style.height]=\"styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\">\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@if (toolbar(); as toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\">\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
2600
2613
  }], propDecorators: { ngOnInit: [], ngAfterViewInit: [] } });
2601
2614
 
2602
2615
  class ConnectionComponent {
@@ -2671,12 +2684,11 @@ class ConnectionComponent {
2671
2684
  @if (model().type === 'default') {
2672
2685
  @if (path(); as path) {
2673
2686
  <svg:path
2674
- [attr.d]="path"
2675
- [attr.marker-end]="markerUrl()"
2676
- [attr.stroke]="defaultColor"
2677
2687
  fill="none"
2678
2688
  stroke-width="2"
2679
- />
2689
+ [attr.d]="path"
2690
+ [attr.marker-end]="markerUrl()"
2691
+ [attr.stroke]="defaultColor" />
2680
2692
  }
2681
2693
  }
2682
2694
 
@@ -2696,12 +2708,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
2696
2708
  @if (model().type === 'default') {
2697
2709
  @if (path(); as path) {
2698
2710
  <svg:path
2699
- [attr.d]="path"
2700
- [attr.marker-end]="markerUrl()"
2701
- [attr.stroke]="defaultColor"
2702
2711
  fill="none"
2703
2712
  stroke-width="2"
2704
- />
2713
+ [attr.d]="path"
2714
+ [attr.marker-end]="markerUrl()"
2715
+ [attr.stroke]="defaultColor" />
2705
2716
  }
2706
2717
  }
2707
2718
 
@@ -2798,9 +2809,7 @@ class BackgroundComponent {
2798
2809
  if (!background.repeat) {
2799
2810
  return background.fixed ? 0 : this.viewportService.readableViewport().x;
2800
2811
  }
2801
- return background.fixed
2802
- ? 0
2803
- : this.viewportService.readableViewport().x % this.scaledImageWidth();
2812
+ return background.fixed ? 0 : this.viewportService.readableViewport().x % this.scaledImageWidth();
2804
2813
  }
2805
2814
  return 0;
2806
2815
  });
@@ -2810,9 +2819,7 @@ class BackgroundComponent {
2810
2819
  if (!background.repeat) {
2811
2820
  return background.fixed ? 0 : this.viewportService.readableViewport().y;
2812
2821
  }
2813
- return background.fixed
2814
- ? 0
2815
- : this.viewportService.readableViewport().y % this.scaledImageHeight();
2822
+ return background.fixed ? 0 : this.viewportService.readableViewport().y % this.scaledImageHeight();
2816
2823
  }
2817
2824
  return 0;
2818
2825
  });
@@ -2835,16 +2842,16 @@ class BackgroundComponent {
2835
2842
  });
2836
2843
  }
2837
2844
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2838
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: BackgroundComponent, isStandalone: true, selector: "g[background]", ngImport: i0, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2845
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: BackgroundComponent, isStandalone: true, selector: "g[background]", ngImport: i0, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n patternUnits=\"userSpaceOnUse\"\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\">\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\" />\n </svg:pattern>\n\n <svg:rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" [attr.fill]=\"patternUrl\" />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n patternUnits=\"userSpaceOnUse\"\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\">\n <svg:image [attr.href]=\"bgImageSrc()\" [attr.width]=\"scaledImageWidth()\" [attr.height]=\"scaledImageHeight()\" />\n </svg:pattern>\n\n <svg:rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" [attr.fill]=\"patternUrl\" />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\" />\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2839
2846
  }
2840
2847
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, decorators: [{
2841
2848
  type: Component,
2842
- args: [{ standalone: true, selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n" }]
2849
+ args: [{ standalone: true, selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n patternUnits=\"userSpaceOnUse\"\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\">\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\" />\n </svg:pattern>\n\n <svg:rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" [attr.fill]=\"patternUrl\" />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n patternUnits=\"userSpaceOnUse\"\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\">\n <svg:image [attr.href]=\"bgImageSrc()\" [attr.width]=\"scaledImageWidth()\" [attr.height]=\"scaledImageHeight()\" />\n </svg:pattern>\n\n <svg:rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" [attr.fill]=\"patternUrl\" />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\" />\n }\n}\n" }]
2843
2850
  }], ctorParameters: () => [] });
2844
2851
  function createImage(url) {
2845
2852
  const image = new Image();
2846
2853
  image.src = url;
2847
- return new Promise(resolve => {
2854
+ return new Promise((resolve) => {
2848
2855
  image.onload = () => resolve(image);
2849
2856
  });
2850
2857
  }
@@ -2855,11 +2862,11 @@ class DefsComponent {
2855
2862
  this.defaultColor = 'rgb(177, 177, 183)';
2856
2863
  }
2857
2864
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2858
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DefsComponent, isStandalone: true, selector: "defs[flowDefs]", inputs: { markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2865
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DefsComponent, isStandalone: true, selector: "defs[flowDefs]", inputs: { markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n viewBox=\"-10 -10 20 20\"\n refX=\"0\"\n refY=\"0\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\">\n @if (marker.value.type === 'arrow-closed' || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\" />\n }\n\n @if (marker.value.type === 'arrow') {\n <polyline\n class=\"marker__arrow_default\"\n points=\"-5,-4 0,0 -5,4\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\" />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2859
2866
  }
2860
2867
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, decorators: [{
2861
2868
  type: Component,
2862
- args: [{ standalone: true, selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KeyValuePipe], template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
2869
+ args: [{ standalone: true, selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KeyValuePipe], template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n viewBox=\"-10 -10 20 20\"\n refX=\"0\"\n refY=\"0\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\">\n @if (marker.value.type === 'arrow-closed' || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\" />\n }\n\n @if (marker.value.type === 'arrow') {\n <polyline\n class=\"marker__arrow_default\"\n points=\"-5,-4 0,0 -5,4\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\" />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
2863
2870
  }] });
2864
2871
 
2865
2872
  class FlowSizeControllerDirective {
@@ -2874,10 +2881,12 @@ class FlowSizeControllerDirective {
2874
2881
  const view = this.flowSettingsService.view();
2875
2882
  return view === 'auto' ? '100%' : view[1];
2876
2883
  });
2877
- resizable([this.host.nativeElement], inject(NgZone)).pipe(tap(([entry]) => {
2884
+ resizable([this.host.nativeElement], inject(NgZone))
2885
+ .pipe(tap(([entry]) => {
2878
2886
  this.flowSettingsService.computedFlowWidth.set(entry.contentRect.width);
2879
2887
  this.flowSettingsService.computedFlowHeight.set(entry.contentRect.height);
2880
- }), takeUntilDestroyed()).subscribe();
2888
+ }), takeUntilDestroyed())
2889
+ .subscribe();
2881
2890
  }
2882
2891
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2883
2892
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: FlowSizeControllerDirective, isStandalone: true, selector: "svg[flowSizeController]", host: { properties: { "attr.width": "flowWidth()", "attr.height": "flowHeight()" } }, ngImport: i0 }); }
@@ -2889,7 +2898,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
2889
2898
  selector: 'svg[flowSizeController]',
2890
2899
  host: {
2891
2900
  '[attr.width]': 'flowWidth()',
2892
- '[attr.height]': 'flowHeight()'
2901
+ '[attr.height]': 'flowHeight()',
2893
2902
  },
2894
2903
  }]
2895
2904
  }], ctorParameters: () => [] });
@@ -3199,7 +3208,7 @@ class VflowComponent {
3199
3208
  ComponentEventBusService,
3200
3209
  KeyboardService,
3201
3210
  OverlaysService,
3202
- ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3211
+ ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3203
3212
  }
3204
3213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
3205
3214
  type: Component,
@@ -3216,10 +3225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
3216
3225
  ComponentEventBusService,
3217
3226
  KeyboardService,
3218
3227
  OverlaysService,
3219
- ], hostDirectives: [
3220
- connectionControllerHostDirective,
3221
- changesControllerHostDirective,
3222
- ], imports: [
3228
+ ], hostDirectives: [connectionControllerHostDirective, changesControllerHostDirective], imports: [
3223
3229
  RootSvgReferenceDirective,
3224
3230
  RootSvgContextDirective,
3225
3231
  RootPointerDirective,
@@ -3232,7 +3238,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
3232
3238
  NodeComponent,
3233
3239
  EdgeComponent,
3234
3240
  NgTemplateOutlet,
3235
- ], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\"\n />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3241
+ ], template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!optimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
3236
3242
  }], propDecorators: { view: [{
3237
3243
  type: Input
3238
3244
  }], minZoom: [{
@@ -3265,7 +3271,7 @@ class DragHandleDirective {
3265
3271
  this.nodeAccessor = inject(NodeAccessorService);
3266
3272
  this.model.dragHandlesCount.update((count) => count + 1);
3267
3273
  inject(DestroyRef).onDestroy(() => {
3268
- this.model.dragHandlesCount.update(count => count - 1);
3274
+ this.model.dragHandlesCount.update((count) => count - 1);
3269
3275
  });
3270
3276
  }
3271
3277
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
@@ -3277,7 +3283,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
3277
3283
  standalone: true,
3278
3284
  selector: '[dragHandle]',
3279
3285
  host: {
3280
- 'class': 'vflow-drag-handle'
3286
+ class: 'vflow-drag-handle',
3281
3287
  },
3282
3288
  }]
3283
3289
  }], ctorParameters: () => [] });
@@ -3371,26 +3377,18 @@ class MiniMapComponent {
3371
3377
  return { x: this.minimapOffset, y: this.minimapOffset };
3372
3378
  case 'top-right':
3373
3379
  return {
3374
- x: this.flowSettingsService.computedFlowWidth() -
3375
- this.minimapWidth() -
3376
- this.minimapOffset,
3380
+ x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3377
3381
  y: this.minimapOffset,
3378
3382
  };
3379
3383
  case 'bottom-left':
3380
3384
  return {
3381
3385
  x: this.minimapOffset,
3382
- y: this.flowSettingsService.computedFlowHeight() -
3383
- this.minimapHeight() -
3384
- this.minimapOffset,
3386
+ y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset,
3385
3387
  };
3386
3388
  case 'bottom-right':
3387
3389
  return {
3388
- x: this.flowSettingsService.computedFlowWidth() -
3389
- this.minimapWidth() -
3390
- this.minimapOffset,
3391
- y: this.flowSettingsService.computedFlowHeight() -
3392
- this.minimapHeight() -
3393
- this.minimapOffset,
3390
+ x: this.flowSettingsService.computedFlowWidth() - this.minimapWidth() - this.minimapOffset,
3391
+ y: this.flowSettingsService.computedFlowHeight() - this.minimapHeight() - this.minimapOffset,
3394
3392
  };
3395
3393
  }
3396
3394
  });
@@ -3427,11 +3425,11 @@ class MiniMapComponent {
3427
3425
  return node;
3428
3426
  }
3429
3427
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3430
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MiniMapComponent, isStandalone: true, selector: "mini-map", inputs: { maskColor: { classPropertyName: "maskColor", publicName: "maskColor", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }] }); }
3428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MiniMapComponent, isStandalone: true, selector: "mini-map", inputs: { maskColor: { classPropertyName: "maskColor", publicName: "maskColor", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n fill=\"none\"\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\" />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\">\n <svg:rect [attr.width]=\"minimapWidth()\" [attr.height]=\"minimapHeight()\" [attr.fill]=\"maskColor()\" />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\" />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\">\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\">\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (model.node.type === 'default-group' || model.node.type === 'template-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\" />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3431
3429
  }
3432
3430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, decorators: [{
3433
3431
  type: Component,
3434
- args: [{ standalone: true, selector: 'mini-map', imports: [DefaultNodeComponent], template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\"\n />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
3432
+ args: [{ standalone: true, selector: 'mini-map', imports: [DefaultNodeComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #minimap>\n <svg:rect\n fill=\"none\"\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\" />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\">\n <svg:rect [attr.width]=\"minimapWidth()\" [attr.height]=\"minimapHeight()\" [attr.fill]=\"maskColor()\" />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\" />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (model.node.type === 'default' || model.node.type === 'html-template' || model.isComponentType) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\">\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\">\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (model.node.type === 'default-group' || model.node.type === 'template-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\n [class.default-group-node_selected]=\"model.selected()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n [style.stroke]=\"model.color()\"\n [style.fill]=\"model.color()\" />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
3435
3433
  }] });
3436
3434
 
3437
3435
  class ToolbarModel {
@@ -3445,22 +3443,22 @@ class ToolbarModel {
3445
3443
  case 'top':
3446
3444
  return {
3447
3445
  x: this.node.size().width / 2 - this.size().width / 2,
3448
- y: -this.size().height - this.offset()
3446
+ y: -this.size().height - this.offset(),
3449
3447
  };
3450
3448
  case 'bottom':
3451
3449
  return {
3452
3450
  x: this.node.size().width / 2 - this.size().width / 2,
3453
- y: this.node.size().height + this.offset()
3451
+ y: this.node.size().height + this.offset(),
3454
3452
  };
3455
3453
  case 'left':
3456
3454
  return {
3457
3455
  x: -this.size().width - this.offset(),
3458
- y: this.node.size().height / 2 - this.size().height / 2
3456
+ y: this.node.size().height / 2 - this.size().height / 2,
3459
3457
  };
3460
3458
  case 'right':
3461
3459
  return {
3462
3460
  x: this.node.size().width + this.offset(),
3463
- y: this.node.size().height / 2 - this.size().height / 2
3461
+ y: this.node.size().height / 2 - this.size().height / 2,
3464
3462
  };
3465
3463
  }
3466
3464
  });
@@ -3522,7 +3520,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
3522
3520
  type: Directive,
3523
3521
  args: [{
3524
3522
  selector: '[nodeToolbarWrapper]',
3525
- standalone: true
3523
+ standalone: true,
3526
3524
  }]
3527
3525
  }] });
3528
3526
 
@@ -3539,7 +3537,7 @@ const Vflow = [
3539
3537
  EdgeLabelHtmlTemplateDirective,
3540
3538
  EdgeTemplateDirective,
3541
3539
  ConnectionTemplateDirective,
3542
- HandleTemplateDirective
3540
+ HandleTemplateDirective,
3543
3541
  ];
3544
3542
 
3545
3543
  const mockModel = () => new NodeModel({ id: 'mock', type: 'default', point: { x: 0, y: 0 } });
@@ -3548,8 +3546,8 @@ function provideCustomNodeMocks() {
3548
3546
  {
3549
3547
  provide: ComponentEventBusService,
3550
3548
  useValue: {
3551
- pushEvent: () => { }
3552
- }
3549
+ pushEvent: () => { },
3550
+ },
3553
3551
  },
3554
3552
  {
3555
3553
  provide: HandleService,
@@ -3557,7 +3555,7 @@ function provideCustomNodeMocks() {
3557
3555
  node: signal(mockModel()),
3558
3556
  createHandle: () => { },
3559
3557
  destroyHandle: () => { },
3560
- })
3558
+ }),
3561
3559
  },
3562
3560
  {
3563
3561
  provide: RootPointerDirective,
@@ -3568,32 +3566,32 @@ function provideCustomNodeMocks() {
3568
3566
  movementX: 0,
3569
3567
  movementY: 0,
3570
3568
  target: null,
3571
- originalEvent: null
3569
+ originalEvent: null,
3572
3570
  }),
3573
- documentPointerEnd$: of(null)
3574
- }
3571
+ documentPointerEnd$: of(null),
3572
+ },
3575
3573
  },
3576
3574
  {
3577
3575
  provide: SpacePointContextDirective,
3578
3576
  useValue: {
3579
- documentPointToFlowPoint: (point) => point
3580
- }
3577
+ documentPointToFlowPoint: (point) => point,
3578
+ },
3581
3579
  },
3582
3580
  {
3583
3581
  provide: NodeAccessorService,
3584
3582
  useFactory: () => ({
3585
- model: signal(mockModel())
3586
- })
3583
+ model: signal(mockModel()),
3584
+ }),
3587
3585
  },
3588
3586
  {
3589
3587
  provide: SelectionService,
3590
3588
  useValue: {
3591
3589
  select: () => { },
3592
- }
3590
+ },
3593
3591
  },
3594
3592
  FlowSettingsService,
3595
3593
  FlowEntitiesService,
3596
- ViewportService
3594
+ ViewportService,
3597
3595
  ];
3598
3596
  }
3599
3597