ngx-vflow 1.14.0 → 1.16.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 (44) hide show
  1. package/esm2022/lib/vflow/components/alignment-helper/alignment-helper.component.mjs +103 -0
  2. package/esm2022/lib/vflow/components/node/node.component.mjs +5 -4
  3. package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +8 -5
  4. package/esm2022/lib/vflow/interfaces/alignment-helper-settings.interface.mjs +2 -0
  5. package/esm2022/lib/vflow/interfaces/flow-entity.interface.mjs +1 -1
  6. package/esm2022/lib/vflow/interfaces/node.interface.mjs +13 -5
  7. package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +2 -1
  8. package/esm2022/lib/vflow/interfaces/rect.mjs +10 -2
  9. package/esm2022/lib/vflow/interfaces/template-context.interface.mjs +1 -1
  10. package/esm2022/lib/vflow/models/edge.model.mjs +4 -9
  11. package/esm2022/lib/vflow/models/node.model.mjs +51 -7
  12. package/esm2022/lib/vflow/services/draggable.service.mjs +7 -1
  13. package/esm2022/lib/vflow/services/edge-rendering.service.mjs +1 -1
  14. package/esm2022/lib/vflow/services/flow-rendering.service.mjs +9 -1
  15. package/esm2022/lib/vflow/services/flow-status.service.mjs +13 -1
  16. package/esm2022/lib/vflow/utils/is-callable.mjs +10 -0
  17. package/esm2022/lib/vflow/utils/is-vflow-component.mjs +9 -0
  18. package/esm2022/public-api.mjs +3 -1
  19. package/esm2022/testing/component-mocks/vflow-mock.component.mjs +4 -3
  20. package/esm2022/testing/provide-custom-node-mocks.mjs +3 -2
  21. package/fesm2022/ngx-vflow-testing.mjs +5 -3
  22. package/fesm2022/ngx-vflow-testing.mjs.map +1 -1
  23. package/fesm2022/ngx-vflow.mjs +387 -201
  24. package/fesm2022/ngx-vflow.mjs.map +1 -1
  25. package/lib/vflow/components/alignment-helper/alignment-helper.component.d.ts +21 -0
  26. package/lib/vflow/components/vflow/vflow.component.d.ts +3 -1
  27. package/lib/vflow/interfaces/alignment-helper-settings.interface.d.ts +4 -0
  28. package/lib/vflow/interfaces/flow-entity.interface.d.ts +2 -1
  29. package/lib/vflow/interfaces/node.interface.d.ts +2 -2
  30. package/lib/vflow/interfaces/optimization.interface.d.ts +4 -0
  31. package/lib/vflow/interfaces/rect.d.ts +7 -0
  32. package/lib/vflow/interfaces/template-context.interface.d.ts +4 -0
  33. package/lib/vflow/models/edge.model.d.ts +2 -0
  34. package/lib/vflow/models/node.model.d.ts +4 -0
  35. package/lib/vflow/public-components/custom-template-edge/custom-template-edge.component.d.ts +1 -0
  36. package/lib/vflow/services/draggable.service.d.ts +1 -0
  37. package/lib/vflow/services/edge-rendering.service.d.ts +1 -1
  38. package/lib/vflow/services/flow-rendering.service.d.ts +4 -0
  39. package/lib/vflow/services/flow-status.service.d.ts +17 -1
  40. package/lib/vflow/utils/is-callable.d.ts +1 -0
  41. package/lib/vflow/utils/is-vflow-component.d.ts +4 -0
  42. package/package.json +1 -1
  43. package/public-api.d.ts +2 -0
  44. package/testing/component-mocks/vflow-mock.component.d.ts +3 -2
@@ -0,0 +1,103 @@
1
+ import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
2
+ import { nodeToRect } from '../../utils/nodes';
3
+ import { FlowStatusService, isNodeDragEndStatus, isNodeDragStartStatus } from '../../services/flow-status.service';
4
+ import { rectToRectWithSides } from '../../interfaces/rect';
5
+ import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
6
+ import { filter, map, tap } from 'rxjs';
7
+ import { extendedComputed } from '../../utils/signals/extended-computed';
8
+ import { NodeRenderingService } from '../../services/node-rendering.service';
9
+ import { getSpacePoints } from '../../utils/get-space-points';
10
+ import * as i0 from "@angular/core";
11
+ export class AlignmentHelperComponent {
12
+ constructor() {
13
+ this.nodeRenderingService = inject(NodeRenderingService);
14
+ this.flowStatus = inject(FlowStatusService);
15
+ this.tolerance = input(10);
16
+ this.lineColor = input('#1b262c');
17
+ this.isNodeDragging = computed(() => isNodeDragStartStatus(this.flowStatus.status()));
18
+ this.intersections = extendedComputed((lastValue) => {
19
+ const status = this.flowStatus.status();
20
+ if (isNodeDragStartStatus(status)) {
21
+ const node = status.payload.node;
22
+ const d = rectToRectWithSides(nodeToRect(node));
23
+ const otherRects = this.nodeRenderingService
24
+ .viewportNodes()
25
+ .filter((n) => n !== node)
26
+ // do not check children of the dragged node
27
+ .filter((n) => !node.children().includes(n))
28
+ .map((n) => rectToRectWithSides(nodeToRect(n)));
29
+ const lines = [];
30
+ let snappedX = d.x;
31
+ let snappedY = d.y;
32
+ let closestXDiff = Infinity;
33
+ let closestYDiff = Infinity;
34
+ otherRects.forEach((o) => {
35
+ const dCenterX = d.left + d.width / 2;
36
+ const oCenterX = o.left + o.width / 2;
37
+ for (const [dX, oX, snapX, isCenter] of [
38
+ // center check
39
+ [dCenterX, oCenterX, oCenterX - d.width / 2, true],
40
+ [d.left, o.left, o.left, false],
41
+ [d.left, o.right, o.right, false],
42
+ [d.right, o.left, o.left - d.width, false],
43
+ [d.right, o.right, o.right - d.width, false],
44
+ ]) {
45
+ const diff = Math.abs(dX - oX);
46
+ if (diff <= this.tolerance()) {
47
+ const y = Math.min(d.top, o.top);
48
+ const y2 = Math.max(d.bottom, o.bottom);
49
+ lines.push({ x: oX, y, x2: oX, y2, isCenter });
50
+ if (diff < closestXDiff) {
51
+ closestXDiff = diff;
52
+ snappedX = snapX;
53
+ }
54
+ if (isCenter)
55
+ break;
56
+ }
57
+ }
58
+ const dCenterY = d.top + d.height / 2;
59
+ const oCenterY = o.top + o.height / 2;
60
+ for (const [dY, oY, snapY, isCenter] of [
61
+ // center check
62
+ [dCenterY, oCenterY, oCenterY - d.height / 2, true],
63
+ [d.top, o.top, o.top, false],
64
+ [d.top, o.bottom, o.bottom, false],
65
+ [d.bottom, o.top, o.top - d.height, false],
66
+ [d.bottom, o.bottom, o.bottom - d.height, false],
67
+ ]) {
68
+ const diff = Math.abs(dY - oY);
69
+ if (diff <= this.tolerance()) {
70
+ const x = Math.min(d.left, o.left);
71
+ const x2 = Math.max(d.right, o.right);
72
+ lines.push({ x, y: oY, x2, y2: oY, isCenter });
73
+ if (diff < closestYDiff) {
74
+ closestYDiff = diff;
75
+ snappedY = snapY;
76
+ }
77
+ if (isCenter)
78
+ break;
79
+ }
80
+ }
81
+ });
82
+ return { lines, snappedX, snappedY };
83
+ }
84
+ return lastValue;
85
+ });
86
+ toObservable(this.flowStatus.status)
87
+ .pipe(filter(isNodeDragEndStatus), map((status) => status.payload.node), map((node) => [node, this.intersections()]), tap(([node, intersections]) => {
88
+ if (intersections) {
89
+ const snapped = { x: intersections.snappedX, y: intersections.snappedY };
90
+ const parentIfExists = node.parent() ? [node.parent()] : [];
91
+ node.setPoint(getSpacePoints(snapped, parentIfExists)[0]);
92
+ }
93
+ }), takeUntilDestroyed())
94
+ .subscribe();
95
+ }
96
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AlignmentHelperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
97
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AlignmentHelperComponent, isStandalone: true, selector: "g[alignmentHelper]", inputs: { tolerance: { classPropertyName: "tolerance", publicName: "tolerance", isSignal: true, isRequired: false, transformFunction: null }, lineColor: { classPropertyName: "lineColor", publicName: "lineColor", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isNodeDragging()) {\n @if (intersections(); as intersections) {\n @for (intersection of intersections.lines; track $index) {\n <svg:line\n [attr.stroke]=\"lineColor()\"\n [attr.stroke-dasharray]=\"intersection.isCenter ? 4 : null\"\n [attr.x1]=\"intersection.x\"\n [attr.y1]=\"intersection.y\"\n [attr.x2]=\"intersection.x2\"\n [attr.y2]=\"intersection.y2\" />\n }\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
98
+ }
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AlignmentHelperComponent, decorators: [{
100
+ type: Component,
101
+ args: [{ selector: 'g[alignmentHelper]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "@if (isNodeDragging()) {\n @if (intersections(); as intersections) {\n @for (intersection of intersections.lines; track $index) {\n <svg:line\n [attr.stroke]=\"lineColor()\"\n [attr.stroke-dasharray]=\"intersection.isCenter ? 4 : null\"\n [attr.x1]=\"intersection.x\"\n [attr.y1]=\"intersection.y\"\n [attr.x2]=\"intersection.x2\"\n [attr.y2]=\"intersection.y2\" />\n }\n }\n}\n" }]
102
+ }], ctorParameters: () => [] });
103
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxpZ25tZW50LWhlbHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvY29tcG9uZW50cy9hbGlnbm1lbnQtaGVscGVyL2FsaWdubWVudC1oZWxwZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXZmbG93LWxpYi9zcmMvbGliL3ZmbG93L2NvbXBvbmVudHMvYWxpZ25tZW50LWhlbHBlci9hbGlnbm1lbnQtaGVscGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ25ILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDOztBQWM5RCxNQUFNLE9BQU8sd0JBQXdCO0lBOEZuQztRQTdGUSx5QkFBb0IsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMs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U3RyYXRlZ3ksIENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgaW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG5vZGVUb1JlY3QgfSBmcm9tICcuLi8uLi91dGlscy9ub2Rlcyc7XG5pbXBvcnQgeyBGbG93U3RhdHVzU2VydmljZSwgaXNOb2RlRHJhZ0VuZFN0YXR1cywgaXNOb2RlRHJhZ1N0YXJ0U3RhdHVzIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmxvdy1zdGF0dXMuc2VydmljZSc7XG5pbXBvcnQgeyByZWN0VG9SZWN0V2l0aFNpZGVzIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZWN0JztcbmltcG9ydCB7IEJveCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvYm94JztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCwgdG9PYnNlcnZhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXAsIHRhcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZXh0ZW5kZWRDb21wdXRlZCB9IGZyb20gJy4uLy4uL3V0aWxzL3NpZ25hbHMvZXh0ZW5kZWQtY29tcHV0ZWQnO1xuaW1wb3J0IHsgTm9kZVJlbmRlcmluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub2RlLXJlbmRlcmluZy5zZXJ2aWNlJztcbmltcG9ydCB7IGdldFNwYWNlUG9pbnRzIH0gZnJvbSAnLi4vLi4vdXRpbHMvZ2V0LXNwYWNlLXBvaW50cyc7XG5cbmludGVyZmFjZSBJbnRlcnNlY3Rpb24ge1xuICBsaW5lczogKEJveCAmIHsgaXNDZW50ZXI6IGJvb2xlYW4gfSlbXTtcbiAgc25hcHBlZFg6IG51bWJlcjtcbiAgc25hcHBlZFk6IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZ1thbGlnbm1lbnRIZWxwZXJdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FsaWdubWVudC1oZWxwZXIuY29tcG9uZW50Lmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQWxpZ25tZW50SGVscGVyQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSBub2RlUmVuZGVyaW5nU2VydmljZSA9IGluamVjdChOb2RlUmVuZGVyaW5nU2VydmljZSk7XG4gIHByaXZhdGUgZmxvd1N0YXR1cyA9IGluamVjdChGbG93U3RhdHVzU2VydmljZSk7XG5cbiAgcmVhZG9ubHkgdG9sZXJhbmNlID0gaW5wdXQoMTApO1xuICByZWFkb25seSBsaW5lQ29sb3IgPSBpbnB1dCgnIzFiMjYyYycpO1xuXG4gIHByb3RlY3RlZCBpc05vZGVEcmFnZ2luZyA9IGNvbXB1dGVkKCgpID0+IGlzTm9kZURyYWdTdGFydFN0YXR1cyh0aGlzLmZsb3dTdGF0dXMuc3RhdHVzKCkpKTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW50ZXJzZWN0aW9ucyA9IGV4dGVuZGVkQ29tcHV0ZWQ8SW50ZXJzZWN0aW9uPigobGFzdFZhbHVlKSA9PiB7XG4gICAgY29uc3Qgc3RhdHVzID0gdGhpcy5mbG93U3RhdHVzLnN0YXR1cygpO1xuXG4gICAgaWYgKGlzTm9kZURyYWdTdGFydFN0YXR1cyhzdGF0dXMpKSB7XG4gICAgICBjb25zdCBub2RlID0gc3RhdHVzLnBheWxvYWQubm9kZTtcblxuICAgICAgY29uc3QgZCA9IHJlY3RUb1JlY3RXaXRoU2lkZXMobm9kZVRvUmVjdChub2RlKSk7XG4gICAgICBjb25zdCBvdGhlclJlY3RzID0gdGhpcy5ub2RlUmVuZGVyaW5nU2VydmljZVxuICAgICAgICAudmlld3BvcnROb2RlcygpXG4gICAgICAgIC5maWx0ZXIoKG4pID0+IG4gIT09IG5vZGUpXG4gICAgICAgIC8vIGRvIG5vdCBjaGVjayBjaGlsZHJlbiBvZiB0aGUgZHJhZ2dlZCBub2RlXG4gICAgICAgIC5maWx0ZXIoKG4pID0+ICFub2RlLmNoaWxkcmVuKCkuaW5jbHVkZXMobikpXG4gICAgICAgIC5tYXAoKG4pID0+IHJlY3RUb1JlY3RXaXRoU2lkZXMobm9kZVRvUmVjdChuKSkpO1xuXG4gICAgICBjb25zdCBsaW5lczogSW50ZXJzZWN0aW9uWydsaW5lcyddID0gW107XG5cbiAgICAgIGxldCBzbmFwcGVkWCA9IGQueDtcbiAgICAgIGxldCBzbmFwcGVkWSA9IGQueTtcbiAgICAgIGxldCBjbG9zZXN0WERpZmYgPSBJbmZpbml0eTtcbiAgICAgIGxldCBjbG9zZXN0WURpZmYgPSBJbmZpbml0eTtcblxuICAgICAgb3RoZXJSZWN0cy5mb3JFYWNoKChvKSA9PiB7XG4gICAgICAgIGNvbnN0IGRDZW50ZXJYID0gZC5sZWZ0ICsgZC53aWR0aCAvIDI7XG4gICAgICAgIGNvbnN0IG9DZW50ZXJYID0gby5sZWZ0ICsgby53aWR0aCAvIDI7XG5cbiAgICAgICAgZm9yIChjb25zdCBbZFgsIG9YLCBzbmFwWCwgaXNDZW50ZXJdIG9mIFtcbiAgICAgICAgICAvLyBjZW50ZXIgY2hlY2tcbiAgICAgICAgICBbZENlbnRlclgsIG9DZW50ZXJYLCBvQ2VudGVyWCAtIGQud2lkdGggLyAyLCB0cnVlXSBhcyBjb25zdCxcbiAgICAgICAgICBbZC5sZWZ0LCBvLmxlZnQsIG8ubGVmdCwgZmFsc2VdIGFzIGNvbnN0LFxuICAgICAgICAgIFtkLmxlZnQsIG8ucmlnaHQsIG8ucmlnaHQsIGZhbHNlXSBhcyBjb25zdCxcbiAgICAgICAgICBbZC5yaWdodCwgby5sZWZ0LCBvLmxlZnQgLSBkLndpZHRoLCBmYWxzZV0gYXMgY29uc3QsXG4gICAgICAgICAgW2QucmlnaHQsIG8ucmlnaHQsIG8ucmlnaHQgLSBkLndpZHRoLCBmYWxzZV0gYXMgY29uc3QsXG4gICAgICAgIF0pIHtcbiAgICAgICAgICBjb25zdCBkaWZmID0gTWF0aC5hYnMoZFggLSBvWCk7XG5cbiAgICAgICAgICBpZiAoZGlmZiA8PSB0aGlzLnRvbGVyYW5jZSgpKSB7XG4gICAgICAgICAgICBjb25zdCB5ID0gTWF0aC5taW4oZC50b3AsIG8udG9wKTtcbiAgICAgICAgICAgIGNvbnN0IHkyID0gTWF0aC5tYXgoZC5ib3R0b20sIG8uYm90dG9tKTtcblxuICAgICAgICAgICAgbGluZXMucHVzaCh7IHg6IG9YLCB5LCB4Mjogb1gsIHkyLCBpc0NlbnRlciB9KTtcblxuICAgICAgICAgICAgaWYgKGRpZmYgPCBjbG9zZXN0WERpZmYpIHtcbiAgICAgICAgICAgICAgY2xvc2VzdFhEaWZmID0gZGlmZjtcbiAgICAgICAgICAgICAgc25hcHBlZFggPSBzbmFwWDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQ2VudGVyKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkQ2VudGVyWSA9IGQudG9wICsgZC5oZWlnaHQgLyAyO1xuICAgICAgICBjb25zdCBvQ2VudGVyWSA9IG8udG9wICsgby5oZWlnaHQgLyAyO1xuXG4gICAgICAgIGZvciAoY29uc3QgW2RZLCBvWSwgc25hcFksIGlzQ2VudGVyXSBvZiBbXG4gICAgICAgICAgLy8gY2VudGVyIGNoZWNrXG4gICAgICAgICAgW2RDZW50ZXJZLCBvQ2VudGVyWSwgb0NlbnRlclkgLSBkLmhlaWdodCAvIDIsIHRydWVdIGFzIGNvbnN0LFxuICAgICAgICAgIFtkLnRvcCwgby50b3AsIG8udG9wLCBmYWxzZV0gYXMgY29uc3QsXG4gICAgICAgICAgW2QudG9wLCBvLmJvdHRvbSwgby5ib3R0b20sIGZhbHNlXSBhcyBjb25zdCxcbiAgICAgICAgICBbZC5ib3R0b20sIG8udG9wLCBvLnRvcCAtIGQuaGVpZ2h0LCBmYWxzZV0gYXMgY29uc3QsXG4gICAgICAgICAgW2QuYm90dG9tLCBvLmJvdHRvbSwgby5ib3R0b20gLSBkLmhlaWdodCwgZmFsc2VdIGFzIGNvbnN0LFxuICAgICAgICBdKSB7XG4gICAgICAgICAgY29uc3QgZGlmZiA9IE1hdGguYWJzKGRZIC0gb1kpO1xuXG4gICAgICAgICAgaWYgKGRpZmYgPD0gdGhpcy50b2xlcmFuY2UoKSkge1xuICAgICAgICAgICAgY29uc3QgeCA9IE1hdGgubWluKGQubGVmdCwgby5sZWZ0KTtcbiAgICAgICAgICAgIGNvbnN0IHgyID0gTWF0aC5tYXgoZC5yaWdodCwgby5yaWdodCk7XG5cbiAgICAgICAgICAgIGxpbmVzLnB1c2goeyB4LCB5OiBvWSwgeDIsIHkyOiBvWSwgaXNDZW50ZXIgfSk7XG5cbiAgICAgICAgICAgIGlmIChkaWZmIDwgY2xvc2VzdFlEaWZmKSB7XG4gICAgICAgICAgICAgIGNsb3Nlc3RZRGlmZiA9IGRpZmY7XG4gICAgICAgICAgICAgIHNuYXBwZWRZID0gc25hcFk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0NlbnRlcikgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHsgbGluZXMsIHNuYXBwZWRYLCBzbmFwcGVkWSB9O1xuICAgIH1cblxuICAgIHJldHVybiBsYXN0VmFsdWU7XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRvT2JzZXJ2YWJsZSh0aGlzLmZsb3dTdGF0dXMuc3RhdHVzKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihpc05vZGVEcmFnRW5kU3RhdHVzKSxcbiAgICAgICAgbWFwKChzdGF0dXMpID0+IHN0YXR1cy5wYXlsb2FkLm5vZGUpLFxuICAgICAgICBtYXAoKG5vZGUpID0+IFtub2RlLCB0aGlzLmludGVyc2VjdGlvbnMoKV0gYXMgY29uc3QpLFxuICAgICAgICB0YXAoKFtub2RlLCBpbnRlcnNlY3Rpb25zXSkgPT4ge1xuICAgICAgICAgIGlmIChpbnRlcnNlY3Rpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBzbmFwcGVkID0geyB4OiBpbnRlcnNlY3Rpb25zLnNuYXBwZWRYLCB5OiBpbnRlcnNlY3Rpb25zLnNuYXBwZWRZIH07XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRJZkV4aXN0cyA9IG5vZGUucGFyZW50KCkgPyBbbm9kZS5wYXJlbnQoKSFdIDogW107XG5cbiAgICAgICAgICAgIG5vZGUuc2V0UG9pbnQoZ2V0U3BhY2VQb2ludHMoc25hcHBlZCwgcGFyZW50SWZFeGlzdHMpWzBdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQoKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxufVxuIiwiQGlmIChpc05vZGVEcmFnZ2luZygpKSB7XG4gIEBpZiAoaW50ZXJzZWN0aW9ucygpOyBhcyBpbnRlcnNlY3Rpb25zKSB7XG4gICAgQGZvciAoaW50ZXJzZWN0aW9uIG9mIGludGVyc2VjdGlvbnMubGluZXM7IHRyYWNrICRpbmRleCkge1xuICAgICAgPHN2ZzpsaW5lXG4gICAgICAgIFthdHRyLnN0cm9rZV09XCJsaW5lQ29sb3IoKVwiXG4gICAgICAgIFthdHRyLnN0cm9rZS1kYXNoYXJyYXldPVwiaW50ZXJzZWN0aW9uLmlzQ2VudGVyID8gNCA6IG51bGxcIlxuICAgICAgICBbYXR0ci54MV09XCJpbnRlcnNlY3Rpb24ueFwiXG4gICAgICAgIFthdHRyLnkxXT1cImludGVyc2VjdGlvbi55XCJcbiAgICAgICAgW2F0dHIueDJdPVwiaW50ZXJzZWN0aW9uLngyXCJcbiAgICAgICAgW2F0dHIueTJdPVwiaW50ZXJzZWN0aW9uLnkyXCIgLz5cbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -9,7 +9,7 @@ import { ConnectionControllerDirective } from '../../directives/connection-contr
9
9
  import { NodeAccessorService } from '../../services/node-accessor.service';
10
10
  import { OverlaysService } from '../../services/overlays.service';
11
11
  import { HandleSizeControllerDirective } from '../../directives/handle-size-controller.directive';
12
- import { NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
12
+ import { NgTemplateOutlet, NgComponentOutlet, AsyncPipe } from '@angular/common';
13
13
  import { DefaultNodeComponent } from '../default-node/default-node.component';
14
14
  import { PointerDirective } from '../../directives/pointer.directive';
15
15
  // TODO: fix loading of these by @defer (should work in Angular 18+)
@@ -85,7 +85,7 @@ export class NodeComponent {
85
85
  }
86
86
  }
87
87
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
88
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeSvgTemplate: { classPropertyName: "nodeSvgTemplate", publicName: "nodeSvgTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], ngImport: i0, template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(model().rawNode.type)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\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 (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\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]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track 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", "offsetX", "offsetY"] }, { 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"] }, { kind: "directive", type: NodeHandlesControllerDirective, selector: "[nodeHandlesController]" }, { kind: "directive", type: NodeResizeControllerDirective, selector: "[nodeResizeController]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
88
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeSvgTemplate: { classPropertyName: "nodeSvgTemplate", publicName: "nodeSvgTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], ngImport: i0, template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n @if (model().componentInstance$ | async; as component) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(component)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n }\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\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 (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\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]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track 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", "offsetX", "offsetY"] }, { 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"] }, { kind: "directive", type: NodeHandlesControllerDirective, selector: "[nodeHandlesController]" }, { kind: "directive", type: NodeResizeControllerDirective, selector: "[nodeResizeController]" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
89
89
  }
90
90
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, decorators: [{
91
91
  type: Component,
@@ -101,6 +101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
101
101
  HandleSizeControllerDirective,
102
102
  NodeHandlesControllerDirective,
103
103
  NodeResizeControllerDirective,
104
- ], template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(model().rawNode.type)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\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 (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\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]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track 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"] }]
104
+ AsyncPipe,
105
+ ], template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n @if (model().componentInstance$ | async; as component) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(component)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n }\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\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 (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\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]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track 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"] }]
105
106
  }] });
106
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvY29tcG9uZW50cy9ub2RlL25vZGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXZmbG93LWxpYi9zcmMvbGliL3ZmbG93L2NvbXBvbmVudHMvbm9kZS9ub2RlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFVBQVUsRUFDVixRQUFRLEVBSVIsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxHQUNOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRXBFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUNqRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbEUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDbEcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFD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LElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7WUFDbEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3QyxDQUFDO0lBQ0gsQ0FBQzsrR0F0RlUsYUFBYTttR0FBYixhQUFhLGdxQkFoQmIsQ0FBQyxhQUFhLEVBQUUsbUJBQW1CLENBQUMsMEJDNUNqRCwyK0pBOEpBLHlQRDdHSSxnQkFBZ0IsNEtBQ2hCLG9CQUFvQiwrRUFDcEIsZUFBZSx5SEFDZixnQkFBZ0Isb0pBQ2hCLGlCQUFpQixvUEFDakIsa0JBQWtCLHNHQUNsQiw2QkFBNkIscUdBQzdCLDhCQUE4QixvRUFDOUIsNkJBQTZCOzs0RkFHcEIsYUFBYTtrQkF0QnpCLFNBQVM7aUNBQ0ksSUFBSSxZQUNOLFNBQVMsbUJBR0YsdUJBQXVCLENBQUMsTUFBTSxhQUNwQyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQyxRQUN6Qzt3QkFDSixLQUFLLEVBQUUsWUFBWTtxQkFDcEIsV0FDUTt3QkFDUCxnQkFBZ0I7d0JBQ2hCLG9CQUFvQjt3QkFDcEIsZUFBZTt3QkFDZixnQkFBZ0I7d0JBQ2hCLGlCQUFpQjt3QkFDakIsa0JBQWtCO3dCQUNsQiw2QkFBNkI7d0JBQzdCLDhCQUE4Qjt3QkFDOUIsNkJBQTZCO3FCQUM5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEluamVjdG9yLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVGVtcGxhdGVSZWYsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIGluamVjdCxcbiAgaW5wdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRHJhZ2dhYmxlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2RyYWdnYWJsZS5zZXJ2aWNlJztcbmltcG9ydCB7IE5vZGVNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9ub2RlLm1vZGVsJztcbmltcG9ydCB7IEZsb3dTdGF0dXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmxvdy1zdGF0dXMuc2VydmljZSc7XG5pbXBvcnQgeyBIYW5kbGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvaGFuZGxlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGFuZGxlTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbHMvaGFuZGxlLm1vZGVsJztcbmltcG9ydCB7IE5vZGVSZW5kZXJpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbm9kZS1yZW5kZXJpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBGbG93U2V0dGluZ3NTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmxvdy1zZXR0aW5ncy5zZXJ2aWNlJztcbmltcG9ydCB7IFNlbGVjdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zZWxlY3Rpb24uc2VydmljZSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uQ29udHJvbGxlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvY29ubmVjdGlvbi1jb250cm9sbGVyLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBOb2RlQWNjZXNzb3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbm9kZS1hY2Nlc3Nvci5zZXJ2aWNlJztcbmltcG9ydCB7IE92ZXJsYXlzU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL292ZXJsYXlzLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGFuZGxlU2l6ZUNvbnRyb2xsZXJEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2hhbmRsZS1zaXplLWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQsIE5nQ29tcG9uZW50T3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IERlZmF1bHROb2RlQ29tcG9uZW50IH0gZnJvbSAnLi4vZGVmYXVsdC1ub2RlL2RlZmF1bHQtbm9kZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgUG9pbnRlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvcG9pbnRlci5kaXJlY3RpdmUnO1xuXG4vLyBUT0RPOiBmaXggbG9hZGluZyBvZiB0aGVzZSBieSBAZGVmZXIgKHNob3VsZCB3b3JrIGluIEFuZ3VsYXIgMTgrKVxuLy8gcHVibGljIGNvbXBvbmVudHMgdGhhdCB1c2VzIGluIGRlZmF1bHQgbm9kZSAobG9hZGVkIGJ5IGRlZmVyKVxuaW1wb3J0IHsgUmVzaXphYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vcHVibGljLWNvbXBvbmVudHMvcmVzaXphYmxlL3Jlc2l6YWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSGFuZGxlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vcHVibGljLWNvbXBvbmVudHMvaGFuZGxlL2hhbmRsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgTm9kZUhhbmRsZXNDb250cm9sbGVyRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9ub2RlLWhhbmRsZXMtY29udHJvbGxlci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTm9kZVJlc2l6ZUNvbnRyb2xsZXJEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL25vZGUtcmVzaXplLWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcblxuZXhwb3J0IHR5cGUgSGFuZGxlU3RhdGUgPSAndmFsaWQnIHwgJ2ludmFsaWQnIHwgJ2lkbGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6ICdnW25vZGVdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25vZGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9ub2RlLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtIYW5kbGVTZXJ2aWNlLCBOb2RlQWNjZXNzb3JTZXJ2aWNlXSxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAndmZsb3ctbm9kZScsXG4gIH0sXG4gIGltcG9ydHM6IFtcbiAgICBQb2ludGVyRGlyZWN0aXZlLFxuICAgIERlZmF1bHROb2RlQ29tcG9uZW50LFxuICAgIEhhbmRsZUNvbXBvbmVudCxcbiAgICBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgIE5nQ29tcG9uZW50T3V0bGV0LFxuICAgIFJlc2l6YWJsZUNvbXBvbmVudCxcbiAgICBIYW5kbGVTaXplQ29udHJvbGxlckRpcmVjdGl2ZSxcbiAgICBOb2RlSGFuZGxlc0NvbnRyb2xsZXJEaXJlY3RpdmUsXG4gICAgTm9kZVJlc2l6ZUNvbnRyb2xsZXJEaXJlY3RpdmUsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5vZGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBpbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG4gIHByaXZhdGUgaGFuZGxlU2VydmljZSA9IGluamVjdChIYW5kbGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBkcmFnZ2FibGVTZXJ2aWNlID0gaW5qZWN0KERyYWdnYWJsZVNlcnZpY2UpO1xuICBwcml2YXRlIGZsb3dTdGF0dXNTZXJ2aWNlID0gaW5qZWN0KEZsb3dTdGF0dXNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBub2RlUmVuZGVyaW5nU2VydmljZSA9IGluamVjdChOb2RlUmVuZGVyaW5nU2VydmljZSk7XG4gIHByaXZhdGUgZmxvd1NldHRpbmdzU2VydmljZSA9IGluamVjdChGbG93U2V0dGluZ3NTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBzZWxlY3Rpb25TZXJ2aWNlID0gaW5qZWN0KFNlbGVjdGlvblNlcnZpY2UpO1xuICBwcml2YXRlIGhvc3RSZWYgPSBpbmplY3Q8RWxlbWVudFJlZjxTVkdFbGVtZW50Pj4oRWxlbWVudFJlZik7XG4gIHByaXZhdGUgbm9kZUFjY2Vzc29yID0gaW5qZWN0KE5vZGVBY2Nlc3NvclNlcnZpY2UpO1xuICBwcml2YXRlIG92ZXJsYXlzU2VydmljZSA9IGluamVjdChPdmVybGF5c1NlcnZpY2UpO1xuXG4gIC8vIFRPRE8gcmVtb3ZlIGRlcGVuZGVuY3kgZnJvbSB0aGlzIGRpcmVjdGl2ZVxuICBwcml2YXRlIGNvbm5lY3Rpb25Db250cm9sbGVyID0gaW5qZWN0KENvbm5lY3Rpb25Db250cm9sbGVyRGlyZWN0aXZlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIHB1YmxpYyBtb2RlbCA9IGlucHV0LnJlcXVpcmVkPE5vZGVNb2RlbD4oKTtcblxuICBwdWJsaWMgbm9kZVRlbXBsYXRlID0gaW5wdXQ8VGVtcGxhdGVSZWY8YW55Pj4oKTtcblxuICBwdWJsaWMgbm9kZVN2Z1RlbXBsYXRlID0gaW5wdXQ8VGVtcGxhdGVSZWY8YW55Pj4oKTtcblxuICBwdWJsaWMgZ3JvdXBOb2RlVGVtcGxhdGUgPSBpbnB1dDxUZW1wbGF0ZVJlZjxhbnk+PigpO1xuXG4gIHByb3RlY3RlZCBzaG93TWFnbmV0ID0gY29tcHV0ZWQoXG4gICAgKCkgPT5cbiAgICAgIHRoaXMuZmxvd1N0YXR1c1NlcnZpY2Uuc3RhdHVzKCkuc3RhdGUgPT09ICdjb25uZWN0aW9uLXN0YXJ0JyB8fFxuICAgICAgdGhpcy5mbG93U3RhdHVzU2VydmljZS5zdGF0dXMoKS5zdGF0ZSA9PT0gJ2Nvbm5lY3Rpb24tdmFsaWRhdGlvbicgfHxcbiAgICAgIHRoaXMuZmxvd1N0YXR1c1NlcnZpY2Uuc3RhdHVzKCkuc3RhdGUgPT09ICdyZWNvbm5lY3Rpb24tc3RhcnQnIHx8XG4gICAgICB0aGlzLmZsb3dTdGF0dXNTZXJ2aWNlLnN0YXR1cygpLnN0YXRlID09PSAncmVjb25uZWN0aW9uLXZhbGlkYXRpb24nLFxuICApO1xuXG4gIHByb3RlY3RlZCB0b29sYmFycyA9IGNvbXB1dGVkKCgpID0+IHRoaXMub3ZlcmxheXNTZXJ2aWNlLm5vZGVUb29sYmFyc01hcCgpLmdldCh0aGlzLm1vZGVsKCkpKTtcblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5tb2RlbCgpLmlzVmlzaWJsZS5zZXQodHJ1ZSk7XG5cbiAgICB0aGlzLm5vZGVBY2Nlc3Nvci5tb2RlbC5zZXQodGhpcy5tb2RlbCgpKTtcbiAgICB0aGlzLmhhbmRsZVNlcnZpY2Uubm9kZS5zZXQodGhpcy5tb2RlbCgpKTtcblxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubW9kZWwoKS5kcmFnZ2FibGUoKSkge1xuICAgICAgICAgIHRoaXMuZHJhZ2dhYmxlU2VydmljZS5lbmFibGUodGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMubW9kZWwoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5kcmFnZ2FibGVTZXJ2aWNlLmRpc2FibGUodGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgeyBpbmplY3RvcjogdGhpcy5pbmplY3RvciB9LFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlbCgpLmlzVmlzaWJsZS5zZXQoZmFsc2UpO1xuXG4gICAgdGhpcy5kcmFnZ2FibGVTZXJ2aWNlLmRlc3Ryb3kodGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHN0YXJ0Q29ubmVjdGlvbihldmVudDogRXZlbnQsIGhhbmRsZTogSGFuZGxlTW9kZWwpIHtcbiAgICAvLyBpZ25vcmUgZHJhZyBieSBzdG9wcGluZyBwcm9wYWdhdGlvblxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uQ29udHJvbGxlcj8uc3RhcnRDb25uZWN0aW9uKGhhbmRsZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdmFsaWRhdGVDb25uZWN0aW9uKGhhbmRsZTogSGFuZGxlTW9kZWwpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25Db250cm9sbGVyPy52YWxpZGF0ZUNvbm5lY3Rpb24oaGFuZGxlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXNldFZhbGlkYXRlQ29ubmVjdGlvbih0YXJnZXRIYW5kbGU6IEhhbmRsZU1vZGVsKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uQ29udHJvbGxlcj8ucmVzZXRWYWxpZGF0ZUNvbm5lY3Rpb24odGFyZ2V0SGFuZGxlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbmRDb25uZWN0aW9uKCkge1xuICAgIHRoaXMuY29ubmVjdGlvbkNvbnRyb2xsZXI/LmVuZENvbm5lY3Rpb24oKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwdWxsTm9kZSgpIHtcbiAgICBpZiAodGhpcy5mbG93U2V0dGluZ3NTZXJ2aWNlLmVsZXZhdGVOb2Rlc09uU2VsZWN0KCkpIHtcbiAgICAgIHRoaXMubm9kZVJlbmRlcmluZ1NlcnZpY2UucHVsbE5vZGUodGhpcy5tb2RlbCgpKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VsZWN0Tm9kZSgpIHtcbiAgICBpZiAodGhpcy5mbG93U2V0dGluZ3NTZXJ2aWNlLmVudGl0aWVzU2VsZWN0YWJsZSgpKSB7XG4gICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0KHRoaXMubW9kZWwoKSk7XG4gICAgfVxuICB9XG59XG4iLCI8IS0tIERlZmF1bHQgbm9kZSAtLT5cbkBpZiAobW9kZWwoKS5yYXdOb2RlLnR5cGUgPT09ICdkZWZhdWx0Jykge1xuICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICBjbGFzcz1cInNlbGVjdGFibGVcIlxuICAgIFthdHRyLndpZHRoXT1cIm1vZGVsKCkuZm9XaWR0aCgpXCJcbiAgICBbYXR0ci5oZWlnaHRdPVwibW9kZWwoKS5mb0hlaWdodCgpXCJcbiAgICAoY2xpY2spPVwicHVsbE5vZGUoKTsgc2VsZWN0Tm9kZSgpXCI+XG4gICAgPGRlZmF1bHQtbm9kZVxuICAgICAgbm9kZUhhbmRsZXNDb250cm9sbGVyXG4gICAgICBbc2VsZWN0ZWRdPVwibW9kZWwoKS5zZWxlY3RlZCgpXCJcbiAgICAgIFtzdHlsZS53aWR0aF09XCJtb2RlbCgpLnN0eWxlV2lkdGgoKVwiXG4gICAgICBbc3R5bGUuaGVpZ2h0XT1cIm1vZGVsKCkuc3R5bGVIZWlnaHQoKVwiXG4gICAgICBbc3R5bGUubWF4LXdpZHRoXT1cIm1vZGVsKCkuc3R5bGVXaWR0aCgpXCJcbiAgICAgIFtzdHlsZS5tYXgtaGVpZ2h0XT1cIm1vZGVsKCkuc3R5bGVIZWlnaHQoKVwiPlxuICAgICAgPGRpdiBbb3V0ZXJIVE1MXT1cIm1vZGVsKCkudGV4dCgpXCI+PC9kaXY+XG5cbiAgICAgIDxoYW5kbGUgdHlwZT1cInNvdXJjZVwiIHBvc2l0aW9uPVwicmlnaHRcIiAvPlxuICAgICAgPGhhbmRsZSB0eXBlPVwidGFyZ2V0XCIgcG9zaXRpb249XCJsZWZ0XCIgLz5cbiAgICA8L2RlZmF1bHQtbm9kZT5cbiAgPC9zdmc6Zm9yZWlnbk9iamVjdD5cbn1cblxuPCEtLSBIVE1MIFRlbXBsYXRlIG5vZGUgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAnaHRtbC10ZW1wbGF0ZScgJiYgbm9kZVRlbXBsYXRlKCkpIHtcbiAgPHN2Zzpmb3JlaWduT2JqZWN0XG4gICAgY2xhc3M9XCJzZWxlY3RhYmxlXCJcbiAgICBbYXR0ci53aWR0aF09XCJtb2RlbCgpLmZvV2lkdGgoKVwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cIm1vZGVsKCkuZm9IZWlnaHQoKVwiXG4gICAgKGNsaWNrKT1cInB1bGxOb2RlKClcIj5cbiAgICA8ZGl2XG4gICAgICBub2RlSGFuZGxlc0NvbnRyb2xsZXJcbiAgICAgIG5vZGVSZXNpemVDb250cm9sbGVyXG4gICAgICBjbGFzcz1cIndyYXBwZXJcIlxuICAgICAgW3N0eWxlLndpZHRoXT1cIm1vZGVsKCkuc3R5bGVXaWR0aCgpXCJcbiAgICAgIFtzdHlsZS5oZWlnaHRdPVwibW9kZWwoKS5zdHlsZUhlaWdodCgpXCI+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm5vZGVUZW1wbGF0ZSgpID8/IG51bGxcIlxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwibW9kZWwoKS5jb250ZXh0XCJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRJbmplY3Rvcl09XCJpbmplY3RvclwiIC8+XG4gICAgPC9kaXY+XG4gIDwvc3ZnOmZvcmVpZ25PYmplY3Q+XG59XG5cbjwhLS0gU1ZHIFRlbXBsYXRlIG5vZGUgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAnc3ZnLXRlbXBsYXRlJyAmJiBub2RlU3ZnVGVtcGxhdGUoKSkge1xuICA8c3ZnOmcgY2xhc3M9XCJzZWxlY3RhYmxlXCIgbm9kZUhhbmRsZXNDb250cm9sbGVyIChjbGljayk9XCJwdWxsTm9kZSgpXCI+XG4gICAgPG5nLWNvbnRhaW5lclxuICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwibm9kZVN2Z1RlbXBsYXRlKCkgPz8gbnVsbFwiXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwibW9kZWwoKS5jb250ZXh0XCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3JdPVwiaW5qZWN0b3JcIiAvPlxuICA8L3N2ZzpnPlxufVxuXG48IS0tIENvbXBvbmVudCBub2RlIC0tPlxuQGlmIChtb2RlbCgpLmlzQ29tcG9uZW50VHlwZSkge1xuICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICBjbGFzcz1cInNlbGVjdGFibGVcIlxuICAgIFthdHRyLndpZHRoXT1cIm1vZGVsKCkuZm9XaWR0aCgpXCJcbiAgICBbYXR0ci5oZWlnaHRdPVwibW9kZWwoKS5mb0hlaWdodCgpXCJcbiAgICAoY2xpY2spPVwicHVsbE5vZGUoKVwiPlxuICAgIDxkaXZcbiAgICAgIG5vZGVIYW5kbGVzQ29udHJvbGxlclxuICAgICAgbm9kZVJlc2l6ZUNvbnRyb2xsZXJcbiAgICAgIGNsYXNzPVwid3JhcHBlclwiXG4gICAgICBbc3R5bGUud2lkdGhdPVwibW9kZWwoKS5zdHlsZVdpZHRoKClcIlxuICAgICAgW3N0eWxlLmhlaWdodF09XCJtb2RlbCgpLnN0eWxlSGVpZ2h0KClcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgW25nQ29tcG9uZW50T3V0bGV0XT1cIiRhbnkobW9kZWwoKS5yYXdOb2RlLnR5cGUpXCJcbiAgICAgICAgW25nQ29tcG9uZW50T3V0bGV0SW5wdXRzXT1cIm1vZGVsKCkuY29tcG9uZW50VHlwZUlucHV0c1wiXG4gICAgICAgIFtuZ0NvbXBvbmVudE91dGxldEluamVjdG9yXT1cImluamVjdG9yXCIgLz5cbiAgICA8L2Rpdj5cbiAgPC9zdmc6Zm9yZWlnbk9iamVjdD5cbn1cblxuPCEtLSBEZWZhdWx0IGdyb3VwIG5vZGUgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAnZGVmYXVsdC1ncm91cCcpIHtcbiAgPHN2ZzpyZWN0XG4gICAgY2xhc3M9XCJkZWZhdWx0LWdyb3VwLW5vZGVcIlxuICAgIHJ4PVwiNVwiXG4gICAgcnk9XCI1XCJcbiAgICBbcmVzaXphYmxlXT1cIm1vZGVsKCkucmVzaXphYmxlKClcIlxuICAgIFtnYXBdPVwiM1wiXG4gICAgW3Jlc2l6ZXJDb2xvcl09XCJtb2RlbCgpLmNvbG9yKClcIlxuICAgIFtjbGFzcy5kZWZhdWx0LWdyb3VwLW5vZGVfc2VsZWN0ZWRdPVwibW9kZWwoKS5zZWxlY3RlZCgpXCJcbiAgICBbYXR0ci53aWR0aF09XCJtb2RlbCgpLnNpemUoKS53aWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cIm1vZGVsKCkuc2l6ZSgpLmhlaWdodFwiXG4gICAgW3N0eWxlLnN0cm9rZV09XCJtb2RlbCgpLmNvbG9yKClcIlxuICAgIFtzdHlsZS5maWxsXT1cIm1vZGVsKCkuY29sb3IoKVwiXG4gICAgKGNsaWNrKT1cInB1bGxOb2RlKCk7IHNlbGVjdE5vZGUoKVwiIC8+XG59XG5cbjwhLS0gVGVtcGxhdGUgZ3JvdXAgbm9kZSAgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAndGVtcGxhdGUtZ3JvdXAnICYmIGdyb3VwTm9kZVRlbXBsYXRlKCkpIHtcbiAgPHN2ZzpnIGNsYXNzPVwic2VsZWN0YWJsZVwiIG5vZGVIYW5kbGVzQ29udHJvbGxlciAoY2xpY2spPVwicHVsbE5vZGUoKVwiPlxuICAgIDxuZy1jb250YWluZXJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdyb3VwTm9kZVRlbXBsYXRlKCkgPz8gbnVsbFwiXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwibW9kZWwoKS5jb250ZXh0XCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3JdPVwiaW5qZWN0b3JcIiAvPlxuICA8L3N2ZzpnPlxufVxuXG48IS0tIFJlc2l6ZXIgLS0+XG5AaWYgKG1vZGVsKCkucmVzaXplclRlbXBsYXRlKCk7IGFzIHRlbXBsYXRlKSB7XG4gIEBpZiAobW9kZWwoKS5yZXNpemFibGUoKSkge1xuICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0ZW1wbGF0ZVwiIC8+XG4gIH1cbn1cblxuPCEtLSBIYW5kbGVzIC0tPlxuQGZvciAoaGFuZGxlIG9mIG1vZGVsKCkuaGFuZGxlcygpOyB0cmFjayBoYW5kbGUpIHtcbiAgQGlmIChoYW5kbGUudGVtcGxhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgIDxzdmc6Y2lyY2xlXG4gICAgICBjbGFzcz1cImRlZmF1bHQtaGFuZGxlXCJcbiAgICAgIHI9XCI1XCJcbiAgICAgIFthdHRyLmN4XT1cImhhbmRsZS5ob3N0T2Zmc2V0KCkueFwiXG4gICAgICBbYXR0ci5jeV09XCJoYW5kbGUuaG9zdE9mZnNldCgpLnlcIlxuICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cImhhbmRsZS5zdHJva2VXaWR0aFwiXG4gICAgICAocG9pbnRlclN0YXJ0KT1cInN0YXJ0Q29ubmVjdGlvbigkZXZlbnQsIGhhbmRsZSlcIlxuICAgICAgKHBvaW50ZXJFbmQpPVwiZW5kQ29ubmVjdGlvbigpXCIgLz5cbiAgfVxuXG4gIEBpZiAoaGFuZGxlLnRlbXBsYXRlID09PSBudWxsKSB7XG4gICAgPHN2ZzpnXG4gICAgICBbaGFuZGxlU2l6ZUNvbnRyb2xsZXJdPVwiaGFuZGxlXCJcbiAgICAgIChwb2ludGVyU3RhcnQpPVwic3RhcnRDb25uZWN0aW9uKCRldmVudCwgaGFuZGxlKVwiXG4gICAgICAocG9pbnRlckVuZCk9XCJlbmRDb25uZWN0aW9uKClcIiAvPlxuICB9XG5cbiAgQGlmIChoYW5kbGUudGVtcGxhdGUpIHtcbiAgICA8c3ZnOmdcbiAgICAgIFtoYW5kbGVTaXplQ29udHJvbGxlcl09XCJoYW5kbGVcIlxuICAgICAgKHBvaW50ZXJTdGFydCk9XCJzdGFydENvbm5lY3Rpb24oJGV2ZW50LCBoYW5kbGUpXCJcbiAgICAgIChwb2ludGVyRW5kKT1cImVuZENvbm5lY3Rpb24oKVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhhbmRsZS50ZW1wbGF0ZTsgY29udGV4dDogaGFuZGxlLnRlbXBsYXRlQ29udGV4dFwiIC8+XG4gICAgPC9zdmc6Zz5cbiAgfVxuXG4gIEBpZiAoc2hvd01hZ25ldCgpKSB7XG4gICAgPHN2ZzpjaXJjbGVcbiAgICAgIGNsYXNzPVwibWFnbmV0XCJcbiAgICAgIFthdHRyLnJdPVwibW9kZWwoKS5tYWduZXRSYWRpdXNcIlxuICAgICAgW2F0dHIuY3hdPVwiaGFuZGxlLmhvc3RPZmZzZXQoKS54XCJcbiAgICAgIFthdHRyLmN5XT1cImhhbmRsZS5ob3N0T2Zmc2V0KCkueVwiXG4gICAgICAocG9pbnRlckVuZCk9XCJlbmRDb25uZWN0aW9uKCk7IHJlc2V0VmFsaWRhdGVDb25uZWN0aW9uKGhhbmRsZSlcIlxuICAgICAgKHBvaW50ZXJPdmVyKT1cInZhbGlkYXRlQ29ubmVjdGlvbihoYW5kbGUpXCJcbiAgICAgIChwb2ludGVyT3V0KT1cInJlc2V0VmFsaWRhdGVDb25uZWN0aW9uKGhhbmRsZSlcIiAvPlxuICB9XG59XG5cbjwhLS0gVG9vbGJhciAtLT5cbkBmb3IgKHRvb2xiYXIgb2YgdG9vbGJhcnMoKTsgdHJhY2sgdG9vbGJhcikge1xuICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICBbYXR0ci53aWR0aF09XCJ0b29sYmFyLnNpemUoKS53aWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cInRvb2xiYXIuc2l6ZSgpLmhlaWdodFwiXG4gICAgW2F0dHIudHJhbnNmb3JtXT1cInRvb2xiYXIudHJhbnNmb3JtKClcIj5cbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRvb2xiYXIudGVtcGxhdGUoKVwiIC8+XG4gIDwvc3ZnOmZvcmVpZ25PYmplY3Q+XG59XG4iXX0=
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvY29tcG9uZW50cy9ub2RlL25vZGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXZmbG93LWxpYi9zcmMvbGliL3ZmbG93L2NvbXBvbmVudHMvbm9kZS9ub2RlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFVBQVUsRUFDVixRQUFRLEVBSVIsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxHQUNOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRXBFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUNqRyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbEUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDbEcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFp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UUFDbEIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQztJQUNILENBQUM7K0dBdEZVLGFBQWE7bUdBQWIsYUFBYSxncUJBakJiLENBQUMsYUFBYSxFQUFFLG1CQUFtQixDQUFDLDBCQzVDakQsbWtLQWdLQSx5UEQvR0ksZ0JBQWdCLDRLQUNoQixvQkFBb0IsK0VBQ3BCLGVBQWUseUhBQ2YsZ0JBQWdCLG9KQUNoQixpQkFBaUIsb1BBQ2pCLGtCQUFrQixzR0FDbEIsNkJBQTZCLHFHQUM3Qiw4QkFBOEIsb0VBQzlCLDZCQUE2Qiw4REFDN0IsU0FBUzs7NEZBR0EsYUFBYTtrQkF2QnpCLFNBQVM7aUNBQ0ksSUFBSSxZQUNOLFNBQVMsbUJBR0YsdUJBQXVCLENBQUMsTUFBTSxhQUNwQyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQyxRQUN6Qzt3QkFDSixLQUFLLEVBQUUsWUFBWTtxQkFDcEIsV0FDUTt3QkFDUCxnQkFBZ0I7d0JBQ2hCLG9CQUFvQjt3QkFDcEIsZUFBZTt3QkFDZixnQkFBZ0I7d0JBQ2hCLGlCQUFpQjt3QkFDakIsa0JBQWtCO3dCQUNsQiw2QkFBNkI7d0JBQzdCLDhCQUE4Qjt3QkFDOUIsNkJBQTZCO3dCQUM3QixTQUFTO3FCQUNWIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0b3IsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBUZW1wbGF0ZVJlZixcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgaW5qZWN0LFxuICBpbnB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEcmFnZ2FibGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZHJhZ2dhYmxlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuaW1wb3J0IHsgRmxvd1N0YXR1c1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9mbG93LXN0YXR1cy5zZXJ2aWNlJztcbmltcG9ydCB7IEhhbmRsZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9oYW5kbGUuc2VydmljZSc7XG5pbXBvcnQgeyBIYW5kbGVNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9oYW5kbGUubW9kZWwnO1xuaW1wb3J0IHsgTm9kZVJlbmRlcmluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub2RlLXJlbmRlcmluZy5zZXJ2aWNlJztcbmltcG9ydCB7IEZsb3dTZXR0aW5nc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9mbG93LXNldHRpbmdzLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3NlbGVjdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IENvbm5lY3Rpb25Db250cm9sbGVyRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9jb25uZWN0aW9uLWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IE5vZGVBY2Nlc3NvclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub2RlLWFjY2Vzc29yLnNlcnZpY2UnO1xuaW1wb3J0IHsgT3ZlcmxheXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvb3ZlcmxheXMuc2VydmljZSc7XG5pbXBvcnQgeyBIYW5kbGVTaXplQ29udHJvbGxlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvaGFuZGxlLXNpemUtY29udHJvbGxlci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTmdUZW1wbGF0ZU91dGxldCwgTmdDb21wb25lbnRPdXRsZXQsIEFzeW5jUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBEZWZhdWx0Tm9kZUNvbXBvbmVudCB9IGZyb20gJy4uL2RlZmF1bHQtbm9kZS9kZWZhdWx0LW5vZGUuY29tcG9uZW50JztcbmltcG9ydCB7IFBvaW50ZXJEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL3BvaW50ZXIuZGlyZWN0aXZlJztcblxuLy8gVE9ETzogZml4IGxvYWRpbmcgb2YgdGhlc2UgYnkgQGRlZmVyIChzaG91bGQgd29yayBpbiBBbmd1bGFyIDE4Kylcbi8vIHB1YmxpYyBjb21wb25lbnRzIHRoYXQgdXNlcyBpbiBkZWZhdWx0IG5vZGUgKGxvYWRlZCBieSBkZWZlcilcbmltcG9ydCB7IFJlc2l6YWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3B1YmxpYy1jb21wb25lbnRzL3Jlc2l6YWJsZS9yZXNpemFibGUuY29tcG9uZW50JztcbmltcG9ydCB7IEhhbmRsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3B1YmxpYy1jb21wb25lbnRzL2hhbmRsZS9oYW5kbGUuY29tcG9uZW50JztcbmltcG9ydCB7IE5vZGVIYW5kbGVzQ29udHJvbGxlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvbm9kZS1oYW5kbGVzLWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IE5vZGVSZXNpemVDb250cm9sbGVyRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9ub2RlLXJlc2l6ZS1jb250cm9sbGVyLmRpcmVjdGl2ZSc7XG5cbmV4cG9ydCB0eXBlIEhhbmRsZVN0YXRlID0gJ3ZhbGlkJyB8ICdpbnZhbGlkJyB8ICdpZGxlJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnZ1tub2RlXScsXG4gIHRlbXBsYXRlVXJsOiAnLi9ub2RlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbm9kZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbSGFuZGxlU2VydmljZSwgTm9kZUFjY2Vzc29yU2VydmljZV0sXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ3ZmbG93LW5vZGUnLFxuICB9LFxuICBpbXBvcnRzOiBbXG4gICAgUG9pbnRlckRpcmVjdGl2ZSxcbiAgICBEZWZhdWx0Tm9kZUNvbXBvbmVudCxcbiAgICBIYW5kbGVDb21wb25lbnQsXG4gICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICBOZ0NvbXBvbmVudE91dGxldCxcbiAgICBSZXNpemFibGVDb21wb25lbnQsXG4gICAgSGFuZGxlU2l6ZUNvbnRyb2xsZXJEaXJlY3RpdmUsXG4gICAgTm9kZUhhbmRsZXNDb250cm9sbGVyRGlyZWN0aXZlLFxuICAgIE5vZGVSZXNpemVDb250cm9sbGVyRGlyZWN0aXZlLFxuICAgIEFzeW5jUGlwZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTm9kZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJvdGVjdGVkIGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcbiAgcHJpdmF0ZSBoYW5kbGVTZXJ2aWNlID0gaW5qZWN0KEhhbmRsZVNlcnZpY2UpO1xuICBwcml2YXRlIGRyYWdnYWJsZVNlcnZpY2UgPSBpbmplY3QoRHJhZ2dhYmxlU2VydmljZSk7XG4gIHByaXZhdGUgZmxvd1N0YXR1c1NlcnZpY2UgPSBpbmplY3QoRmxvd1N0YXR1c1NlcnZpY2UpO1xuICBwcml2YXRlIG5vZGVSZW5kZXJpbmdTZXJ2aWNlID0gaW5qZWN0KE5vZGVSZW5kZXJpbmdTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBmbG93U2V0dGluZ3NTZXJ2aWNlID0gaW5qZWN0KEZsb3dTZXR0aW5nc1NlcnZpY2UpO1xuICBwcml2YXRlIHNlbGVjdGlvblNlcnZpY2UgPSBpbmplY3QoU2VsZWN0aW9uU2VydmljZSk7XG4gIHByaXZhdGUgaG9zdFJlZiA9IGluamVjdDxFbGVtZW50UmVmPFNWR0VsZW1lbnQ+PihFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSBub2RlQWNjZXNzb3IgPSBpbmplY3QoTm9kZUFjY2Vzc29yU2VydmljZSk7XG4gIHByaXZhdGUgb3ZlcmxheXNTZXJ2aWNlID0gaW5qZWN0KE92ZXJsYXlzU2VydmljZSk7XG5cbiAgLy8gVE9ETyByZW1vdmUgZGVwZW5kZW5jeSBmcm9tIHRoaXMgZGlyZWN0aXZlXG4gIHByaXZhdGUgY29ubmVjdGlvbkNvbnRyb2xsZXIgPSBpbmplY3QoQ29ubmVjdGlvbkNvbnRyb2xsZXJEaXJlY3RpdmUsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgcHVibGljIG1vZGVsID0gaW5wdXQucmVxdWlyZWQ8Tm9kZU1vZGVsPigpO1xuXG4gIHB1YmxpYyBub2RlVGVtcGxhdGUgPSBpbnB1dDxUZW1wbGF0ZVJlZjxhbnk+PigpO1xuXG4gIHB1YmxpYyBub2RlU3ZnVGVtcGxhdGUgPSBpbnB1dDxUZW1wbGF0ZVJlZjxhbnk+PigpO1xuXG4gIHB1YmxpYyBncm91cE5vZGVUZW1wbGF0ZSA9IGlucHV0PFRlbXBsYXRlUmVmPGFueT4+KCk7XG5cbiAgcHJvdGVjdGVkIHNob3dNYWduZXQgPSBjb21wdXRlZChcbiAgICAoKSA9PlxuICAgICAgdGhpcy5mbG93U3RhdHVzU2VydmljZS5zdGF0dXMoKS5zdGF0ZSA9PT0gJ2Nvbm5lY3Rpb24tc3RhcnQnIHx8XG4gICAgICB0aGlzLmZsb3dTdGF0dXNTZXJ2aWNlLnN0YXR1cygpLnN0YXRlID09PSAnY29ubmVjdGlvbi12YWxpZGF0aW9uJyB8fFxuICAgICAgdGhpcy5mbG93U3RhdHVzU2VydmljZS5zdGF0dXMoKS5zdGF0ZSA9PT0gJ3JlY29ubmVjdGlvbi1zdGFydCcgfHxcbiAgICAgIHRoaXMuZmxvd1N0YXR1c1NlcnZpY2Uuc3RhdHVzKCkuc3RhdGUgPT09ICdyZWNvbm5lY3Rpb24tdmFsaWRhdGlvbicsXG4gICk7XG5cbiAgcHJvdGVjdGVkIHRvb2xiYXJzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5vdmVybGF5c1NlcnZpY2Uubm9kZVRvb2xiYXJzTWFwKCkuZ2V0KHRoaXMubW9kZWwoKSkpO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLm1vZGVsKCkuaXNWaXNpYmxlLnNldCh0cnVlKTtcblxuICAgIHRoaXMubm9kZUFjY2Vzc29yLm1vZGVsLnNldCh0aGlzLm1vZGVsKCkpO1xuICAgIHRoaXMuaGFuZGxlU2VydmljZS5ub2RlLnNldCh0aGlzLm1vZGVsKCkpO1xuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tb2RlbCgpLmRyYWdnYWJsZSgpKSB7XG4gICAgICAgICAgdGhpcy5kcmFnZ2FibGVTZXJ2aWNlLmVuYWJsZSh0aGlzLmhvc3RSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5tb2RlbCgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmRyYWdnYWJsZVNlcnZpY2UuZGlzYWJsZSh0aGlzLmhvc3RSZWYubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7IGluamVjdG9yOiB0aGlzLmluamVjdG9yIH0sXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm1vZGVsKCkuaXNWaXNpYmxlLnNldChmYWxzZSk7XG5cbiAgICB0aGlzLmRyYWdnYWJsZVNlcnZpY2UuZGVzdHJveSh0aGlzLmhvc3RSZWYubmF0aXZlRWxlbWVudCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3RhcnRDb25uZWN0aW9uKGV2ZW50OiBFdmVudCwgaGFuZGxlOiBIYW5kbGVNb2RlbCkge1xuICAgIC8vIGlnbm9yZSBkcmFnIGJ5IHN0b3BwaW5nIHByb3BhZ2F0aW9uXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb25Db250cm9sbGVyPy5zdGFydENvbm5lY3Rpb24oaGFuZGxlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUNvbm5lY3Rpb24oaGFuZGxlOiBIYW5kbGVNb2RlbCkge1xuICAgIHRoaXMuY29ubmVjdGlvbkNvbnRyb2xsZXI/LnZhbGlkYXRlQ29ubmVjdGlvbihoYW5kbGUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlc2V0VmFsaWRhdGVDb25uZWN0aW9uKHRhcmdldEhhbmRsZTogSGFuZGxlTW9kZWwpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25Db250cm9sbGVyPy5yZXNldFZhbGlkYXRlQ29ubmVjdGlvbih0YXJnZXRIYW5kbGUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGVuZENvbm5lY3Rpb24oKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uQ29udHJvbGxlcj8uZW5kQ29ubmVjdGlvbigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHB1bGxOb2RlKCkge1xuICAgIGlmICh0aGlzLmZsb3dTZXR0aW5nc1NlcnZpY2UuZWxldmF0ZU5vZGVzT25TZWxlY3QoKSkge1xuICAgICAgdGhpcy5ub2RlUmVuZGVyaW5nU2VydmljZS5wdWxsTm9kZSh0aGlzLm1vZGVsKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBzZWxlY3ROb2RlKCkge1xuICAgIGlmICh0aGlzLmZsb3dTZXR0aW5nc1NlcnZpY2UuZW50aXRpZXNTZWxlY3RhYmxlKCkpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5zZWxlY3QodGhpcy5tb2RlbCgpKTtcbiAgICB9XG4gIH1cbn1cbiIsIjwhLS0gRGVmYXVsdCBub2RlIC0tPlxuQGlmIChtb2RlbCgpLnJhd05vZGUudHlwZSA9PT0gJ2RlZmF1bHQnKSB7XG4gIDxzdmc6Zm9yZWlnbk9iamVjdFxuICAgIGNsYXNzPVwic2VsZWN0YWJsZVwiXG4gICAgW2F0dHIud2lkdGhdPVwibW9kZWwoKS5mb1dpZHRoKClcIlxuICAgIFthdHRyLmhlaWdodF09XCJtb2RlbCgpLmZvSGVpZ2h0KClcIlxuICAgIChjbGljayk9XCJwdWxsTm9kZSgpOyBzZWxlY3ROb2RlKClcIj5cbiAgICA8ZGVmYXVsdC1ub2RlXG4gICAgICBub2RlSGFuZGxlc0NvbnRyb2xsZXJcbiAgICAgIFtzZWxlY3RlZF09XCJtb2RlbCgpLnNlbGVjdGVkKClcIlxuICAgICAgW3N0eWxlLndpZHRoXT1cIm1vZGVsKCkuc3R5bGVXaWR0aCgpXCJcbiAgICAgIFtzdHlsZS5oZWlnaHRdPVwibW9kZWwoKS5zdHlsZUhlaWdodCgpXCJcbiAgICAgIFtzdHlsZS5tYXgtd2lkdGhdPVwibW9kZWwoKS5zdHlsZVdpZHRoKClcIlxuICAgICAgW3N0eWxlLm1heC1oZWlnaHRdPVwibW9kZWwoKS5zdHlsZUhlaWdodCgpXCI+XG4gICAgICA8ZGl2IFtvdXRlckhUTUxdPVwibW9kZWwoKS50ZXh0KClcIj48L2Rpdj5cblxuICAgICAgPGhhbmRsZSB0eXBlPVwic291cmNlXCIgcG9zaXRpb249XCJyaWdodFwiIC8+XG4gICAgICA8aGFuZGxlIHR5cGU9XCJ0YXJnZXRcIiBwb3NpdGlvbj1cImxlZnRcIiAvPlxuICAgIDwvZGVmYXVsdC1ub2RlPlxuICA8L3N2Zzpmb3JlaWduT2JqZWN0PlxufVxuXG48IS0tIEhUTUwgVGVtcGxhdGUgbm9kZSAtLT5cbkBpZiAobW9kZWwoKS5yYXdOb2RlLnR5cGUgPT09ICdodG1sLXRlbXBsYXRlJyAmJiBub2RlVGVtcGxhdGUoKSkge1xuICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICBjbGFzcz1cInNlbGVjdGFibGVcIlxuICAgIFthdHRyLndpZHRoXT1cIm1vZGVsKCkuZm9XaWR0aCgpXCJcbiAgICBbYXR0ci5oZWlnaHRdPVwibW9kZWwoKS5mb0hlaWdodCgpXCJcbiAgICAoY2xpY2spPVwicHVsbE5vZGUoKVwiPlxuICAgIDxkaXZcbiAgICAgIG5vZGVIYW5kbGVzQ29udHJvbGxlclxuICAgICAgbm9kZVJlc2l6ZUNvbnRyb2xsZXJcbiAgICAgIGNsYXNzPVwid3JhcHBlclwiXG4gICAgICBbc3R5bGUud2lkdGhdPVwibW9kZWwoKS5zdHlsZVdpZHRoKClcIlxuICAgICAgW3N0eWxlLmhlaWdodF09XCJtb2RlbCgpLnN0eWxlSGVpZ2h0KClcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwibm9kZVRlbXBsYXRlKCkgPz8gbnVsbFwiXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJtb2RlbCgpLmNvbnRleHRcIlxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldEluamVjdG9yXT1cImluamVjdG9yXCIgLz5cbiAgICA8L2Rpdj5cbiAgPC9zdmc6Zm9yZWlnbk9iamVjdD5cbn1cblxuPCEtLSBTVkcgVGVtcGxhdGUgbm9kZSAtLT5cbkBpZiAobW9kZWwoKS5yYXdOb2RlLnR5cGUgPT09ICdzdmctdGVtcGxhdGUnICYmIG5vZGVTdmdUZW1wbGF0ZSgpKSB7XG4gIDxzdmc6ZyBjbGFzcz1cInNlbGVjdGFibGVcIiBub2RlSGFuZGxlc0NvbnRyb2xsZXIgKGNsaWNrKT1cInB1bGxOb2RlKClcIj5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJub2RlU3ZnVGVtcGxhdGUoKSA/PyBudWxsXCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJtb2RlbCgpLmNvbnRleHRcIlxuICAgICAgW25nVGVtcGxhdGVPdXRsZXRJbmplY3Rvcl09XCJpbmplY3RvclwiIC8+XG4gIDwvc3ZnOmc+XG59XG5cbjwhLS0gQ29tcG9uZW50IG5vZGUgLS0+XG5AaWYgKG1vZGVsKCkuaXNDb21wb25lbnRUeXBlKSB7XG4gIEBpZiAobW9kZWwoKS5jb21wb25lbnRJbnN0YW5jZSQgfCBhc3luYzsgYXMgY29tcG9uZW50KSB7XG4gICAgPHN2Zzpmb3JlaWduT2JqZWN0XG4gICAgICBjbGFzcz1cInNlbGVjdGFibGVcIlxuICAgICAgW2F0dHIud2lkdGhdPVwibW9kZWwoKS5mb1dpZHRoKClcIlxuICAgICAgW2F0dHIuaGVpZ2h0XT1cIm1vZGVsKCkuZm9IZWlnaHQoKVwiXG4gICAgICAoY2xpY2spPVwicHVsbE5vZGUoKVwiPlxuICAgICAgPGRpdlxuICAgICAgICBub2RlSGFuZGxlc0NvbnRyb2xsZXJcbiAgICAgICAgbm9kZVJlc2l6ZUNvbnRyb2xsZXJcbiAgICAgICAgY2xhc3M9XCJ3cmFwcGVyXCJcbiAgICAgICAgW3N0eWxlLndpZHRoXT1cIm1vZGVsKCkuc3R5bGVXaWR0aCgpXCJcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCJtb2RlbCgpLnN0eWxlSGVpZ2h0KClcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgIFtuZ0NvbXBvbmVudE91dGxldF09XCIkYW55KGNvbXBvbmVudClcIlxuICAgICAgICAgIFtuZ0NvbXBvbmVudE91dGxldElucHV0c109XCJtb2RlbCgpLmNvbXBvbmVudFR5cGVJbnB1dHNcIlxuICAgICAgICAgIFtuZ0NvbXBvbmVudE91dGxldEluamVjdG9yXT1cImluamVjdG9yXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgIDwvc3ZnOmZvcmVpZ25PYmplY3Q+XG4gIH1cbn1cblxuPCEtLSBEZWZhdWx0IGdyb3VwIG5vZGUgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAnZGVmYXVsdC1ncm91cCcpIHtcbiAgPHN2ZzpyZWN0XG4gICAgY2xhc3M9XCJkZWZhdWx0LWdyb3VwLW5vZGVcIlxuICAgIHJ4PVwiNVwiXG4gICAgcnk9XCI1XCJcbiAgICBbcmVzaXphYmxlXT1cIm1vZGVsKCkucmVzaXphYmxlKClcIlxuICAgIFtnYXBdPVwiM1wiXG4gICAgW3Jlc2l6ZXJDb2xvcl09XCJtb2RlbCgpLmNvbG9yKClcIlxuICAgIFtjbGFzcy5kZWZhdWx0LWdyb3VwLW5vZGVfc2VsZWN0ZWRdPVwibW9kZWwoKS5zZWxlY3RlZCgpXCJcbiAgICBbYXR0ci53aWR0aF09XCJtb2RlbCgpLnNpemUoKS53aWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cIm1vZGVsKCkuc2l6ZSgpLmhlaWdodFwiXG4gICAgW3N0eWxlLnN0cm9rZV09XCJtb2RlbCgpLmNvbG9yKClcIlxuICAgIFtzdHlsZS5maWxsXT1cIm1vZGVsKCkuY29sb3IoKVwiXG4gICAgKGNsaWNrKT1cInB1bGxOb2RlKCk7IHNlbGVjdE5vZGUoKVwiIC8+XG59XG5cbjwhLS0gVGVtcGxhdGUgZ3JvdXAgbm9kZSAgLS0+XG5AaWYgKG1vZGVsKCkucmF3Tm9kZS50eXBlID09PSAndGVtcGxhdGUtZ3JvdXAnICYmIGdyb3VwTm9kZVRlbXBsYXRlKCkpIHtcbiAgPHN2ZzpnIGNsYXNzPVwic2VsZWN0YWJsZVwiIG5vZGVIYW5kbGVzQ29udHJvbGxlciAoY2xpY2spPVwicHVsbE5vZGUoKVwiPlxuICAgIDxuZy1jb250YWluZXJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdyb3VwTm9kZVRlbXBsYXRlKCkgPz8gbnVsbFwiXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwibW9kZWwoKS5jb250ZXh0XCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3JdPVwiaW5qZWN0b3JcIiAvPlxuICA8L3N2ZzpnPlxufVxuXG48IS0tIFJlc2l6ZXIgLS0+XG5AaWYgKG1vZGVsKCkucmVzaXplclRlbXBsYXRlKCk7IGFzIHRlbXBsYXRlKSB7XG4gIEBpZiAobW9kZWwoKS5yZXNpemFibGUoKSkge1xuICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0ZW1wbGF0ZVwiIC8+XG4gIH1cbn1cblxuPCEtLSBIYW5kbGVzIC0tPlxuQGZvciAoaGFuZGxlIG9mIG1vZGVsKCkuaGFuZGxlcygpOyB0cmFjayBoYW5kbGUpIHtcbiAgQGlmIChoYW5kbGUudGVtcGxhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgIDxzdmc6Y2lyY2xlXG4gICAgICBjbGFzcz1cImRlZmF1bHQtaGFuZGxlXCJcbiAgICAgIHI9XCI1XCJcbiAgICAgIFthdHRyLmN4XT1cImhhbmRsZS5ob3N0T2Zmc2V0KCkueFwiXG4gICAgICBbYXR0ci5jeV09XCJoYW5kbGUuaG9zdE9mZnNldCgpLnlcIlxuICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cImhhbmRsZS5zdHJva2VXaWR0aFwiXG4gICAgICAocG9pbnRlclN0YXJ0KT1cInN0YXJ0Q29ubmVjdGlvbigkZXZlbnQsIGhhbmRsZSlcIlxuICAgICAgKHBvaW50ZXJFbmQpPVwiZW5kQ29ubmVjdGlvbigpXCIgLz5cbiAgfVxuXG4gIEBpZiAoaGFuZGxlLnRlbXBsYXRlID09PSBudWxsKSB7XG4gICAgPHN2ZzpnXG4gICAgICBbaGFuZGxlU2l6ZUNvbnRyb2xsZXJdPVwiaGFuZGxlXCJcbiAgICAgIChwb2ludGVyU3RhcnQpPVwic3RhcnRDb25uZWN0aW9uKCRldmVudCwgaGFuZGxlKVwiXG4gICAgICAocG9pbnRlckVuZCk9XCJlbmRDb25uZWN0aW9uKClcIiAvPlxuICB9XG5cbiAgQGlmIChoYW5kbGUudGVtcGxhdGUpIHtcbiAgICA8c3ZnOmdcbiAgICAgIFtoYW5kbGVTaXplQ29udHJvbGxlcl09XCJoYW5kbGVcIlxuICAgICAgKHBvaW50ZXJTdGFydCk9XCJzdGFydENvbm5lY3Rpb24oJGV2ZW50LCBoYW5kbGUpXCJcbiAgICAgIChwb2ludGVyRW5kKT1cImVuZENvbm5lY3Rpb24oKVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhhbmRsZS50ZW1wbGF0ZTsgY29udGV4dDogaGFuZGxlLnRlbXBsYXRlQ29udGV4dFwiIC8+XG4gICAgPC9zdmc6Zz5cbiAgfVxuXG4gIEBpZiAoc2hvd01hZ25ldCgpKSB7XG4gICAgPHN2ZzpjaXJjbGVcbiAgICAgIGNsYXNzPVwibWFnbmV0XCJcbiAgICAgIFthdHRyLnJdPVwibW9kZWwoKS5tYWduZXRSYWRpdXNcIlxuICAgICAgW2F0dHIuY3hdPVwiaGFuZGxlLmhvc3RPZmZzZXQoKS54XCJcbiAgICAgIFthdHRyLmN5XT1cImhhbmRsZS5ob3N0T2Zmc2V0KCkueVwiXG4gICAgICAocG9pbnRlckVuZCk9XCJlbmRDb25uZWN0aW9uKCk7IHJlc2V0VmFsaWRhdGVDb25uZWN0aW9uKGhhbmRsZSlcIlxuICAgICAgKHBvaW50ZXJPdmVyKT1cInZhbGlkYXRlQ29ubmVjdGlvbihoYW5kbGUpXCJcbiAgICAgIChwb2ludGVyT3V0KT1cInJlc2V0VmFsaWRhdGVDb25uZWN0aW9uKGhhbmRsZSlcIiAvPlxuICB9XG59XG5cbjwhLS0gVG9vbGJhciAtLT5cbkBmb3IgKHRvb2xiYXIgb2YgdG9vbGJhcnMoKTsgdHJhY2sgdG9vbGJhcikge1xuICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICBbYXR0ci53aWR0aF09XCJ0b29sYmFyLnNpemUoKS53aWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cInRvb2xiYXIuc2l6ZSgpLmhlaWdodFwiXG4gICAgW2F0dHIudHJhbnNmb3JtXT1cInRvb2xiYXIudHJhbnNmb3JtKClcIj5cbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInRvb2xiYXIudGVtcGxhdGUoKVwiIC8+XG4gIDwvc3ZnOmZvcmVpZ25PYmplY3Q+XG59XG4iXX0=