@limble/limble-tree 2.0.0 → 4.0.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.
- package/README.md +2 -0
- package/esm2022/lib/components/branch/branch.component.mjs +79 -0
- package/esm2022/lib/components/dragover-no-change-detect.mjs +39 -0
- package/{esm2020 → esm2022}/lib/components/dropzone/dropzone.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/root/root.component.mjs +5 -5
- package/esm2022/lib/core/tree-branch/branch-controller.mjs +99 -0
- package/esm2022/lib/core/tree-branch/tree-branch.mjs +429 -0
- package/esm2022/lib/core/tree-node-base.mjs +77 -0
- package/esm2022/lib/core/tree-root/tree-root.mjs +193 -0
- package/{esm2020 → esm2022}/lib/core/tree-service/tree.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/extras/collapse/collapse.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/extras/collapse/collapse.service.mjs +4 -4
- package/esm2022/lib/extras/drag-and-drop/drag-and-drop.mjs +83 -0
- package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-and-drop.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-and-drop.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/extras/drag-and-drop/draggable.directive.mjs +5 -5
- package/esm2022/lib/extras/drag-and-drop/dropzone-renderer.mjs +176 -0
- package/esm2022/lib/legacy/legacy-tree.mjs +73 -0
- package/esm2022/lib/legacy/limble-tree-legacy.module.mjs +20 -0
- package/esm2022/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +78 -0
- package/{esm2020 → esm2022}/lib/limble-tree.module.mjs +5 -5
- package/esm2022/shared/assert.mjs +7 -0
- package/{fesm2020 → fesm2022}/limble-limble-tree.mjs +72 -75
- package/fesm2022/limble-limble-tree.mjs.map +1 -0
- package/lib/components/branch/branch.component.d.ts +1 -1
- package/lib/components/dropzone/dropzone.component.d.ts +1 -1
- package/lib/core/tree-node-base.d.ts +2 -1
- package/lib/extras/drag-and-drop/draggable.directive.d.ts +1 -1
- package/lib/legacy/limble-tree-root/limble-tree-root.component.d.ts +2 -2
- package/package.json +7 -13
- package/esm2020/lib/components/branch/branch.component.mjs +0 -79
- package/esm2020/lib/components/dragover-no-change-detect.mjs +0 -39
- package/esm2020/lib/core/tree-branch/branch-controller.mjs +0 -99
- package/esm2020/lib/core/tree-branch/tree-branch.mjs +0 -429
- package/esm2020/lib/core/tree-node-base.mjs +0 -80
- package/esm2020/lib/core/tree-root/tree-root.mjs +0 -193
- package/esm2020/lib/extras/drag-and-drop/drag-and-drop.mjs +0 -83
- package/esm2020/lib/extras/drag-and-drop/dropzone-renderer.mjs +0 -176
- package/esm2020/lib/legacy/legacy-tree.mjs +0 -73
- package/esm2020/lib/legacy/limble-tree-legacy.module.mjs +0 -20
- package/esm2020/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +0 -78
- package/esm2020/shared/assert.mjs +0 -7
- package/fesm2015/limble-limble-tree.mjs +0 -1812
- package/fesm2015/limble-limble-tree.mjs.map +0 -1
- package/fesm2020/limble-limble-tree.mjs.map +0 -1
- /package/{esm2020 → esm2022}/lib/components/branch/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/dropzone/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/host-component.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/node-component.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/root/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/branch-options.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/branchable.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/component-container.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/configuration/configuration.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/configuration/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/configuration/tree-options.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-branch/graftable.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-branch/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-node.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-plot.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-root/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-root/root-controller.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/core/tree-service/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/errors/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/errors/tree-error.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/drag/drag-end-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/drag/drag-start-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/drag/drop-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/drag/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/general/destruction-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/general/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/relational/graft-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/relational/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/relational/prune-event.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/relational/relational-tree-event.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/relational/tree-relationship.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/events/tree-event.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/extras/collapse/collapse.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/extras/collapse/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-state.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/extras/drag-and-drop/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/legacy/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/legacy/legacy-component-obj.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/legacy/legacy-tree-data.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/legacy/legacy-tree-options.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/limble-limble-tree.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/shared/has-property.mjs +0 -0
- /package/{esm2020 → esm2022}/shared/index.mjs +0 -0
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { createComponent, EnvironmentInjector } from "@angular/core";
|
|
2
|
-
import { assert } from "../../../shared";
|
|
3
|
-
import { filter } from "rxjs";
|
|
4
|
-
import { BranchComponent } from "../../components";
|
|
5
|
-
import { dropzoneRenderer } from "../../extras/drag-and-drop";
|
|
6
|
-
/**
|
|
7
|
-
* A wrapper around the BranchComponent that helps instantiate it and handles its events.
|
|
8
|
-
*/
|
|
9
|
-
export class BranchController {
|
|
10
|
-
constructor(treeBranch, parentBranchesContainer) {
|
|
11
|
-
this.treeBranch = treeBranch;
|
|
12
|
-
this.outputBindingSubscriptions = [];
|
|
13
|
-
this.branchComponentRef = createComponent(BranchComponent, {
|
|
14
|
-
environmentInjector: parentBranchesContainer.injector.get(EnvironmentInjector)
|
|
15
|
-
});
|
|
16
|
-
this.branchComponentRef.instance.contentToHost =
|
|
17
|
-
this.treeBranch.branchOptions.component;
|
|
18
|
-
this.instanceSubscriptions = this.getInstanceSubscriptions(this.branchComponentRef.instance);
|
|
19
|
-
}
|
|
20
|
-
destroy() {
|
|
21
|
-
this.instanceSubscriptions.forEach((sub) => {
|
|
22
|
-
sub.unsubscribe();
|
|
23
|
-
});
|
|
24
|
-
this.outputBindingSubscriptions.forEach((sub) => {
|
|
25
|
-
sub.unsubscribe();
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
detectChanges() {
|
|
29
|
-
this.branchComponentRef.changeDetectorRef.detectChanges();
|
|
30
|
-
}
|
|
31
|
-
getBranchesContainer() {
|
|
32
|
-
return this.branchComponentRef.instance.branchesContainer;
|
|
33
|
-
}
|
|
34
|
-
getComponentInstance() {
|
|
35
|
-
return this.branchComponentRef.instance;
|
|
36
|
-
}
|
|
37
|
-
getHostView() {
|
|
38
|
-
return this.branchComponentRef.hostView;
|
|
39
|
-
}
|
|
40
|
-
getNativeElement() {
|
|
41
|
-
return this.branchComponentRef.location.nativeElement;
|
|
42
|
-
}
|
|
43
|
-
getUserlandComponentRef() {
|
|
44
|
-
return this.branchComponentRef.instance.getHostedContent();
|
|
45
|
-
}
|
|
46
|
-
getContentCreatedSub(instance) {
|
|
47
|
-
return instance.contentCreated.subscribe((userlandComponentInstance) => {
|
|
48
|
-
const component = userlandComponentInstance;
|
|
49
|
-
Object.entries(this.treeBranch.branchOptions.inputBindings ?? {}).forEach(([key, value]) => {
|
|
50
|
-
component[key] = value;
|
|
51
|
-
});
|
|
52
|
-
Object.entries(this.treeBranch.branchOptions.outputBindings ?? {}).forEach(([key, value]) => {
|
|
53
|
-
this.outputBindingSubscriptions.push(component[key].subscribe(value));
|
|
54
|
-
});
|
|
55
|
-
component.treeBranch = this.treeBranch;
|
|
56
|
-
const dropzones = instance.dropzones;
|
|
57
|
-
assert(dropzones !== undefined);
|
|
58
|
-
dropzoneRenderer.registerDropzones(dropzones, this.treeBranch);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
getInstanceSubscriptions(instance) {
|
|
62
|
-
const droppedSub = instance.dropped.subscribe((placement) => {
|
|
63
|
-
dropzoneRenderer.handleDrop(this.treeBranch, placement);
|
|
64
|
-
});
|
|
65
|
-
return [
|
|
66
|
-
this.getContentCreatedSub(instance),
|
|
67
|
-
this.getShowLowerZonesSub(instance),
|
|
68
|
-
this.getShowUpperZonesSub(instance),
|
|
69
|
-
droppedSub
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
getShowLowerZonesSub(instance) {
|
|
73
|
-
return instance.showDropzones
|
|
74
|
-
.pipe(filter((direction) => direction === "lower"))
|
|
75
|
-
.subscribe(() => {
|
|
76
|
-
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
77
|
-
if (currentDropzoneDisplayed?.treeBranch === this.treeBranch &&
|
|
78
|
-
currentDropzoneDisplayed.direction === "lower") {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
dropzoneRenderer.showLowerZones(this.treeBranch);
|
|
82
|
-
instance.triggerChangeDetection();
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
getShowUpperZonesSub(instance) {
|
|
86
|
-
return instance.showDropzones
|
|
87
|
-
.pipe(filter((direction) => direction === "upper"))
|
|
88
|
-
.subscribe(() => {
|
|
89
|
-
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
90
|
-
if (currentDropzoneDisplayed?.treeBranch === this.treeBranch &&
|
|
91
|
-
currentDropzoneDisplayed.direction === "upper") {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
dropzoneRenderer.showUpperZones(this.treeBranch);
|
|
95
|
-
instance.triggerChangeDetection();
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJhbmNoLWNvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1icmFuY2gvYnJhbmNoLWNvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVKLGVBQWUsRUFDZixtQkFBbUIsRUFHckIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQXFCLE1BQU0sTUFBTSxDQUFDO0FBQ2pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUk5RDs7R0FFRztBQUNILE1BQU0sT0FBTyxnQkFBZ0I7SUFTMUIsWUFDb0IsVUFBeUMsRUFDMUQsdUJBQXlDO1FBRHhCLGVBQVUsR0FBVixVQUFVLENBQStCO1FBRzFELElBQUksQ0FBQywwQkFBMEIsR0FBRyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGVBQWUsQ0FFdkMsZUFBZSxFQUFFO1lBQ2hCLG1CQUFtQixFQUNoQix1QkFBdUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO1NBQzlELENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsYUFBYTtZQUMzQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUM7UUFDM0MsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FDdkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FDbEMsQ0FBQztJQUNMLENBQUM7SUFFTSxPQUFPO1FBQ1gsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3hDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM3QyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU0sYUFBYTtRQUNqQixJQUFJLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDN0QsQ0FBQztJQUVNLG9CQUFvQjtRQUN4QixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUM7SUFDN0QsQ0FBQztJQUVNLG9CQUFvQjtRQUN4QixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUM7SUFDM0MsQ0FBQztJQUVNLFdBQVc7UUFDZixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUM7SUFDM0MsQ0FBQztJQUVNLGdCQUFnQjtRQUNwQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO0lBQ3pELENBQUM7SUFFTSx1QkFBdUI7UUFHM0IsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDOUQsQ0FBQztJQUVPLG9CQUFvQixDQUN6QixRQUE0QztRQUU1QyxPQUFPLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMseUJBQXlCLEVBQUUsRUFBRTtZQUNwRSxNQUFNLFNBQVMsR0FBRyx5QkFBZ0MsQ0FBQztZQUNuRCxNQUFNLENBQUMsT0FBTyxDQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQ25ELENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtnQkFDeEIsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUMxQixDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxPQUFPLENBQ1gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsY0FBYyxJQUFJLEVBQUUsQ0FDcEQsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO2dCQUN4QixJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUNqQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUNqQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxTQUFTLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDdkMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztZQUNyQyxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1lBQ2hDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU8sd0JBQXdCLENBQzdCLFFBQTRDO1FBRTVDLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDekQsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPO1lBQ0osSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztZQUNuQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDO1lBQ25DLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7WUFDbkMsVUFBVTtTQUNaLENBQUM7SUFDTCxDQUFDO0lBRU8sb0JBQW9CLENBQ3pCLFFBQTRDO1FBRTVDLE9BQU8sUUFBUSxDQUFDLGFBQWE7YUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxDQUFDO2FBQ2xELFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDYixNQUFNLHdCQUF3QixHQUMzQixnQkFBZ0IsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3hDLElBQ0csd0JBQXdCLEVBQUUsVUFBVSxLQUFLLElBQUksQ0FBQyxVQUFVO2dCQUN4RCx3QkFBd0IsQ0FBQyxTQUFTLEtBQUssT0FBTyxFQUMvQztnQkFDQyxPQUFPO2FBQ1Q7WUFDRCxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2pELFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ1QsQ0FBQztJQUVPLG9CQUFvQixDQUN6QixRQUE0QztRQUU1QyxPQUFPLFFBQVEsQ0FBQyxhQUFhO2FBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsQ0FBQzthQUNsRCxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2IsTUFBTSx3QkFBd0IsR0FDM0IsZ0JBQWdCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN4QyxJQUNHLHdCQUF3QixFQUFFLFVBQVUsS0FBSyxJQUFJLENBQUMsVUFBVTtnQkFDeEQsd0JBQXdCLENBQUMsU0FBUyxLQUFLLE9BQU8sRUFDL0M7Z0JBQ0MsT0FBTzthQUNUO1lBQ0QsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNqRCxRQUFRLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNULENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICB0eXBlIENvbXBvbmVudFJlZixcbiAgIGNyZWF0ZUNvbXBvbmVudCxcbiAgIEVudmlyb25tZW50SW5qZWN0b3IsXG4gICB0eXBlIFZpZXdDb250YWluZXJSZWYsXG4gICB0eXBlIFZpZXdSZWZcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi8uLi9zaGFyZWRcIjtcbmltcG9ydCB7IGZpbHRlciwgdHlwZSBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgQnJhbmNoQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudHNcIjtcbmltcG9ydCB7IGRyb3B6b25lUmVuZGVyZXIgfSBmcm9tIFwiLi4vLi4vZXh0cmFzL2RyYWctYW5kLWRyb3BcIjtcbmltcG9ydCB0eXBlIHsgQ29tcG9uZW50Q29udGFpbmVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC1jb250YWluZXIuaW50ZXJmYWNlXCI7XG5pbXBvcnQgdHlwZSB7IFRyZWVCcmFuY2ggfSBmcm9tIFwiLi90cmVlLWJyYW5jaFwiO1xuXG4vKipcbiAqIEEgd3JhcHBlciBhcm91bmQgdGhlIEJyYW5jaENvbXBvbmVudCB0aGF0IGhlbHBzIGluc3RhbnRpYXRlIGl0IGFuZCBoYW5kbGVzIGl0cyBldmVudHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBCcmFuY2hDb250cm9sbGVyPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgaW1wbGVtZW50cyBDb21wb25lbnRDb250YWluZXI8QnJhbmNoQ29tcG9uZW50PFVzZXJsYW5kQ29tcG9uZW50Pj5cbntcbiAgIHByaXZhdGUgcmVhZG9ubHkgYnJhbmNoQ29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8XG4gICAgICBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+XG4gICA+O1xuICAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZVN1YnNjcmlwdGlvbnM6IEFycmF5PFN1YnNjcmlwdGlvbj47XG4gICBwcml2YXRlIHJlYWRvbmx5IG91dHB1dEJpbmRpbmdTdWJzY3JpcHRpb25zOiBBcnJheTxTdWJzY3JpcHRpb24+O1xuXG4gICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVCcmFuY2g6IFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgcGFyZW50QnJhbmNoZXNDb250YWluZXI6IFZpZXdDb250YWluZXJSZWZcbiAgICkge1xuICAgICAgdGhpcy5vdXRwdXRCaW5kaW5nU3Vic2NyaXB0aW9ucyA9IFtdO1xuICAgICAgdGhpcy5icmFuY2hDb21wb25lbnRSZWYgPSBjcmVhdGVDb21wb25lbnQ8XG4gICAgICAgICBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+XG4gICAgICA+KEJyYW5jaENvbXBvbmVudCwge1xuICAgICAgICAgZW52aXJvbm1lbnRJbmplY3RvcjpcbiAgICAgICAgICAgIHBhcmVudEJyYW5jaGVzQ29udGFpbmVyLmluamVjdG9yLmdldChFbnZpcm9ubWVudEluamVjdG9yKVxuICAgICAgfSk7XG4gICAgICB0aGlzLmJyYW5jaENvbXBvbmVudFJlZi5pbnN0YW5jZS5jb250ZW50VG9Ib3N0ID1cbiAgICAgICAgIHRoaXMudHJlZUJyYW5jaC5icmFuY2hPcHRpb25zLmNvbXBvbmVudDtcbiAgICAgIHRoaXMuaW5zdGFuY2VTdWJzY3JpcHRpb25zID0gdGhpcy5nZXRJbnN0YW5jZVN1YnNjcmlwdGlvbnMoXG4gICAgICAgICB0aGlzLmJyYW5jaENvbXBvbmVudFJlZi5pbnN0YW5jZVxuICAgICAgKTtcbiAgIH1cblxuICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICB0aGlzLmluc3RhbmNlU3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzdWIpID0+IHtcbiAgICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm91dHB1dEJpbmRpbmdTdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YikgPT4ge1xuICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9KTtcbiAgIH1cblxuICAgcHVibGljIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgICB0aGlzLmJyYW5jaENvbXBvbmVudFJlZi5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICB9XG5cbiAgIHB1YmxpYyBnZXRCcmFuY2hlc0NvbnRhaW5lcigpOiBWaWV3Q29udGFpbmVyUmVmIHwgdW5kZWZpbmVkIHtcbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbXBvbmVudFJlZi5pbnN0YW5jZS5icmFuY2hlc0NvbnRhaW5lcjtcbiAgIH1cblxuICAgcHVibGljIGdldENvbXBvbmVudEluc3RhbmNlKCk6IEJyYW5jaENvbXBvbmVudDxVc2VybGFuZENvbXBvbmVudD4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29tcG9uZW50UmVmLmluc3RhbmNlO1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0SG9zdFZpZXcoKTogVmlld1JlZiB7XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb21wb25lbnRSZWYuaG9zdFZpZXc7XG4gICB9XG5cbiAgIHB1YmxpYyBnZXROYXRpdmVFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbXBvbmVudFJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0VXNlcmxhbmRDb21wb25lbnRSZWYoKTpcbiAgICAgIHwgQ29tcG9uZW50UmVmPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgICAgfCB1bmRlZmluZWQge1xuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29tcG9uZW50UmVmLmluc3RhbmNlLmdldEhvc3RlZENvbnRlbnQoKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBnZXRDb250ZW50Q3JlYXRlZFN1YihcbiAgICAgIGluc3RhbmNlOiBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApOiBTdWJzY3JpcHRpb24ge1xuICAgICAgcmV0dXJuIGluc3RhbmNlLmNvbnRlbnRDcmVhdGVkLnN1YnNjcmliZSgodXNlcmxhbmRDb21wb25lbnRJbnN0YW5jZSkgPT4ge1xuICAgICAgICAgY29uc3QgY29tcG9uZW50ID0gdXNlcmxhbmRDb21wb25lbnRJbnN0YW5jZSBhcyBhbnk7XG4gICAgICAgICBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICAgIHRoaXMudHJlZUJyYW5jaC5icmFuY2hPcHRpb25zLmlucHV0QmluZGluZ3MgPz8ge31cbiAgICAgICAgICkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICBjb21wb25lbnRba2V5XSA9IHZhbHVlO1xuICAgICAgICAgfSk7XG4gICAgICAgICBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICAgIHRoaXMudHJlZUJyYW5jaC5icmFuY2hPcHRpb25zLm91dHB1dEJpbmRpbmdzID8/IHt9XG4gICAgICAgICApLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vdXRwdXRCaW5kaW5nU3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgY29tcG9uZW50W2tleV0uc3Vic2NyaWJlKHZhbHVlKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgIH0pO1xuICAgICAgICAgY29tcG9uZW50LnRyZWVCcmFuY2ggPSB0aGlzLnRyZWVCcmFuY2g7XG4gICAgICAgICBjb25zdCBkcm9wem9uZXMgPSBpbnN0YW5jZS5kcm9wem9uZXM7XG4gICAgICAgICBhc3NlcnQoZHJvcHpvbmVzICE9PSB1bmRlZmluZWQpO1xuICAgICAgICAgZHJvcHpvbmVSZW5kZXJlci5yZWdpc3RlckRyb3B6b25lcyhkcm9wem9uZXMsIHRoaXMudHJlZUJyYW5jaCk7XG4gICAgICB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBnZXRJbnN0YW5jZVN1YnNjcmlwdGlvbnMoXG4gICAgICBpbnN0YW5jZTogQnJhbmNoQ29tcG9uZW50PFVzZXJsYW5kQ29tcG9uZW50PlxuICAgKTogQXJyYXk8U3Vic2NyaXB0aW9uPiB7XG4gICAgICBjb25zdCBkcm9wcGVkU3ViID0gaW5zdGFuY2UuZHJvcHBlZC5zdWJzY3JpYmUoKHBsYWNlbWVudCkgPT4ge1xuICAgICAgICAgZHJvcHpvbmVSZW5kZXJlci5oYW5kbGVEcm9wKHRoaXMudHJlZUJyYW5jaCwgcGxhY2VtZW50KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgIHRoaXMuZ2V0Q29udGVudENyZWF0ZWRTdWIoaW5zdGFuY2UpLFxuICAgICAgICAgdGhpcy5nZXRTaG93TG93ZXJab25lc1N1YihpbnN0YW5jZSksXG4gICAgICAgICB0aGlzLmdldFNob3dVcHBlclpvbmVzU3ViKGluc3RhbmNlKSxcbiAgICAgICAgIGRyb3BwZWRTdWJcbiAgICAgIF07XG4gICB9XG5cbiAgIHByaXZhdGUgZ2V0U2hvd0xvd2VyWm9uZXNTdWIoXG4gICAgICBpbnN0YW5jZTogQnJhbmNoQ29tcG9uZW50PFVzZXJsYW5kQ29tcG9uZW50PlxuICAgKTogU3Vic2NyaXB0aW9uIHtcbiAgICAgIHJldHVybiBpbnN0YW5jZS5zaG93RHJvcHpvbmVzXG4gICAgICAgICAucGlwZShmaWx0ZXIoKGRpcmVjdGlvbikgPT4gZGlyZWN0aW9uID09PSBcImxvd2VyXCIpKVxuICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RHJvcHpvbmVEaXNwbGF5ZWQgPVxuICAgICAgICAgICAgICAgZHJvcHpvbmVSZW5kZXJlci5nZXRDdXJyZW50RGlzcGxheSgpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgY3VycmVudERyb3B6b25lRGlzcGxheWVkPy50cmVlQnJhbmNoID09PSB0aGlzLnRyZWVCcmFuY2ggJiZcbiAgICAgICAgICAgICAgIGN1cnJlbnREcm9wem9uZURpc3BsYXllZC5kaXJlY3Rpb24gPT09IFwibG93ZXJcIlxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkcm9wem9uZVJlbmRlcmVyLnNob3dMb3dlclpvbmVzKHRoaXMudHJlZUJyYW5jaCk7XG4gICAgICAgICAgICBpbnN0YW5jZS50cmlnZ2VyQ2hhbmdlRGV0ZWN0aW9uKCk7XG4gICAgICAgICB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBnZXRTaG93VXBwZXJab25lc1N1YihcbiAgICAgIGluc3RhbmNlOiBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApOiBTdWJzY3JpcHRpb24ge1xuICAgICAgcmV0dXJuIGluc3RhbmNlLnNob3dEcm9wem9uZXNcbiAgICAgICAgIC5waXBlKGZpbHRlcigoZGlyZWN0aW9uKSA9PiBkaXJlY3Rpb24gPT09IFwidXBwZXJcIikpXG4gICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREcm9wem9uZURpc3BsYXllZCA9XG4gICAgICAgICAgICAgICBkcm9wem9uZVJlbmRlcmVyLmdldEN1cnJlbnREaXNwbGF5KCk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICBjdXJyZW50RHJvcHpvbmVEaXNwbGF5ZWQ/LnRyZWVCcmFuY2ggPT09IHRoaXMudHJlZUJyYW5jaCAmJlxuICAgICAgICAgICAgICAgY3VycmVudERyb3B6b25lRGlzcGxheWVkLmRpcmVjdGlvbiA9PT0gXCJ1cHBlclwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRyb3B6b25lUmVuZGVyZXIuc2hvd1VwcGVyWm9uZXModGhpcy50cmVlQnJhbmNoKTtcbiAgICAgICAgICAgIGluc3RhbmNlLnRyaWdnZXJDaGFuZ2VEZXRlY3Rpb24oKTtcbiAgICAgICAgIH0pO1xuICAgfVxufVxuIl19
|
|
@@ -1,429 +0,0 @@
|
|
|
1
|
-
import { assert } from "../../../shared";
|
|
2
|
-
import { TreeError } from "../../errors";
|
|
3
|
-
import { dropzoneRenderer } from "../../extras/drag-and-drop";
|
|
4
|
-
import { TreeRoot } from "../tree-root";
|
|
5
|
-
import { TreeNodeBase } from "../tree-node-base";
|
|
6
|
-
import { config } from "../configuration";
|
|
7
|
-
import { BranchController } from "./branch-controller";
|
|
8
|
-
import { treeCollapser } from "../../extras/collapse";
|
|
9
|
-
import { DestructionEvent, GraftEvent, PruneEvent } from "../../events";
|
|
10
|
-
/** Represents a standard node in a tree. Renders a BranchComponent.
|
|
11
|
-
*
|
|
12
|
-
* @remarks
|
|
13
|
-
* This class renders a branch component, which does the following:
|
|
14
|
-
* 1. Renders a component provided by the user
|
|
15
|
-
* 2. Provides a container in which child branches may be rendered
|
|
16
|
-
* 3. Contains two Dropzones: one for dropping branches below this branch (as a
|
|
17
|
-
* sibling), and one for dropping branches as a first child of this branch.
|
|
18
|
-
*/
|
|
19
|
-
export class TreeBranch {
|
|
20
|
-
constructor(parent, branchOptions) {
|
|
21
|
-
this.branchOptions = branchOptions;
|
|
22
|
-
this.detachedView = null;
|
|
23
|
-
this.treeNodeBase = new TreeNodeBase();
|
|
24
|
-
const parentBranchesContainer = parent.getBranchesContainer();
|
|
25
|
-
assert(parentBranchesContainer !== undefined);
|
|
26
|
-
this.branchController = new BranchController(this, parentBranchesContainer);
|
|
27
|
-
const hostView = this.branchController.getHostView();
|
|
28
|
-
if (parent instanceof TreeBranch &&
|
|
29
|
-
parent.branchOptions.defaultCollapsed === true) {
|
|
30
|
-
treeCollapser.storePrecollapsedNode(parent, this);
|
|
31
|
-
this.detachedView = hostView;
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
parentBranchesContainer.insert(hostView);
|
|
35
|
-
this._parent = parent;
|
|
36
|
-
this.dispatch(new GraftEvent(this, {
|
|
37
|
-
parent: this._parent,
|
|
38
|
-
child: this,
|
|
39
|
-
index: this._parent.branches().length
|
|
40
|
-
}));
|
|
41
|
-
this.setIndentation();
|
|
42
|
-
}
|
|
43
|
-
this.detectChanges();
|
|
44
|
-
}
|
|
45
|
-
/** @returns All child branches as an array of TreeBranch instances, in order. */
|
|
46
|
-
branches() {
|
|
47
|
-
return this.treeNodeBase.branches();
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Recursively destroys all descendant branches, as well as itself. This
|
|
51
|
-
* releases all resources held or consumed by this branch and its descendants.
|
|
52
|
-
*
|
|
53
|
-
* @remarks
|
|
54
|
-
* It is important to call this method when a branch is discarded, otherwise
|
|
55
|
-
* the branch will remain in memory and continue to consume resources.
|
|
56
|
-
*/
|
|
57
|
-
destroy() {
|
|
58
|
-
if (this.isDestroyed()) {
|
|
59
|
-
throw new TreeError("Cannot destroy a destroyed tree branch");
|
|
60
|
-
}
|
|
61
|
-
this.prune();
|
|
62
|
-
treeCollapser.expand(this);
|
|
63
|
-
dropzoneRenderer.clearTreeFromRegistry(this);
|
|
64
|
-
this.branchController.getHostView().destroy();
|
|
65
|
-
this.treeNodeBase.destroy();
|
|
66
|
-
this.branchController.destroy();
|
|
67
|
-
this.dispatch(new DestructionEvent(this));
|
|
68
|
-
}
|
|
69
|
-
/** Run Angular change detection on this branch */
|
|
70
|
-
detectChanges() {
|
|
71
|
-
this.branchController.detectChanges();
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Emits the specified TreeEvent.
|
|
75
|
-
*
|
|
76
|
-
* @remarks
|
|
77
|
-
* Caution: It is not recommended to manually emit TreeEvents that are already
|
|
78
|
-
* provided by the library. For example, it is not recommended to emit a
|
|
79
|
-
* `GraftEvent`, `DestructionEvent`, etc. These events may be used by the tree,
|
|
80
|
-
* and emitting them manually may cause unexpected behavior. Instead, we
|
|
81
|
-
* recommend implementing the TreeEvent interface with your own custom events
|
|
82
|
-
* and dispatching those.
|
|
83
|
-
*
|
|
84
|
-
* @param event - The TreeEvent that will be emitted.
|
|
85
|
-
*/
|
|
86
|
-
dispatch(event) {
|
|
87
|
-
this.treeNodeBase.dispatch(event);
|
|
88
|
-
this._parent?.dispatch(event);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* @returns
|
|
92
|
-
* An observable that emits TreeEvents whenever an event is dispatched
|
|
93
|
-
* in this branch or any of its descendant branches.
|
|
94
|
-
*/
|
|
95
|
-
events() {
|
|
96
|
-
return this.treeNodeBase.events();
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* @param index - The index of the child branch to retrieve.
|
|
100
|
-
*
|
|
101
|
-
* @returns
|
|
102
|
-
* The child branch at the specified index, or undefined if there is
|
|
103
|
-
* no child branch at the specified index.
|
|
104
|
-
*/
|
|
105
|
-
getBranch(index) {
|
|
106
|
-
return this.treeNodeBase.getBranch(index);
|
|
107
|
-
}
|
|
108
|
-
/** @returns The ViewContainerRef in which child branches are rendered */
|
|
109
|
-
getBranchesContainer() {
|
|
110
|
-
if (this.isDestroyed()) {
|
|
111
|
-
throw new TreeError("Cannot get branches container from a destroyed tree branch");
|
|
112
|
-
}
|
|
113
|
-
return this.branchController.getBranchesContainer();
|
|
114
|
-
}
|
|
115
|
-
/** @returns The instance of BranchComponent that is rendered by this class. */
|
|
116
|
-
getComponentInstance() {
|
|
117
|
-
if (this.isDestroyed()) {
|
|
118
|
-
throw new TreeError("Cannot get component instance from a destroyed tree branch");
|
|
119
|
-
}
|
|
120
|
-
return this.branchController.getComponentInstance();
|
|
121
|
-
}
|
|
122
|
-
/** @returns The Host View in which the BranchComponent is rendered */
|
|
123
|
-
getHostView() {
|
|
124
|
-
if (this.isDestroyed()) {
|
|
125
|
-
throw new TreeError("Cannot get component host view from a destroyed tree branch");
|
|
126
|
-
}
|
|
127
|
-
return this.branchController.getHostView();
|
|
128
|
-
}
|
|
129
|
-
/** @returns The BranchComponent as a native HTML Element */
|
|
130
|
-
getNativeElement() {
|
|
131
|
-
if (this.isDestroyed()) {
|
|
132
|
-
throw new TreeError("Cannot get native element from a destroyed tree branch");
|
|
133
|
-
}
|
|
134
|
-
return this.branchController.getNativeElement();
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* @returns
|
|
138
|
-
* A ComponentRef containing the instance of the user-provided
|
|
139
|
-
* component which is rendered by this branch.
|
|
140
|
-
*/
|
|
141
|
-
getUserlandComponentRef() {
|
|
142
|
-
if (this.isDestroyed()) {
|
|
143
|
-
throw new TreeError("Cannot get userland component from a destroyed tree branch");
|
|
144
|
-
}
|
|
145
|
-
return this.branchController.getUserlandComponentRef();
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Attaches a branch to a new parent node.
|
|
149
|
-
*
|
|
150
|
-
* @remarks
|
|
151
|
-
* If not already pruned, this method prunes (removes) this branch from its
|
|
152
|
-
* current position in the tree; then grafts (reattaches) it as a child of the
|
|
153
|
-
* specified parent branch at the specified index. If no index is specified,
|
|
154
|
-
* the branch is appended as the last child of the parent. This causes this
|
|
155
|
-
* branch's associated BranchComponent to be re-rendered in the DOM at the
|
|
156
|
-
* new location.
|
|
157
|
-
*
|
|
158
|
-
* @param newParent - The new parent branch unto which this branch will be grafted.
|
|
159
|
-
* @param index - The index at which this branch will be grafted. If not specified,
|
|
160
|
-
* this branch will be appended as the last child of the new parent.
|
|
161
|
-
*
|
|
162
|
-
* @returns The index at which this branch was grafted.
|
|
163
|
-
*/
|
|
164
|
-
graftTo(newParent, index) {
|
|
165
|
-
this.checkGraftLocationValidity(newParent, index);
|
|
166
|
-
const ownIndex = this.index();
|
|
167
|
-
if (ownIndex !== undefined) {
|
|
168
|
-
this.prune();
|
|
169
|
-
}
|
|
170
|
-
this._parent = newParent;
|
|
171
|
-
const newIndex = index ?? newParent.branches().length;
|
|
172
|
-
this.reattachView(newIndex);
|
|
173
|
-
this.dispatch(new GraftEvent(this, {
|
|
174
|
-
parent: newParent,
|
|
175
|
-
child: this,
|
|
176
|
-
index: newIndex
|
|
177
|
-
}));
|
|
178
|
-
return newIndex;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Appends a new child branch to this branch. The child branch will render
|
|
182
|
-
* the specified component according to the (optional) configuration parameter.
|
|
183
|
-
*
|
|
184
|
-
* @param component - The component to render in the new child branch.
|
|
185
|
-
* @param options - Configuration options for the new child branch.
|
|
186
|
-
*
|
|
187
|
-
* @returns
|
|
188
|
-
* The newly-created child branch.
|
|
189
|
-
*/
|
|
190
|
-
grow(component, options) {
|
|
191
|
-
if (this.isDestroyed()) {
|
|
192
|
-
throw new TreeError("Cannot grow a branch on a destroyed tree branch");
|
|
193
|
-
}
|
|
194
|
-
try {
|
|
195
|
-
return new TreeBranch(this, { component, ...options });
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
this.handleUserlandError(error);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Determines this branch's index in relation to its sibling branches.
|
|
203
|
-
*
|
|
204
|
-
* @remarks
|
|
205
|
-
* For example, if it is the first child of its parent, this method will return
|
|
206
|
-
* 0. If it is the second child of its parent, this method will return 1.
|
|
207
|
-
*
|
|
208
|
-
* If this branch has no parent, (eg, if this branch has been pruned) this
|
|
209
|
-
* method will return undefined.
|
|
210
|
-
*
|
|
211
|
-
* @returns
|
|
212
|
-
* The index of this branch in relation to its sibling branches, or undefined.
|
|
213
|
-
*/
|
|
214
|
-
index() {
|
|
215
|
-
if (!this._parent) {
|
|
216
|
-
return undefined;
|
|
217
|
-
}
|
|
218
|
-
const index = this._parent
|
|
219
|
-
.branches()
|
|
220
|
-
.findIndex((branch) => branch === this);
|
|
221
|
-
assert(index >= 0);
|
|
222
|
-
return index;
|
|
223
|
-
}
|
|
224
|
-
/** @returns `true` if the branch is destroyed, `false` otherwise */
|
|
225
|
-
isDestroyed() {
|
|
226
|
-
return this.treeNodeBase.isDestroyed();
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* @returns
|
|
230
|
-
* The data that was passed into the `branchOptions`' `meta` property
|
|
231
|
-
* at construction.
|
|
232
|
-
*/
|
|
233
|
-
meta() {
|
|
234
|
-
return this.branchOptions.meta ?? {};
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* @returns
|
|
238
|
-
* This branch's parent node (which may be a TreeBranch or TreeRoot).
|
|
239
|
-
* If this branch has no parent, (eg, if this branch has been pruned) this
|
|
240
|
-
* method will return undefined.
|
|
241
|
-
*/
|
|
242
|
-
parent() {
|
|
243
|
-
return this._parent;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Provides a model describing this branch's descendants.
|
|
247
|
-
*
|
|
248
|
-
* @returns
|
|
249
|
-
* A multi-dimensional Map which describes the shape of this branch's
|
|
250
|
-
* descendants.
|
|
251
|
-
*
|
|
252
|
-
* @example
|
|
253
|
-
* A branch with no children will return an empty Map. A branch with
|
|
254
|
-
* a single child will return a Map with a single entry, where the key is the index
|
|
255
|
-
* of the branch (zero) and the value is an empty Map. A Tree like this:
|
|
256
|
-
*
|
|
257
|
-
* ```
|
|
258
|
-
* ---Branch-------Branch
|
|
259
|
-
* /
|
|
260
|
-
* Branch-------Branch
|
|
261
|
-
* \
|
|
262
|
-
* ---Branch
|
|
263
|
-
* ```
|
|
264
|
-
* Will return a Map of matching shape:
|
|
265
|
-
* ```
|
|
266
|
-
* Map {
|
|
267
|
-
* 0: Map { 0: Map {}},
|
|
268
|
-
* 1: Map {},
|
|
269
|
-
* 2: Map {}
|
|
270
|
-
* }
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
plot() {
|
|
274
|
-
return this.treeNodeBase.plot();
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Calculates the branch's position in the tree relative to the Root.
|
|
278
|
-
*
|
|
279
|
-
* @remarks
|
|
280
|
-
* The position is described as an array of numbers, where each number
|
|
281
|
-
* represents the index of the branch at that level of the tree.
|
|
282
|
-
*
|
|
283
|
-
* For example, if this branch is the first child of the Root, this method
|
|
284
|
-
* will return [0]. If this branch is the second child of the first child
|
|
285
|
-
* of the Root, this method will return [0, 1].
|
|
286
|
-
*
|
|
287
|
-
* If the branch is not related to a TreeRoot, (such as when it has been
|
|
288
|
-
* pruned,) this method will throw an error.
|
|
289
|
-
*
|
|
290
|
-
* @returns
|
|
291
|
-
* An array of numbers which describe the branch's position in the tree
|
|
292
|
-
* relative to the Root.
|
|
293
|
-
*/
|
|
294
|
-
position() {
|
|
295
|
-
const index = this.index();
|
|
296
|
-
if (index === undefined) {
|
|
297
|
-
throw new TreeError("branch has no parent. Position cannot be determined.");
|
|
298
|
-
}
|
|
299
|
-
if (this._parent instanceof TreeBranch) {
|
|
300
|
-
const parentPosition = this._parent.position();
|
|
301
|
-
return [...parentPosition, index];
|
|
302
|
-
}
|
|
303
|
-
return [index];
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Removes a branch from its tree without destroying it.
|
|
307
|
-
*
|
|
308
|
-
* @remarks
|
|
309
|
-
* Removes this branch from its parent and detaches its associated
|
|
310
|
-
* BranchComponent from the DOM. This puts the branch in a "pruned" state,
|
|
311
|
-
* which may affect the behavior of other methods.
|
|
312
|
-
*
|
|
313
|
-
* A pruned branch can be reattached to any other node using the `graftTo` method.
|
|
314
|
-
*
|
|
315
|
-
* @returns
|
|
316
|
-
* Itself, or undefined if it is already in a pruned state.
|
|
317
|
-
*/
|
|
318
|
-
prune() {
|
|
319
|
-
if (this.isDestroyed()) {
|
|
320
|
-
throw new TreeError("Cannot prune a destroyed tree branch");
|
|
321
|
-
}
|
|
322
|
-
const parent = this._parent;
|
|
323
|
-
const index = this.index();
|
|
324
|
-
if (index === undefined || parent === undefined)
|
|
325
|
-
return;
|
|
326
|
-
const container = parent.getBranchesContainer();
|
|
327
|
-
assert(container !== undefined);
|
|
328
|
-
this.detachedView = container.detach(index);
|
|
329
|
-
assert(this.detachedView !== null);
|
|
330
|
-
this.detachedView.detach();
|
|
331
|
-
this.dispatch(new PruneEvent(this, {
|
|
332
|
-
parent: parent,
|
|
333
|
-
child: this,
|
|
334
|
-
index: index
|
|
335
|
-
}));
|
|
336
|
-
this._parent = undefined;
|
|
337
|
-
return this;
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Get the root of the tree to which this Branch is attached.
|
|
341
|
-
*
|
|
342
|
-
* @returns
|
|
343
|
-
* The TreeRoot of the tree this branch is in. If this branch is
|
|
344
|
-
* does not have a root (such as when it has been pruned) this method will
|
|
345
|
-
* return undefined.
|
|
346
|
-
*/
|
|
347
|
-
root() {
|
|
348
|
-
const parent = this.parent();
|
|
349
|
-
if (parent instanceof TreeBranch) {
|
|
350
|
-
return parent.root();
|
|
351
|
-
}
|
|
352
|
-
assert(parent instanceof TreeRoot || parent === undefined);
|
|
353
|
-
return parent;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Traverses this branch's descendants in depth-first pre-order, executing
|
|
357
|
-
* the provided callback function on each node. Traversal includes this branch.
|
|
358
|
-
*
|
|
359
|
-
* @param callback - A function to execute on each node.
|
|
360
|
-
*/
|
|
361
|
-
traverse(callback) {
|
|
362
|
-
callback(this);
|
|
363
|
-
this.treeNodeBase.traverse(callback);
|
|
364
|
-
}
|
|
365
|
-
checkGraftLocationValidity(newParent, index) {
|
|
366
|
-
if (this.isDestroyed()) {
|
|
367
|
-
throw new TreeError("Cannot graft a destroyed tree branch");
|
|
368
|
-
}
|
|
369
|
-
if (newParent.isDestroyed()) {
|
|
370
|
-
throw new TreeError("Cannot graft to a destroyed tree branch");
|
|
371
|
-
}
|
|
372
|
-
if (typeof index === "number" &&
|
|
373
|
-
this.indexIsOutOfRange(newParent, index)) {
|
|
374
|
-
throw new TreeError(`Cannot graft branch at index ${index} of the parent. Out of range.`);
|
|
375
|
-
}
|
|
376
|
-
this.traverse((node) => {
|
|
377
|
-
if (node === newParent) {
|
|
378
|
-
throw new TreeError("Cannot graft a branch to itself or any of its own descendants");
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
handleUserlandError(error) {
|
|
383
|
-
// When an error occurs in a userland component during a tree operation,
|
|
384
|
-
// it can cause undefined, bizarre behavior in the tree. To prevent this,
|
|
385
|
-
// we destroy the tree and throw an error instead. This helps protect
|
|
386
|
-
// the end-user's data from corruption.
|
|
387
|
-
this.furthestAncestor().destroy();
|
|
388
|
-
this.treeNodeBase.handleUserlandError(error);
|
|
389
|
-
}
|
|
390
|
-
indexIsOutOfRange(parent, index) {
|
|
391
|
-
return index < 0 || index > parent.branches().length;
|
|
392
|
-
}
|
|
393
|
-
furthestAncestor() {
|
|
394
|
-
// eslint-disable-next-line typescript/no-this-alias -- This code is for an iteration, not to make `this` available in other scopes (which is what the rule is intended to protect against).
|
|
395
|
-
let node = this;
|
|
396
|
-
while (node instanceof TreeBranch) {
|
|
397
|
-
const parent = node.parent();
|
|
398
|
-
if (parent === undefined)
|
|
399
|
-
break;
|
|
400
|
-
node = parent;
|
|
401
|
-
}
|
|
402
|
-
return node;
|
|
403
|
-
}
|
|
404
|
-
reattachView(index) {
|
|
405
|
-
assert(this._parent !== undefined);
|
|
406
|
-
assert(this.detachedView !== null);
|
|
407
|
-
const container = this._parent.getBranchesContainer();
|
|
408
|
-
assert(container !== undefined);
|
|
409
|
-
this.detachedView.reattach();
|
|
410
|
-
container.insert(this.detachedView, index);
|
|
411
|
-
this.detachedView = null;
|
|
412
|
-
this.setIndentation();
|
|
413
|
-
}
|
|
414
|
-
setIndentation() {
|
|
415
|
-
assert(this._parent !== undefined);
|
|
416
|
-
const root = this._parent.root();
|
|
417
|
-
if (root === undefined) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
const options = config.getConfig(root);
|
|
421
|
-
const branchesContainerEl = this.branchController
|
|
422
|
-
.getNativeElement()
|
|
423
|
-
.getElementsByClassName("branches-container")
|
|
424
|
-
.item(0);
|
|
425
|
-
assert(branchesContainerEl instanceof HTMLElement);
|
|
426
|
-
branchesContainerEl.style.marginLeft = `${options?.indentation ?? 16}px`;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1icmFuY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1icmFuY2gvdHJlZS1icmFuY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBU3pDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd4QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBSzFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQ0osZ0JBQWdCLEVBQ2hCLFVBQVUsRUFDVixVQUFVLEVBRVosTUFBTSxjQUFjLENBQUM7QUFFdEI7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQVFwQixZQUNHLE1BQW1DLEVBQ25CLGFBQW1EO1FBQW5ELGtCQUFhLEdBQWIsYUFBYSxDQUFzQztRQU45RCxpQkFBWSxHQUFtQixJQUFJLENBQUM7UUFRekMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sdUJBQXVCLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUQsTUFBTSxDQUFDLHVCQUF1QixLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixDQUN6QyxJQUFJLEVBQ0osdUJBQXVCLENBQ3pCLENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckQsSUFDRyxNQUFNLFlBQVksVUFBVTtZQUM1QixNQUFNLENBQUMsYUFBYSxDQUFDLGdCQUFnQixLQUFLLElBQUksRUFDL0M7WUFDQyxhQUFhLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDO1NBQy9CO2FBQU07WUFDSix1QkFBdUIsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7WUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FDVixJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUU7Z0JBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTztnQkFDcEIsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTTthQUN2QyxDQUFDLENBQ0osQ0FBQztZQUNGLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUN4QjtRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsaUZBQWlGO0lBQzFFLFFBQVE7UUFDWixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxPQUFPO1FBQ1gsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1NBQ2hFO1FBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2IsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGtEQUFrRDtJQUMzQyxhQUFhO1FBQ2pCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksUUFBUSxDQUFDLEtBQW1DO1FBQ2hELElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTTtRQUNWLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksU0FBUyxDQUFDLEtBQWE7UUFDM0IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQseUVBQXlFO0lBQ2xFLG9CQUFvQjtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw0REFBNEQsQ0FDOUQsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUN2RCxDQUFDO0lBRUQsK0VBQStFO0lBQ3hFLG9CQUFvQjtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw0REFBNEQsQ0FDOUQsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUN2RCxDQUFDO0lBRUQsc0VBQXNFO0lBQy9ELFdBQVc7UUFDZixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw2REFBNkQsQ0FDL0QsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVELDREQUE0RDtJQUNyRCxnQkFBZ0I7UUFDcEIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsd0RBQXdELENBQzFELENBQUM7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSx1QkFBdUI7UUFHM0IsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsNERBQTRELENBQzlELENBQUM7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDMUQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ0ksT0FBTyxDQUNYLFNBQXNDLEVBQ3RDLEtBQWM7UUFFZCxJQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5QixJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUU7WUFDekIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ2Y7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN6QixNQUFNLFFBQVEsR0FBRyxLQUFLLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUN0RCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxRQUFRLENBQ1YsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLEtBQUssRUFBRSxJQUFJO1lBQ1gsS0FBSyxFQUFFLFFBQVE7U0FDakIsQ0FBQyxDQUNKLENBQUM7UUFDRixPQUFPLFFBQVEsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksSUFBSSxDQUNSLFNBQWtDLEVBQ2xDLE9BQTBDO1FBRTFDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3JCLE1BQU0sSUFBSSxTQUFTLENBQUMsaURBQWlELENBQUMsQ0FBQztTQUN6RTtRQUNELElBQUk7WUFDRCxPQUFPLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7U0FDekQ7UUFBQyxPQUFPLEtBQWMsRUFBRTtZQUN0QixJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbEM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksS0FBSztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLE9BQU8sU0FBUyxDQUFDO1NBQ25CO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU87YUFDdEIsUUFBUSxFQUFFO2FBQ1YsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNuQixPQUFPLEtBQUssQ0FBQztJQUNoQixDQUFDO0lBRUQsb0VBQW9FO0lBQzdELFdBQVc7UUFDZixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxJQUFJO1FBQ1IsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTTtRQUNWLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTJCRztJQUNJLElBQUk7UUFDUixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNJLFFBQVE7UUFDWixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFO1lBQ3RCLE1BQU0sSUFBSSxTQUFTLENBQ2hCLHNEQUFzRCxDQUN4RCxDQUFDO1NBQ0o7UUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksVUFBVSxFQUFFO1lBQ3JDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDL0MsT0FBTyxDQUFDLEdBQUcsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3BDO1FBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxLQUFLO1FBQ1QsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQzlEO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQUUsT0FBTztRQUN4RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUNoRCxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxRQUFRLENBQ1YsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsS0FBSyxFQUFFLElBQUk7WUFDWCxLQUFLLEVBQUUsS0FBSztTQUNkLENBQUMsQ0FDSixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLElBQUk7UUFDUixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0IsSUFBSSxNQUFNLFlBQVksVUFBVSxFQUFFO1lBQy9CLE9BQU8sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsTUFBTSxDQUFDLE1BQU0sWUFBWSxRQUFRLElBQUksTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQzNELE9BQU8sTUFBTSxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFFBQVEsQ0FDWixRQUF1RDtRQUV2RCxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRU8sMEJBQTBCLENBQy9CLFNBQXNDLEVBQ3RDLEtBQWM7UUFFZCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxJQUFJLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUMxQixNQUFNLElBQUksU0FBUyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7U0FDakU7UUFDRCxJQUNHLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFDekIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDekM7WUFDQyxNQUFNLElBQUksU0FBUyxDQUNoQixnQ0FBZ0MsS0FBSywrQkFBK0IsQ0FDdEUsQ0FBQztTQUNKO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3BCLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtnQkFDckIsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsK0RBQStELENBQ2pFLENBQUM7YUFDSjtRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUVPLG1CQUFtQixDQUFDLEtBQWM7UUFDdkMsd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSxxRUFBcUU7UUFDckUsdUNBQXVDO1FBQ3ZDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVPLGlCQUFpQixDQUN0QixNQUFtQyxFQUNuQyxLQUFhO1FBRWIsT0FBTyxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ3hELENBQUM7SUFFTyxnQkFBZ0I7UUFDckIsNExBQTRMO1FBQzVMLElBQUksSUFBSSxHQUFnQyxJQUFJLENBQUM7UUFDN0MsT0FBTyxJQUFJLFlBQVksVUFBVSxFQUFFO1lBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixJQUFJLE1BQU0sS0FBSyxTQUFTO2dCQUFFLE1BQU07WUFDaEMsSUFBSSxHQUFHLE1BQU0sQ0FBQztTQUNoQjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2YsQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFjO1FBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQ25DLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUN0RCxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0IsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRU8sY0FBYztRQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQztRQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pDLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtZQUNyQixPQUFPO1NBQ1Q7UUFDRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQjthQUM3QyxnQkFBZ0IsRUFBRTthQUNsQixzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQzthQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDWixNQUFNLENBQUMsbUJBQW1CLFlBQVksV0FBVyxDQUFDLENBQUM7UUFDbkQsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHLE9BQU8sRUFBRSxXQUFXLElBQUksRUFBRSxJQUFJLENBQUM7SUFDNUUsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uLy4uL3NoYXJlZFwiO1xuaW1wb3J0IHR5cGUgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB0eXBlIHtcbiAgIENvbXBvbmVudFJlZixcbiAgIFR5cGUsXG4gICBWaWV3Q29udGFpbmVyUmVmLFxuICAgVmlld1JlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQnJhbmNoQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudHNcIjtcbmltcG9ydCB7IFRyZWVFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB7IGRyb3B6b25lUmVuZGVyZXIgfSBmcm9tIFwiLi4vLi4vZXh0cmFzL2RyYWctYW5kLWRyb3BcIjtcbmltcG9ydCB7IFRyZWVSb290IH0gZnJvbSBcIi4uL3RyZWUtcm9vdFwiO1xuaW1wb3J0IHR5cGUgeyBUcmVlTm9kZSB9IGZyb20gXCIuLi90cmVlLW5vZGUuaW50ZXJmYWNlXCI7XG5pbXBvcnQgdHlwZSB7IFRyZWVQbG90IH0gZnJvbSBcIi4uL3RyZWUtcGxvdC5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRyZWVOb2RlQmFzZSB9IGZyb20gXCIuLi90cmVlLW5vZGUtYmFzZVwiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4uL2NvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB0eXBlIHtcbiAgIEJyYW5jaE9wdGlvbnMsXG4gICBGdWxsQnJhbmNoT3B0aW9uc1xufSBmcm9tIFwiLi4vYnJhbmNoLW9wdGlvbnMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBCcmFuY2hDb250cm9sbGVyIH0gZnJvbSBcIi4vYnJhbmNoLWNvbnRyb2xsZXJcIjtcbmltcG9ydCB0eXBlIHsgR3JhZnRhYmxlIH0gZnJvbSBcIi4vZ3JhZnRhYmxlLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgdHJlZUNvbGxhcHNlciB9IGZyb20gXCIuLi8uLi9leHRyYXMvY29sbGFwc2VcIjtcbmltcG9ydCB7XG4gICBEZXN0cnVjdGlvbkV2ZW50LFxuICAgR3JhZnRFdmVudCxcbiAgIFBydW5lRXZlbnQsXG4gICB0eXBlIFRyZWVFdmVudFxufSBmcm9tIFwiLi4vLi4vZXZlbnRzXCI7XG5cbi8qKiBSZXByZXNlbnRzIGEgc3RhbmRhcmQgbm9kZSBpbiBhIHRyZWUuIFJlbmRlcnMgYSBCcmFuY2hDb21wb25lbnQuXG4gKlxuICogQHJlbWFya3NcbiAqIFRoaXMgY2xhc3MgcmVuZGVycyBhIGJyYW5jaCBjb21wb25lbnQsIHdoaWNoIGRvZXMgdGhlIGZvbGxvd2luZzpcbiAqIDEuIFJlbmRlcnMgYSBjb21wb25lbnQgcHJvdmlkZWQgYnkgdGhlIHVzZXJcbiAqIDIuIFByb3ZpZGVzIGEgY29udGFpbmVyIGluIHdoaWNoIGNoaWxkIGJyYW5jaGVzIG1heSBiZSByZW5kZXJlZFxuICogMy4gQ29udGFpbnMgdHdvIERyb3B6b25lczogb25lIGZvciBkcm9wcGluZyBicmFuY2hlcyBiZWxvdyB0aGlzIGJyYW5jaCAoYXMgYVxuICogc2libGluZyksIGFuZCBvbmUgZm9yIGRyb3BwaW5nIGJyYW5jaGVzIGFzIGEgZmlyc3QgY2hpbGQgb2YgdGhpcyBicmFuY2guXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgaW1wbGVtZW50cyBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4sIEdyYWZ0YWJsZTxVc2VybGFuZENvbXBvbmVudD5cbntcbiAgIHByaXZhdGUgcmVhZG9ubHkgYnJhbmNoQ29udHJvbGxlcjogQnJhbmNoQ29udHJvbGxlcjxVc2VybGFuZENvbXBvbmVudD47XG4gICBwcml2YXRlIGRldGFjaGVkVmlldzogVmlld1JlZiB8IG51bGwgPSBudWxsO1xuICAgcHJpdmF0ZSBfcGFyZW50OiBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQ7XG4gICBwcml2YXRlIHJlYWRvbmx5IHRyZWVOb2RlQmFzZTogVHJlZU5vZGVCYXNlPFVzZXJsYW5kQ29tcG9uZW50PjtcblxuICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgcGFyZW50OiBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYnJhbmNoT3B0aW9uczogRnVsbEJyYW5jaE9wdGlvbnM8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApIHtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlID0gbmV3IFRyZWVOb2RlQmFzZSgpO1xuICAgICAgY29uc3QgcGFyZW50QnJhbmNoZXNDb250YWluZXIgPSBwYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChwYXJlbnRCcmFuY2hlc0NvbnRhaW5lciAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlciA9IG5ldyBCcmFuY2hDb250cm9sbGVyKFxuICAgICAgICAgdGhpcyxcbiAgICAgICAgIHBhcmVudEJyYW5jaGVzQ29udGFpbmVyXG4gICAgICApO1xuICAgICAgY29uc3QgaG9zdFZpZXcgPSB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0SG9zdFZpZXcoKTtcbiAgICAgIGlmIChcbiAgICAgICAgIHBhcmVudCBpbnN0YW5jZW9mIFRyZWVCcmFuY2ggJiZcbiAgICAgICAgIHBhcmVudC5icmFuY2hPcHRpb25zLmRlZmF1bHRDb2xsYXBzZWQgPT09IHRydWVcbiAgICAgICkge1xuICAgICAgICAgdHJlZUNvbGxhcHNlci5zdG9yZVByZWNvbGxhcHNlZE5vZGUocGFyZW50LCB0aGlzKTtcbiAgICAgICAgIHRoaXMuZGV0YWNoZWRWaWV3ID0gaG9zdFZpZXc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgcGFyZW50QnJhbmNoZXNDb250YWluZXIuaW5zZXJ0KGhvc3RWaWV3KTtcbiAgICAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgICAgICAgIHRoaXMuZGlzcGF0Y2goXG4gICAgICAgICAgICBuZXcgR3JhZnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICBwYXJlbnQ6IHRoaXMuX3BhcmVudCxcbiAgICAgICAgICAgICAgIGNoaWxkOiB0aGlzLFxuICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuX3BhcmVudC5icmFuY2hlcygpLmxlbmd0aFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICk7XG4gICAgICAgICB0aGlzLnNldEluZGVudGF0aW9uKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIEFsbCBjaGlsZCBicmFuY2hlcyBhcyBhbiBhcnJheSBvZiBUcmVlQnJhbmNoIGluc3RhbmNlcywgaW4gb3JkZXIuICovXG4gICBwdWJsaWMgYnJhbmNoZXMoKTogQXJyYXk8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5icmFuY2hlcygpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFJlY3Vyc2l2ZWx5IGRlc3Ryb3lzIGFsbCBkZXNjZW5kYW50IGJyYW5jaGVzLCBhcyB3ZWxsIGFzIGl0c2VsZi4gVGhpc1xuICAgICogcmVsZWFzZXMgYWxsIHJlc291cmNlcyBoZWxkIG9yIGNvbnN1bWVkIGJ5IHRoaXMgYnJhbmNoIGFuZCBpdHMgZGVzY2VuZGFudHMuXG4gICAgKlxuICAgICogQHJlbWFya3NcbiAgICAqIEl0IGlzIGltcG9ydGFudCB0byBjYWxsIHRoaXMgbWV0aG9kIHdoZW4gYSBicmFuY2ggaXMgZGlzY2FyZGVkLCBvdGhlcndpc2VcbiAgICAqIHRoZSBicmFuY2ggd2lsbCByZW1haW4gaW4gbWVtb3J5IGFuZCBjb250aW51ZSB0byBjb25zdW1lIHJlc291cmNlcy5cbiAgICAqL1xuICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGRlc3Ryb3kgYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnBydW5lKCk7XG4gICAgICB0cmVlQ29sbGFwc2VyLmV4cGFuZCh0aGlzKTtcbiAgICAgIGRyb3B6b25lUmVuZGVyZXIuY2xlYXJUcmVlRnJvbVJlZ2lzdHJ5KHRoaXMpO1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEhvc3RWaWV3KCkuZGVzdHJveSgpO1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGVzdHJveSgpO1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2gobmV3IERlc3RydWN0aW9uRXZlbnQodGhpcykpO1xuICAgfVxuXG4gICAvKiogUnVuIEFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvbiBvbiB0aGlzIGJyYW5jaCAqL1xuICAgcHVibGljIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgICB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEVtaXRzIHRoZSBzcGVjaWZpZWQgVHJlZUV2ZW50LlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBDYXV0aW9uOiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gbWFudWFsbHkgZW1pdCBUcmVlRXZlbnRzIHRoYXQgYXJlIGFscmVhZHlcbiAgICAqIHByb3ZpZGVkIGJ5IHRoZSBsaWJyYXJ5LiBGb3IgZXhhbXBsZSwgaXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGVtaXQgYVxuICAgICogYEdyYWZ0RXZlbnRgLCBgRGVzdHJ1Y3Rpb25FdmVudGAsIGV0Yy4gVGhlc2UgZXZlbnRzIG1heSBiZSB1c2VkIGJ5IHRoZSB0cmVlLFxuICAgICogYW5kIGVtaXR0aW5nIHRoZW0gbWFudWFsbHkgbWF5IGNhdXNlIHVuZXhwZWN0ZWQgYmVoYXZpb3IuIEluc3RlYWQsIHdlXG4gICAgKiByZWNvbW1lbmQgaW1wbGVtZW50aW5nIHRoZSBUcmVlRXZlbnQgaW50ZXJmYWNlIHdpdGggeW91ciBvd24gY3VzdG9tIGV2ZW50c1xuICAgICogYW5kIGRpc3BhdGNoaW5nIHRob3NlLlxuICAgICpcbiAgICAqIEBwYXJhbSBldmVudCAtIFRoZSBUcmVlRXZlbnQgdGhhdCB3aWxsIGJlIGVtaXR0ZWQuXG4gICAgKi9cbiAgIHB1YmxpYyBkaXNwYXRjaChldmVudDogVHJlZUV2ZW50PFVzZXJsYW5kQ29tcG9uZW50Pik6IHZvaWQge1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGlzcGF0Y2goZXZlbnQpO1xuICAgICAgdGhpcy5fcGFyZW50Py5kaXNwYXRjaChldmVudCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQHJldHVybnNcbiAgICAqIEFuIG9ic2VydmFibGUgdGhhdCBlbWl0cyBUcmVlRXZlbnRzIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWRcbiAgICAqIGluIHRoaXMgYnJhbmNoIG9yIGFueSBvZiBpdHMgZGVzY2VuZGFudCBicmFuY2hlcy5cbiAgICAqL1xuICAgcHVibGljIGV2ZW50cygpOiBPYnNlcnZhYmxlPFRyZWVFdmVudDxVc2VybGFuZENvbXBvbmVudD4+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5ldmVudHMoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcGFyYW0gaW5kZXggLSBUaGUgaW5kZXggb2YgdGhlIGNoaWxkIGJyYW5jaCB0byByZXRyaWV2ZS5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIGNoaWxkIGJyYW5jaCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXNcbiAgICAqIG5vIGNoaWxkIGJyYW5jaCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LlxuICAgICovXG4gICBwdWJsaWMgZ2V0QnJhbmNoKGluZGV4OiBudW1iZXIpOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UuZ2V0QnJhbmNoKGluZGV4KTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIFRoZSBWaWV3Q29udGFpbmVyUmVmIGluIHdoaWNoIGNoaWxkIGJyYW5jaGVzIGFyZSByZW5kZXJlZCAqL1xuICAgcHVibGljIGdldEJyYW5jaGVzQ29udGFpbmVyKCk6IFZpZXdDb250YWluZXJSZWYgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBicmFuY2hlcyBjb250YWluZXIgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgfVxuXG4gICAvKiogQHJldHVybnMgVGhlIGluc3RhbmNlIG9mIEJyYW5jaENvbXBvbmVudCB0aGF0IGlzIHJlbmRlcmVkIGJ5IHRoaXMgY2xhc3MuICovXG4gICBwdWJsaWMgZ2V0Q29tcG9uZW50SW5zdGFuY2UoKTogQnJhbmNoQ29tcG9uZW50PFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IGNvbXBvbmVudCBpbnN0YW5jZSBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldENvbXBvbmVudEluc3RhbmNlKCk7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBUaGUgSG9zdCBWaWV3IGluIHdoaWNoIHRoZSBCcmFuY2hDb21wb25lbnQgaXMgcmVuZGVyZWQgKi9cbiAgIHB1YmxpYyBnZXRIb3N0VmlldygpOiBWaWV3UmVmIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgY29tcG9uZW50IGhvc3QgdmlldyBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEhvc3RWaWV3KCk7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBUaGUgQnJhbmNoQ29tcG9uZW50IGFzIGEgbmF0aXZlIEhUTUwgRWxlbWVudCAqL1xuICAgcHVibGljIGdldE5hdGl2ZUVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBuYXRpdmUgZWxlbWVudCBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldE5hdGl2ZUVsZW1lbnQoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcmV0dXJuc1xuICAgICogQSBDb21wb25lbnRSZWYgY29udGFpbmluZyB0aGUgaW5zdGFuY2Ugb2YgdGhlIHVzZXItcHJvdmlkZWRcbiAgICAqIGNvbXBvbmVudCB3aGljaCBpcyByZW5kZXJlZCBieSB0aGlzIGJyYW5jaC5cbiAgICAqL1xuICAgcHVibGljIGdldFVzZXJsYW5kQ29tcG9uZW50UmVmKCk6XG4gICAgICB8IENvbXBvbmVudFJlZjxVc2VybGFuZENvbXBvbmVudD5cbiAgICAgIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgdXNlcmxhbmQgY29tcG9uZW50IGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0VXNlcmxhbmRDb21wb25lbnRSZWYoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBBdHRhY2hlcyBhIGJyYW5jaCB0byBhIG5ldyBwYXJlbnQgbm9kZS5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogSWYgbm90IGFscmVhZHkgcHJ1bmVkLCB0aGlzIG1ldGhvZCBwcnVuZXMgKHJlbW92ZXMpIHRoaXMgYnJhbmNoIGZyb20gaXRzXG4gICAgKiBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSB0cmVlOyB0aGVuIGdyYWZ0cyAocmVhdHRhY2hlcykgaXQgYXMgYSBjaGlsZCBvZiB0aGVcbiAgICAqIHNwZWNpZmllZCBwYXJlbnQgYnJhbmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIElmIG5vIGluZGV4IGlzIHNwZWNpZmllZCxcbiAgICAqIHRoZSBicmFuY2ggaXMgYXBwZW5kZWQgYXMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHBhcmVudC4gVGhpcyBjYXVzZXMgdGhpc1xuICAgICogYnJhbmNoJ3MgYXNzb2NpYXRlZCBCcmFuY2hDb21wb25lbnQgdG8gYmUgcmUtcmVuZGVyZWQgaW4gdGhlIERPTSBhdCB0aGVcbiAgICAqIG5ldyBsb2NhdGlvbi5cbiAgICAqXG4gICAgKiBAcGFyYW0gbmV3UGFyZW50IC0gVGhlIG5ldyBwYXJlbnQgYnJhbmNoIHVudG8gd2hpY2ggdGhpcyBicmFuY2ggd2lsbCBiZSBncmFmdGVkLlxuICAgICogQHBhcmFtIGluZGV4IC0gVGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgYnJhbmNoIHdpbGwgYmUgZ3JhZnRlZC4gSWYgbm90IHNwZWNpZmllZCxcbiAgICAqIHRoaXMgYnJhbmNoIHdpbGwgYmUgYXBwZW5kZWQgYXMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIG5ldyBwYXJlbnQuXG4gICAgKlxuICAgICogQHJldHVybnMgVGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgYnJhbmNoIHdhcyBncmFmdGVkLlxuICAgICovXG4gICBwdWJsaWMgZ3JhZnRUbyhcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IG51bWJlciB7XG4gICAgICB0aGlzLmNoZWNrR3JhZnRMb2NhdGlvblZhbGlkaXR5KG5ld1BhcmVudCwgaW5kZXgpO1xuICAgICAgY29uc3Qgb3duSW5kZXggPSB0aGlzLmluZGV4KCk7XG4gICAgICBpZiAob3duSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgdGhpcy5wcnVuZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fcGFyZW50ID0gbmV3UGFyZW50O1xuICAgICAgY29uc3QgbmV3SW5kZXggPSBpbmRleCA/PyBuZXdQYXJlbnQuYnJhbmNoZXMoKS5sZW5ndGg7XG4gICAgICB0aGlzLnJlYXR0YWNoVmlldyhuZXdJbmRleCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IEdyYWZ0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBuZXdQYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBuZXdJbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gbmV3SW5kZXg7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQXBwZW5kcyBhIG5ldyBjaGlsZCBicmFuY2ggdG8gdGhpcyBicmFuY2guIFRoZSBjaGlsZCBicmFuY2ggd2lsbCByZW5kZXJcbiAgICAqIHRoZSBzcGVjaWZpZWQgY29tcG9uZW50IGFjY29yZGluZyB0byB0aGUgKG9wdGlvbmFsKSBjb25maWd1cmF0aW9uIHBhcmFtZXRlci5cbiAgICAqXG4gICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCB0byByZW5kZXIgaW4gdGhlIG5ldyBjaGlsZCBicmFuY2guXG4gICAgKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIG5ldyBjaGlsZCBicmFuY2guXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBuZXdseS1jcmVhdGVkIGNoaWxkIGJyYW5jaC5cbiAgICAqL1xuICAgcHVibGljIGdyb3coXG4gICAgICBjb21wb25lbnQ6IFR5cGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgb3B0aW9ucz86IEJyYW5jaE9wdGlvbnM8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGdyb3cgYSBicmFuY2ggb24gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIik7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICAgcmV0dXJuIG5ldyBUcmVlQnJhbmNoKHRoaXMsIHsgY29tcG9uZW50LCAuLi5vcHRpb25zIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgIHRoaXMuaGFuZGxlVXNlcmxhbmRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKlxuICAgICogRGV0ZXJtaW5lcyB0aGlzIGJyYW5jaCdzIGluZGV4IGluIHJlbGF0aW9uIHRvIGl0cyBzaWJsaW5nIGJyYW5jaGVzLlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBGb3IgZXhhbXBsZSwgaWYgaXQgaXMgdGhlIGZpcnN0IGNoaWxkIG9mIGl0cyBwYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG4gICAgKiAwLiBJZiBpdCBpcyB0aGUgc2Vjb25kIGNoaWxkIG9mIGl0cyBwYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDEuXG4gICAgKlxuICAgICogSWYgdGhpcyBicmFuY2ggaGFzIG5vIHBhcmVudCwgKGVnLCBpZiB0aGlzIGJyYW5jaCBoYXMgYmVlbiBwcnVuZWQpIHRoaXNcbiAgICAqIG1ldGhvZCB3aWxsIHJldHVybiB1bmRlZmluZWQuXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBpbmRleCBvZiB0aGlzIGJyYW5jaCBpbiByZWxhdGlvbiB0byBpdHMgc2libGluZyBicmFuY2hlcywgb3IgdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgaW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICghdGhpcy5fcGFyZW50KSB7XG4gICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9wYXJlbnRcbiAgICAgICAgIC5icmFuY2hlcygpXG4gICAgICAgICAuZmluZEluZGV4KChicmFuY2gpID0+IGJyYW5jaCA9PT0gdGhpcyk7XG4gICAgICBhc3NlcnQoaW5kZXggPj0gMCk7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGJyYW5jaCBpcyBkZXN0cm95ZWQsIGBmYWxzZWAgb3RoZXJ3aXNlICovXG4gICBwdWJsaWMgaXNEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UuaXNEZXN0cm95ZWQoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIGRhdGEgdGhhdCB3YXMgcGFzc2VkIGludG8gdGhlIGBicmFuY2hPcHRpb25zYCcgYG1ldGFgIHByb3BlcnR5XG4gICAgKiBhdCBjb25zdHJ1Y3Rpb24uXG4gICAgKi9cbiAgIHB1YmxpYyBtZXRhKCk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoT3B0aW9ucy5tZXRhID8/IHt9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEByZXR1cm5zXG4gICAgKiBUaGlzIGJyYW5jaCdzIHBhcmVudCBub2RlICh3aGljaCBtYXkgYmUgYSBUcmVlQnJhbmNoIG9yIFRyZWVSb290KS5cbiAgICAqIElmIHRoaXMgYnJhbmNoIGhhcyBubyBwYXJlbnQsIChlZywgaWYgdGhpcyBicmFuY2ggaGFzIGJlZW4gcHJ1bmVkKSB0aGlzXG4gICAgKiBtZXRob2Qgd2lsbCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgcGFyZW50KCk6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy5fcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFByb3ZpZGVzIGEgbW9kZWwgZGVzY3JpYmluZyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBIG11bHRpLWRpbWVuc2lvbmFsIE1hcCB3aGljaCBkZXNjcmliZXMgdGhlIHNoYXBlIG9mIHRoaXMgYnJhbmNoJ3NcbiAgICAqIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEBleGFtcGxlXG4gICAgKiBBIGJyYW5jaCB3aXRoIG5vIGNoaWxkcmVuIHdpbGwgcmV0dXJuIGFuIGVtcHR5IE1hcC4gQSBicmFuY2ggd2l0aFxuICAgICogYSBzaW5nbGUgY2hpbGQgd2lsbCByZXR1cm4gYSBNYXAgd2l0aCBhIHNpbmdsZSBlbnRyeSwgd2hlcmUgdGhlIGtleSBpcyB0aGUgaW5kZXhcbiAgICAqIG9mIHRoZSBicmFuY2ggKHplcm8pIGFuZCB0aGUgdmFsdWUgaXMgYW4gZW1wdHkgTWFwLiBBIFRyZWUgbGlrZSB0aGlzOlxuICAgICpcbiAgICAqIGBgYFxuICAgICogICAgICAgICAtLS1CcmFuY2gtLS0tLS0tQnJhbmNoXG4gICAgKiAgICAgICAgL1xuICAgICogQnJhbmNoLS0tLS0tLUJyYW5jaFxuICAgICogICAgICAgIFxcXG4gICAgKiAgICAgICAgIC0tLUJyYW5jaFxuICAgICogYGBgXG4gICAgKiBXaWxsIHJldHVybiBhIE1hcCBvZiBtYXRjaGluZyBzaGFwZTpcbiAgICAqIGBgYFxuICAgICogTWFwIHtcbiAgICAqICAgIDA6IE1hcCB7IDA6IE1hcCB7fX0sXG4gICAgKiAgICAxOiBNYXAge30sXG4gICAgKiAgICAyOiBNYXAge31cbiAgICAqIH1cbiAgICAqIGBgYFxuICAgICovXG4gICBwdWJsaWMgcGxvdCgpOiBUcmVlUGxvdCB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UucGxvdCgpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIENhbGN1bGF0ZXMgdGhlIGJyYW5jaCdzIHBvc2l0aW9uIGluIHRoZSB0cmVlIHJlbGF0aXZlIHRvIHRoZSBSb290LlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBUaGUgcG9zaXRpb24gaXMgZGVzY3JpYmVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIHdoZXJlIGVhY2ggbnVtYmVyXG4gICAgKiByZXByZXNlbnRzIHRoZSBpbmRleCBvZiB0aGUgYnJhbmNoIGF0IHRoYXQgbGV2ZWwgb2YgdGhlIHRyZWUuXG4gICAgKlxuICAgICogRm9yIGV4YW1wbGUsIGlmIHRoaXMgYnJhbmNoIGlzIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgUm9vdCwgdGhpcyBtZXRob2RcbiAgICAqIHdpbGwgcmV0dXJuIFswXS4gSWYgdGhpcyBicmFuY2ggaXMgdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgZmlyc3QgY2hpbGRcbiAgICAqIG9mIHRoZSBSb290LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBbMCwgMV0uXG4gICAgKlxuICAgICogSWYgdGhlIGJyYW5jaCBpcyBub3QgcmVsYXRlZCB0byBhIFRyZWVSb290LCAoc3VjaCBhcyB3aGVuIGl0IGhhcyBiZWVuXG4gICAgKiBwcnVuZWQsKSB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBbiBhcnJheSBvZiBudW1iZXJzIHdoaWNoIGRlc2NyaWJlIHRoZSBicmFuY2gncyBwb3NpdGlvbiBpbiB0aGUgdHJlZVxuICAgICogcmVsYXRpdmUgdG8gdGhlIFJvb3QuXG4gICAgKi9cbiAgIHB1YmxpYyBwb3NpdGlvbigpOiBBcnJheTxudW1iZXI+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcImJyYW5jaCBoYXMgbm8gcGFyZW50LiBQb3NpdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9wYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuX3BhcmVudC5wb3NpdGlvbigpO1xuICAgICAgICAgcmV0dXJuIFsuLi5wYXJlbnRQb3NpdGlvbiwgaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtpbmRleF07XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVtb3ZlcyBhIGJyYW5jaCBmcm9tIGl0cyB0cmVlIHdpdGhvdXQgZGVzdHJveWluZyBpdC5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogUmVtb3ZlcyB0aGlzIGJyYW5jaCBmcm9tIGl0cyBwYXJlbnQgYW5kIGRldGFjaGVzIGl0cyBhc3NvY2lhdGVkXG4gICAgKiBCcmFuY2hDb21wb25lbnQgZnJvbSB0aGUgRE9NLiBUaGlzIHB1dHMgdGhlIGJyYW5jaCBpbiBhIFwicHJ1bmVkXCIgc3RhdGUsXG4gICAgKiB3aGljaCBtYXkgYWZmZWN0IHRoZSBiZWhhdmlvciBvZiBvdGhlciBtZXRob2RzLlxuICAgICpcbiAgICAqIEEgcHJ1bmVkIGJyYW5jaCBjYW4gYmUgcmVhdHRhY2hlZCB0byBhbnkgb3RoZXIgbm9kZSB1c2luZyB0aGUgYGdyYWZ0VG9gIG1ldGhvZC5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogSXRzZWxmLCBvciB1bmRlZmluZWQgaWYgaXQgaXMgYWxyZWFkeSBpbiBhIHBydW5lZCBzdGF0ZS5cbiAgICAqL1xuICAgcHVibGljIHBydW5lKCk6IHRoaXMgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBwcnVuZSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuX3BhcmVudDtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQgfHwgcGFyZW50ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudC5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgICAgYXNzZXJ0KGNvbnRhaW5lciAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuZGV0YWNoZWRWaWV3ID0gY29udGFpbmVyLmRldGFjaChpbmRleCk7XG4gICAgICBhc3NlcnQodGhpcy5kZXRhY2hlZFZpZXcgIT09IG51bGwpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcuZGV0YWNoKCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IFBydW5lRXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBwYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBpbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLl9wYXJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdGhpcztcbiAgIH1cblxuICAgLyoqXG4gICAgKiBHZXQgdGhlIHJvb3Qgb2YgdGhlIHRyZWUgdG8gd2hpY2ggdGhpcyBCcmFuY2ggaXMgYXR0YWNoZWQuXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBUcmVlUm9vdCBvZiB0aGUgdHJlZSB0aGlzIGJyYW5jaCBpcyBpbi4gSWYgdGhpcyBicmFuY2ggaXNcbiAgICAqIGRvZXMgbm90IGhhdmUgYSByb290IChzdWNoIGFzIHdoZW4gaXQgaGFzIGJlZW4gcHJ1bmVkKSB0aGlzIG1ldGhvZCB3aWxsXG4gICAgKiByZXR1cm4gdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgcm9vdCgpOiBUcmVlUm9vdDxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQge1xuICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5wYXJlbnQoKTtcbiAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICByZXR1cm4gcGFyZW50LnJvb3QoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlUm9vdCB8fCBwYXJlbnQgPT09IHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm4gcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFRyYXZlcnNlcyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzIGluIGRlcHRoLWZpcnN0IHByZS1vcmRlciwgZXhlY3V0aW5nXG4gICAgKiB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gb24gZWFjaCBub2RlLiBUcmF2ZXJzYWwgaW5jbHVkZXMgdGhpcyBicmFuY2guXG4gICAgKlxuICAgICogQHBhcmFtIGNhbGxiYWNrIC0gQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGVhY2ggbm9kZS5cbiAgICAqL1xuICAgcHVibGljIHRyYXZlcnNlKFxuICAgICAgY2FsbGJhY2s6IChub2RlOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PikgPT4gdm9pZFxuICAgKTogdm9pZCB7XG4gICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlLnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBjaGVja0dyYWZ0TG9jYXRpb25WYWxpZGl0eShcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXdQYXJlbnQuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCB0byBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgdGhpcy5pbmRleElzT3V0T2ZSYW5nZShuZXdQYXJlbnQsIGluZGV4KVxuICAgICAgKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgYENhbm5vdCBncmFmdCBicmFuY2ggYXQgaW5kZXggJHtpbmRleH0gb2YgdGhlIHBhcmVudC4gT3V0IG9mIHJhbmdlLmBcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYXZlcnNlKChub2RlKSA9PiB7XG4gICAgICAgICBpZiAobm9kZSA9PT0gbmV3UGFyZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgICAgXCJDYW5ub3QgZ3JhZnQgYSBicmFuY2ggdG8gaXRzZWxmIG9yIGFueSBvZiBpdHMgb3duIGRlc2NlbmRhbnRzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICB9XG4gICAgICB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBoYW5kbGVVc2VybGFuZEVycm9yKGVycm9yOiB1bmtub3duKTogbmV2ZXIge1xuICAgICAgLy8gV2hlbiBhbiBlcnJvciBvY2N1cnMgaW4gYSB1c2VybGFuZCBjb21wb25lbnQgZHVyaW5nIGEgdHJlZSBvcGVyYXRpb24sXG4gICAgICAvLyBpdCBjYW4gY2F1c2UgdW5kZWZpbmVkLCBiaXphcnJlIGJlaGF2aW9yIGluIHRoZSB0cmVlLiBUbyBwcmV2ZW50IHRoaXMsXG4gICAgICAvLyB3ZSBkZXN0cm95IHRoZSB0cmVlIGFuZCB0aHJvdyBhbiBlcnJvciBpbnN0ZWFkLiBUaGlzIGhlbHBzIHByb3RlY3RcbiAgICAgIC8vIHRoZSBlbmQtdXNlcidzIGRhdGEgZnJvbSBjb3JydXB0aW9uLlxuICAgICAgdGhpcy5mdXJ0aGVzdEFuY2VzdG9yKCkuZGVzdHJveSgpO1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuaGFuZGxlVXNlcmxhbmRFcnJvcihlcnJvcik7XG4gICB9XG5cbiAgIHByaXZhdGUgaW5kZXhJc091dE9mUmFuZ2UoXG4gICAgICBwYXJlbnQ6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PixcbiAgICAgIGluZGV4OiBudW1iZXJcbiAgICk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGluZGV4IDwgMCB8fCBpbmRleCA+IHBhcmVudC5icmFuY2hlcygpLmxlbmd0aDtcbiAgIH1cblxuICAgcHJpdmF0ZSBmdXJ0aGVzdEFuY2VzdG9yKCk6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdHlwZXNjcmlwdC9uby10aGlzLWFsaWFzIC0tIFRoaXMgY29kZSBpcyBmb3IgYW4gaXRlcmF0aW9uLCBub3QgdG8gbWFrZSBgdGhpc2AgYXZhaWxhYmxlIGluIG90aGVyIHNjb3BlcyAod2hpY2ggaXMgd2hhdCB0aGUgcnVsZSBpcyBpbnRlbmRlZCB0byBwcm90ZWN0IGFnYWluc3QpLlxuICAgICAgbGV0IG5vZGU6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiA9IHRoaXM7XG4gICAgICB3aGlsZSAobm9kZSBpbnN0YW5jZW9mIFRyZWVCcmFuY2gpIHtcbiAgICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50KCk7XG4gICAgICAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIGJyZWFrO1xuICAgICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgfVxuXG4gICBwcml2YXRlIHJlYXR0YWNoVmlldyhpbmRleD86IG51bWJlcik6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydCh0aGlzLmRldGFjaGVkVmlldyAhPT0gbnVsbCk7XG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9wYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChjb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmRldGFjaGVkVmlldy5yZWF0dGFjaCgpO1xuICAgICAgY29udGFpbmVyLmluc2VydCh0aGlzLmRldGFjaGVkVmlldywgaW5kZXgpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcgPSBudWxsO1xuICAgICAgdGhpcy5zZXRJbmRlbnRhdGlvbigpO1xuICAgfVxuXG4gICBwcml2YXRlIHNldEluZGVudGF0aW9uKCk6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGNvbnN0IHJvb3QgPSB0aGlzLl9wYXJlbnQucm9vdCgpO1xuICAgICAgaWYgKHJvb3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbmZpZy5nZXRDb25maWcocm9vdCk7XG4gICAgICBjb25zdCBicmFuY2hlc0NvbnRhaW5lckVsID0gdGhpcy5icmFuY2hDb250cm9sbGVyXG4gICAgICAgICAuZ2V0TmF0aXZlRWxlbWVudCgpXG4gICAgICAgICAuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJyYW5jaGVzLWNvbnRhaW5lclwiKVxuICAgICAgICAgLml0ZW0oMCk7XG4gICAgICBhc3NlcnQoYnJhbmNoZXNDb250YWluZXJFbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KTtcbiAgICAgIGJyYW5jaGVzQ29udGFpbmVyRWwuc3R5bGUubWFyZ2luTGVmdCA9IGAke29wdGlvbnM/LmluZGVudGF0aW9uID8/IDE2fXB4YDtcbiAgIH1cbn1cbiJdfQ==
|