ngx-vflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/vflow/components/connection/connection.component.mjs +100 -0
  3. package/esm2022/lib/vflow/components/defs/defs.component.mjs +19 -0
  4. package/esm2022/lib/vflow/components/edge/edge.component.mjs +42 -0
  5. package/esm2022/lib/vflow/components/edge-label/edge-label.component.mjs +58 -0
  6. package/esm2022/lib/vflow/components/node/node.component.mjs +146 -0
  7. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +183 -0
  8. package/esm2022/lib/vflow/directives/changes-controller.directive.mjs +34 -0
  9. package/esm2022/lib/vflow/directives/connection-controller.directive.mjs +36 -0
  10. package/esm2022/lib/vflow/directives/map-context.directive.mjs +62 -0
  11. package/esm2022/lib/vflow/directives/reference.directive.mjs +16 -0
  12. package/esm2022/lib/vflow/directives/root-svg-context.directive.mjs +26 -0
  13. package/esm2022/lib/vflow/directives/space-point-context.directive.mjs +29 -0
  14. package/esm2022/lib/vflow/directives/template.directive.mjs +58 -0
  15. package/esm2022/lib/vflow/interfaces/connection-settings.interface.mjs +2 -0
  16. package/esm2022/lib/vflow/interfaces/connection.interface.mjs +2 -0
  17. package/esm2022/lib/vflow/interfaces/edge-label.interface.mjs +2 -0
  18. package/esm2022/lib/vflow/interfaces/edge.interface.mjs +2 -0
  19. package/esm2022/lib/vflow/interfaces/handle-positions.interface.mjs +2 -0
  20. package/esm2022/lib/vflow/interfaces/marker.interface.mjs +2 -0
  21. package/esm2022/lib/vflow/interfaces/node.interface.mjs +2 -0
  22. package/esm2022/lib/vflow/interfaces/path-data.interface.mjs +2 -0
  23. package/esm2022/lib/vflow/interfaces/point.interface.mjs +2 -0
  24. package/esm2022/lib/vflow/interfaces/template-context.interface.mjs +2 -0
  25. package/esm2022/lib/vflow/interfaces/viewport.interface.mjs +2 -0
  26. package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +77 -0
  27. package/esm2022/lib/vflow/math/edge-path/straigh-path.mjs +18 -0
  28. package/esm2022/lib/vflow/math/point-on-line-by-ratio.mjs +12 -0
  29. package/esm2022/lib/vflow/models/connection.model.mjs +9 -0
  30. package/esm2022/lib/vflow/models/edge-label.model.mjs +8 -0
  31. package/esm2022/lib/vflow/models/edge.model.mjs +30 -0
  32. package/esm2022/lib/vflow/models/flow.model.mjs +16 -0
  33. package/esm2022/lib/vflow/models/node.model.mjs +90 -0
  34. package/esm2022/lib/vflow/services/draggable.service.mjs +66 -0
  35. package/esm2022/lib/vflow/services/edge-changes.service.mjs +38 -0
  36. package/esm2022/lib/vflow/services/flow-entities.service.mjs +49 -0
  37. package/esm2022/lib/vflow/services/flow-status.service.mjs +39 -0
  38. package/esm2022/lib/vflow/services/node-changes.service.mjs +32 -0
  39. package/esm2022/lib/vflow/services/viewport.service.mjs +32 -0
  40. package/esm2022/lib/vflow/types/edge-change.type.mjs +2 -0
  41. package/esm2022/lib/vflow/types/node-change.type.mjs +2 -0
  42. package/esm2022/lib/vflow/types/position.type.mjs +2 -0
  43. package/esm2022/lib/vflow/types/using-points.type.mjs +2 -0
  44. package/esm2022/lib/vflow/types/viewport-change-type.type.mjs +2 -0
  45. package/esm2022/lib/vflow/utils/add-nodes-to-edges.mjs +11 -0
  46. package/esm2022/lib/vflow/utils/hash.mjs +7 -0
  47. package/esm2022/lib/vflow/utils/is-defined.mjs +4 -0
  48. package/esm2022/lib/vflow/utils/reference-keeper.mjs +31 -0
  49. package/esm2022/lib/vflow/utils/round.mjs +2 -0
  50. package/esm2022/lib/vflow/vflow.module.mjs +68 -0
  51. package/esm2022/ngx-vflow.mjs +5 -0
  52. package/esm2022/public-api.mjs +23 -0
  53. package/fesm2022/ngx-vflow.mjs +1332 -0
  54. package/fesm2022/ngx-vflow.mjs.map +1 -0
  55. package/index.d.ts +5 -0
  56. package/lib/vflow/components/connection/connection.component.d.ts +20 -0
  57. package/lib/vflow/components/defs/defs.component.d.ts +8 -0
  58. package/lib/vflow/components/edge/edge.component.d.ts +16 -0
  59. package/lib/vflow/components/edge-label/edge-label.component.d.ts +31 -0
  60. package/lib/vflow/components/node/node.component.d.ts +53 -0
  61. package/lib/vflow/components/vflow/vflow.component.d.ts +73 -0
  62. package/lib/vflow/directives/changes-controller.directive.d.ts +16 -0
  63. package/lib/vflow/directives/connection-controller.directive.d.ts +11 -0
  64. package/lib/vflow/directives/map-context.directive.d.ts +19 -0
  65. package/lib/vflow/directives/reference.directive.d.ts +6 -0
  66. package/lib/vflow/directives/root-svg-context.directive.d.ts +7 -0
  67. package/lib/vflow/directives/space-point-context.directive.d.ts +14 -0
  68. package/lib/vflow/directives/template.directive.d.ts +28 -0
  69. package/lib/vflow/interfaces/connection-settings.interface.d.ts +10 -0
  70. package/lib/vflow/interfaces/connection.interface.d.ts +4 -0
  71. package/lib/vflow/interfaces/edge-label.interface.d.ts +6 -0
  72. package/lib/vflow/interfaces/edge.interface.d.ts +18 -0
  73. package/lib/vflow/interfaces/handle-positions.interface.d.ts +5 -0
  74. package/lib/vflow/interfaces/marker.interface.d.ts +9 -0
  75. package/lib/vflow/interfaces/node.interface.d.ts +16 -0
  76. package/lib/vflow/interfaces/path-data.interface.d.ts +8 -0
  77. package/lib/vflow/interfaces/point.interface.d.ts +4 -0
  78. package/lib/vflow/interfaces/template-context.interface.d.ts +10 -0
  79. package/lib/vflow/interfaces/viewport.interface.d.ts +9 -0
  80. package/lib/vflow/math/edge-path/bezier-path.d.ts +5 -0
  81. package/lib/vflow/math/edge-path/straigh-path.d.ts +4 -0
  82. package/lib/vflow/math/point-on-line-by-ratio.d.ts +7 -0
  83. package/lib/vflow/models/connection.model.d.ts +9 -0
  84. package/lib/vflow/models/edge-label.model.d.ts +9 -0
  85. package/lib/vflow/models/edge.model.d.ts +17 -0
  86. package/lib/vflow/models/flow.model.d.ts +14 -0
  87. package/lib/vflow/models/node.model.d.ts +70 -0
  88. package/lib/vflow/services/draggable.service.d.ts +32 -0
  89. package/lib/vflow/services/edge-changes.service.d.ts +22 -0
  90. package/lib/vflow/services/flow-entities.service.d.ts +15 -0
  91. package/lib/vflow/services/flow-status.service.d.ts +43 -0
  92. package/lib/vflow/services/node-changes.service.d.ts +26 -0
  93. package/lib/vflow/services/viewport.service.d.ts +24 -0
  94. package/lib/vflow/types/edge-change.type.d.ts +14 -0
  95. package/lib/vflow/types/node-change.type.d.ts +16 -0
  96. package/lib/vflow/types/position.type.d.ts +1 -0
  97. package/lib/vflow/types/using-points.type.d.ts +5 -0
  98. package/lib/vflow/types/viewport-change-type.type.d.ts +3 -0
  99. package/lib/vflow/utils/add-nodes-to-edges.d.ts +3 -0
  100. package/lib/vflow/utils/hash.d.ts +1 -0
  101. package/lib/vflow/utils/is-defined.d.ts +1 -0
  102. package/lib/vflow/utils/reference-keeper.d.ts +14 -0
  103. package/lib/vflow/utils/round.d.ts +1 -0
  104. package/lib/vflow/vflow.module.d.ts +18 -0
  105. package/package.json +25 -0
  106. package/public-api.d.ts +18 -0
@@ -0,0 +1,77 @@
1
+ import { path as d3Path } from 'd3-path';
2
+ import { getPointOnLineByRatio } from '../point-on-line-by-ratio';
3
+ export function bezierPath(source, target, sourcePosition, targetPosition, usingPoints = [false, false, false]) {
4
+ const path = d3Path();
5
+ path.moveTo(source.x, source.y);
6
+ const distanceVector = { x: source.x - target.x, y: source.y - target.y };
7
+ const firstControl = calcControlPoint(source, sourcePosition, distanceVector);
8
+ const secondControl = calcControlPoint(target, targetPosition, distanceVector);
9
+ path.bezierCurveTo(firstControl.x, firstControl.y, secondControl.x, secondControl.y, target.x, target.y);
10
+ return getPathData(path, source, target, firstControl, secondControl, usingPoints);
11
+ }
12
+ /**
13
+ * Calculate control point based on provided point
14
+ *
15
+ * @param point relative this point control point is gonna be computed (the source or the target)
16
+ * @param pointPosition position of {point} on block
17
+ * @param distanceVector transmits the distance between the source and the target as x and y coordinates
18
+ */
19
+ function calcControlPoint(point, pointPosition, distanceVector) {
20
+ const factorPoint = { x: 0, y: 0 };
21
+ switch (pointPosition) {
22
+ case 'top':
23
+ factorPoint.y = 1;
24
+ break;
25
+ case 'bottom':
26
+ factorPoint.y = -1;
27
+ break;
28
+ case 'right':
29
+ factorPoint.x = 1;
30
+ break;
31
+ case 'left':
32
+ factorPoint.x = -1;
33
+ break;
34
+ }
35
+ // TODO: explain name
36
+ const fullDistanceVector = {
37
+ x: distanceVector.x * Math.abs(factorPoint.x),
38
+ y: distanceVector.y * Math.abs(factorPoint.y),
39
+ };
40
+ // TODO: probably need to make this configurable
41
+ const curvature = 0.25;
42
+ // thanks colleagues from react/svelte world
43
+ // https://github.com/xyflow/xyflow/blob/f0117939bae934447fa7f232081f937169ee23b5/packages/system/src/utils/edges/bezier-edge.ts#L56
44
+ const controlOffset = curvature * 25 * Math.sqrt(Math.abs(fullDistanceVector.x + fullDistanceVector.y));
45
+ return {
46
+ x: point.x + factorPoint.x * controlOffset,
47
+ y: point.y - factorPoint.y * controlOffset,
48
+ };
49
+ }
50
+ function getPathData(path, source, target, firstControl, secondControl, usingPoints) {
51
+ const [start, center, end] = usingPoints;
52
+ const nullPoint = { x: 0, y: 0 };
53
+ return {
54
+ path: path.toString(),
55
+ points: {
56
+ start: start
57
+ ? getPointOnBezier(source, target, firstControl, secondControl, 0.1)
58
+ : nullPoint,
59
+ center: center
60
+ ? getPointOnBezier(source, target, firstControl, secondControl, 0.5)
61
+ : nullPoint,
62
+ end: end
63
+ ? getPointOnBezier(source, target, firstControl, secondControl, 0.9)
64
+ : nullPoint,
65
+ },
66
+ };
67
+ }
68
+ /**
69
+ * Get point on bezier curve by ratio
70
+ */
71
+ function getPointOnBezier(sourcePoint, targetPoint, controlPoint1, controlPoint2, ratio) {
72
+ const fromSourceToFirstControl = getPointOnLineByRatio(sourcePoint, controlPoint1, ratio);
73
+ const fromFirstControlToSecond = getPointOnLineByRatio(controlPoint1, controlPoint2, ratio);
74
+ const fromSecondControlToTarget = getPointOnLineByRatio(controlPoint2, targetPoint, ratio);
75
+ return getPointOnLineByRatio(getPointOnLineByRatio(fromSourceToFirstControl, fromFirstControlToSecond, ratio), getPointOnLineByRatio(fromFirstControlToSecond, fromSecondControlToTarget, ratio), ratio);
76
+ }
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmV6aWVyLXBhdGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvbWF0aC9lZGdlLXBhdGgvYmV6aWVyLXBhdGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFRLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFHL0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFbEUsTUFBTSxVQUFVLFVBQVUsQ0FDeEIsTUFBYSxFQUNiLE1BQWEsRUFDYixjQUF3QixFQUN4QixjQUF3QixFQUN4QixjQUEyQixDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO0lBRWhELE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDO0lBRXRCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFaEMsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUUxRSxNQUFNLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQzlFLE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFFL0UsSUFBSSxDQUFDLGFBQWEsQ0FDaEIsWUFBWSxDQUFDLENBQUMsRUFDZCxZQUFZLENBQUMsQ0FBQyxFQUNkLGFBQWEsQ0FBQyxDQUFDLEVBQ2YsYUFBYSxDQUFDLENBQUMsRUFDZixNQUFNLENBQUMsQ0FBQyxFQUNSLE1BQU0sQ0FBQyxDQUFD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QUFvQixFQUNwQixhQUFvQixFQUNwQixLQUFhO0lBRWIsTUFBTSx3QkFBd0IsR0FBVSxxQkFBcUIsQ0FDM0QsV0FBVyxFQUNYLGFBQWEsRUFDYixLQUFLLENBQ04sQ0FBQztJQUNGLE1BQU0sd0JBQXdCLEdBQVUscUJBQXFCLENBQzNELGFBQWEsRUFDYixhQUFhLEVBQ2IsS0FBSyxDQUNOLENBQUM7SUFDRixNQUFNLHlCQUF5QixHQUFVLHFCQUFxQixDQUM1RCxhQUFhLEVBQ2IsV0FBVyxFQUNYLEtBQUssQ0FDTixDQUFDO0lBRUYsT0FBTyxxQkFBcUIsQ0FDMUIscUJBQXFCLENBQUMsd0JBQXdCLEVBQUUsd0JBQXdCLEVBQUUsS0FBSyxDQUFDLEVBQ2hGLHFCQUFxQixDQUFDLHdCQUF3QixFQUFFLHlCQUF5QixFQUFFLEtBQUssQ0FBQyxFQUNqRixLQUFLLENBQ04sQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXRoRGF0YSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcGF0aC1kYXRhLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQb2ludCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcG9pbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFBhdGgsIHBhdGggYXMgZDNQYXRoIH0gZnJvbSAnZDMtcGF0aCc7XG5pbXBvcnQgeyBVc2luZ1BvaW50cyB9IGZyb20gJy4uLy4uL3R5cGVzL3VzaW5nLXBvaW50cy50eXBlJztcbmltcG9ydCB7IFBvc2l0aW9uIH0gZnJvbSAnLi4vLi4vdHlwZXMvcG9zaXRpb24udHlwZSc7XG5pbXBvcnQgeyBnZXRQb2ludE9uTGluZUJ5UmF0aW8gfSBmcm9tICcuLi9wb2ludC1vbi1saW5lLWJ5LXJhdGlvJztcblxuZXhwb3J0IGZ1bmN0aW9uIGJlemllclBhdGgoXG4gIHNvdXJjZTogUG9pbnQsXG4gIHRhcmdldDogUG9pbnQsXG4gIHNvdXJjZVBvc2l0aW9uOiBQb3NpdGlvbixcbiAgdGFyZ2V0UG9zaXRpb246IFBvc2l0aW9uLFxuICB1c2luZ1BvaW50czogVXNpbmdQb2ludHMgPSBbZmFsc2UsIGZhbHNlLCBmYWxzZV1cbik6IFBhdGhEYXRhIHtcbiAgY29uc3QgcGF0aCA9IGQzUGF0aCgpO1xuXG4gIHBhdGgubW92ZVRvKHNvdXJjZS54LCBzb3VyY2UueSk7XG5cbiAgY29uc3QgZGlzdGFuY2VWZWN0b3IgPSB7IHg6IHNvdXJjZS54IC0gdGFyZ2V0LngsIHk6IHNvdXJjZS55IC0gdGFyZ2V0LnkgfTtcblxuICBjb25zdCBmaXJzdENvbnRyb2wgPSBjYWxjQ29udHJvbFBvaW50KHNvdXJjZSwgc291cmNlUG9zaXRpb24sIGRpc3RhbmNlVmVjdG9yKTtcbiAgY29uc3Qgc2Vjb25kQ29udHJvbCA9IGNhbGNDb250cm9sUG9pbnQodGFyZ2V0LCB0YXJnZXRQb3NpdGlvbiwgZGlzdGFuY2VWZWN0b3IpO1xuXG4gIHBhdGguYmV6aWVyQ3VydmVUbyhcbiAgICBmaXJzdENvbnRyb2wueCxcbiAgICBmaXJzdENvbnRyb2wueSxcbiAgICBzZWNvbmRDb250cm9sLngsXG4gICAgc2Vjb25kQ29udHJvbC55LFxuICAgIHRhcmdldC54LFxuICAgIHRhcmdldC55XG4gICk7XG5cbiAgcmV0dXJuIGdldFBhdGhEYXRhKFxuICAgIHBhdGgsXG4gICAgc291cmNlLFxuICAgIHRhcmdldCxcbiAgICBmaXJzdENvbnRyb2wsXG4gICAgc2Vjb25kQ29udHJvbCxcbiAgICB1c2luZ1BvaW50c1xuICApO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBjb250cm9sIHBvaW50IGJhc2VkIG9uIHByb3ZpZGVkIHBvaW50XG4gKlxuICogQHBhcmFtIHBvaW50IHJlbGF0aXZlIHRoaXMgcG9pbnQgY29udHJvbCBwb2ludCBpcyBnb25uYSBiZSBjb21wdXRlZCAodGhlIHNvdXJjZSBvciB0aGUgdGFyZ2V0KVxuICogQHBhcmFtIHBvaW50UG9zaXRpb24gcG9zaXRpb24gb2Yge3BvaW50fSBvbiBibG9ja1xuICogQHBhcmFtIGRpc3RhbmNlVmVjdG9yIHRyYW5zbWl0cyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgc291cmNlIGFuZCB0aGUgdGFyZ2V0IGFzIHggYW5kIHkgY29vcmRpbmF0ZXNcbiAqL1xuXG5mdW5jdGlvbiBjYWxjQ29udHJvbFBvaW50KFxuICBwb2ludDogUG9pbnQsXG4gIHBvaW50UG9zaXRpb246IFBvc2l0aW9uLFxuICBkaXN0YW5jZVZlY3RvcjogUG9pbnRcbikge1xuICBjb25zdCBmYWN0b3JQb2ludCA9IHsgeDogMCwgeTogMCB9O1xuXG4gIHN3aXRjaCAocG9pbnRQb3NpdGlvbikge1xuICAgIGNhc2UgJ3RvcCc6XG4gICAgICBmYWN0b3JQb2ludC55ID0gMTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICBmYWN0b3JQb2ludC55ID0gLTE7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyaWdodCc6XG4gICAgICBmYWN0b3JQb2ludC54ID0gMTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgZmFjdG9yUG9pbnQueCA9IC0xO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICAvLyBUT0RPOiBleHBsYWluIG5hbWVcbiAgY29uc3QgZnVsbERpc3RhbmNlVmVjdG9yID0ge1xuICAgIHg6IGRpc3RhbmNlVmVjdG9yLnggKiBNYXRoLmFicyhmYWN0b3JQb2ludC54KSxcbiAgICB5OiBkaXN0YW5jZVZlY3Rvci55ICogTWF0aC5hYnMoZmFjdG9yUG9pbnQueSksXG4gIH07XG5cbiAgLy8gVE9ETzogcHJvYmFibHkgbmVlZCB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlXG4gIGNvbnN0IGN1cnZhdHVyZSA9IDAuMjU7XG4gIC8vIHRoYW5rcyBjb2xsZWFndWVzIGZyb20gcmVhY3Qvc3ZlbHRlIHdvcmxkXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS94eWZsb3cveHlmbG93L2Jsb2IvZjAxMTc5MzliYWU5MzQ0NDdmYTdmMjMyMDgxZjkzNzE2OWVlMjNiNS9wYWNrYWdlcy9zeXN0ZW0vc3JjL3V0aWxzL2VkZ2VzL2Jlemllci1lZGdlLnRzI0w1NlxuICBjb25zdCBjb250cm9sT2Zmc2V0ID1cbiAgICBjdXJ2YXR1cmUgKiAyNSAqIE1hdGguc3FydChNYXRoLmFicyhmdWxsRGlzdGFuY2VWZWN0b3IueCArIGZ1bGxEaXN0YW5jZVZlY3Rvci55KSk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBwb2ludC54ICsgZmFjdG9yUG9pbnQueCAqIGNvbnRyb2xPZmZzZXQsXG4gICAgeTogcG9pbnQueSAtIGZhY3RvclBvaW50LnkgKiBjb250cm9sT2Zmc2V0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRQYXRoRGF0YShcbiAgcGF0aDogUGF0aCxcbiAgc291cmNlOiBQb2ludCxcbiAgdGFyZ2V0OiBQb2ludCxcbiAgZmlyc3RDb250cm9sOiBQb2ludCxcbiAgc2Vjb25kQ29udHJvbDogUG9pbnQsXG4gIHVzaW5nUG9pbnRzOiBVc2luZ1BvaW50c1xuKTogUGF0aERhdGEge1xuICBjb25zdCBbc3RhcnQsIGNlbnRlciwgZW5kXSA9IHVzaW5nUG9pbnRzO1xuXG4gIGNvbnN0IG51bGxQb2ludCA9IHsgeDogMCwgeTogMCB9O1xuXG4gIHJldHVybiB7XG4gICAgcGF0aDogcGF0aC50b1N0cmluZygpLFxuICAgIHBvaW50czoge1xuICAgICAgc3RhcnQ6IHN0YXJ0XG4gICAgICAgID8gZ2V0UG9pbnRPbkJlemllcihzb3VyY2UsIHRhcmdldCwgZmlyc3RDb250cm9sLCBzZWNvbmRDb250cm9sLCAwLjEpXG4gICAgICAgIDogbnVsbFBvaW50LFxuICAgICAgY2VudGVyOiBjZW50ZXJcbiAgICAgICAgPyBnZXRQb2ludE9uQmV6aWVyKHNvdXJjZSwgdGFyZ2V0LCBmaXJzdENvbnRyb2wsIHNlY29uZENvbnRyb2wsIDAuNSlcbiAgICAgICAgOiBudWxsUG9pbnQsXG4gICAgICBlbmQ6IGVuZFxuICAgICAgICA/IGdldFBvaW50T25CZXppZXIoc291cmNlLCB0YXJnZXQsIGZpcnN0Q29udHJvbCwgc2Vjb25kQ29udHJvbCwgMC45KVxuICAgICAgICA6IG51bGxQb2ludCxcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEdldCBwb2ludCBvbiBiZXppZXIgY3VydmUgYnkgcmF0aW9cbiAqL1xuZnVuY3Rpb24gZ2V0UG9pbnRPbkJlemllcihcbiAgc291cmNlUG9pbnQ6IFBvaW50LFxuICB0YXJnZXRQb2ludDogUG9pbnQsXG4gIGNvbnRyb2xQb2ludDE6IFBvaW50LFxuICBjb250cm9sUG9pbnQyOiBQb2ludCxcbiAgcmF0aW86IG51bWJlclxuKTogUG9pbnQge1xuICBjb25zdCBmcm9tU291cmNlVG9GaXJzdENvbnRyb2w6IFBvaW50ID0gZ2V0UG9pbnRPbkxpbmVCeVJhdGlvKFxuICAgIHNvdXJjZVBvaW50LFxuICAgIGNvbnRyb2xQb2ludDEsXG4gICAgcmF0aW9cbiAgKTtcbiAgY29uc3QgZnJvbUZpcnN0Q29udHJvbFRvU2Vjb25kOiBQb2ludCA9IGdldFBvaW50T25MaW5lQnlSYXRpbyhcbiAgICBjb250cm9sUG9pbnQxLFxuICAgIGNvbnRyb2xQb2ludDIsXG4gICAgcmF0aW9cbiAgKTtcbiAgY29uc3QgZnJvbVNlY29uZENvbnRyb2xUb1RhcmdldDogUG9pbnQgPSBnZXRQb2ludE9uTGluZUJ5UmF0aW8oXG4gICAgY29udHJvbFBvaW50MixcbiAgICB0YXJnZXRQb2ludCxcbiAgICByYXRpb1xuICApO1xuXG4gIHJldHVybiBnZXRQb2ludE9uTGluZUJ5UmF0aW8oXG4gICAgZ2V0UG9pbnRPbkxpbmVCeVJhdGlvKGZyb21Tb3VyY2VUb0ZpcnN0Q29udHJvbCwgZnJvbUZpcnN0Q29udHJvbFRvU2Vjb25kLCByYXRpbyksXG4gICAgZ2V0UG9pbnRPbkxpbmVCeVJhdGlvKGZyb21GaXJzdENvbnRyb2xUb1NlY29uZCwgZnJvbVNlY29uZENvbnRyb2xUb1RhcmdldCwgcmF0aW8pLFxuICAgIHJhdGlvXG4gICk7XG59XG4iXX0=
@@ -0,0 +1,18 @@
1
+ import { path as d3Path } from 'd3-path';
2
+ import { getPointOnLineByRatio } from "../point-on-line-by-ratio";
3
+ export function straightPath(source, target, usingPoints = [false, false, false]) {
4
+ const [start, center, end] = usingPoints;
5
+ const nullPoint = { x: 0, y: 0 };
6
+ const path = d3Path();
7
+ path.moveTo(source.x, source.y);
8
+ path.lineTo(target.x, target.y);
9
+ return {
10
+ path: path.toString(),
11
+ points: {
12
+ start: start ? getPointOnLineByRatio(source, target, .15) : nullPoint,
13
+ center: center ? getPointOnLineByRatio(source, target, .50) : nullPoint,
14
+ end: end ? getPointOnLineByRatio(source, target, .85) : nullPoint,
15
+ }
16
+ };
17
+ }
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyYWlnaC1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXZmbG93LWxpYi9zcmMvbGliL3ZmbG93L21hdGgvZWRnZS1wYXRoL3N0cmFpZ2gtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsSUFBSSxJQUFJLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUV4QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVsRSxNQUFNLFVBQVUsWUFBWSxDQUMxQixNQUFhLEVBQ2IsTUFBYSxFQUNiLGNBQTJCLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7SUFFaEQsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFBO0lBQ3hDLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUE7SUFFaEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLENBQUE7SUFFckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBRS9CLE9BQU87UUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtRQUNyQixNQUFNLEVBQUU7WUFDTixLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ3JFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDdkUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUNsRTtLQUNGLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGF0aERhdGEgfSBmcm9tIFwiLi4vLi4vaW50ZXJmYWNlcy9wYXRoLWRhdGEuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQb2ludCB9IGZyb20gXCIuLi8uLi9pbnRlcmZhY2VzL3BvaW50LmludGVyZmFjZVwiO1xuaW1wb3J0IHsgcGF0aCBhcyBkM1BhdGggfSBmcm9tICdkMy1wYXRoJ1xuaW1wb3J0IHsgVXNpbmdQb2ludHMgfSBmcm9tIFwiLi4vLi4vdHlwZXMvdXNpbmctcG9pbnRzLnR5cGVcIjtcbmltcG9ydCB7IGdldFBvaW50T25MaW5lQnlSYXRpbyB9IGZyb20gXCIuLi9wb2ludC1vbi1saW5lLWJ5LXJhdGlvXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJhaWdodFBhdGgoXG4gIHNvdXJjZTogUG9pbnQsXG4gIHRhcmdldDogUG9pbnQsXG4gIHVzaW5nUG9pbnRzOiBVc2luZ1BvaW50cyA9IFtmYWxzZSwgZmFsc2UsIGZhbHNlXVxuKTogUGF0aERhdGEge1xuICBjb25zdCBbc3RhcnQsIGNlbnRlciwgZW5kXSA9IHVzaW5nUG9pbnRzXG4gIGNvbnN0IG51bGxQb2ludCA9IHsgeDogMCwgeTogMCB9XG5cbiAgY29uc3QgcGF0aCA9IGQzUGF0aCgpXG5cbiAgcGF0aC5tb3ZlVG8oc291cmNlLngsIHNvdXJjZS55KVxuICBwYXRoLmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpXG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoOiBwYXRoLnRvU3RyaW5nKCksXG4gICAgcG9pbnRzOiB7XG4gICAgICBzdGFydDogc3RhcnQgPyBnZXRQb2ludE9uTGluZUJ5UmF0aW8oc291cmNlLCB0YXJnZXQsIC4xNSkgOiBudWxsUG9pbnQsXG4gICAgICBjZW50ZXI6IGNlbnRlciA/IGdldFBvaW50T25MaW5lQnlSYXRpbyhzb3VyY2UsIHRhcmdldCwgLjUwKSA6IG51bGxQb2ludCxcbiAgICAgIGVuZDogZW5kID8gZ2V0UG9pbnRPbkxpbmVCeVJhdGlvKHNvdXJjZSwgdGFyZ2V0LCAuODUpIDogbnVsbFBvaW50LFxuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Get point on line
3
+ *
4
+ * https://math.stackexchange.com/questions/563566/how-do-i-find-the-middle1-2-1-3-1-4-etc-of-a-line
5
+ */
6
+ export function getPointOnLineByRatio(start, end, ratio) {
7
+ return {
8
+ x: (1 - ratio) * start.x + ratio * end.x,
9
+ y: (1 - ratio) * start.y + ratio * end.y,
10
+ };
11
+ }
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnQtb24tbGluZS1ieS1yYXRpby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tYXRoL3BvaW50LW9uLWxpbmUtYnktcmF0aW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUE7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFZLEVBQUUsR0FBVSxFQUFFLEtBQWE7SUFDM0UsT0FBTztRQUNMLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztRQUN4QyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7S0FDekMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQb2ludCB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL3BvaW50LmludGVyZmFjZVwiO1xuXG4vKipcbiAqIEdldCBwb2ludCBvbiBsaW5lXG4gKlxuICogaHR0cHM6Ly9tYXRoLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy81NjM1NjYvaG93LWRvLWktZmluZC10aGUtbWlkZGxlMS0yLTEtMy0xLTQtZXRjLW9mLWEtbGluZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UG9pbnRPbkxpbmVCeVJhdGlvKHN0YXJ0OiBQb2ludCwgZW5kOiBQb2ludCwgcmF0aW86IG51bWJlcik6IFBvaW50IHtcbiAgcmV0dXJuIHtcbiAgICB4OiAoMSAtIHJhdGlvKSAqIHN0YXJ0LnggKyByYXRpbyAqIGVuZC54LFxuICAgIHk6ICgxIC0gcmF0aW8pICogc3RhcnQueSArIHJhdGlvICogZW5kLnksXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,9 @@
1
+ export class ConnectionModel {
2
+ constructor(connection) {
3
+ this.connection = connection;
4
+ this.curve = connection.curve ?? 'bezier';
5
+ this.type = connection.type ?? 'default';
6
+ this.validator = connection.validator ?? (() => true);
7
+ }
8
+ }
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbi5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tb2RlbHMvY29ubmVjdGlvbi5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxNQUFNLE9BQU8sZUFBZTtJQUsxQixZQUFtQixVQUE4QjtRQUE5QixlQUFVLEdBQVYsVUFBVSxDQUFvQjtRQUMvQyxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLElBQUksUUFBUSxDQUFBO1FBQ3pDLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksSUFBSSxTQUFTLENBQUE7UUFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsU0FBUyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDdkQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29ubmVjdGlvblNldHRpbmdzLCBDb25uZWN0aW9uVmFsaWRhdG9yRm4gfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9jb25uZWN0aW9uLXNldHRpbmdzLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgQ3VydmUsIEVkZ2VUeXBlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvZWRnZS5pbnRlcmZhY2VcIjtcblxuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25Nb2RlbCB7XG4gIHB1YmxpYyBjdXJ2ZTogQ3VydmVcbiAgcHVibGljIHR5cGU6IEVkZ2VUeXBlXG4gIHB1YmxpYyB2YWxpZGF0b3I6IENvbm5lY3Rpb25WYWxpZGF0b3JGblxuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBjb25uZWN0aW9uOiBDb25uZWN0aW9uU2V0dGluZ3MpIHtcbiAgICB0aGlzLmN1cnZlID0gY29ubmVjdGlvbi5jdXJ2ZSA/PyAnYmV6aWVyJ1xuICAgIHRoaXMudHlwZSA9IGNvbm5lY3Rpb24udHlwZSA/PyAnZGVmYXVsdCdcbiAgICB0aGlzLnZhbGlkYXRvciA9IGNvbm5lY3Rpb24udmFsaWRhdG9yID8/ICgoKSA9PiB0cnVlKVxuICB9XG59XG4iXX0=
@@ -0,0 +1,8 @@
1
+ import { signal } from "@angular/core";
2
+ export class EdgeLabelModel {
3
+ constructor(edgeLabel) {
4
+ this.edgeLabel = edgeLabel;
5
+ this.size = signal({ width: 0, height: 0 });
6
+ }
7
+ }
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1sYWJlbC5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tb2RlbHMvZWRnZS1sYWJlbC5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBR3RDLE1BQU0sT0FBTyxjQUFjO0lBR3pCLFlBQW1CLFNBQW9CO1FBQXBCLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFGaEMsU0FBSSxHQUFHLE1BQU0sQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFRixDQUFDO0NBQzdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2lnbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIlxuaW1wb3J0IHsgRWRnZUxhYmVsIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvZWRnZS1sYWJlbC5pbnRlcmZhY2VcIlxuXG5leHBvcnQgY2xhc3MgRWRnZUxhYmVsTW9kZWwge1xuICBwdWJsaWMgc2l6ZSA9IHNpZ25hbCh7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSlcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWRnZUxhYmVsOiBFZGdlTGFiZWwpIHsgfVxufVxuIl19
@@ -0,0 +1,30 @@
1
+ import { computed } from "@angular/core";
2
+ import { EdgeLabelModel } from "./edge-label.model";
3
+ import { straightPath } from "../math/edge-path/straigh-path";
4
+ import { bezierPath } from "../math/edge-path/bezier-path";
5
+ export class EdgeModel {
6
+ constructor(edge) {
7
+ this.edge = edge;
8
+ this.path = computed(() => {
9
+ const source = this.source.sourcePointAbsolute();
10
+ const target = this.target.targetPointAbsolute();
11
+ switch (this.curve) {
12
+ case 'straight':
13
+ return straightPath(source, target, this.usingPoints);
14
+ case 'bezier':
15
+ return bezierPath(source, target, this.source.sourcePosition(), this.target.targetPosition(), this.usingPoints);
16
+ }
17
+ });
18
+ this.edgeLabels = {};
19
+ this.type = edge.type ?? 'default';
20
+ this.curve = edge.curve ?? 'bezier';
21
+ if (edge.edgeLabels?.start)
22
+ this.edgeLabels.start = new EdgeLabelModel(edge.edgeLabels.start);
23
+ if (edge.edgeLabels?.center)
24
+ this.edgeLabels.center = new EdgeLabelModel(edge.edgeLabels.center);
25
+ if (edge.edgeLabels?.end)
26
+ this.edgeLabels.end = new EdgeLabelModel(edge.edgeLabels.end);
27
+ this.usingPoints = [!!this.edgeLabels.start, !!this.edgeLabels.center, !!this.edgeLabels.end];
28
+ }
29
+ }
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tb2RlbHMvZWRnZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRzNELE1BQU0sT0FBTyxTQUFTO0lBMkJwQixZQUFtQixJQUFVO1FBQVYsU0FBSSxHQUFKLElBQUksQ0FBTTtRQXJCdEIsU0FBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO1lBQ2hELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtZQUVoRCxRQUFRLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ2xCLEtBQUssVUFBVTtvQkFDYixPQUFPLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtnQkFDdkQsS0FBSyxRQUFRO29CQUNYLE9BQU8sVUFBVSxDQUNmLE1BQU0sRUFBRSxNQUFNLEVBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsRUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsRUFDNUIsSUFBSSxDQUFDLFdBQVcsQ0FDakIsQ0FBQTthQUNKO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFFSyxlQUFVLEdBQXlELEVBQUUsQ0FBQTtRQUsxRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFBO1FBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxRQUFRLENBQUE7UUFFbkMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUs7WUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQzdGLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNO1lBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNoRyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsR0FBRztZQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUE7UUFFdkYsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDL0YsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29tcHV0ZWQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRWRnZUxhYmVsUG9zaXRpb24gfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9lZGdlLWxhYmVsLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgRWRnZSwgQ3VydmUsIEVkZ2VUeXBlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvZWRnZS5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVkZ2VMYWJlbE1vZGVsIH0gZnJvbSBcIi4vZWRnZS1sYWJlbC5tb2RlbFwiO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSBcIi4vbm9kZS5tb2RlbFwiO1xuaW1wb3J0IHsgc3RyYWlnaHRQYXRoIH0gZnJvbSBcIi4uL21hdGgvZWRnZS1wYXRoL3N0cmFpZ2gtcGF0aFwiO1xuaW1wb3J0IHsgYmV6aWVyUGF0aCB9IGZyb20gXCIuLi9tYXRoL2VkZ2UtcGF0aC9iZXppZXItcGF0aFwiO1xuaW1wb3J0IHsgVXNpbmdQb2ludHMgfSBmcm9tIFwiLi4vdHlwZXMvdXNpbmctcG9pbnRzLnR5cGVcIjtcblxuZXhwb3J0IGNsYXNzIEVkZ2VNb2RlbCB7XG4gIHB1YmxpYyBzb3VyY2UhOiBOb2RlTW9kZWxcbiAgcHVibGljIHRhcmdldCE6IE5vZGVNb2RlbFxuICBwdWJsaWMgY3VydmU6IEN1cnZlXG4gIHB1YmxpYyB0eXBlOiBFZGdlVHlwZVxuXG4gIHB1YmxpYyBwYXRoID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuc291cmNlLnNvdXJjZVBvaW50QWJzb2x1dGUoKVxuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMudGFyZ2V0LnRhcmdldFBvaW50QWJzb2x1dGUoKVxuXG4gICAgc3dpdGNoICh0aGlzLmN1cnZlKSB7XG4gICAgICBjYXNlICdzdHJhaWdodCc6XG4gICAgICAgIHJldHVybiBzdHJhaWdodFBhdGgoc291cmNlLCB0YXJnZXQsIHRoaXMudXNpbmdQb2ludHMpXG4gICAgICBjYXNlICdiZXppZXInOlxuICAgICAgICByZXR1cm4gYmV6aWVyUGF0aChcbiAgICAgICAgICBzb3VyY2UsIHRhcmdldCxcbiAgICAgICAgICB0aGlzLnNvdXJjZS5zb3VyY2VQb3NpdGlvbigpLFxuICAgICAgICAgIHRoaXMudGFyZ2V0LnRhcmdldFBvc2l0aW9uKCksXG4gICAgICAgICAgdGhpcy51c2luZ1BvaW50c1xuICAgICAgICApXG4gICAgfVxuICB9KVxuXG4gIHB1YmxpYyBlZGdlTGFiZWxzOiB7IFtwb3NpdGlvbiBpbiBFZGdlTGFiZWxQb3NpdGlvbl0/OiBFZGdlTGFiZWxNb2RlbCB9ID0ge31cblxuICBwcml2YXRlIHVzaW5nUG9pbnRzOiBVc2luZ1BvaW50c1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlZGdlOiBFZGdlKSB7XG4gICAgdGhpcy50eXBlID0gZWRnZS50eXBlID8/ICdkZWZhdWx0J1xuICAgIHRoaXMuY3VydmUgPSBlZGdlLmN1cnZlID8/ICdiZXppZXInXG5cbiAgICBpZiAoZWRnZS5lZGdlTGFiZWxzPy5zdGFydCkgdGhpcy5lZGdlTGFiZWxzLnN0YXJ0ID0gbmV3IEVkZ2VMYWJlbE1vZGVsKGVkZ2UuZWRnZUxhYmVscy5zdGFydClcbiAgICBpZiAoZWRnZS5lZGdlTGFiZWxzPy5jZW50ZXIpIHRoaXMuZWRnZUxhYmVscy5jZW50ZXIgPSBuZXcgRWRnZUxhYmVsTW9kZWwoZWRnZS5lZGdlTGFiZWxzLmNlbnRlcilcbiAgICBpZiAoZWRnZS5lZGdlTGFiZWxzPy5lbmQpIHRoaXMuZWRnZUxhYmVscy5lbmQgPSBuZXcgRWRnZUxhYmVsTW9kZWwoZWRnZS5lZGdlTGFiZWxzLmVuZClcblxuICAgIHRoaXMudXNpbmdQb2ludHMgPSBbISF0aGlzLmVkZ2VMYWJlbHMuc3RhcnQsICEhdGhpcy5lZGdlTGFiZWxzLmNlbnRlciwgISF0aGlzLmVkZ2VMYWJlbHMuZW5kXVxuICB9XG59XG4iXX0=
@@ -0,0 +1,16 @@
1
+ import { computed, signal } from "@angular/core";
2
+ export class FlowModel {
3
+ constructor() {
4
+ /**
5
+ * Global setting with handle positions. Nodes derive this value
6
+ */
7
+ this.handlePositions = signal({ source: 'right', target: 'left' });
8
+ /**
9
+ * @see {VflowComponent.view}
10
+ */
11
+ this.view = signal([400, 400]);
12
+ this.flowWidth = computed(() => this.view() === 'auto' ? '100%' : this.view()[0]);
13
+ this.flowHeight = computed(() => this.view() === 'auto' ? '100%' : this.view()[1]);
14
+ }
15
+ }
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvdy5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tb2RlbHMvZmxvdy5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTBCLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHekUsTUFBTSxPQUFPLFNBQVM7SUFBdEI7UUFDRTs7V0FFRztRQUNJLG9CQUFlLEdBQW9DLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7UUFFckc7O1dBRUc7UUFDSSxTQUFJLEdBQThDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBRXBFLGNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUU1RSxlQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdEYsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2lnbmFsLCBXcml0YWJsZVNpZ25hbCwgY29tcHV0ZWQsIHNpZ25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBIYW5kbGVQb3NpdGlvbnMgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9oYW5kbGUtcG9zaXRpb25zLmludGVyZmFjZVwiO1xuXG5leHBvcnQgY2xhc3MgRmxvd01vZGVsIHtcbiAgLyoqXG4gICAqIEdsb2JhbCBzZXR0aW5nIHdpdGggaGFuZGxlIHBvc2l0aW9ucy4gTm9kZXMgZGVyaXZlIHRoaXMgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBoYW5kbGVQb3NpdGlvbnM6IFdyaXRhYmxlU2lnbmFsPEhhbmRsZVBvc2l0aW9ucz4gPSBzaWduYWwoeyBzb3VyY2U6ICdyaWdodCcsIHRhcmdldDogJ2xlZnQnIH0pXG5cbiAgLyoqXG4gICAqIEBzZWUge1ZmbG93Q29tcG9uZW50LnZpZXd9XG4gICAqL1xuICBwdWJsaWMgdmlldzogV3JpdGFibGVTaWduYWw8W251bWJlciwgbnVtYmVyXSB8ICdhdXRvJz4gPSBzaWduYWwoWzQwMCwgNDAwXSlcblxuICBwdWJsaWMgZmxvd1dpZHRoID0gY29tcHV0ZWQoKCkgPT4gdGhpcy52aWV3KCkgPT09ICdhdXRvJyA/ICcxMDAlJyA6IHRoaXMudmlldygpWzBdKVxuXG4gIHB1YmxpYyBmbG93SGVpZ2h0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy52aWV3KCkgPT09ICdhdXRvJyA/ICcxMDAlJyA6IHRoaXMudmlldygpWzFdKVxufVxuIl19
@@ -0,0 +1,90 @@
1
+ import { computed, signal } from '@angular/core';
2
+ import { isDefined } from '../utils/is-defined';
3
+ import { toObservable } from '@angular/core/rxjs-interop';
4
+ export class NodeModel {
5
+ constructor(node) {
6
+ this.node = node;
7
+ this.point = signal({ x: 0, y: 0 });
8
+ this.point$ = toObservable(this.point);
9
+ this.size = signal({ width: 0, height: 0 });
10
+ this.pointTransform = computed(() => `translate(${this.point().x}, ${this.point().y})`);
11
+ this.sourceOffset = computed(() => {
12
+ const { width, height } = this.size();
13
+ switch (this.sourcePosition()) {
14
+ case 'left': return { x: 0, y: height / 2 };
15
+ case 'right': return { x: width, y: height / 2 };
16
+ case 'top': return { x: width / 2, y: 0 };
17
+ case 'bottom': return { x: width / 2, y: height };
18
+ }
19
+ });
20
+ this.targetOffset = computed(() => {
21
+ const { width, height } = this.size();
22
+ switch (this.targetPosition()) {
23
+ case 'left': return { x: 0, y: (height / 2) };
24
+ case 'right': return { x: width, y: height / 2 };
25
+ case 'top': return { x: width / 2, y: 0 };
26
+ case 'bottom': return { x: width / 2, y: height };
27
+ }
28
+ });
29
+ this.sourcePointAbsolute = computed(() => {
30
+ return {
31
+ x: this.point().x + this.sourceOffset().x + this.sourceHandleOffset().x,
32
+ y: this.point().y + this.sourceOffset().y + this.sourceHandleOffset().y
33
+ };
34
+ });
35
+ this.targetPointAbsolute = computed(() => {
36
+ return {
37
+ x: this.point().x + this.targetOffset().x + this.targetHandleOffset().x,
38
+ y: this.point().y + this.targetOffset().y + this.targetHandleOffset().y
39
+ };
40
+ });
41
+ // Now source and handle positions derived from parent flow
42
+ this.sourcePosition = computed(() => this.flow.handlePositions().source);
43
+ this.targetPosition = computed(() => this.flow.handlePositions().target);
44
+ this.sourceHandleSize = signal({ width: 0, height: 0 });
45
+ this.targetHandleSize = signal({ width: 0, height: 0 });
46
+ this.sourceHandleOffset = computed(() => {
47
+ switch (this.sourcePosition()) {
48
+ case 'left': return { x: -(this.sourceHandleSize().width / 2), y: 0 };
49
+ case 'right': return { x: this.sourceHandleSize().width / 2, y: 0 };
50
+ case 'top': return { x: 0, y: -(this.sourceHandleSize().height / 2) };
51
+ case 'bottom': return { x: 0, y: this.sourceHandleSize().height / 2 };
52
+ }
53
+ });
54
+ this.targetHandleOffset = computed(() => {
55
+ switch (this.targetPosition()) {
56
+ case 'left': return { x: -(this.targetHandleSize().width / 2), y: 0 };
57
+ case 'right': return { x: this.targetHandleSize().width / 2, y: 0 };
58
+ case 'top': return { x: 0, y: -(this.targetHandleSize().height / 2) };
59
+ case 'bottom': return { x: 0, y: this.targetHandleSize().height / 2 };
60
+ }
61
+ });
62
+ this.sourceOffsetAligned = computed(() => {
63
+ return {
64
+ x: this.sourceOffset().x - (this.sourceHandleSize().width / 2),
65
+ y: this.sourceOffset().y - (this.sourceHandleSize().height / 2),
66
+ };
67
+ });
68
+ this.targetOffsetAligned = computed(() => {
69
+ return {
70
+ x: this.targetOffset().x - (this.targetHandleSize().width / 2),
71
+ y: this.targetOffset().y - (this.targetHandleSize().height / 2),
72
+ };
73
+ });
74
+ this.draggable = true;
75
+ // disabled for configuration for now
76
+ this.magnetRadius = 20;
77
+ this.point.set(node.point);
78
+ if (isDefined(node.draggable))
79
+ this.draggable = node.draggable;
80
+ }
81
+ /**
82
+ * Bind parent flow model to node
83
+ *
84
+ * @param flow parent flow
85
+ */
86
+ bindFlow(flow) {
87
+ this.flow = flow;
88
+ }
89
+ }
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9tb2RlbHMvbm9kZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVksUUFBUSxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUdsRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBRXpELE1BQU0sT0FBTyxTQUFTO0lBMkZwQixZQUNTLElBQWE7UUFBYixTQUFJLEdBQUosSUFBSSxDQUFTO1FBM0ZmLFVBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBRTlCLFdBQU0sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRWpDLFNBQUksR0FBRyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBRXRDLG1CQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUVsRixpQkFBWSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDbEMsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUE7WUFFckMsUUFBUSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUU7Z0JBQzdCLEtBQUssTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUs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Q0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2FBQ2hFLENBQUE7UUFDSCxDQUFDLENBQUMsQ0FBQTtRQUVLLGNBQVMsR0FBRyxJQUFJLENBQUE7UUFFdkIscUNBQXFDO1FBQ3JCLGlCQUFZLEdBQUcsRUFBRSxDQUFBO1FBTy9CLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUUxQixJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFBO0lBQ2hFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksUUFBUSxDQUFDLElBQWU7UUFDN0IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0b3IsIGNvbXB1dGVkLCBpbmplY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlLmludGVyZmFjZSdcbmltcG9ydCB7IEZsb3dNb2RlbCB9IGZyb20gJy4vZmxvdy5tb2RlbCdcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gJy4uL3V0aWxzL2lzLWRlZmluZWQnXG5pbXBvcnQgeyB0b09ic2VydmFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCdcblxuZXhwb3J0IGNsYXNzIE5vZGVNb2RlbDxUID0gdW5rbm93bj4ge1xuICBwdWJsaWMgcG9pbnQgPSBzaWduYWwoeyB4OiAwLCB5OiAwIH0pXG5cbiAgcHVibGljIHBvaW50JCA9IHRvT2JzZXJ2YWJsZSh0aGlzLnBvaW50KVxuXG4gIHB1YmxpYyBzaXplID0gc2lnbmFsKHsgd2lkdGg6IDAsIGhlaWdodDogMCB9KVxuXG4gIHB1YmxpYyBwb2ludFRyYW5zZm9ybSA9IGNvbXB1dGVkKCgpID0+IGB0cmFuc2xhdGUoJHt0aGlzLnBvaW50KCkueH0sICR7dGhpcy5wb2ludCgpLnl9KWApXG5cbiAgcHVibGljIHNvdXJjZU9mZnNldCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IHRoaXMuc2l6ZSgpXG5cbiAgICBzd2l0Y2ggKHRoaXMuc291cmNlUG9zaXRpb24oKSkge1xuICAgICAgY2FzZSAnbGVmdCc6IHJldHVybiB7IHg6IDAsIHk6IGhlaWdodCAvIDIgfVxuICAgICAgY2FzZSAncmlnaHQnOiByZXR1cm4geyB4OiB3aWR0aCwgeTogaGVpZ2h0IC8gMiB9XG4gICAgICBjYXNlICd0b3AnOiByZXR1cm4geyB4OiB3aWR0aCAvIDIsIHk6IDAgfVxuICAgICAgY2FzZSAnYm90dG9tJzogcmV0dXJuIHsgeDogd2lkdGggLyAyLCB5OiBoZWlnaHQgfVxuICAgIH1cbiAgfSlcblxuICBwdWJsaWMgdGFyZ2V0T2Zmc2V0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5zaXplKClcblxuICAgIHN3aXRjaCAodGhpcy50YXJnZXRQb3NpdGlvbigpKSB7XG4gICAgICBjYXNlICdsZWZ0JzogcmV0dXJuIHsgeDogMCwgeTogKGhlaWdodCAvIDIpIH1cbiAgICAgIGNhc2UgJ3JpZ2h0JzogcmV0dXJuIHsgeDogd2lkdGgsIHk6IGhlaWdodCAvIDIgfVxuICAgICAgY2FzZSAndG9wJzogcmV0dXJuIHsgeDogd2lkdGggLyAyLCB5OiAwIH1cbiAgICAgIGNhc2UgJ2JvdHRvbSc6IHJldHVybiB7IHg6IHdpZHRoIC8gMiwgeTogaGVpZ2h0IH1cbiAgICB9XG4gIH0pXG5cbiAgcHVibGljIHNvdXJjZVBvaW50QWJzb2x1dGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMucG9pbnQoKS54ICsgdGhpcy5zb3VyY2VPZmZzZXQoKS54ICsgdGhpcy5zb3VyY2VIYW5kbGVPZmZzZXQoKS54LFxuICAgICAgeTogdGhpcy5wb2ludCgpLnkgKyB0aGlzLnNvdXJjZU9mZnNldCgpLnkgKyB0aGlzLnNvdXJjZUhhbmRsZU9mZnNldCgpLnlcbiAgICB9XG4gIH0pXG5cbiAgcHVibGljIHRhcmdldFBvaW50QWJzb2x1dGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMucG9pbnQoKS54ICsgdGhpcy50YXJnZXRPZmZzZXQoKS54ICsgdGhpcy50YXJnZXRIYW5kbGVPZmZzZXQoKS54LFxuICAgICAgeTogdGhpcy5wb2ludCgpLnkgKyB0aGlzLnRhcmdldE9mZnNldCgpLnkgKyB0aGlzLnRhcmdldEhhbmRsZU9mZnNldCgpLnlcbiAgICB9XG4gIH0pXG5cbiAgLy8gTm93IHNvdXJjZSBhbmQgaGFuZGxlIHBvc2l0aW9ucyBkZXJpdmVkIGZyb20gcGFyZW50IGZsb3dcbiAgcHVibGljIHNvdXJjZVBvc2l0aW9uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5mbG93LmhhbmRsZVBvc2l0aW9ucygpLnNvdXJjZSlcbiAgcHVibGljIHRhcmdldFBvc2l0aW9uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5mbG93LmhhbmRsZVBvc2l0aW9ucygpLnRhcmdldClcblxuICBwdWJsaWMgc291cmNlSGFuZGxlU2l6ZSA9IHNpZ25hbCh7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSlcbiAgcHVibGljIHRhcmdldEhhbmRsZVNpemUgPSBzaWduYWwoeyB3aWR0aDogMCwgaGVpZ2h0OiAwIH0pXG5cbiAgcHVibGljIHNvdXJjZUhhbmRsZU9mZnNldCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBzd2l0Y2ggKHRoaXMuc291cmNlUG9zaXRpb24oKSkge1xuICAgICAgY2FzZSAnbGVmdCc6IHJldHVybiB7IHg6IC0odGhpcy5zb3VyY2VIYW5kbGVTaXplKCkud2lkdGggLyAyKSwgeTogMCB9XG4gICAgICBjYXNlICdyaWdodCc6IHJldHVybiB7IHg6IHRoaXMuc291cmNlSGFuZGxlU2l6ZSgpLndpZHRoIC8gMiwgeTogMCB9XG4gICAgICBjYXNlICd0b3AnOiByZXR1cm4geyB4OiAwLCB5OiAtKHRoaXMuc291cmNlSGFuZGxlU2l6ZSgpLmhlaWdodCAvIDIpIH1cbiAgICAgIGNhc2UgJ2JvdHRvbSc6IHJldHVybiB7IHg6IDAsIHk6IHRoaXMuc291cmNlSGFuZGxlU2l6ZSgpLmhlaWdodCAvIDIgfVxuICAgIH1cbiAgfSlcblxuICBwdWJsaWMgdGFyZ2V0SGFuZGxlT2Zmc2V0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHN3aXRjaCAodGhpcy50YXJnZXRQb3NpdGlvbigpKSB7XG4gICAgICBjYXNlICdsZWZ0JzogcmV0dXJuIHsgeDogLSh0aGlzLnRhcmdldEhhbmRsZVNpemUoKS53aWR0aCAvIDIpLCB5OiAwIH1cbiAgICAgIGNhc2UgJ3JpZ2h0JzogcmV0dXJuIHsgeDogdGhpcy50YXJnZXRIYW5kbGVTaXplKCkud2lkdGggLyAyLCB5OiAwIH1cbiAgICAgIGNhc2UgJ3RvcCc6IHJldHVybiB7IHg6IDAsIHk6IC0odGhpcy50YXJnZXRIYW5kbGVTaXplKCkuaGVpZ2h0IC8gMikgfVxuICAgICAgY2FzZSAnYm90dG9tJzogcmV0dXJuIHsgeDogMCwgeTogdGhpcy50YXJnZXRIYW5kbGVTaXplKCkuaGVpZ2h0IC8gMiB9XG4gICAgfVxuICB9KVxuXG4gIHB1YmxpYyBzb3VyY2VPZmZzZXRBbGlnbmVkID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICB4OiB0aGlzLnNvdXJjZU9mZnNldCgpLnggLSAodGhpcy5zb3VyY2VIYW5kbGVTaXplKCkud2lkdGggLyAyKSxcbiAgICAgIHk6IHRoaXMuc291cmNlT2Zmc2V0KCkueSAtICh0aGlzLnNvdXJjZUhhbmRsZVNpemUoKS5oZWlnaHQgLyAyKSxcbiAgICB9XG4gIH0pXG5cbiAgcHVibGljIHRhcmdldE9mZnNldEFsaWduZWQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHRoaXMudGFyZ2V0T2Zmc2V0KCkueCAtICh0aGlzLnRhcmdldEhhbmRsZVNpemUoKS53aWR0aCAvIDIpLFxuICAgICAgeTogdGhpcy50YXJnZXRPZmZzZXQoKS55IC0gKHRoaXMudGFyZ2V0SGFuZGxlU2l6ZSgpLmhlaWdodCAvIDIpLFxuICAgIH1cbiAgfSlcblxuICBwdWJsaWMgZHJhZ2dhYmxlID0gdHJ1ZVxuXG4gIC8vIGRpc2FibGVkIGZvciBjb25maWd1cmF0aW9uIGZvciBub3dcbiAgcHVibGljIHJlYWRvbmx5IG1hZ25ldFJhZGl1cyA9IDIwXG5cbiAgcHJpdmF0ZSBmbG93ITogRmxvd01vZGVsXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG5vZGU6IE5vZGU8VD5cbiAgKSB7XG4gICAgdGhpcy5wb2ludC5zZXQobm9kZS5wb2ludClcblxuICAgIGlmIChpc0RlZmluZWQobm9kZS5kcmFnZ2FibGUpKSB0aGlzLmRyYWdnYWJsZSA9IG5vZGUuZHJhZ2dhYmxlXG4gIH1cblxuICAvKipcbiAgICogQmluZCBwYXJlbnQgZmxvdyBtb2RlbCB0byBub2RlXG4gICAqXG4gICAqIEBwYXJhbSBmbG93IHBhcmVudCBmbG93XG4gICAqL1xuICBwdWJsaWMgYmluZEZsb3coZmxvdzogRmxvd01vZGVsKSB7XG4gICAgdGhpcy5mbG93ID0gZmxvd1xuICB9XG59XG4iXX0=
@@ -0,0 +1,66 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { select } from 'd3-selection';
3
+ import { drag } from 'd3-drag';
4
+ import { round } from '../utils/round';
5
+ import * as i0 from "@angular/core";
6
+ export class DraggableService {
7
+ /**
8
+ * Enable or disable draggable behavior for element.
9
+ * model contains draggable flag which declares if draggable should be enabled or not
10
+ *
11
+ * @param element target element for toggling draggable
12
+ * @param model model with data for this element
13
+ */
14
+ toggleDraggable(element, model) {
15
+ const d3Element = select(element);
16
+ const behavior = model.draggable
17
+ ? this.getDragBehavior(model)
18
+ : this.getIgnoreDragBehavior();
19
+ d3Element.call(behavior);
20
+ }
21
+ /**
22
+ * TODO: not shure if this work, need to check
23
+ *
24
+ * @param element
25
+ */
26
+ destroy(element) {
27
+ select(element).on('.drag', null);
28
+ }
29
+ /**
30
+ * Node drag behavior. Updated node's coordinate according to dragging
31
+ *
32
+ * @param model
33
+ * @returns
34
+ */
35
+ getDragBehavior(model) {
36
+ let deltaX;
37
+ let deltaY;
38
+ return drag()
39
+ .on('start', (event) => {
40
+ deltaX = model.point().x - event.x;
41
+ deltaY = model.point().y - event.y;
42
+ })
43
+ .on('drag', (event) => {
44
+ model.point.set({
45
+ x: round(event.x + deltaX),
46
+ y: round(event.y + deltaY)
47
+ });
48
+ });
49
+ }
50
+ /**
51
+ * Specify ignoring drag behavior. It's responsible for not moving the map when user tries to drag node
52
+ * with disabled drag behavior
53
+ */
54
+ getIgnoreDragBehavior() {
55
+ return drag()
56
+ .on('drag', (event) => {
57
+ event.sourceEvent.stopPropagation();
58
+ });
59
+ }
60
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
61
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService }); }
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DraggableService, decorators: [{
64
+ type: Injectable
65
+ }] });
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvc2VydmljZXMvZHJhZ2dhYmxlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFBZSxJQUFJLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFNUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQUt2QyxNQUFNLE9BQU8sZ0JBQWdCO0lBQzNCOzs7Ozs7T0FNRztJQUNJLGVBQWUsQ0FBQyxPQUFnQixFQUFFLEtBQWdCO1FBQ3ZELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUVqQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsU0FBUztZQUM5QixDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7WUFDN0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFBO1FBRWhDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDMUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxPQUFPLENBQUMsT0FBZ0I7UUFDN0IsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssZUFBZSxDQUFDLEtBQWdCO1FBQ3RDLElBQUksTUFBYyxDQUFBO1FBQ2xCLElBQUksTUFBYyxDQUFBO1FBRWxCLE9BQU8sSUFBSSxFQUFFO2FBQ1YsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQWdCLEVBQUUsRUFBRTtZQUNoQyxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFBO1lBQ2xDLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDcEMsQ0FBQyxDQUFDO2FBRUQsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQWdCLEVBQUUsRUFBRTtZQUMvQixLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FDYjtnQkFDRSxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMxQixDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO2FBQzNCLENBQ0YsQ0FBQTtRQUNILENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQztJQUVEOzs7T0FHRztJQUNLLHFCQUFxQjtRQUMzQixPQUFPLElBQUksRUFBRTthQUNWLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFnQixFQUFFLEVBQUU7WUFDOUIsS0FBSyxDQUFDLFdBQXFCLENBQUMsZUFBZSxFQUFFLENBQUE7UUFDaEQsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDOytHQTlEVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQjs7NEZBQWhCLGdCQUFnQjtrQkFENUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHNlbGVjdCB9IGZyb20gJ2QzLXNlbGVjdGlvbic7XG5pbXBvcnQgeyBEM0RyYWdFdmVudCwgZHJhZyB9IGZyb20gJ2QzLWRyYWcnO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuaW1wb3J0IHsgcm91bmQgfSBmcm9tICcuLi91dGlscy9yb3VuZCc7XG5cbnR5cGUgRHJhZ0V2ZW50ID0gRDNEcmFnRXZlbnQ8RWxlbWVudCwgdW5rbm93biwgdW5rbm93bj5cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIERyYWdnYWJsZVNlcnZpY2Uge1xuICAvKipcbiAgICogRW5hYmxlIG9yIGRpc2FibGUgZHJhZ2dhYmxlIGJlaGF2aW9yIGZvciBlbGVtZW50LlxuICAgKiBtb2RlbCBjb250YWlucyBkcmFnZ2FibGUgZmxhZyB3aGljaCBkZWNsYXJlcyBpZiBkcmFnZ2FibGUgc2hvdWxkIGJlIGVuYWJsZWQgb3Igbm90XG4gICAqXG4gICAqIEBwYXJhbSBlbGVtZW50IHRhcmdldCBlbGVtZW50IGZvciB0b2dnbGluZyBkcmFnZ2FibGVcbiAgICogQHBhcmFtIG1vZGVsIG1vZGVsIHdpdGggZGF0YSBmb3IgdGhpcyBlbGVtZW50XG4gICAqL1xuICBwdWJsaWMgdG9nZ2xlRHJhZ2dhYmxlKGVsZW1lbnQ6IEVsZW1lbnQsIG1vZGVsOiBOb2RlTW9kZWwpIHtcbiAgICBjb25zdCBkM0VsZW1lbnQgPSBzZWxlY3QoZWxlbWVudClcblxuICAgIGNvbnN0IGJlaGF2aW9yID0gbW9kZWwuZHJhZ2dhYmxlXG4gICAgICA/IHRoaXMuZ2V0RHJhZ0JlaGF2aW9yKG1vZGVsKVxuICAgICAgOiB0aGlzLmdldElnbm9yZURyYWdCZWhhdmlvcigpXG5cbiAgICBkM0VsZW1lbnQuY2FsbChiZWhhdmlvcilcbiAgfVxuXG4gIC8qKlxuICAgKiBUT0RPOiBub3Qgc2h1cmUgaWYgdGhpcyB3b3JrLCBuZWVkIHRvIGNoZWNrXG4gICAqXG4gICAqIEBwYXJhbSBlbGVtZW50XG4gICAqL1xuICBwdWJsaWMgZGVzdHJveShlbGVtZW50OiBFbGVtZW50KSB7XG4gICAgc2VsZWN0KGVsZW1lbnQpLm9uKCcuZHJhZycsIG51bGwpXG4gIH1cblxuICAvKipcbiAgICogTm9kZSBkcmFnIGJlaGF2aW9yLiBVcGRhdGVkIG5vZGUncyBjb29yZGluYXRlIGFjY29yZGluZyB0byBkcmFnZ2luZ1xuICAgKlxuICAgKiBAcGFyYW0gbW9kZWxcbiAgICogQHJldHVybnNcbiAgICovXG4gIHByaXZhdGUgZ2V0RHJhZ0JlaGF2aW9yKG1vZGVsOiBOb2RlTW9kZWwpIHtcbiAgICBsZXQgZGVsdGFYOiBudW1iZXJcbiAgICBsZXQgZGVsdGFZOiBudW1iZXJcblxuICAgIHJldHVybiBkcmFnKClcbiAgICAgIC5vbignc3RhcnQnLCAoZXZlbnQ6IERyYWdFdmVudCkgPT4ge1xuICAgICAgICBkZWx0YVggPSBtb2RlbC5wb2ludCgpLnggLSBldmVudC54XG4gICAgICAgIGRlbHRhWSA9IG1vZGVsLnBvaW50KCkueSAtIGV2ZW50LnlcbiAgICAgIH0pXG5cbiAgICAgIC5vbignZHJhZycsIChldmVudDogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICAgIG1vZGVsLnBvaW50LnNldChcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4OiByb3VuZChldmVudC54ICsgZGVsdGFYKSxcbiAgICAgICAgICAgIHk6IHJvdW5kKGV2ZW50LnkgKyBkZWx0YVkpXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgaWdub3JpbmcgZHJhZyBiZWhhdmlvci4gSXQncyByZXNwb25zaWJsZSBmb3Igbm90IG1vdmluZyB0aGUgbWFwIHdoZW4gdXNlciB0cmllcyB0byBkcmFnIG5vZGVcbiAgICogd2l0aCBkaXNhYmxlZCBkcmFnIGJlaGF2aW9yXG4gICAqL1xuICBwcml2YXRlIGdldElnbm9yZURyYWdCZWhhdmlvcigpIHtcbiAgICByZXR1cm4gZHJhZygpXG4gICAgICAub24oJ2RyYWcnLCAoZXZlbnQ6IERyYWdFdmVudCkgPT4ge1xuICAgICAgICAoZXZlbnQuc291cmNlRXZlbnQgYXMgRXZlbnQpLnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICB9KVxuICB9XG59XG4iXX0=
@@ -0,0 +1,38 @@
1
+ import { Injectable, computed, inject, untracked } from '@angular/core';
2
+ import { FlowEntitiesService } from './flow-entities.service';
3
+ import { asyncScheduler, filter, map, merge, observeOn, pairwise } from 'rxjs';
4
+ import { toObservable } from '@angular/core/rxjs-interop';
5
+ import * as i0 from "@angular/core";
6
+ export class EdgeChangesService {
7
+ constructor() {
8
+ this.entitiesService = inject(FlowEntitiesService);
9
+ this.edgeDetachedChange$ = toObservable(computed(() => {
10
+ const nodes = this.entitiesService.nodes();
11
+ const edges = untracked(this.entitiesService.edges);
12
+ return edges.filter(({ source, target }) => !nodes.includes(source) || !nodes.includes(target));
13
+ })).pipe(
14
+ // TODO check why there are 2 emits from single call inside computed
15
+ filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'detached', id: edge.id }))));
16
+ this.edgeAddChange$ = toObservable(this.entitiesService.edges)
17
+ .pipe(pairwise(), map(([oldList, newList]) => {
18
+ return newList.filter(edge => !oldList.includes(edge));
19
+ }), filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'add', id: edge.id }))));
20
+ this.edgeRemoveChange$ = toObservable(this.entitiesService.edges)
21
+ .pipe(pairwise(), map(([oldList, newList]) => {
22
+ return oldList.filter(edge => !newList.includes(edge));
23
+ }), filter(edges => !!edges.length), map((edges) => edges.map(({ edge }) => ({ type: 'remove', id: edge.id }))));
24
+ this.changes$ = merge(this.edgeDetachedChange$, this.edgeAddChange$, this.edgeRemoveChange$)
25
+ .pipe(
26
+ // this fixes the case when user gets 'deteched' changes
27
+ // and tries to delete these edges inside stream
28
+ // angular may ignore this change because [edges] input changed
29
+ // right after [nodes] input change
30
+ observeOn(asyncScheduler));
31
+ }
32
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
33
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService }); }
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeChangesService, decorators: [{
36
+ type: Injectable
37
+ }] });
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1jaGFuZ2VzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvc2VydmljZXMvZWRnZS1jaGFuZ2VzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQWMsY0FBYyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQVEsTUFBTSxNQUFNLENBQUM7QUFDakcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDOztBQUkxRCxNQUFNLE9BQU8sa0JBQWtCO0lBRC9CO1FBRVksb0JBQWUsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtRQUU3Qyx3QkFBbUIsR0FBRyxZQUFZLENBQzFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDWixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFBO1lBQzFDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBRW5ELE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FDekMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FDbkQsQ0FBQTtRQUNILENBQUMsQ0FBQyxDQUNILENBQUMsSUFBSTtRQUNKLG9FQUFvRTtRQUNwRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUMvQixHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNaLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FDN0QsQ0FDaUMsQ0FBQTtRQUUxQixtQkFBYyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQzthQUNoRSxJQUFJLENBQ0gsUUFBUSxFQUFFLEVBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUN6QixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUN4RCxDQUFDLENBQUMsRUFDRixNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUMvQixHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNaLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FDeEQsQ0FDaUMsQ0FBQTtRQUU1QixzQkFBaUIsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7YUFDbkUsSUFBSSxDQUNILFFBQVEsRUFBRSxFQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUU7WUFDekIsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDeEQsQ0FBQyxDQUFDLEVBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFDL0IsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDWixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQzNELENBQ2lDLENBQUE7UUFFdEIsYUFBUSxHQUE2QixLQUFLLENBQ3hELElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLGlCQUFpQixDQUN2QjthQUNFLElBQUk7UUFDSCx3REFBd0Q7UUFDeEQsZ0RBQWdEO1FBQ2hELCtEQUErRDtRQUMvRCxtQ0FBbUM7UUFDbkMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUMxQixDQUFBO0tBQ0o7K0dBeERZLGtCQUFrQjttSEFBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgY29tcHV0ZWQsIGluamVjdCwgdW50cmFja2VkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGbG93RW50aXRpZXNTZXJ2aWNlIH0gZnJvbSAnLi9mbG93LWVudGl0aWVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgYXN5bmNTY2hlZHVsZXIsIGZpbHRlciwgbWFwLCBtZXJnZSwgb2JzZXJ2ZU9uLCBwYWlyd2lzZSwgc2tpcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdG9PYnNlcnZhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRWRnZUNoYW5nZSB9IGZyb20gJy4uL3R5cGVzL2VkZ2UtY2hhbmdlLnR5cGUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRWRnZUNoYW5nZXNTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIGVudGl0aWVzU2VydmljZSA9IGluamVjdChGbG93RW50aXRpZXNTZXJ2aWNlKVxuXG4gIHByb3RlY3RlZCBlZGdlRGV0YWNoZWRDaGFuZ2UkID0gdG9PYnNlcnZhYmxlKFxuICAgIGNvbXB1dGVkKCgpID0+IHtcbiAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5lbnRpdGllc1NlcnZpY2Uubm9kZXMoKVxuICAgICAgY29uc3QgZWRnZXMgPSB1bnRyYWNrZWQodGhpcy5lbnRpdGllc1NlcnZpY2UuZWRnZXMpXG5cbiAgICAgIHJldHVybiBlZGdlcy5maWx0ZXIoKHsgc291cmNlLCB0YXJnZXQgfSkgPT5cbiAgICAgICAgIW5vZGVzLmluY2x1ZGVzKHNvdXJjZSkgfHwgIW5vZGVzLmluY2x1ZGVzKHRhcmdldClcbiAgICAgIClcbiAgICB9KVxuICApLnBpcGUoXG4gICAgLy8gVE9ETyBjaGVjayB3aHkgdGhlcmUgYXJlIDIgZW1pdHMgZnJvbSBzaW5nbGUgY2FsbCBpbnNpZGUgY29tcHV0ZWRcbiAgICBmaWx0ZXIoZWRnZXMgPT4gISFlZGdlcy5sZW5ndGgpLFxuICAgIG1hcCgoZWRnZXMpID0+XG4gICAgICBlZGdlcy5tYXAoKHsgZWRnZSB9KSA9PiAoeyB0eXBlOiAnZGV0YWNoZWQnLCBpZDogZWRnZS5pZCB9KSlcbiAgICApXG4gICkgc2F0aXNmaWVzIE9ic2VydmFibGU8RWRnZUNoYW5nZVtdPlxuXG4gIHByb3RlY3RlZCBlZGdlQWRkQ2hhbmdlJCA9IHRvT2JzZXJ2YWJsZSh0aGlzLmVudGl0aWVzU2VydmljZS5lZGdlcylcbiAgICAucGlwZShcbiAgICAgIHBhaXJ3aXNlKCksXG4gICAgICBtYXAoKFtvbGRMaXN0LCBuZXdMaXN0XSkgPT4ge1xuICAgICAgICByZXR1cm4gbmV3TGlzdC5maWx0ZXIoZWRnZSA9PiAhb2xkTGlzdC5pbmNsdWRlcyhlZGdlKSlcbiAgICAgIH0pLFxuICAgICAgZmlsdGVyKGVkZ2VzID0+ICEhZWRnZXMubGVuZ3RoKSxcbiAgICAgIG1hcCgoZWRnZXMpID0+XG4gICAgICAgIGVkZ2VzLm1hcCgoeyBlZGdlIH0pID0+ICh7IHR5cGU6ICdhZGQnLCBpZDogZWRnZS5pZCB9KSlcbiAgICAgIClcbiAgICApIHNhdGlzZmllcyBPYnNlcnZhYmxlPEVkZ2VDaGFuZ2VbXT5cblxuICBwcm90ZWN0ZWQgZWRnZVJlbW92ZUNoYW5nZSQgPSB0b09ic2VydmFibGUodGhpcy5lbnRpdGllc1NlcnZpY2UuZWRnZXMpXG4gICAgLnBpcGUoXG4gICAgICBwYWlyd2lzZSgpLFxuICAgICAgbWFwKChbb2xkTGlzdCwgbmV3TGlzdF0pID0+IHtcbiAgICAgICAgcmV0dXJuIG9sZExpc3QuZmlsdGVyKGVkZ2UgPT4gIW5ld0xpc3QuaW5jbHVkZXMoZWRnZSkpXG4gICAgICB9KSxcbiAgICAgIGZpbHRlcihlZGdlcyA9PiAhIWVkZ2VzLmxlbmd0aCksXG4gICAgICBtYXAoKGVkZ2VzKSA9PlxuICAgICAgICBlZGdlcy5tYXAoKHsgZWRnZSB9KSA9PiAoeyB0eXBlOiAncmVtb3ZlJywgaWQ6IGVkZ2UuaWQgfSkpXG4gICAgICApXG4gICAgKSBzYXRpc2ZpZXMgT2JzZXJ2YWJsZTxFZGdlQ2hhbmdlW10+XG5cbiAgcHVibGljIHJlYWRvbmx5IGNoYW5nZXMkOiBPYnNlcnZhYmxlPEVkZ2VDaGFuZ2VbXT4gPSBtZXJnZShcbiAgICB0aGlzLmVkZ2VEZXRhY2hlZENoYW5nZSQsXG4gICAgdGhpcy5lZGdlQWRkQ2hhbmdlJCxcbiAgICB0aGlzLmVkZ2VSZW1vdmVDaGFuZ2UkXG4gIClcbiAgICAucGlwZShcbiAgICAgIC8vIHRoaXMgZml4ZXMgdGhlIGNhc2Ugd2hlbiB1c2VyIGdldHMgJ2RldGVjaGVkJyBjaGFuZ2VzXG4gICAgICAvLyBhbmQgdHJpZXMgdG8gZGVsZXRlIHRoZXNlIGVkZ2VzIGluc2lkZSBzdHJlYW1cbiAgICAgIC8vIGFuZ3VsYXIgbWF5IGlnbm9yZSB0aGlzIGNoYW5nZSBiZWNhdXNlIFtlZGdlc10gaW5wdXQgY2hhbmdlZFxuICAgICAgLy8gcmlnaHQgYWZ0ZXIgW25vZGVzXSBpbnB1dCBjaGFuZ2VcbiAgICAgIG9ic2VydmVPbihhc3luY1NjaGVkdWxlciksXG4gICAgKVxufVxuIl19
@@ -0,0 +1,49 @@
1
+ import { Injectable, computed, signal } from '@angular/core';
2
+ import { ConnectionModel } from '../models/connection.model';
3
+ import { hashCode } from '../utils/hash';
4
+ import * as i0 from "@angular/core";
5
+ export class FlowEntitiesService {
6
+ constructor() {
7
+ this.nodes = signal([], {
8
+ // empty arrays considered equal, other arrays may not be equal
9
+ equal: (a, b) => !a.length && !b.length ? true : a === b
10
+ });
11
+ this.edges = signal([], {
12
+ // empty arrays considered equal, other arrays may not be equal
13
+ equal: (a, b) => !a.length && !b.length ? true : a === b
14
+ });
15
+ this.connection = signal(new ConnectionModel({}));
16
+ this.markers = computed(() => {
17
+ const markersMap = new Map();
18
+ this.validEdges().forEach(e => {
19
+ if (e.edge.markers?.start) {
20
+ const hash = hashCode(JSON.stringify(e.edge.markers.start));
21
+ markersMap.set(hash, e.edge.markers.start);
22
+ }
23
+ if (e.edge.markers?.end) {
24
+ const hash = hashCode(JSON.stringify(e.edge.markers.end));
25
+ markersMap.set(hash, e.edge.markers.end);
26
+ }
27
+ });
28
+ const connectionMarker = this.connection().connection.marker;
29
+ if (connectionMarker) {
30
+ const hash = hashCode(JSON.stringify(connectionMarker));
31
+ markersMap.set(hash, connectionMarker);
32
+ }
33
+ return markersMap;
34
+ });
35
+ this.validEdges = computed(() => {
36
+ const nodes = this.nodes();
37
+ return this.edges().filter(e => nodes.includes(e.source) && nodes.includes(e.target));
38
+ });
39
+ }
40
+ getNode(id) {
41
+ return this.nodes().find(({ node }) => node.id === id);
42
+ }
43
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
44
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService }); }
45
+ }
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowEntitiesService, decorators: [{
47
+ type: Injectable
48
+ }] });
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvdy1lbnRpdGllcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXZmbG93LWxpYi9zcmMvbGliL3ZmbG93L3NlcnZpY2VzL2Zsb3ctZW50aXRpZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBVSxNQUFNLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFHaEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTdELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBR3pDLE1BQU0sT0FBTyxtQkFBbUI7SUFEaEM7UUFFa0IsVUFBSyxHQUFHLE1BQU0sQ0FBYyxFQUFFLEVBQUU7WUFDOUMsK0RBQStEO1lBQy9ELEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7U0FDekQsQ0FBQyxDQUFBO1FBRWMsVUFBSyxHQUFHLE1BQU0sQ0FBYyxFQUFFLEVBQUU7WUFDOUMsK0RBQStEO1lBQy9ELEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7U0FDekQsQ0FBQyxDQUFBO1FBRWMsZUFBVSxHQUFHLE1BQU0sQ0FBa0IsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUU3RCxZQUFPLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUN0QyxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQTtZQUU1QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM1QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRTtvQkFDekIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtvQkFDM0QsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7aUJBQzNDO2dCQUVELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO29CQUN2QixNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO29CQUN6RCxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtpQkFDekM7WUFDSCxDQUFDLENBQUMsQ0FBQTtZQUVGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUE7WUFDNUQsSUFBSSxnQkFBZ0IsRUFBRTtnQkFDcEIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFBO2dCQUN2RCxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO2FBQ3ZDO1lBRUQsT0FBTyxVQUFVLENBQUE7UUFDbkIsQ0FBQyxDQUFDLENBQUE7UUFFYyxlQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUN6QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUE7WUFFMUIsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUN2RixDQUFDLENBQUMsQ0FBQTtLQUtIO0lBSFEsT0FBTyxDQUFJLEVBQVU7UUFDMUIsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQTZCLENBQUE7SUFDcEYsQ0FBQzsrR0E3Q1UsbUJBQW1CO21IQUFuQixtQkFBbUI7OzRGQUFuQixtQkFBbUI7a0JBRC9CLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBjb21wdXRlZCwgZWZmZWN0LCBzaWduYWwsIHVudHJhY2tlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuaW1wb3J0IHsgRWRnZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL2VkZ2UubW9kZWwnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbk1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL2Nvbm5lY3Rpb24ubW9kZWwnO1xuaW1wb3J0IHsgTWFya2VyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9tYXJrZXIuaW50ZXJmYWNlJztcbmltcG9ydCB7IGhhc2hDb2RlIH0gZnJvbSAnLi4vdXRpbHMvaGFzaCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBGbG93RW50aXRpZXNTZXJ2aWNlIHtcbiAgcHVibGljIHJlYWRvbmx5IG5vZGVzID0gc2lnbmFsPE5vZGVNb2RlbFtdPihbXSwge1xuICAgIC8vIGVtcHR5IGFycmF5cyBjb25zaWRlcmVkIGVxdWFsLCBvdGhlciBhcnJheXMgbWF5IG5vdCBiZSBlcXVhbFxuICAgIGVxdWFsOiAoYSwgYikgPT4gIWEubGVuZ3RoICYmICFiLmxlbmd0aCA/IHRydWUgOiBhID09PSBiXG4gIH0pXG5cbiAgcHVibGljIHJlYWRvbmx5IGVkZ2VzID0gc2lnbmFsPEVkZ2VNb2RlbFtdPihbXSwge1xuICAgIC8vIGVtcHR5IGFycmF5cyBjb25zaWRlcmVkIGVxdWFsLCBvdGhlciBhcnJheXMgbWF5IG5vdCBiZSBlcXVhbFxuICAgIGVxdWFsOiAoYSwgYikgPT4gIWEubGVuZ3RoICYmICFiLmxlbmd0aCA/IHRydWUgOiBhID09PSBiXG4gIH0pXG5cbiAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3Rpb24gPSBzaWduYWw8Q29ubmVjdGlvbk1vZGVsPihuZXcgQ29ubmVjdGlvbk1vZGVsKHt9KSlcblxuICBwdWJsaWMgcmVhZG9ubHkgbWFya2VycyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBtYXJrZXJzTWFwID0gbmV3IE1hcDxudW1iZXIsIE1hcmtlcj4oKVxuXG4gICAgdGhpcy52YWxpZEVkZ2VzKCkuZm9yRWFjaChlID0+IHtcbiAgICAgIGlmIChlLmVkZ2UubWFya2Vycz8uc3RhcnQpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IGhhc2hDb2RlKEpTT04uc3RyaW5naWZ5KGUuZWRnZS5tYXJrZXJzLnN0YXJ0KSlcbiAgICAgICAgbWFya2Vyc01hcC5zZXQoaGFzaCwgZS5lZGdlLm1hcmtlcnMuc3RhcnQpXG4gICAgICB9XG5cbiAgICAgIGlmIChlLmVkZ2UubWFya2Vycz8uZW5kKSB7XG4gICAgICAgIGNvbnN0IGhhc2ggPSBoYXNoQ29kZShKU09OLnN0cmluZ2lmeShlLmVkZ2UubWFya2Vycy5lbmQpKVxuICAgICAgICBtYXJrZXJzTWFwLnNldChoYXNoLCBlLmVkZ2UubWFya2Vycy5lbmQpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25NYXJrZXIgPSB0aGlzLmNvbm5lY3Rpb24oKS5jb25uZWN0aW9uLm1hcmtlclxuICAgIGlmIChjb25uZWN0aW9uTWFya2VyKSB7XG4gICAgICBjb25zdCBoYXNoID0gaGFzaENvZGUoSlNPTi5zdHJpbmdpZnkoY29ubmVjdGlvbk1hcmtlcikpXG4gICAgICBtYXJrZXJzTWFwLnNldChoYXNoLCBjb25uZWN0aW9uTWFya2VyKVxuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJzTWFwXG4gIH0pXG5cbiAgcHVibGljIHJlYWRvbmx5IHZhbGlkRWRnZXMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3Qgbm9kZXMgPSB0aGlzLm5vZGVzKClcblxuICAgIHJldHVybiB0aGlzLmVkZ2VzKCkuZmlsdGVyKGUgPT4gbm9kZXMuaW5jbHVkZXMoZS5zb3VyY2UpICYmIG5vZGVzLmluY2x1ZGVzKGUudGFyZ2V0KSlcbiAgfSlcblxuICBwdWJsaWMgZ2V0Tm9kZTxUPihpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZXMoKS5maW5kKCh7IG5vZGUgfSkgPT4gbm9kZS5pZCA9PT0gaWQpIGFzIE5vZGVNb2RlbDxUPiB8IHVuZGVmaW5lZFxuICB9XG59XG4iXX0=
@@ -0,0 +1,39 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class FlowStatusService {
4
+ constructor() {
5
+ this.status = signal({ state: 'idle', payload: null });
6
+ }
7
+ setIdleStatus() {
8
+ this.status.set({ state: 'idle', payload: null });
9
+ }
10
+ setConnectionStartStatus(sourceNode) {
11
+ this.status.set({ state: 'connection-start', payload: { sourceNode } });
12
+ }
13
+ setConnectionValidationStatus(sourceNode, targetNode, valid) {
14
+ this.status.set({ state: 'connection-validation', payload: { sourceNode, targetNode, valid } });
15
+ }
16
+ setConnectionEndStatus(sourceNode, targetNode) {
17
+ this.status.set({ state: 'connection-end', payload: { sourceNode, targetNode } });
18
+ }
19
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
20
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService }); }
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FlowStatusService, decorators: [{
23
+ type: Injectable
24
+ }] });
25
+ /**
26
+ * Batch status changes together to call them one after another
27
+ *
28
+ * @param changes list of set[FlowStatus.state]Status() calls
29
+ */
30
+ export function batchStatusChanges(...changes) {
31
+ if (changes.length) {
32
+ const [firstChange, ...restChanges] = changes;
33
+ // first change is sync
34
+ firstChange();
35
+ // without timer, subscribed effects/comuted signals only get latest value
36
+ restChanges.forEach(change => setTimeout(() => change()));
37
+ }
38
+ }
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvdy1zdGF0dXMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy9zZXJ2aWNlcy9mbG93LXN0YXR1cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQXVDbkQsTUFBTSxPQUFPLGlCQUFpQjtJQUQ5QjtRQUVrQixXQUFNLEdBQUcsTUFBTSxDQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtLQWlCOUU7SUFmUSxhQUFhO1FBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUNuRCxDQUFDO0lBRU0sd0JBQXdCLENBQUMsVUFBcUI7UUFDbkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ3pFLENBQUM7SUFFTSw2QkFBNkIsQ0FBQyxVQUFxQixFQUFFLFVBQXFCLEVBQUUsS0FBYztRQUMvRixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxPQUFPLEVBQUUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNqRyxDQUFDO0lBRU0sc0JBQXNCLENBQUMsVUFBcUIsRUFBRSxVQUFxQjtRQUN4RSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ25GLENBQUM7K0dBakJVLGlCQUFpQjttSEFBakIsaUJBQWlCOzs0RkFBakIsaUJBQWlCO2tCQUQ3QixVQUFVOztBQXFCWDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEdBQUcsT0FBbUI7SUFDdkQsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO1FBQ2xCLE1BQU0sQ0FBQyxXQUFXLEVBQUUsR0FBRyxXQUFXLENBQUMsR0FBRyxPQUFPLENBQUE7UUFDN0MsdUJBQXVCO1FBQ3ZCLFdBQVcsRUFBRSxDQUFBO1FBQ2IsMEVBQTBFO1FBQzFFLFdBQVcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFBO0tBQzFEO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dTdGF0dXNJZGxlIHtcbiAgc3RhdGU6ICdpZGxlJyxcbiAgcGF5bG9hZDogbnVsbFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dTdGF0dXNDb25uZWN0aW9uU3RhcnQge1xuICBzdGF0ZTogJ2Nvbm5lY3Rpb24tc3RhcnQnLFxuICBwYXlsb2FkOiB7XG4gICAgc291cmNlTm9kZTogTm9kZU1vZGVsXG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBGbG93U3RhdHVzQ29ubmVjdGlvblZhbGlkYXRpb24ge1xuICBzdGF0ZTogJ2Nvbm5lY3Rpb24tdmFsaWRhdGlvbicsXG4gIHBheWxvYWQ6IHtcbiAgICBzb3VyY2VOb2RlOiBOb2RlTW9kZWxcbiAgICB0YXJnZXROb2RlOiBOb2RlTW9kZWxcbiAgICB2YWxpZDogYm9vbGVhblxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmxvd1N0YXR1c0Nvbm5lY3Rpb25FbmQge1xuICBzdGF0ZTogJ2Nvbm5lY3Rpb24tZW5kJyxcbiAgcGF5bG9hZDoge1xuICAgIHNvdXJjZU5vZGU6IE5vZGVNb2RlbFxuICAgIHRhcmdldE5vZGU6IE5vZGVNb2RlbFxuICB9XG59XG5cbmV4cG9ydCB0eXBlIEZsb3dTdGF0dXMgPVxuICBGbG93U3RhdHVzSWRsZSB8XG4gIEZsb3dTdGF0dXNDb25uZWN0aW9uU3RhcnQgfFxuICBGbG93U3RhdHVzQ29ubmVjdGlvblZhbGlkYXRpb24gfFxuICBGbG93U3RhdHVzQ29ubmVjdGlvbkVuZFxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRmxvd1N0YXR1c1NlcnZpY2Uge1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzID0gc2lnbmFsPEZsb3dTdGF0dXM+KHsgc3RhdGU6ICdpZGxlJywgcGF5bG9hZDogbnVsbCB9KVxuXG4gIHB1YmxpYyBzZXRJZGxlU3RhdHVzKCkge1xuICAgIHRoaXMuc3RhdHVzLnNldCh7IHN0YXRlOiAnaWRsZScsIHBheWxvYWQ6IG51bGwgfSlcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb25uZWN0aW9uU3RhcnRTdGF0dXMoc291cmNlTm9kZTogTm9kZU1vZGVsKSB7XG4gICAgdGhpcy5zdGF0dXMuc2V0KHsgc3RhdGU6ICdjb25uZWN0aW9uLXN0YXJ0JywgcGF5bG9hZDogeyBzb3VyY2VOb2RlIH0gfSlcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb25uZWN0aW9uVmFsaWRhdGlvblN0YXR1cyhzb3VyY2VOb2RlOiBOb2RlTW9kZWwsIHRhcmdldE5vZGU6IE5vZGVNb2RlbCwgdmFsaWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnN0YXR1cy5zZXQoeyBzdGF0ZTogJ2Nvbm5lY3Rpb24tdmFsaWRhdGlvbicsIHBheWxvYWQ6IHsgc291cmNlTm9kZSwgdGFyZ2V0Tm9kZSwgdmFsaWQgfSB9KVxuICB9XG5cbiAgcHVibGljIHNldENvbm5lY3Rpb25FbmRTdGF0dXMoc291cmNlTm9kZTogTm9kZU1vZGVsLCB0YXJnZXROb2RlOiBOb2RlTW9kZWwpIHtcbiAgICB0aGlzLnN0YXR1cy5zZXQoeyBzdGF0ZTogJ2Nvbm5lY3Rpb24tZW5kJywgcGF5bG9hZDogeyBzb3VyY2VOb2RlLCB0YXJnZXROb2RlIH0gfSlcbiAgfVxufVxuXG4vKipcbiAqIEJhdGNoIHN0YXR1cyBjaGFuZ2VzIHRvZ2V0aGVyIHRvIGNhbGwgdGhlbSBvbmUgYWZ0ZXIgYW5vdGhlclxuICpcbiAqIEBwYXJhbSBjaGFuZ2VzIGxpc3Qgb2Ygc2V0W0Zsb3dTdGF0dXMuc3RhdGVdU3RhdHVzKCkgY2FsbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJhdGNoU3RhdHVzQ2hhbmdlcyguLi5jaGFuZ2VzOiBGdW5jdGlvbltdKSB7XG4gIGlmIChjaGFuZ2VzLmxlbmd0aCkge1xuICAgIGNvbnN0IFtmaXJzdENoYW5nZSwgLi4ucmVzdENoYW5nZXNdID0gY2hhbmdlc1xuICAgIC8vIGZpcnN0IGNoYW5nZSBpcyBzeW5jXG4gICAgZmlyc3RDaGFuZ2UoKVxuICAgIC8vIHdpdGhvdXQgdGltZXIsIHN1YnNjcmliZWQgZWZmZWN0cy9jb211dGVkIHNpZ25hbHMgb25seSBnZXQgbGF0ZXN0IHZhbHVlXG4gICAgcmVzdENoYW5nZXMuZm9yRWFjaChjaGFuZ2UgPT4gc2V0VGltZW91dCgoKSA9PiBjaGFuZ2UoKSkpXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,32 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { FlowEntitiesService } from './flow-entities.service';
3
+ import { toObservable } from '@angular/core/rxjs-interop';
4
+ import { filter, map, merge, pairwise, skip, switchMap } from 'rxjs';
5
+ import * as i0 from "@angular/core";
6
+ export class NodesChangeService {
7
+ constructor() {
8
+ this.entitiesService = inject(FlowEntitiesService);
9
+ this.nodesPositionChange$ = toObservable(this.entitiesService.nodes)
10
+ .pipe(
11
+ // Check for nodes list change and watch for specific node from this list change its position
12
+ switchMap((nodes) => merge(...nodes.map(node => node.point$.pipe(
13
+ // skip initial position from signal
14
+ skip(1), map(() => node))))),
15
+ // For now it's a single node, later this list will also be filled
16
+ // with child node position changes
17
+ map(changedNode => [
18
+ { type: 'position', id: changedNode.node.id, point: changedNode.point() }
19
+ ]));
20
+ this.nodeAddChange$ = toObservable(this.entitiesService.nodes)
21
+ .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 }))));
22
+ this.nodeRemoveChange$ = toObservable(this.entitiesService.nodes)
23
+ .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 }))));
24
+ this.changes$ = merge(this.nodesPositionChange$, this.nodeAddChange$, this.nodeRemoveChange$);
25
+ }
26
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
27
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService }); }
28
+ }
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodesChangeService, decorators: [{
30
+ type: Injectable
31
+ }] });
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1jaGFuZ2VzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvc2VydmljZXMvbm9kZS1jaGFuZ2VzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBYyxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBTSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUFJckYsTUFBTSxPQUFPLGtCQUFrQjtJQUQvQjtRQUVZLG9CQUFlLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUE7UUFFN0MseUJBQW9CLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO2FBQ3RFLElBQUk7UUFDSCw2RkFBNkY7UUFDN0YsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDbEIsS0FBSyxDQUNILEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUk7UUFDZCxvQ0FBb0M7UUFDcEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FDaEIsQ0FDRixDQUNGLENBQ0Y7UUFDRCxrRUFBa0U7UUFDbEUsbUNBQW1DO1FBQ25DLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ2pCLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRTtTQUMxRSxDQUFDLENBQ2dDLENBQUE7UUFFNUIsbUJBQWMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7YUFDaEUsSUFBSSxDQUNILFFBQVEsRUFBRSxFQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FDekIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUNoRCxFQUNELE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFDakMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDWixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUN2RCxDQUNpQyxDQUFBO1FBRTVCLHNCQUFpQixHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQzthQUNuRSxJQUFJLENBQ0gsUUFBUSxFQUFFLEVBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUN6QixPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQ2hELEVBQ0QsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUNqQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNaLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQzFELENBQ2lDLENBQUE7UUFFdEIsYUFBUSxHQUE2QixLQUFLLENBQ3hELElBQUksQ0FBQyxvQkFBb0IsRUFDekIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLGlCQUFpQixDQUN2QixDQUFBO0tBQ0Y7K0dBckRZLGtCQUFrQjttSEFBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgU2lnbmFsLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZsb3dFbnRpdGllc1NlcnZpY2UgfSBmcm9tICcuL2Zsb3ctZW50aXRpZXMuc2VydmljZSc7XG5pbXBvcnQgeyB0b09ic2VydmFibGUsIHRvU2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZmlsdGVyLCBtYXAsIG1lcmdlLCBvZiwgcGFpcndpc2UsIHNraXAsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTm9kZUNoYW5nZSB9IGZyb20gJy4uL3R5cGVzL25vZGUtY2hhbmdlLnR5cGUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTm9kZXNDaGFuZ2VTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIGVudGl0aWVzU2VydmljZSA9IGluamVjdChGbG93RW50aXRpZXNTZXJ2aWNlKVxuXG4gIHByb3RlY3RlZCBub2Rlc1Bvc2l0aW9uQ2hhbmdlJCA9IHRvT2JzZXJ2YWJsZSh0aGlzLmVudGl0aWVzU2VydmljZS5ub2RlcylcbiAgICAucGlwZShcbiAgICAgIC8vIENoZWNrIGZvciBub2RlcyBsaXN0IGNoYW5nZSBhbmQgd2F0Y2ggZm9yIHNwZWNpZmljIG5vZGUgZnJvbSB0aGlzIGxpc3QgY2hhbmdlIGl0cyBwb3NpdGlvblxuICAgICAgc3dpdGNoTWFwKChub2RlcykgPT5cbiAgICAgICAgbWVyZ2UoXG4gICAgICAgICAgLi4ubm9kZXMubWFwKG5vZGUgPT5cbiAgICAgICAgICAgIG5vZGUucG9pbnQkLnBpcGUoXG4gICAgICAgICAgICAgIC8vIHNraXAgaW5pdGlhbCBwb3NpdGlvbiBmcm9tIHNpZ25hbFxuICAgICAgICAgICAgICBza2lwKDEpLFxuICAgICAgICAgICAgICBtYXAoKCkgPT4gbm9kZSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgICksXG4gICAgICAvLyBGb3Igbm93IGl0J3MgYSBzaW5nbGUgbm9kZSwgbGF0ZXIgdGhpcyBsaXN0IHdpbGwgYWxzbyBiZSBmaWxsZWRcbiAgICAgIC8vIHdpdGggY2hpbGQgbm9kZSBwb3NpdGlvbiBjaGFuZ2VzXG4gICAgICBtYXAoY2hhbmdlZE5vZGUgPT4gW1xuICAgICAgICB7IHR5cGU6ICdwb3NpdGlvbicsIGlkOiBjaGFuZ2VkTm9kZS5ub2RlLmlkLCBwb2ludDogY2hhbmdlZE5vZGUucG9pbnQoKSB9XG4gICAgICBdKVxuICAgICkgc2F0aXNmaWVzIE9ic2VydmFibGU8Tm9kZUNoYW5nZVtdPlxuXG4gIHByb3RlY3RlZCBub2RlQWRkQ2hhbmdlJCA9IHRvT2JzZXJ2YWJsZSh0aGlzLmVudGl0aWVzU2VydmljZS5ub2RlcylcbiAgICAucGlwZShcbiAgICAgIHBhaXJ3aXNlKCksXG4gICAgICBtYXAoKFtvbGRMaXN0LCBuZXdMaXN0XSkgPT5cbiAgICAgICAgbmV3TGlzdC5maWx0ZXIobm9kZSA9PiAhb2xkTGlzdC5pbmNsdWRlcyhub2RlKSlcbiAgICAgICksXG4gICAgICBmaWx0ZXIoKG5vZGVzKSA9PiAhIW5vZGVzLmxlbmd0aCksXG4gICAgICBtYXAoKG5vZGVzKSA9PlxuICAgICAgICBub2Rlcy5tYXAobm9kZSA9PiAoeyB0eXBlOiAnYWRkJywgaWQ6IG5vZGUubm9kZS5pZCB9KSlcbiAgICAgIClcbiAgICApIHNhdGlzZmllcyBPYnNlcnZhYmxlPE5vZGVDaGFuZ2VbXT5cblxuICBwcm90ZWN0ZWQgbm9kZVJlbW92ZUNoYW5nZSQgPSB0b09ic2VydmFibGUodGhpcy5lbnRpdGllc1NlcnZpY2Uubm9kZXMpXG4gICAgLnBpcGUoXG4gICAgICBwYWlyd2lzZSgpLFxuICAgICAgbWFwKChbb2xkTGlzdCwgbmV3TGlzdF0pID0+XG4gICAgICAgIG9sZExpc3QuZmlsdGVyKG5vZGUgPT4gIW5ld0xpc3QuaW5jbHVkZXMobm9kZSkpXG4gICAgICApLFxuICAgICAgZmlsdGVyKChub2RlcykgPT4gISFub2Rlcy5sZW5ndGgpLFxuICAgICAgbWFwKChub2RlcykgPT5cbiAgICAgICAgbm9kZXMubWFwKG5vZGUgPT4gKHsgdHlwZTogJ3JlbW92ZScsIGlkOiBub2RlLm5vZGUuaWQgfSkpXG4gICAgICApXG4gICAgKSBzYXRpc2ZpZXMgT2JzZXJ2YWJsZTxOb2RlQ2hhbmdlW10+XG5cbiAgcHVibGljIHJlYWRvbmx5IGNoYW5nZXMkOiBPYnNlcnZhYmxlPE5vZGVDaGFuZ2VbXT4gPSBtZXJnZShcbiAgICB0aGlzLm5vZGVzUG9zaXRpb25DaGFuZ2UkLFxuICAgIHRoaXMubm9kZUFkZENoYW5nZSQsXG4gICAgdGhpcy5ub2RlUmVtb3ZlQ2hhbmdlJFxuICApXG59XG4iXX0=