@limble/limble-tree 0.12.2 → 0.13.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 (45) hide show
  1. package/README.md +149 -149
  2. package/{esm2015/lib/classes/Branch.js → esm2020/lib/classes/Branch.mjs} +1 -1
  3. package/{esm2015/lib/classes/DropZone.js → esm2020/lib/classes/DropZone.mjs} +1 -1
  4. package/{esm2015/lib/classes/DropZoneLocation.js → esm2020/lib/classes/DropZoneLocation.mjs} +1 -1
  5. package/{esm2015/lib/custom-event-bindings/dragleave-no-change-detect.directive.js → esm2020/lib/custom-event-bindings/dragleave-no-change-detect.directive.mjs} +0 -0
  6. package/{esm2015/lib/custom-event-bindings/dragover-no-change-detect.directive.js → esm2020/lib/custom-event-bindings/dragover-no-change-detect.directive.mjs} +1 -1
  7. package/esm2020/lib/drop-zone/drop-zone.component.mjs +75 -0
  8. package/esm2020/lib/limble-tree-branch/limble-tree-branch.component.mjs +110 -0
  9. package/esm2020/lib/limble-tree-node/limble-tree-node.component.mjs +467 -0
  10. package/{esm2015/lib/limble-tree-placeholder/limble-tree-placeholder.component.js → esm2020/lib/limble-tree-placeholder/limble-tree-placeholder.component.mjs} +3 -8
  11. package/esm2020/lib/limble-tree-root/drop-zone.service.mjs +376 -0
  12. package/esm2020/lib/limble-tree-root/limble-tree-root.component.mjs +172 -0
  13. package/{esm2015/lib/limble-tree-root/tree-construction-status.service.js → esm2020/lib/limble-tree-root/tree-construction-status.service.mjs} +1 -1
  14. package/esm2020/lib/limble-tree-root/tree.service.mjs +297 -0
  15. package/{esm2015/lib/limble-tree.module.js → esm2020/lib/limble-tree.module.mjs} +5 -5
  16. package/{esm2015/lib/singletons/component-creator.service.js → esm2020/lib/singletons/component-creator.service.mjs} +1 -1
  17. package/esm2020/lib/singletons/drag-state.service.mjs +63 -0
  18. package/esm2020/lib/singletons/global-events.service.mjs +136 -0
  19. package/{esm2015/lib/util.js → esm2020/lib/util.mjs} +1 -1
  20. package/{esm2015/limble-limble-tree.js → esm2020/limble-limble-tree.mjs} +0 -0
  21. package/{esm2015/public-api.js → esm2020/public-api.mjs} +1 -1
  22. package/fesm2015/limble-limble-tree.mjs +2256 -0
  23. package/fesm2015/limble-limble-tree.mjs.map +1 -0
  24. package/{fesm2015/limble-limble-tree.js → fesm2020/limble-limble-tree.mjs} +105 -147
  25. package/fesm2020/limble-limble-tree.mjs.map +1 -0
  26. package/{limble-limble-tree.d.ts → index.d.ts} +0 -0
  27. package/lib/custom-event-bindings/dragleave-no-change-detect.directive.d.ts +1 -1
  28. package/lib/custom-event-bindings/dragover-no-change-detect.directive.d.ts +1 -1
  29. package/lib/drop-zone/drop-zone.component.d.ts +1 -1
  30. package/lib/limble-tree-branch/limble-tree-branch.component.d.ts +1 -1
  31. package/lib/limble-tree-node/limble-tree-node.component.d.ts +1 -1
  32. package/lib/limble-tree-placeholder/limble-tree-placeholder.component.d.ts +1 -1
  33. package/lib/limble-tree-root/limble-tree-root.component.d.ts +1 -1
  34. package/package.json +24 -10
  35. package/bundles/limble-limble-tree.umd.js +0 -2905
  36. package/bundles/limble-limble-tree.umd.js.map +0 -1
  37. package/esm2015/lib/drop-zone/drop-zone.component.js +0 -81
  38. package/esm2015/lib/limble-tree-branch/limble-tree-branch.component.js +0 -116
  39. package/esm2015/lib/limble-tree-node/limble-tree-node.component.js +0 -484
  40. package/esm2015/lib/limble-tree-root/drop-zone.service.js +0 -372
  41. package/esm2015/lib/limble-tree-root/limble-tree-root.component.js +0 -178
  42. package/esm2015/lib/limble-tree-root/tree.service.js +0 -301
  43. package/esm2015/lib/singletons/drag-state.service.js +0 -64
  44. package/esm2015/lib/singletons/global-events.service.js +0 -137
  45. package/fesm2015/limble-limble-tree.js.map +0 -1
@@ -1,178 +0,0 @@
1
- import { Component, EventEmitter, Input, NgZone, Output, ViewChild, ViewContainerRef } from "@angular/core";
2
- import { DropZoneService } from "./drop-zone.service";
3
- import { TreeService } from "./tree.service";
4
- import { isElementDescendant, isFirefox } from "../util";
5
- import { first } from "rxjs/operators";
6
- import { TreeConstructionStatus } from "./tree-construction-status.service";
7
- import * as i0 from "@angular/core";
8
- import * as i1 from "./tree.service";
9
- import * as i2 from "./drop-zone.service";
10
- import * as i3 from "../singletons/drag-state.service";
11
- import * as i4 from "../singletons/global-events.service";
12
- import * as i5 from "../custom-event-bindings/dragover-no-change-detect.directive";
13
- import * as i6 from "../custom-event-bindings/dragleave-no-change-detect.directive";
14
- import * as i7 from "@angular/common";
15
- import * as i8 from "../limble-tree-placeholder/limble-tree-placeholder.component";
16
- const _c0 = ["host"];
17
- function LimbleTreeRootComponent_limble_tree_placeholder_1_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelement(0, "limble-tree-placeholder");
19
- } }
20
- function LimbleTreeRootComponent_ng_template_2_Template(rf, ctx) { }
21
- export class LimbleTreeRootComponent {
22
- constructor(treeService, dropZoneService, dragStateService, globalEventsService, ngZone, changeDetectorRef, el) {
23
- this.treeService = treeService;
24
- this.dropZoneService = dropZoneService;
25
- this.dragStateService = dragStateService;
26
- this.globalEventsService = globalEventsService;
27
- this.ngZone = ngZone;
28
- this.changeDetectorRef = changeDetectorRef;
29
- this.el = el;
30
- this.treeChange = new EventEmitter();
31
- this.treeDrop = new EventEmitter();
32
- this.changesSubscription = this.treeService.changes$.subscribe(() => {
33
- //"In dev mode, Angular performs an additional check after each change
34
- //detection run, to ensure the bindings haven’t changed." We use a timeout here
35
- //to preclude the possibility of causing a binding to update in the parent
36
- //component after change detection runs but before the additional check.
37
- //See https://angular.io/errors/NG0100 for details.
38
- setTimeout(() => {
39
- this.treeChange.emit();
40
- });
41
- });
42
- this.dropSubscription = this.treeService.drops$.subscribe((drop) => {
43
- setTimeout(() => {
44
- this.treeDrop.emit(drop);
45
- });
46
- });
47
- this.placeholder = false;
48
- this.treeService.placeholder$.subscribe((value) => {
49
- this.placeholder = value;
50
- if (!NgZone.isInAngularZone()) {
51
- this.changeDetectorRef.detectChanges();
52
- }
53
- });
54
- }
55
- ngAfterViewInit() {
56
- var _a;
57
- if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.listMode) !== true &&
58
- (this.itemsPerPage !== undefined || this.page !== undefined)) {
59
- console.warn("pagination is only allowed in listMode; `itemsPerPage` and `page` inputs will be ignored");
60
- }
61
- this.update();
62
- this.changeDetectorRef.detectChanges();
63
- this.ngZone.runOutsideAngular(() => {
64
- //this is for mac os - without this dragover handler drop events aren't firing correctly
65
- this.el.nativeElement.addEventListener("dragover", (event) => {
66
- event.preventDefault();
67
- });
68
- });
69
- }
70
- ngOnChanges() {
71
- if (this.host !== undefined && this.data !== undefined) {
72
- this.update();
73
- }
74
- }
75
- /** Rebuild the tree */
76
- update() {
77
- if (this.host === undefined) {
78
- throw new Error("Failed to render limble tree. Failure occurred at root.");
79
- }
80
- if (this.data === undefined) {
81
- throw new Error(`limbleTree requires a data object`);
82
- }
83
- this.treeService.init(this.host, this.data, this.options, this.itemsPerPage, this.page);
84
- //We check for firefox here because there is a bug in Firefox that causes the
85
- //custom scrolling to break. See https://bugzilla.mozilla.org/show_bug.cgi?id=505521#c80
86
- if (!isFirefox()) {
87
- this.globalEventsService.addScrolling();
88
- }
89
- }
90
- dragoverHandler(event) {
91
- if (event.dataTransfer === null) {
92
- return;
93
- }
94
- event.stopPropagation();
95
- event.preventDefault();
96
- event.dataTransfer.dropEffect = "move";
97
- }
98
- dragleaveHandler(event) {
99
- const currentTarget = event.currentTarget;
100
- const relatedTarget = event.relatedTarget;
101
- if (!(currentTarget instanceof Node) ||
102
- !(relatedTarget instanceof Node) ||
103
- isElementDescendant(currentTarget, relatedTarget) !== false) {
104
- //event came from deeper in the tree. Ignore it.
105
- return;
106
- }
107
- //Mouse has left the tree, so clear the drop zones
108
- this.dropZoneService.clearVisibleZones();
109
- this.changeDetectorRef.detectChanges();
110
- }
111
- dropHandler(event) {
112
- event.stopPropagation();
113
- if (this.dragStateService.getState() !== "droppable") {
114
- return;
115
- }
116
- const sourceBranch = this.dragStateService.capture();
117
- if (sourceBranch === undefined) {
118
- throw new Error("failed to get current branch in dragendHandler");
119
- }
120
- const dropZone = this.dropZoneService.getActiveDropZone();
121
- if (dropZone === null) {
122
- throw new Error("failed to get active drop zone at drop handler");
123
- }
124
- this.treeService.captured = true;
125
- this.dragStateService.state$
126
- .pipe(first((message) => message === "idle"))
127
- .subscribe(() => {
128
- this.treeService.captured = false;
129
- });
130
- this.dropZoneService.clearVisibleZones();
131
- this.treeService.drop(sourceBranch, dropZone.getFullInsertCoordinates());
132
- }
133
- ngOnDestroy() {
134
- this.changesSubscription.unsubscribe();
135
- this.dropSubscription.unsubscribe();
136
- }
137
- }
138
- LimbleTreeRootComponent.ɵfac = function LimbleTreeRootComponent_Factory(t) { return new (t || LimbleTreeRootComponent)(i0.ɵɵdirectiveInject(i1.TreeService), i0.ɵɵdirectiveInject(i2.DropZoneService), i0.ɵɵdirectiveInject(i3.DragStateService), i0.ɵɵdirectiveInject(i4.GlobalEventsService), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.ElementRef)); };
139
- LimbleTreeRootComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LimbleTreeRootComponent, selectors: [["limble-tree-root"]], viewQuery: function LimbleTreeRootComponent_Query(rf, ctx) { if (rf & 1) {
140
- i0.ɵɵviewQuery(_c0, 5, ViewContainerRef);
141
- } if (rf & 2) {
142
- let _t;
143
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.host = _t.first);
144
- } }, inputs: { data: "data", options: "options", itemsPerPage: "itemsPerPage", page: "page" }, outputs: { treeChange: "treeChange", treeDrop: "treeDrop" }, features: [i0.ɵɵProvidersFeature([TreeService, DropZoneService, TreeConstructionStatus]), i0.ɵɵNgOnChangesFeature], decls: 4, vars: 1, consts: [[1, "tree-event-host", 3, "dragoverNoChangeDetect", "dragleaveNoChangeDetect", "drop"], [4, "ngIf"], ["host", ""]], template: function LimbleTreeRootComponent_Template(rf, ctx) { if (rf & 1) {
145
- i0.ɵɵelementStart(0, "div", 0);
146
- i0.ɵɵlistener("dragoverNoChangeDetect", function LimbleTreeRootComponent_Template_div_dragoverNoChangeDetect_0_listener($event) { return ctx.dragoverHandler($event); })("dragleaveNoChangeDetect", function LimbleTreeRootComponent_Template_div_dragleaveNoChangeDetect_0_listener($event) { return ctx.dragleaveHandler($event); })("drop", function LimbleTreeRootComponent_Template_div_drop_0_listener($event) { return ctx.dropHandler($event); });
147
- i0.ɵɵtemplate(1, LimbleTreeRootComponent_limble_tree_placeholder_1_Template, 1, 0, "limble-tree-placeholder", 1);
148
- i0.ɵɵtemplate(2, LimbleTreeRootComponent_ng_template_2_Template, 0, 0, "ng-template", null, 2, i0.ɵɵtemplateRefExtractor);
149
- i0.ɵɵelementEnd();
150
- } if (rf & 2) {
151
- i0.ɵɵadvance(1);
152
- i0.ɵɵproperty("ngIf", ctx.placeholder === true);
153
- } }, directives: [i5.DragoverNoChangeDetectDirective, i6.DragleaveNoChangeDetectDirective, i7.NgIf, i8.LimbleTreePlaceholderComponent], styles: [""] });
154
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LimbleTreeRootComponent, [{
155
- type: Component,
156
- args: [{
157
- selector: "limble-tree-root",
158
- templateUrl: "./limble-tree-root.component.html",
159
- styleUrls: ["./limble-tree-root.component.scss"],
160
- providers: [TreeService, DropZoneService, TreeConstructionStatus]
161
- }]
162
- }], function () { return [{ type: i1.TreeService }, { type: i2.DropZoneService }, { type: i3.DragStateService }, { type: i4.GlobalEventsService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, { data: [{
163
- type: Input
164
- }], options: [{
165
- type: Input
166
- }], itemsPerPage: [{
167
- type: Input
168
- }], page: [{
169
- type: Input
170
- }], host: [{
171
- type: ViewChild,
172
- args: ["host", { read: ViewContainerRef }]
173
- }], treeChange: [{
174
- type: Output
175
- }], treeDrop: [{
176
- type: Output
177
- }] }); })();
178
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltYmxlLXRyZWUtcm9vdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLXJvb3QvbGltYmxlLXRyZWUtcm9vdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLXJvb3QvbGltYmxlLXRyZWUtcm9vdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0osU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQU10RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUd6RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7Ozs7Ozs7Ozs7OztJQ3BCekUsMENBRTJCOzs7QUQwQjlCLE1BQU0sT0FBTyx1QkFBdUI7SUFvQmpDLFlBQ29CLFdBQXdCLEVBQ3hCLGVBQWdDLEVBQ2hDLGdCQUFrQyxFQUNsQyxtQkFBd0MsRUFDeEMsTUFBYyxFQUNkLGlCQUFvQyxFQUNwQyxFQUF1QjtRQU52QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLE9BQUUsR0FBRixFQUFFLENBQXFCO1FBZnhCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXRDLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBWSxDQUFDO1FBZXhELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2pFLHNFQUFzRTtZQUN0RSwrRUFBK0U7WUFDL0UsMEVBQTBFO1lBQzFFLHdFQUF3RTtZQUN4RSxtREFBbUQ7WUFDbkQsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDYixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDaEUsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDYixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDL0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO2FBQ3pDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsZUFBZTs7UUFDWixJQUNHLENBQUEsTUFBQSxJQUFJLENBQUMsT0FBTywwQ0FBRSxRQUFRLE1BQUssSUFBSTtZQUMvQixDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLEVBQzdEO1lBQ0MsT0FBTyxDQUFDLElBQUksQ0FDVCwwRkFBMEYsQ0FDNUYsQ0FBQztTQUNKO1FBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXZDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2hDLHdGQUF3RjtZQUN4RixJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDMUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsV0FBVztRQUNSLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUU7WUFDckQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2hCO0lBQ0osQ0FBQztJQUVELHVCQUF1QjtJQUNoQixNQUFNO1FBQ1YsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtZQUMxQixNQUFNLElBQUksS0FBSyxDQUNaLHlEQUF5RCxDQUMzRCxDQUFDO1NBQ0o7UUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztTQUN2RDtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUNsQixJQUFJLENBQUMsSUFBSSxFQUNULElBQUksQ0FBQyxJQUFJLEVBQ1QsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsWUFBWSxFQUNqQixJQUFJLENBQUMsSUFBSSxDQUNYLENBQUM7UUFDRiw2RUFBNkU7UUFDN0Usd0ZBQXdGO1FBQ3hGLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNmLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUMxQztJQUNKLENBQUM7SUFFTSxlQUFlLENBQUMsS0FBZ0I7UUFDcEMsSUFBSSxLQUFLLENBQUMsWUFBWSxLQUFLLElBQUksRUFBRTtZQUM5QixPQUFPO1NBQ1Q7UUFDRCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxZQUFZLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztJQUMxQyxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsS0FBZ0I7UUFDckMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQztRQUMxQyxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDO1FBQzFDLElBQ0csQ0FBQyxDQUFDLGFBQWEsWUFBWSxJQUFJLENBQUM7WUFDaEMsQ0FBQyxDQUFDLGFBQWEsWUFBWSxJQUFJLENBQUM7WUFDaEMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxLQUFLLEtBQUssRUFDNUQ7WUFDQyxnREFBZ0Q7WUFDaEQsT0FBTztTQUNUO1FBQ0Qsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVNLFdBQVcsQ0FBQyxLQUFnQjtRQUNoQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLEtBQUssV0FBVyxFQUFFO1lBQ25ELE9BQU87U0FDVDtRQUNELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNyRCxJQUFJLFlBQVksS0FBSyxTQUFTLEVBQUU7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1NBQ3BFO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzFELElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7U0FDcEU7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU07YUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxLQUFLLE1BQU0sQ0FBQyxDQUFDO2FBQzVDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDYixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFDTixJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELFdBQVc7UUFDUixJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7OzhGQTFKUyx1QkFBdUI7MEVBQXZCLHVCQUF1QjsrQkFRTixnQkFBZ0I7Ozs7aU1BVmhDLENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxzQkFBc0IsQ0FBQztRQ2hDcEUsOEJBS0M7UUFKRSx5SUFBMEIsMkJBQXVCLElBQUMsOEhBQ3ZCLDRCQUF3QixJQURELHdGQUUxQyx1QkFBbUIsSUFGdUI7UUFLbEQsZ0hBRTJCO1FBQzNCLHlIQUFpQztRQUNwQyxpQkFBTTs7UUFIQyxlQUEwQjtRQUExQiwrQ0FBMEI7O3VGRDJCcEIsdUJBQXVCO2NBTm5DLFNBQVM7ZUFBQztnQkFDUixRQUFRLEVBQUUsa0JBQWtCO2dCQUM1QixXQUFXLEVBQUUsbUNBQW1DO2dCQUNoRCxTQUFTLEVBQUUsQ0FBQyxtQ0FBbUMsQ0FBQztnQkFDaEQsU0FBUyxFQUFFLENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxzQkFBc0IsQ0FBQzthQUNuRTsyT0FJVyxJQUFJO2tCQUFaLEtBQUs7WUFDRyxPQUFPO2tCQUFmLEtBQUs7WUFDRyxZQUFZO2tCQUFwQixLQUFLO1lBQ0csSUFBSTtrQkFBWixLQUFLO1lBRWlELElBQUk7a0JBQTFELFNBQVM7bUJBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1lBSTFCLFVBQVU7a0JBQTVCLE1BQU07WUFFWSxRQUFRO2tCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgIENvbXBvbmVudCxcclxuICAgRWxlbWVudFJlZixcclxuICAgRXZlbnRFbWl0dGVyLFxyXG4gICBJbnB1dCxcclxuICAgTmdab25lLFxyXG4gICBPbkNoYW5nZXMsXHJcbiAgIE9uRGVzdHJveSxcclxuICAgT3V0cHV0LFxyXG4gICBWaWV3Q2hpbGQsXHJcbiAgIFZpZXdDb250YWluZXJSZWZcclxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBEcm9wWm9uZVNlcnZpY2UgfSBmcm9tIFwiLi9kcm9wLXpvbmUuc2VydmljZVwiO1xyXG5pbXBvcnQge1xyXG4gICBMaW1ibGVUcmVlRGF0YSxcclxuICAgTGltYmxlVHJlZU9wdGlvbnMsXHJcbiAgIFRyZWVEcm9wXHJcbn0gZnJvbSBcIi4uL2xpbWJsZS10cmVlLXJvb3QvdHJlZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFRyZWVTZXJ2aWNlIH0gZnJvbSBcIi4vdHJlZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IGlzRWxlbWVudERlc2NlbmRhbnQsIGlzRmlyZWZveCB9IGZyb20gXCIuLi91dGlsXCI7XHJcbmltcG9ydCB7IERyYWdTdGF0ZVNlcnZpY2UgfSBmcm9tIFwiLi4vc2luZ2xldG9ucy9kcmFnLXN0YXRlLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgR2xvYmFsRXZlbnRzU2VydmljZSB9IGZyb20gXCIuLi9zaW5nbGV0b25zL2dsb2JhbC1ldmVudHMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBmaXJzdCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQgeyBUcmVlQ29uc3RydWN0aW9uU3RhdHVzIH0gZnJvbSBcIi4vdHJlZS1jb25zdHJ1Y3Rpb24tc3RhdHVzLnNlcnZpY2VcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICBzZWxlY3RvcjogXCJsaW1ibGUtdHJlZS1yb290XCIsXHJcbiAgIHRlbXBsYXRlVXJsOiBcIi4vbGltYmxlLXRyZWUtcm9vdC5jb21wb25lbnQuaHRtbFwiLFxyXG4gICBzdHlsZVVybHM6IFtcIi4vbGltYmxlLXRyZWUtcm9vdC5jb21wb25lbnQuc2Nzc1wiXSxcclxuICAgcHJvdmlkZXJzOiBbVHJlZVNlcnZpY2UsIERyb3Bab25lU2VydmljZSwgVHJlZUNvbnN0cnVjdGlvblN0YXR1c11cclxufSlcclxuZXhwb3J0IGNsYXNzIExpbWJsZVRyZWVSb290Q29tcG9uZW50XHJcbiAgIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3lcclxue1xyXG4gICBASW5wdXQoKSBkYXRhOiBMaW1ibGVUcmVlRGF0YSB8IHVuZGVmaW5lZDtcclxuICAgQElucHV0KCkgb3B0aW9uczogTGltYmxlVHJlZU9wdGlvbnMgfCB1bmRlZmluZWQ7XHJcbiAgIEBJbnB1dCgpIGl0ZW1zUGVyUGFnZTogbnVtYmVyIHwgdW5kZWZpbmVkO1xyXG4gICBASW5wdXQoKSBwYWdlOiBudW1iZXIgfCB1bmRlZmluZWQ7XHJcblxyXG4gICBAVmlld0NoaWxkKFwiaG9zdFwiLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYgfSkgcHJpdmF0ZSBob3N0OlxyXG4gICAgICB8IFZpZXdDb250YWluZXJSZWZcclxuICAgICAgfCB1bmRlZmluZWQ7XHJcblxyXG4gICBAT3V0cHV0KCkgcmVhZG9ubHkgdHJlZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVsbD4oKTtcclxuXHJcbiAgIEBPdXRwdXQoKSByZWFkb25seSB0cmVlRHJvcCA9IG5ldyBFdmVudEVtaXR0ZXI8VHJlZURyb3A+KCk7XHJcblxyXG4gICBwcml2YXRlIHJlYWRvbmx5IGNoYW5nZXNTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICAgcHJpdmF0ZSByZWFkb25seSBkcm9wU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgIHB1YmxpYyBwbGFjZWhvbGRlcjogYm9vbGVhbjtcclxuXHJcbiAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVTZXJ2aWNlOiBUcmVlU2VydmljZSxcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcm9wWm9uZVNlcnZpY2U6IERyb3Bab25lU2VydmljZSxcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcmFnU3RhdGVTZXJ2aWNlOiBEcmFnU3RhdGVTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGdsb2JhbEV2ZW50c1NlcnZpY2U6IEdsb2JhbEV2ZW50c1NlcnZpY2UsXHJcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgbmdab25lOiBOZ1pvbmUsXHJcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGVsOiBFbGVtZW50UmVmPEVsZW1lbnQ+XHJcbiAgICkge1xyXG4gICAgICB0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24gPSB0aGlzLnRyZWVTZXJ2aWNlLmNoYW5nZXMkLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgIC8vXCJJbiBkZXYgbW9kZSwgQW5ndWxhciBwZXJmb3JtcyBhbiBhZGRpdGlvbmFsIGNoZWNrIGFmdGVyIGVhY2ggY2hhbmdlXHJcbiAgICAgICAgIC8vZGV0ZWN0aW9uIHJ1biwgdG8gZW5zdXJlIHRoZSBiaW5kaW5ncyBoYXZlbuKAmXQgY2hhbmdlZC5cIiBXZSB1c2UgYSB0aW1lb3V0IGhlcmVcclxuICAgICAgICAgLy90byBwcmVjbHVkZSB0aGUgcG9zc2liaWxpdHkgb2YgY2F1c2luZyBhIGJpbmRpbmcgdG8gdXBkYXRlIGluIHRoZSBwYXJlbnRcclxuICAgICAgICAgLy9jb21wb25lbnQgYWZ0ZXIgY2hhbmdlIGRldGVjdGlvbiBydW5zIGJ1dCBiZWZvcmUgdGhlIGFkZGl0aW9uYWwgY2hlY2suXHJcbiAgICAgICAgIC8vU2VlIGh0dHBzOi8vYW5ndWxhci5pby9lcnJvcnMvTkcwMTAwIGZvciBkZXRhaWxzLlxyXG4gICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy50cmVlQ2hhbmdlLmVtaXQoKTtcclxuICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLmRyb3BTdWJzY3JpcHRpb24gPSB0aGlzLnRyZWVTZXJ2aWNlLmRyb3BzJC5zdWJzY3JpYmUoKGRyb3ApID0+IHtcclxuICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudHJlZURyb3AuZW1pdChkcm9wKTtcclxuICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLnBsYWNlaG9sZGVyID0gZmFsc2U7XHJcbiAgICAgIHRoaXMudHJlZVNlcnZpY2UucGxhY2Vob2xkZXIkLnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgICAgdGhpcy5wbGFjZWhvbGRlciA9IHZhbHVlO1xyXG4gICAgICAgICBpZiAoIU5nWm9uZS5pc0luQW5ndWxhclpvbmUoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgfVxyXG5cclxuICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIHRoaXMub3B0aW9ucz8ubGlzdE1vZGUgIT09IHRydWUgJiZcclxuICAgICAgICAgKHRoaXMuaXRlbXNQZXJQYWdlICE9PSB1bmRlZmluZWQgfHwgdGhpcy5wYWdlICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICkge1xyXG4gICAgICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgICAgIFwicGFnaW5hdGlvbiBpcyBvbmx5IGFsbG93ZWQgaW4gbGlzdE1vZGU7IGBpdGVtc1BlclBhZ2VgIGFuZCBgcGFnZWAgaW5wdXRzIHdpbGwgYmUgaWdub3JlZFwiXHJcbiAgICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy51cGRhdGUoKTtcclxuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgIC8vdGhpcyBpcyBmb3IgbWFjIG9zIC0gd2l0aG91dCB0aGlzIGRyYWdvdmVyIGhhbmRsZXIgZHJvcCBldmVudHMgYXJlbid0IGZpcmluZyBjb3JyZWN0bHlcclxuICAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJkcmFnb3ZlclwiLCAoZXZlbnQpID0+IHtcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICB9XHJcblxyXG4gICBuZ09uQ2hhbmdlcygpIHtcclxuICAgICAgaWYgKHRoaXMuaG9zdCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZGF0YSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgIHRoaXMudXBkYXRlKCk7XHJcbiAgICAgIH1cclxuICAgfVxyXG5cclxuICAgLyoqIFJlYnVpbGQgdGhlIHRyZWUgKi9cclxuICAgcHVibGljIHVwZGF0ZSgpIHtcclxuICAgICAgaWYgKHRoaXMuaG9zdCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgICAgICAgXCJGYWlsZWQgdG8gcmVuZGVyIGxpbWJsZSB0cmVlLiBGYWlsdXJlIG9jY3VycmVkIGF0IHJvb3QuXCJcclxuICAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5kYXRhID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBsaW1ibGVUcmVlIHJlcXVpcmVzIGEgZGF0YSBvYmplY3RgKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnRyZWVTZXJ2aWNlLmluaXQoXHJcbiAgICAgICAgIHRoaXMuaG9zdCxcclxuICAgICAgICAgdGhpcy5kYXRhLFxyXG4gICAgICAgICB0aGlzLm9wdGlvbnMsXHJcbiAgICAgICAgIHRoaXMuaXRlbXNQZXJQYWdlLFxyXG4gICAgICAgICB0aGlzLnBhZ2VcclxuICAgICAgKTtcclxuICAgICAgLy9XZSBjaGVjayBmb3IgZmlyZWZveCBoZXJlIGJlY2F1c2UgdGhlcmUgaXMgYSBidWcgaW4gRmlyZWZveCB0aGF0IGNhdXNlcyB0aGVcclxuICAgICAgLy9jdXN0b20gc2Nyb2xsaW5nIHRvIGJyZWFrLiBTZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NTA1NTIxI2M4MFxyXG4gICAgICBpZiAoIWlzRmlyZWZveCgpKSB7XHJcbiAgICAgICAgIHRoaXMuZ2xvYmFsRXZlbnRzU2VydmljZS5hZGRTY3JvbGxpbmcoKTtcclxuICAgICAgfVxyXG4gICB9XHJcblxyXG4gICBwdWJsaWMgZHJhZ292ZXJIYW5kbGVyKGV2ZW50OiBEcmFnRXZlbnQpIHtcclxuICAgICAgaWYgKGV2ZW50LmRhdGFUcmFuc2ZlciA9PT0gbnVsbCkge1xyXG4gICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5kcm9wRWZmZWN0ID0gXCJtb3ZlXCI7XHJcbiAgIH1cclxuXHJcbiAgIHB1YmxpYyBkcmFnbGVhdmVIYW5kbGVyKGV2ZW50OiBEcmFnRXZlbnQpIHtcclxuICAgICAgY29uc3QgY3VycmVudFRhcmdldCA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XHJcbiAgICAgIGNvbnN0IHJlbGF0ZWRUYXJnZXQgPSBldmVudC5yZWxhdGVkVGFyZ2V0O1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgICEoY3VycmVudFRhcmdldCBpbnN0YW5jZW9mIE5vZGUpIHx8XHJcbiAgICAgICAgICEocmVsYXRlZFRhcmdldCBpbnN0YW5jZW9mIE5vZGUpIHx8XHJcbiAgICAgICAgIGlzRWxlbWVudERlc2NlbmRhbnQoY3VycmVudFRhcmdldCwgcmVsYXRlZFRhcmdldCkgIT09IGZhbHNlXHJcbiAgICAgICkge1xyXG4gICAgICAgICAvL2V2ZW50IGNhbWUgZnJvbSBkZWVwZXIgaW4gdGhlIHRyZWUuIElnbm9yZSBpdC5cclxuICAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIC8vTW91c2UgaGFzIGxlZnQgdGhlIHRyZWUsIHNvIGNsZWFyIHRoZSBkcm9wIHpvbmVzXHJcbiAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmNsZWFyVmlzaWJsZVpvbmVzKCk7XHJcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICB9XHJcblxyXG4gICBwdWJsaWMgZHJvcEhhbmRsZXIoZXZlbnQ6IERyYWdFdmVudCkge1xyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlU2VydmljZS5nZXRTdGF0ZSgpICE9PSBcImRyb3BwYWJsZVwiKSB7XHJcbiAgICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBzb3VyY2VCcmFuY2ggPSB0aGlzLmRyYWdTdGF0ZVNlcnZpY2UuY2FwdHVyZSgpO1xyXG4gICAgICBpZiAoc291cmNlQnJhbmNoID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmFpbGVkIHRvIGdldCBjdXJyZW50IGJyYW5jaCBpbiBkcmFnZW5kSGFuZGxlclwiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBkcm9wWm9uZSA9IHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmdldEFjdGl2ZURyb3Bab25lKCk7XHJcbiAgICAgIGlmIChkcm9wWm9uZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmYWlsZWQgdG8gZ2V0IGFjdGl2ZSBkcm9wIHpvbmUgYXQgZHJvcCBoYW5kbGVyXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudHJlZVNlcnZpY2UuY2FwdHVyZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLmRyYWdTdGF0ZVNlcnZpY2Uuc3RhdGUkXHJcbiAgICAgICAgIC5waXBlKGZpcnN0KChtZXNzYWdlKSA9PiBtZXNzYWdlID09PSBcImlkbGVcIikpXHJcbiAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLmNhcHR1cmVkID0gZmFsc2U7XHJcbiAgICAgICAgIH0pO1xyXG4gICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5jbGVhclZpc2libGVab25lcygpO1xyXG4gICAgICB0aGlzLnRyZWVTZXJ2aWNlLmRyb3Aoc291cmNlQnJhbmNoLCBkcm9wWm9uZS5nZXRGdWxsSW5zZXJ0Q29vcmRpbmF0ZXMoKSk7XHJcbiAgIH1cclxuXHJcbiAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICB0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgdGhpcy5kcm9wU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgIH1cclxufVxyXG4iLCI8ZGl2XHJcbiAgIChkcmFnb3Zlck5vQ2hhbmdlRGV0ZWN0KT1cImRyYWdvdmVySGFuZGxlcigkZXZlbnQpXCJcclxuICAgKGRyYWdsZWF2ZU5vQ2hhbmdlRGV0ZWN0KT1cImRyYWdsZWF2ZUhhbmRsZXIoJGV2ZW50KVwiXHJcbiAgIChkcm9wKT1cImRyb3BIYW5kbGVyKCRldmVudClcIlxyXG4gICBjbGFzcz1cInRyZWUtZXZlbnQtaG9zdFwiXHJcbj5cclxuICAgPGxpbWJsZS10cmVlLXBsYWNlaG9sZGVyXHJcbiAgICAgICpuZ0lmPVwicGxhY2Vob2xkZXIgPT09IHRydWVcIlxyXG4gICA+PC9saW1ibGUtdHJlZS1wbGFjZWhvbGRlcj5cclxuICAgPG5nLXRlbXBsYXRlICNob3N0PjwvbmctdGVtcGxhdGU+XHJcbjwvZGl2PlxyXG4iXX0=
@@ -1,301 +0,0 @@
1
- import { Injectable } from "@angular/core";
2
- import { Branch } from "../classes/Branch";
3
- import { LimbleTreeNodeComponent } from "../limble-tree-node/limble-tree-node.component";
4
- import { BehaviorSubject, EMPTY, Subject } from "rxjs";
5
- import { arraysAreEqual } from "../util";
6
- import { debounce, debounceTime, filter, tap } from "rxjs/operators";
7
- import * as i0 from "@angular/core";
8
- import * as i1 from "../singletons/component-creator.service";
9
- import * as i2 from "./drop-zone.service";
10
- import * as i3 from "../singletons/drag-state.service";
11
- import * as i4 from "./tree-construction-status.service";
12
- /** The default value for the `indent` option */
13
- export const INDENT = 45;
14
- export class TreeService {
15
- constructor(componentCreatorService, dropZoneService, dragStateService, treeConstructionStatus) {
16
- this.componentCreatorService = componentCreatorService;
17
- this.dropZoneService = dropZoneService;
18
- this.dragStateService = dragStateService;
19
- this.treeConstructionStatus = treeConstructionStatus;
20
- this.changes$ = new Subject();
21
- this.drops$ = new Subject();
22
- this.treeModel = new Branch(null);
23
- this.placeholder = false;
24
- this.captured = false;
25
- this.cleanupSignal$ = new Subject();
26
- let rebuild = false;
27
- let treeIsStable = false;
28
- const treeIsStable$ = this.treeConstructionStatus.stable$.pipe(tap((value) => {
29
- treeIsStable = value;
30
- }), filter((value) => value === true));
31
- this.cleanupSignal$
32
- .pipe(tap((value) => {
33
- rebuild = value;
34
- }), debounce(() => {
35
- if (treeIsStable === true) {
36
- //If tree is stable, continue right away
37
- return EMPTY;
38
- }
39
- //If tree is not stable, wait for it to become so.
40
- return treeIsStable$;
41
- }),
42
- //We use this timed debounce to throttle chained destruction of components
43
- debounceTime(5))
44
- .subscribe(() => {
45
- this.cleanup(rebuild);
46
- rebuild = false;
47
- });
48
- this.placeholder$ = new BehaviorSubject(false);
49
- this.placeholder$.subscribe((value) => {
50
- this.placeholder = value;
51
- });
52
- }
53
- drop(source, targetCoordinates) {
54
- var _a;
55
- //prep
56
- const sourceParent = source.getParent();
57
- if (sourceParent === null) {
58
- throw new Error("can't drop root of tree");
59
- }
60
- const sourceIndex = source.getIndex();
61
- if (sourceIndex === undefined || sourceIndex === null) {
62
- throw new Error("Cannot move the hidden root node");
63
- }
64
- let targetParentCoordinates;
65
- let newIndex;
66
- if (this.placeholder === true) {
67
- targetParentCoordinates = [];
68
- newIndex = 0;
69
- }
70
- else {
71
- targetParentCoordinates = [...targetCoordinates];
72
- newIndex = targetParentCoordinates.pop();
73
- }
74
- if (newIndex === undefined) {
75
- throw new Error("target coordinates are empty");
76
- }
77
- const targetParent = this.treeModel.getDescendant(targetParentCoordinates);
78
- if (targetParent === undefined) {
79
- throw new Error("could not get to target");
80
- }
81
- const target = this.dropZoneService.getDropZone(targetCoordinates);
82
- const targetIndex = target === null || target === void 0 ? void 0 : target.getLocation().insertIndex;
83
- const targetHost = target === null || target === void 0 ? void 0 : target.getHost();
84
- const sourceHost = (_a = this.dragStateService.getData()) === null || _a === void 0 ? void 0 : _a.parentContainer;
85
- if (this.placeholder === true) {
86
- this.placeholder$.next(false);
87
- }
88
- //Change the treeModel
89
- targetParent.insertChild(source, newIndex);
90
- //Prepare to update the view
91
- if (targetHost === undefined ||
92
- sourceHost === undefined ||
93
- targetIndex === undefined) {
94
- //Hitting this means there is a bug, but not a fatal one.
95
- //Just render the whole tree again.
96
- console.warn("Could not perform a precise update. Re-rendering the entire tree instead");
97
- this.render();
98
- this.changes$.next(null);
99
- return;
100
- }
101
- //Update the view
102
- const nodesInSource = sourceHost.length;
103
- const componentRef = this.componentCreatorService.appendComponent(LimbleTreeNodeComponent, targetHost, newIndex);
104
- componentRef.instance.branch = source;
105
- componentRef.instance.parentHost = targetHost;
106
- if (targetIndex < sourceIndex &&
107
- sourceHost.length > nodesInSource &&
108
- arraysAreEqual(sourceParent.getCoordinates(), targetParentCoordinates)) {
109
- sourceHost.remove(sourceIndex + 1);
110
- }
111
- else {
112
- sourceHost.remove(sourceIndex);
113
- }
114
- //Update the tree data
115
- this.rebuildTreeData();
116
- //Publish drop data
117
- this.drops$.next({
118
- target: source.data,
119
- oldParent: sourceParent.data,
120
- oldIndex: sourceIndex,
121
- newParent: targetParent.data,
122
- newIndex: newIndex
123
- });
124
- this.cleanupSignal$.next(false);
125
- }
126
- /** Initializes the service and renders the tree.
127
- * @param host - The ViewContainerRef into which the tree will be rendered.
128
- * @param data - The data array that was passed in to LimbleTreeRoot, which is
129
- * the users' representation of the tree
130
- * @param options - The options object that was passed in to LimbleTreeRoot
131
- */
132
- init(host, data, options, itemsPerPage, page) {
133
- this.host = host;
134
- this.originalData = data;
135
- this.treeOptions = this.processOptions(options, itemsPerPage, page);
136
- if (this.treeOptions.listMode === true) {
137
- let start = this.treeOptions.itemsPerPage * (this.treeOptions.page - 1);
138
- if (isNaN(start)) {
139
- //This catches the case where itemsPerPage was not passed by the user,
140
- //causing `start` to equal infinity*0, which is NaN.
141
- start = 0;
142
- }
143
- const end = start + this.treeOptions.itemsPerPage;
144
- this.treeData = this.originalData.slice(start, end);
145
- }
146
- else {
147
- this.treeData = [...this.originalData];
148
- }
149
- this.render();
150
- }
151
- cleanup(rebuild = false) {
152
- var _a;
153
- if (rebuild) {
154
- this.rebuildTreeData();
155
- }
156
- if (((_a = this.treeData) === null || _a === void 0 ? void 0 : _a.length) === 0) {
157
- //We do a full render here because it isn't actually any slower
158
- //when there are no nodes, and it is a little more straightforward
159
- this.render();
160
- }
161
- else {
162
- this.changes$.next(null);
163
- this.dropZoneService.update();
164
- }
165
- }
166
- /** Renders the entire tree from root to leaves */
167
- render() {
168
- if (this.host === undefined ||
169
- this.treeData === undefined ||
170
- this.treeOptions === undefined) {
171
- throw new Error("TreeModel not initialized");
172
- }
173
- this.treeConstructionStatus.ready(false);
174
- this.host.clear();
175
- this.dropZoneService.restart();
176
- this.placeholder$.next(false);
177
- this.treeModel = new Branch(null);
178
- if (this.treeData.length === 0) {
179
- //Tree is empty, but we have to to have something there so other trees' items can be dropped into it
180
- this.placeholder$.next(true);
181
- }
182
- else {
183
- for (const node of this.treeData) {
184
- const branch = new Branch(node);
185
- this.treeModel.appendChild(branch);
186
- }
187
- for (const branch of this.treeModel.getChildren()) {
188
- const componentRef = this.componentCreatorService.appendComponent(LimbleTreeNodeComponent, this.host);
189
- componentRef.instance.branch = branch;
190
- componentRef.instance.parentHost = this.host;
191
- //The LimbleTreeNodeComponent will (indirectly) call the `renderBranch` method of this service to render
192
- //its own children
193
- }
194
- }
195
- this.treeConstructionStatus.ready(true);
196
- this.changes$.next(null);
197
- this.dropZoneService.init(this.treeModel, this.treeOptions);
198
- }
199
- /** Renders a branch of the tree and all of its descendants */
200
- renderBranch(host, branch) {
201
- var _a, _b;
202
- if (this.treeModel === undefined) {
203
- throw new Error("TreeModel not initialized");
204
- }
205
- host.clear();
206
- branch.clearChildren();
207
- for (const node of (_b = (_a = branch.data) === null || _a === void 0 ? void 0 : _a.nodes) !== null && _b !== void 0 ? _b : []) {
208
- const newBranch = new Branch(node);
209
- branch.appendChild(newBranch);
210
- const componentRef = this.componentCreatorService.appendComponent(LimbleTreeNodeComponent, host);
211
- componentRef.instance.branch = newBranch;
212
- componentRef.instance.parentHost = host;
213
- //The LimbleTreeNodeComponent will (indirectly) call the `renderBranch` method of this service to render
214
- //its own children
215
- }
216
- }
217
- processOptions(options = {}, itemsPerPage = Infinity, page = 1) {
218
- var _a, _b, _c, _d, _e;
219
- if (options.listMode === true &&
220
- options.allowNesting !== undefined &&
221
- options.allowNesting !== false) {
222
- console.warn("The value of `allowNesting` will be ignored; it must be false when `listMode` is true");
223
- }
224
- const result = {
225
- defaultComponent: options.defaultComponent,
226
- indent: (_a = options.indent) !== null && _a !== void 0 ? _a : INDENT,
227
- allowNesting: options.listMode !== true && ((_b = options.allowNesting) !== null && _b !== void 0 ? _b : true),
228
- allowDragging: (_c = options.allowDragging) !== null && _c !== void 0 ? _c : true,
229
- allowDrop: (_d = options.allowDrop) !== null && _d !== void 0 ? _d : (() => true),
230
- listMode: (_e = options.listMode) !== null && _e !== void 0 ? _e : false,
231
- itemsPerPage: options.listMode ? itemsPerPage : undefined,
232
- page: options.listMode ? page : undefined
233
- };
234
- return result;
235
- }
236
- rebuildTreeData() {
237
- if (this.originalData === undefined ||
238
- this.treeData === undefined ||
239
- this.treeOptions === undefined ||
240
- this.host === undefined) {
241
- throw new Error("Tree data not initialized");
242
- }
243
- this.treeData = [];
244
- for (const branch of this.treeModel.getChildren()) {
245
- this.treeData.push(this.rebuildBranch(branch));
246
- }
247
- if (this.treeOptions.listMode === true &&
248
- this.treeOptions.itemsPerPage < Infinity) {
249
- const itemsPerPage = this.treeOptions.itemsPerPage;
250
- const start = itemsPerPage * (this.treeOptions.page - 1);
251
- this.originalData.splice(start, itemsPerPage, ...this.treeData);
252
- if (this.treeData.length !== itemsPerPage) {
253
- let action = false;
254
- if (this.treeData.length < itemsPerPage &&
255
- start + itemsPerPage <= this.originalData.length) {
256
- //The current page does not have enough nodes. Add some to the view from the next page.
257
- const count = itemsPerPage - this.treeData.length;
258
- for (let index = itemsPerPage - 1; index < itemsPerPage + count - 1; index++) {
259
- const branch = new Branch(this.originalData[start + index]);
260
- this.treeModel.appendChild(branch);
261
- const componentRef = this.componentCreatorService.appendComponent(LimbleTreeNodeComponent, this.host);
262
- componentRef.instance.branch = branch;
263
- componentRef.instance.parentHost = this.host;
264
- }
265
- action = true;
266
- }
267
- else if (this.treeData.length > itemsPerPage) {
268
- //The current page has too many nodes. Remove some of them from the view.
269
- const count = this.treeData.length - itemsPerPage;
270
- for (let index = itemsPerPage + count - 1; index >= itemsPerPage; index--) {
271
- this.treeModel.removeChild(index);
272
- this.host.remove(index);
273
- }
274
- action = true;
275
- }
276
- if (action === true) {
277
- const end = start + itemsPerPage;
278
- this.treeData = this.originalData.slice(start, end);
279
- }
280
- }
281
- }
282
- else {
283
- this.originalData.length = 0;
284
- this.originalData.push(...this.treeData);
285
- }
286
- }
287
- rebuildBranch(branch) {
288
- const temp = branch.data;
289
- temp.nodes = [];
290
- for (const child of branch.getChildren()) {
291
- temp.nodes.push(this.rebuildBranch(child));
292
- }
293
- return temp;
294
- }
295
- }
296
- TreeService.ɵfac = function TreeService_Factory(t) { return new (t || TreeService)(i0.ɵɵinject(i1.ComponentCreatorService), i0.ɵɵinject(i2.DropZoneService), i0.ɵɵinject(i3.DragStateService), i0.ɵɵinject(i4.TreeConstructionStatus)); };
297
- TreeService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TreeService, factory: TreeService.ɵfac });
298
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TreeService, [{
299
- type: Injectable
300
- }], function () { return [{ type: i1.ComponentCreatorService }, { type: i2.DropZoneService }, { type: i3.DragStateService }, { type: i4.TreeConstructionStatus }]; }, null); })();
301
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbGltYmxlLXRyZWUvc3JjL2xpYi9saW1ibGUtdHJlZS1yb290L3RyZWUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUEwQixNQUFNLGVBQWUsQ0FBQztBQUduRSxPQUFPLEVBQUUsTUFBTSxFQUFxQixNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBRXpGLE9BQU8sRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBK0RyRSxnREFBZ0Q7QUFDaEQsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztBQWtEekIsTUFBTSxPQUFPLFdBQVc7SUFjckIsWUFDb0IsdUJBQWdELEVBQ2hELGVBQWdDLEVBQ2hDLGdCQUFrQyxFQUNsQyxzQkFBOEM7UUFIOUMsNEJBQXVCLEdBQXZCLHVCQUF1QixDQUF5QjtRQUNoRCxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBRS9ELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMs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QUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUM3QztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2YsQ0FBQzs7c0VBOVZTLFdBQVc7aUVBQVgsV0FBVyxXQUFYLFdBQVc7dUZBQVgsV0FBVztjQUR2QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgVHlwZSwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IENvbXBvbmVudENyZWF0b3JTZXJ2aWNlIH0gZnJvbSBcIi4uL3NpbmdsZXRvbnMvY29tcG9uZW50LWNyZWF0b3Iuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcm9wWm9uZVNlcnZpY2UgfSBmcm9tIFwiLi9kcm9wLXpvbmUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBCcmFuY2gsIEJyYW5jaENvb3JkaW5hdGVzIH0gZnJvbSBcIi4uL2NsYXNzZXMvQnJhbmNoXCI7XHJcbmltcG9ydCB7IExpbWJsZVRyZWVOb2RlQ29tcG9uZW50IH0gZnJvbSBcIi4uL2xpbWJsZS10cmVlLW5vZGUvbGltYmxlLXRyZWUtbm9kZS5jb21wb25lbnRcIjtcclxuaW1wb3J0IHsgRHJhZ1N0YXRlU2VydmljZSB9IGZyb20gXCIuLi9zaW5nbGV0b25zL2RyYWctc3RhdGUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIEVNUFRZLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgYXJyYXlzQXJlRXF1YWwgfSBmcm9tIFwiLi4vdXRpbFwiO1xyXG5pbXBvcnQgeyBkZWJvdW5jZSwgZGVib3VuY2VUaW1lLCBmaWx0ZXIsIHRhcCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQgeyBUcmVlQ29uc3RydWN0aW9uU3RhdHVzIH0gZnJvbSBcIi4vdHJlZS1jb25zdHJ1Y3Rpb24tc3RhdHVzLnNlcnZpY2VcIjtcclxuXHJcbi8qKiBBbiBvYmplY3QgZGVzY3JpYmluZyBhIG5vZGUgb2YgdGhlIHRyZWUgKi9cclxuZXhwb3J0IGludGVyZmFjZSBMaW1ibGVUcmVlTm9kZSB7XHJcbiAgIC8qKiBBIGxpc3Qgb2Ygbm9kZXMgdG8gYmUgcmVuZGVyZWQgXCJ1bmRlclwiIHRoaXMgb25lLCBvbmUgbGV2ZWwgZGVlcGVyIGluIHRoZSB0cmVlLiAqL1xyXG4gICBub2Rlcz86IExpbWJsZVRyZWVEYXRhO1xyXG4gICAvLyAvKiogQSBjdXN0b20gZGF0YSBvYmplY3QgdGhhdCB3aWxsIGJlIHBhc3NlZCBpbnRvIHRoZSBjb21wb25lbnQgYXMgYW4gYElucHV0KClgIGJpbmRpbmcgY2FsbGVkIGBub2RlRGF0YWAgKi9cclxuICAgLy8gZGF0YTogdW5rbm93bjtcclxuICAgLyoqIEFuIG9iamVjdCB0aGF0IGRlc2NyaWJlcyB0aGUgY29tcG9uZW50IHdoaWNoIHdpbGwgcmVwcmVzZW50IHRoaXMgbm9kZSBpbiB0aGUgdmlzdWFsIHRyZWUgKi9cclxuICAgY29tcG9uZW50PzogQ29tcG9uZW50T2JqO1xyXG4gICBjb2xsYXBzZWQ/OiBib29sZWFuO1xyXG4gICBbaW5kZXg6IHN0cmluZ106IHVua25vd247XHJcbn1cclxuXHJcbi8qKiBBbiBvYmplY3QgdGhhdCB0aGUgbGltYmxlLXRyZWUtcm9vdCBjb21wb25lbnQgdXNlcyB0byBidWlsZCB0aGUgdHJlZSAqL1xyXG5leHBvcnQgdHlwZSBMaW1ibGVUcmVlRGF0YSA9IEFycmF5PExpbWJsZVRyZWVOb2RlPjtcclxuXHJcbi8qKiBBIGdyb3VwIG9mIHNldHRpbmdzIGZvciBjaGFuZ2luZyB0aGUgZnVuY3Rpb25hbGl0eSBvZiB0aGUgdHJlZSAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIExpbWJsZVRyZWVPcHRpb25zIHtcclxuICAgLyoqIFRoZSBjb21wb25lbnQgb2JqZWN0IHRvIHVzZSBpZiBvbmUgaXMgbm90IHNwZWNpZmllZCBmb3IgYSBwYXJ0aWN1bGFyIG5vZGUgKi9cclxuICAgZGVmYXVsdENvbXBvbmVudD86IENvbXBvbmVudE9iajtcclxuICAgLyoqIFRoZSBudW1iZXIgb2YgcGl4ZWxzIHRvIGluZGVudCBlYWNoIGxldmVsIG9mIHRoZSB0cmVlLiBEZWZhdWx0cyB0byA0NSAqL1xyXG4gICBpbmRlbnQ/OiBudW1iZXI7XHJcbiAgIC8qKlxyXG4gICAgKiBXaGV0aGVyIHRvIGFsbG93IFwibmVzdGluZ1wiIChwbGFjaW5nIGEgbm9kZSBvbmUgbGV2ZWwgZGVlcGVyIHRoYW4gY3VycmVudGx5IGV4aXN0cyBvbiB0aGUgYnJhbmNoKS5cclxuICAgICogV2hlbiB0aGlzIGlzIGEgYm9vbGVhbiwgaXQgYXBwbGllcyB0byBhbGwgbm9kZXMuIFdoZW4gdGhpcyBpcyBhIGZ1bmN0aW9uLCB0aGUgbm9kZSBpbiBxdWVzdGlvblxyXG4gICAgKiBpcyBwYXNzZWQgaW4uIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAqL1xyXG4gICBhbGxvd05lc3Rpbmc/OiBib29sZWFuIHwgKChub2RlRGF0YTogTGltYmxlVHJlZU5vZGUpID0+IGJvb2xlYW4pO1xyXG4gICAvKipcclxuICAgICogV2hldGhlciB0byBhbGxvdyBhIG5vZGUgdG8gYmUgZHJhZ2dlZC4gV2hlbiB0aGlzIGlzIGEgYm9vbGVhbiwgaXQgYXBwbGllcyB0byBhbGwgbm9kZXMuIFdoZW4gdGhpc1xyXG4gICAgKiBpcyBhIGZ1bmN0aW9uLCB0aGUgbm9kZSBpbiBxdWVzdGlvbiBpcyBwYXNzZWQgaW4uIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAqL1xyXG4gICBhbGxvd0RyYWdnaW5nPzogYm9vbGVhbiB8ICgobm9kZURhdGE6IExpbWJsZVRyZWVOb2RlKSA9PiBib29sZWFuKTtcclxuICAgLyoqIEEgY2FsbGJhY2sgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBzb3VyY2VOb2RlIGNhbiBiZSBkcm9wcGVkIGF0IGEgcGFydGljdWxhciBsb2NhdGlvbi4gKi9cclxuICAgYWxsb3dEcm9wPzogKFxyXG4gICAgICBzb3VyY2VOb2RlOiBMaW1ibGVUcmVlTm9kZSxcclxuICAgICAgcHJvcG9zZWRQYXJlbnQ6IExpbWJsZVRyZWVOb2RlIHwgbnVsbCxcclxuICAgICAgcHJvcG9zZWRJbmRleDogbnVtYmVyXHJcbiAgICkgPT4gYm9vbGVhbjtcclxuICAgLyoqIFdoZW4gc2V0IHRvIHRydWUsIGxpc3QgbW9kZSB3aWxsIGVuZm9yY2UgYSBmbGF0IHRyZWUgc3RydWN0dXJlLCBtZWFuaW5nIHRoZXJlXHJcbiAgICAqIGNhbiBvbmx5IGJlIG9uZSBsZXZlbCBvZiB0aGUgdHJlZS4gYGFsbG93TmVzdGluZ2AgaXMgYXV0b21hdGljYWxseSBzZXQgdG8gYGZhbHNlYFxyXG4gICAgKiBhbmQgYW55IGNoaWxkcmVuIHdpbGwgYmUgZGVsZXRlZC5cclxuICAgICpcclxuICAgICogVGhpcyBtb2RlIGNhbiBiZSB1c2VkIHdoZW4gdGhlIHNhbWUgZHluYW1pYyBkcmFnIGFuZCBkcm9wIGZ1bmN0aW9uYWxpdHkgb2ZcclxuICAgICogdGhlIHRyZWUgaXMgZGVzaXJlZCwgYnV0IHRoZSB0cmVlIHN0cnVjdHVyZSBpdHNlbGYgaXMgbm90IG5lY2Vzc2FyeS4gVGhpc1xyXG4gICAgKiBhbHNvIG9wZW5zIHVwIHRoZSBwYWdpbmF0aW9uIEFQSSBvbiB0aGUgbGltYmxlLXRyZWUtcm9vdCBjb21wb25lbnQuIFNlZSB0aGVcclxuICAgICogUkVBRE1FIGZvciBkZXRhaWxzIG9uIHBhZ2luYXRpb24uXHJcbiAgICAqL1xyXG4gICBsaXN0TW9kZT86IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKiBBbiBvYmplY3QgdGhhdCByZWZlcmVuY2VzIHRoZSBjb21wb25lbnQgdG8gYmUgcmVuZGVyZWQgYW5kIGl0cyBiaW5kaW5ncyAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudE9iaiB7XHJcbiAgIC8qKiBUaGUgY29tcG9uZW50IGNsYXNzICovXHJcbiAgIGNsYXNzOiBUeXBlPHVua25vd24+O1xyXG4gICAvKiogVGhlIGJpbmRpbmdzIChpbnB1dHMgYW5kIG91dHB1dHMpIG9mIHRoZSBjbGFzcyAqL1xyXG4gICBiaW5kaW5ncz86IHtcclxuICAgICAgW2luZGV4OiBzdHJpbmddOiB1bmtub3duO1xyXG4gICB9O1xyXG59XHJcblxyXG4vKiogVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBgaW5kZW50YCBvcHRpb24gKi9cclxuZXhwb3J0IGNvbnN0IElOREVOVCA9IDQ1O1xyXG5cclxuLyoqIEFuIG9wdGlvbnMgb2JqZWN0IHdpdGggZGVmYXVsdCB2YWx1ZXMgbG9hZGVkIHdoZXJlIGFwcGxpY2FibGUgKi9cclxuZXhwb3J0IGludGVyZmFjZSBQcm9jZXNzZWRPcHRpb25zQmFzZSBleHRlbmRzIExpbWJsZVRyZWVPcHRpb25zIHtcclxuICAgZGVmYXVsdENvbXBvbmVudD86IENvbXBvbmVudE9iajtcclxuICAgaW5kZW50OiBudW1iZXI7XHJcbiAgIGFsbG93TmVzdGluZzogYm9vbGVhbiB8ICgobm9kZURhdGE6IExpbWJsZVRyZWVOb2RlKSA9PiBib29sZWFuKTtcclxuICAgYWxsb3dEcmFnZ2luZzogYm9vbGVhbiB8ICgobm9kZURhdGE6IExpbWJsZVRyZWVOb2RlKSA9PiBib29sZWFuKTtcclxuICAgYWxsb3dEcm9wOiAoXHJcbiAgICAgIHNvdXJjZU5vZGU6IExpbWJsZVRyZWVOb2RlLFxyXG4gICAgICBwcm9wb3NlZFBhcmVudDogTGltYmxlVHJlZU5vZGUgfCBudWxsLFxyXG4gICAgICBwcm9wb3NlZEluZGV4OiBudW1iZXJcclxuICAgKSA9PiBib29sZWFuO1xyXG4gICBsaXN0TW9kZTogYm9vbGVhbjtcclxuICAgaXRlbXNQZXJQYWdlOiBudW1iZXIgfCB1bmRlZmluZWQ7XHJcbiAgIHBhZ2U6IG51bWJlciB8IHVuZGVmaW5lZDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQcm9jZXNzZWRPcHRpb25zV2l0aFBhZ2luYXRpb24gZXh0ZW5kcyBQcm9jZXNzZWRPcHRpb25zQmFzZSB7XHJcbiAgIGxpc3RNb2RlOiB0cnVlO1xyXG4gICBpdGVtc1BlclBhZ2U6IG51bWJlcjtcclxuICAgcGFnZTogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NlZE9wdGlvbnNXaXRob3V0UGFnaW5hdGlvblxyXG4gICBleHRlbmRzIFByb2Nlc3NlZE9wdGlvbnNCYXNlIHtcclxuICAgbGlzdE1vZGU6IGZhbHNlO1xyXG4gICBpdGVtc1BlclBhZ2U6IHVuZGVmaW5lZDtcclxuICAgcGFnZTogdW5kZWZpbmVkO1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBQcm9jZXNzZWRPcHRpb25zID1cclxuICAgfCBQcm9jZXNzZWRPcHRpb25zV2l0aFBhZ2luYXRpb25cclxuICAgfCBQcm9jZXNzZWRPcHRpb25zV2l0aG91dFBhZ2luYXRpb247XHJcblxyXG4vKiogdGhlIHZhbHVlIGVtaXR0ZWQgZnJvbSB0aGUgcm9vdCBjb21wb25lbnQgYWZ0ZXIgYSBub2RlIGlzIGRyb3BwZWQgKi9cclxuZXhwb3J0IGludGVyZmFjZSBUcmVlRHJvcCB7XHJcbiAgIC8qKiBUaGUgbm9kZSB0aGF0IHdhcyBkcm9wcGVkICovXHJcbiAgIHRhcmdldDogTGltYmxlVHJlZU5vZGU7XHJcbiAgIC8qKiB0aGUgdGFyZ2V0J3MgcGFyZW50IGJlZm9yZSB0aGUgZHJhZyBhbmQgZHJvcCwgb3IgbnVsbCBpZiBpdCB3YXMgYSB0b3AtbGV2ZWwgbm9kZSAqL1xyXG4gICBvbGRQYXJlbnQ6IExpbWJsZVRyZWVOb2RlIHwgbnVsbDtcclxuICAgLyoqIHRoZSBpbmRleCBvZiB0aGUgbm9kZSBiZWZvcmUgdGhlIGRyYWcgYW5kIGRyb3AgcmVsYXRpdmUgdG8gaXRzIG9sZCBzaWJsaW5ncyAqL1xyXG4gICBvbGRJbmRleDogbnVtYmVyO1xyXG4gICAvKiogdGhlIHRhcmdldCdzIHBhcmVudCBhZnRlciB0aGUgZHJhZyBhbmQgZHJvcCwgb3IgbnVsbCBpZiBpdCBpcyBub3cgYSB0b3AtbGV2ZWwgbm9kZSAqL1xyXG4gICBuZXdQYXJlbnQ6IExpbWJsZVRyZWVOb2RlIHwgbnVsbDtcclxuICAgLyoqIHRoZSBpbmRleCBvZiB0aGUgbm9kZSBhZnRlciB0aGUgZHJhZyBhbmQgZHJvcCByZWxhdGl2ZSB0byBpdHMgbmV3IHNpYmxpbmdzICovXHJcbiAgIG5ld0luZGV4OiBudW1iZXI7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFRyZWVTZXJ2aWNlIHtcclxuICAgcHVibGljIHJlYWRvbmx5IGNoYW5nZXMkOiBTdWJqZWN0PG51bGw+O1xyXG4gICBwdWJsaWMgcmVhZG9ubHkgZHJvcHMkOiBTdWJqZWN0PFRyZWVEcm9wPjtcclxuICAgcHVibGljIGhvc3Q6IFZpZXdDb250YWluZXJSZWYgfCB1bmRlZmluZWQ7XHJcbiAgIHB1YmxpYyB0cmVlRGF0YTogTGltYmxlVHJlZURhdGEgfCB1bmRlZmluZWQ7XHJcbiAgIC8qKiBUaGlzIHNob3VsZCBuZXZlciBiZSByZWFzc2lnbmVkLiBJdCBpcyBhc3NpZ25lZCBpbiBpbml0KCkgYW5kIG5vIHdoZXJlIGVsc2UuIFdlIG5lZWQgdG8ga2VlcCB0aGUgcmVmZXJlbmNlIGZyb20gYnJlYWtpbmcuICovXHJcbiAgIHByaXZhdGUgb3JpZ2luYWxEYXRhOiBMaW1ibGVUcmVlRGF0YSB8IHVuZGVmaW5lZDtcclxuICAgcHVibGljIHRyZWVPcHRpb25zOiBQcm9jZXNzZWRPcHRpb25zIHwgdW5kZWZpbmVkO1xyXG4gICBwdWJsaWMgdHJlZU1vZGVsOiBCcmFuY2g8YW55PjtcclxuICAgcHJpdmF0ZSBwbGFjZWhvbGRlcjogYm9vbGVhbjtcclxuICAgcHVibGljIGNhcHR1cmVkOiBib29sZWFuO1xyXG4gICBwdWJsaWMgcmVhZG9ubHkgY2xlYW51cFNpZ25hbCQ6IFN1YmplY3Q8Ym9vbGVhbj47XHJcbiAgIHB1YmxpYyBwbGFjZWhvbGRlciQ6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPjtcclxuXHJcbiAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGNvbXBvbmVudENyZWF0b3JTZXJ2aWNlOiBDb21wb25lbnRDcmVhdG9yU2VydmljZSxcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcm9wWm9uZVNlcnZpY2U6IERyb3Bab25lU2VydmljZSxcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcmFnU3RhdGVTZXJ2aWNlOiBEcmFnU3RhdGVTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVDb25zdHJ1Y3Rpb25TdGF0dXM6IFRyZWVDb25zdHJ1Y3Rpb25TdGF0dXNcclxuICAgKSB7XHJcbiAgICAgIHRoaXMuY2hhbmdlcyQgPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgICB0aGlzLmRyb3BzJCA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgIHRoaXMudHJlZU1vZGVsID0gbmV3IEJyYW5jaChudWxsKTtcclxuICAgICAgdGhpcy5wbGFjZWhvbGRlciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmNhcHR1cmVkID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuY2xlYW51cFNpZ25hbCQgPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgICBsZXQgcmVidWlsZCA9IGZhbHNlO1xyXG4gICAgICBsZXQgdHJlZUlzU3RhYmxlID0gZmFsc2U7XHJcbiAgICAgIGNvbnN0IHRyZWVJc1N0YWJsZSQgPSB0aGlzLnRyZWVDb25zdHJ1Y3Rpb25TdGF0dXMuc3RhYmxlJC5waXBlKFxyXG4gICAgICAgICB0YXAoKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgIHRyZWVJc1N0YWJsZSA9IHZhbHVlO1xyXG4gICAgICAgICB9KSxcclxuICAgICAgICAgZmlsdGVyKCh2YWx1ZSkgPT4gdmFsdWUgPT09IHRydWUpXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuY2xlYW51cFNpZ25hbCRcclxuICAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgIHRhcCgodmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgcmVidWlsZCA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgZGVib3VuY2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICBpZiAodHJlZUlzU3RhYmxlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vSWYgdHJlZSBpcyBzdGFibGUsIGNvbnRpbnVlIHJpZ2h0IGF3YXlcclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xyXG4gICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgIC8vSWYgdHJlZSBpcyBub3Qgc3RhYmxlLCB3YWl0IGZvciBpdCB0byBiZWNvbWUgc28uXHJcbiAgICAgICAgICAgICAgIHJldHVybiB0cmVlSXNTdGFibGUkO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgLy9XZSB1c2UgdGhpcyB0aW1lZCBkZWJvdW5jZSB0byB0aHJvdHRsZSBjaGFpbmVkIGRlc3RydWN0aW9uIG9mIGNvbXBvbmVudHNcclxuICAgICAgICAgICAgZGVib3VuY2VUaW1lKDUpXHJcbiAgICAgICAgIClcclxuICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xlYW51cChyZWJ1aWxkKTtcclxuICAgICAgICAgICAgcmVidWlsZCA9IGZhbHNlO1xyXG4gICAgICAgICB9KTtcclxuICAgICAgdGhpcy5wbGFjZWhvbGRlciQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICAgICAgdGhpcy5wbGFjZWhvbGRlciQuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xyXG4gICAgICAgICB0aGlzLnBsYWNlaG9sZGVyID0gdmFsdWU7XHJcbiAgICAgIH0pO1xyXG4gICB9XHJcblxyXG4gICBwdWJsaWMgZHJvcChzb3VyY2U6IEJyYW5jaDxhbnk+LCB0YXJnZXRDb29yZGluYXRlczogQnJhbmNoQ29vcmRpbmF0ZXMpIHtcclxuICAgICAgLy9wcmVwXHJcbiAgICAgIGNvbnN0IHNvdXJjZVBhcmVudCA9IHNvdXJjZS5nZXRQYXJlbnQoKTtcclxuICAgICAgaWYgKHNvdXJjZVBhcmVudCA9PT0gbnVsbCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYW4ndCBkcm9wIHJvb3Qgb2YgdHJlZVwiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBzb3VyY2VJbmRleCA9IHNvdXJjZS5nZXRJbmRleCgpO1xyXG4gICAgICBpZiAoc291cmNlSW5kZXggPT09IHVuZGVmaW5lZCB8fCBzb3VyY2VJbmRleCA9PT0gbnVsbCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgbW92ZSB0aGUgaGlkZGVuIHJvb3Qgbm9kZVwiKTtcclxuICAgICAgfVxyXG4gICAgICBsZXQgdGFyZ2V0UGFyZW50Q29vcmRpbmF0ZXM6IEJyYW5jaENvb3JkaW5hdGVzO1xyXG4gICAgICBsZXQgbmV3SW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZDtcclxuICAgICAgaWYgKHRoaXMucGxhY2Vob2xkZXIgPT09IHRydWUpIHtcclxuICAgICAgICAgdGFyZ2V0UGFyZW50Q29vcmRpbmF0ZXMgPSBbXTtcclxuICAgICAgICAgbmV3SW5kZXggPSAwO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgICB0YXJnZXRQYXJlbnRDb29yZGluYXRlcyA9IFsuLi50YXJnZXRDb29yZGluYXRlc107XHJcbiAgICAgICAgIG5ld0luZGV4ID0gdGFyZ2V0UGFyZW50Q29vcmRpbmF0ZXMucG9wKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKG5ld0luZGV4ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGFyZ2V0IGNvb3JkaW5hdGVzIGFyZSBlbXB0eVwiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCB0YXJnZXRQYXJlbnQgPSB0aGlzLnRyZWVNb2RlbC5nZXREZXNjZW5kYW50KFxyXG4gICAgICAgICB0YXJnZXRQYXJlbnRDb29yZGluYXRlc1xyXG4gICAgICApO1xyXG4gICAgICBpZiAodGFyZ2V0UGFyZW50ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY291bGQgbm90IGdldCB0byB0YXJnZXRcIik7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5kcm9wWm9uZVNlcnZpY2UuZ2V0RHJvcFpvbmUodGFyZ2V0Q29vcmRpbmF0ZXMpO1xyXG4gICAgICBjb25zdCB0YXJnZXRJbmRleCA9IHRhcmdldD8uZ2V0TG9jYXRpb24oKS5pbnNlcnRJbmRleDtcclxuICAgICAgY29uc3QgdGFyZ2V0SG9zdCA9IHRhcmdldD8uZ2V0SG9zdCgpO1xyXG4gICAgICBjb25zdCBzb3VyY2VIb3N0ID0gdGhpcy5kcmFnU3RhdGVTZXJ2aWNlLmdldERhdGEoKT8ucGFyZW50Q29udGFpbmVyO1xyXG4gICAgICBpZiAodGhpcy5wbGFjZWhvbGRlciA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICB0aGlzLnBsYWNlaG9sZGVyJC5uZXh0KGZhbHNlKTtcclxuICAgICAgfVxyXG4gICAgICAvL0NoYW5nZSB0aGUgdHJlZU1vZGVsXHJcbiAgICAgIHRhcmdldFBhcmVudC5pbnNlcnRDaGlsZChzb3VyY2UsIG5ld0luZGV4KTtcclxuICAgICAgLy9QcmVwYXJlIHRvIHVwZGF0ZSB0aGUgdmlld1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIHRhcmdldEhvc3QgPT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICBzb3VyY2VIb3N0ID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgdGFyZ2V0SW5kZXggPT09IHVuZGVmaW5lZFxyXG4gICAgICApIHtcclxuICAgICAgICAgLy9IaXR0aW5nIHRoaXMgbWVhbnMgdGhlcmUgaXMgYSBidWcsIGJ1dCBub3QgYSBmYXRhbCBvbmUuXHJcbiAgICAgICAgIC8vSnVzdCByZW5kZXIgdGhlIHdob2xlIHRyZWUgYWdhaW4uXHJcbiAgICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgICAgXCJDb3VsZCBub3QgcGVyZm9ybSBhIHByZWNpc2UgdXBkYXRlLiBSZS1yZW5kZXJpbmcgdGhlIGVudGlyZSB0cmVlIGluc3RlYWRcIlxyXG4gICAgICAgICApO1xyXG4gICAgICAgICB0aGlzLnJlbmRlcigpO1xyXG4gICAgICAgICB0aGlzLmNoYW5nZXMkLm5leHQobnVsbCk7XHJcbiAgICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICAvL1VwZGF0ZSB0aGUgdmlld1xyXG4gICAgICBjb25zdCBub2Rlc0luU291cmNlID0gc291cmNlSG9zdC5sZW5ndGg7XHJcbiAgICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IHRoaXMuY29tcG9uZW50Q3JlYXRvclNlcnZpY2UuYXBwZW5kQ29tcG9uZW50KFxyXG4gICAgICAgICBMaW1ibGVUcmVlTm9kZUNvbXBvbmVudCxcclxuICAgICAgICAgdGFyZ2V0SG9zdCxcclxuICAgICAgICAgbmV3SW5kZXhcclxuICAgICAgKTtcclxuICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmJyYW5jaCA9IHNvdXJjZTtcclxuICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLnBhcmVudEhvc3QgPSB0YXJnZXRIb3N0O1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIHRhcmdldEluZGV4IDwgc291cmNlSW5kZXggJiZcclxuICAgICAgICAgc291cmNlSG9zdC5sZW5ndGggPiBub2Rlc0luU291cmNlICYmXHJcbiAgICAgICAgIGFycmF5c0FyZUVxdWFsKHNvdXJjZVBhcmVudC5nZXRDb29yZGluYXRlcygpLCB0YXJnZXRQYXJlbnRDb29yZGluYXRlcylcclxuICAgICAgKSB7XHJcbiAgICAgICAgIHNvdXJjZUhvc3QucmVtb3ZlKHNvdXJjZUluZGV4ICsgMSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIHNvdXJjZUhvc3QucmVtb3ZlKHNvdXJjZUluZGV4KTtcclxuICAgICAgfVxyXG4gICAgICAvL1VwZGF0ZSB0aGUgdHJlZSBkYXRhXHJcbiAgICAgIHRoaXMucmVidWlsZFRyZWVEYXRhKCk7XHJcbiAgICAgIC8vUHVibGlzaCBkcm9wIGRhdGFcclxuICAgICAgdGhpcy5kcm9wcyQubmV4dCh7XHJcbiAgICAgICAgIHRhcmdldDogc291cmNlLmRhdGEsXHJcbiAgICAgICAgIG9sZFBhcmVudDogc291cmNlUGFyZW50LmRhdGEgYXMgTGltYmxlVHJlZU5vZGUsXHJcbiAgICAgICAgIG9sZEluZGV4OiBzb3VyY2VJbmRleCxcclxuICAgICAgICAgbmV3UGFyZW50OiB0YXJnZXRQYXJlbnQuZGF0YSxcclxuICAgICAgICAgbmV3SW5kZXg6IG5ld0luZGV4XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLmNsZWFudXBTaWduYWwkLm5leHQoZmFsc2UpO1xyXG4gICB9XHJcblxyXG4gICAvKiogSW5pdGlhbGl6ZXMgdGhlIHNlcnZpY2UgYW5kIHJlbmRlcnMgdGhlIHRyZWUuXHJcbiAgICAqIEBwYXJhbSBob3N0IC0gVGhlIFZpZXdDb250YWluZXJSZWYgaW50byB3aGljaCB0aGUgdHJlZSB3aWxsIGJlIHJlbmRlcmVkLlxyXG4gICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBkYXRhIGFycmF5IHRoYXQgd2FzIHBhc3NlZCBpbiB0byBMaW1ibGVUcmVlUm9vdCwgd2hpY2ggaXNcclxuICAgICogdGhlIHVzZXJzJyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHJlZVxyXG4gICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIG9iamVjdCB0aGF0IHdhcyBwYXNzZWQgaW4gdG8gTGltYmxlVHJlZVJvb3RcclxuICAgICovXHJcbiAgIHB1YmxpYyBpbml0KFxyXG4gICAgICBob3N0OiBWaWV3Q29udGFpbmVyUmVmLFxyXG4gICAgICBkYXRhOiBMaW1ibGVUcmVlRGF0YSxcclxuICAgICAgb3B0aW9ucz86IExpbWJsZVRyZWVPcHRpb25zLFxyXG4gICAgICBpdGVtc1BlclBhZ2U/OiBudW1iZXIsXHJcbiAgICAgIHBhZ2U/OiBudW1iZXJcclxuICAgKTogdm9pZCB7XHJcbiAgICAgIHRoaXMuaG9zdCA9IGhvc3Q7XHJcbiAgICAgIHRoaXMub3JpZ2luYWxEYXRhID0gZGF0YTtcclxuICAgICAgdGhpcy50cmVlT3B0aW9ucyA9IHRoaXMucHJvY2Vzc09wdGlvbnMob3B0aW9ucywgaXRlbXNQZXJQYWdlLCBwYWdlKTtcclxuICAgICAgaWYgKHRoaXMudHJlZU9wdGlvbnMubGlzdE1vZGUgPT09IHRydWUpIHtcclxuICAgICAgICAgbGV0IHN0YXJ0ID1cclxuICAgICAgICAgICAgdGhpcy50cmVlT3B0aW9ucy5pdGVtc1BlclBhZ2UgKiAodGhpcy50cmVlT3B0aW9ucy5wYWdlIC0gMSk7XHJcbiAgICAgICAgIGlmIChpc05hTihzdGFydCkpIHtcclxuICAgICAgICAgICAgLy9UaGlzIGNhdGNoZXMgdGhlIGNhc2Ugd2hlcmUgaXRlbXNQZXJQYWdlIHdhcyBub3QgcGFzc2VkIGJ5IHRoZSB1c2VyLFxyXG4gICAgICAgICAgICAvL2NhdXNpbmcgYHN0YXJ0YCB0byBlcXVhbCBpbmZpbml0eSowLCB3aGljaCBpcyBOYU4uXHJcbiAgICAgICAgICAgIHN0YXJ0ID0gMDtcclxuICAgICAgICAgfVxyXG4gICAgICAgICBjb25zdCBlbmQgPSBzdGFydCArIHRoaXMudHJlZU9wdGlvbnMuaXRlbXNQZXJQYWdlO1xyXG4gICAgICAgICB0aGlzLnRyZWVEYXRhID0gdGhpcy5vcmlnaW5hbERhdGEuc2xpY2Uoc3RhcnQsIGVuZCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIHRoaXMudHJlZURhdGEgPSBbLi4udGhpcy5vcmlnaW5hbERhdGFdO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucmVuZGVyKCk7XHJcbiAgIH1cclxuXHJcbiAgIHByaXZhdGUgY2xlYW51cChyZWJ1aWxkID0gZmFsc2UpOiB2b2lkIHtcclxuICAgICAgaWYgKHJlYnVpbGQpIHtcclxuICAgICAgICAgdGhpcy5yZWJ1aWxkVHJlZURhdGEoKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy50cmVlRGF0YT8ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgIC8vV2UgZG8gYSBmdWxsIHJlbmRlciBoZXJlIGJlY2F1c2UgaXQgaXNuJ3QgYWN0dWFsbHkgYW55IHNsb3dlclxyXG4gICAgICAgICAvL3doZW4gdGhlcmUgYXJlIG5vIG5vZGVzLCBhbmQgaXQgaXMgYSBsaXR0bGUgbW9yZSBzdHJhaWdodGZvcndhcmRcclxuICAgICAgICAgdGhpcy5yZW5kZXIoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgdGhpcy5jaGFuZ2VzJC5uZXh0KG51bGwpO1xyXG4gICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS51cGRhdGUoKTtcclxuICAgICAgfVxyXG4gICB9XHJcblxyXG4gICAvKiogUmVuZGVycyB0aGUgZW50aXJlIHRyZWUgZnJvbSByb290IHRvIGxlYXZlcyAqL1xyXG4gICBwcml2YXRlIHJlbmRlcigpIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgICB0aGlzLmhvc3QgPT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICB0aGlzLnRyZWVEYXRhID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgdGhpcy50cmVlT3B0aW9ucyA9PT0gdW5kZWZpbmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUcmVlTW9kZWwgbm90IGluaXRpYWxpemVkXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudHJlZUNvbnN0cnVjdGlvblN0YXR1cy5yZWFkeShmYWxzZSk7XHJcbiAgICAgIHRoaXMuaG9zdC5jbGVhcigpO1xyXG4gICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5yZXN0YXJ0KCk7XHJcbiAgICAgIHRoaXMucGxhY2Vob2xkZXIkLm5leHQoZmFsc2UpO1xyXG4gICAgICB0aGlzLnRyZWVNb2RlbCA9IG5ldyBCcmFuY2gobnVsbCk7XHJcbiAgICAgIGlmICh0aGlzLnRyZWVEYXRhLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAvL1RyZWUgaXMgZW1wdHksIGJ1dCB3ZSBoYXZlIHRvIHRvIGhhdmUgc29tZXRoaW5nIHRoZXJlIHNvIG90aGVyIHRyZWVzJyBpdGVtcyBjYW4gYmUgZHJvcHBlZCBpbnRvIGl0XHJcbiAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIkLm5leHQodHJ1ZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLnRyZWVEYXRhKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJyYW5jaCA9IG5ldyBCcmFuY2gobm9kZSk7XHJcbiAgICAgICAgICAgIHRoaXMudHJlZU1vZGVsLmFwcGVuZENoaWxkKGJyYW5jaCk7XHJcbiAgICAgICAgIH1cclxuICAgICAgICAgZm9yIChjb25zdCBicmFuY2ggb2YgdGhpcy50cmVlTW9kZWwuZ2V0Q2hpbGRyZW4oKSkge1xyXG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnRSZWYgPSB0aGlzLmNvbXBvbmVudENyZWF0b3JTZXJ2aWNlLmFwcGVuZENvbXBvbmVudDxMaW1ibGVUcmVlTm9kZUNvbXBvbmVudD4oXHJcbiAgICAgICAgICAgICAgIExpbWJsZVRyZWVOb2RlQ29tcG9uZW50LFxyXG4gICAgICAgICAgICAgICB0aGlzLmhvc3RcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmJyYW5jaCA9IGJyYW5jaDtcclxuICAgICAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLnBhcmVudEhvc3QgPSB0aGlzLmhvc3Q7XHJcbiAgICAgICAgICAgIC8vVGhlIExpbWJsZVRyZWVOb2RlQ29tcG9uZW50IHdpbGwgKGluZGlyZWN0bHkpIGNhbGwgdGhlIGByZW5kZXJCcmFuY2hgIG1ldGhvZCBvZiB0aGlzIHNlcnZpY2UgdG8gcmVuZGVyXHJcbiAgICAgICAgICAgIC8vaXRzIG93biBjaGlsZHJlblxyXG4gICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy50cmVlQ29uc3RydWN0aW9uU3RhdHVzLnJlYWR5KHRydWUpO1xyXG4gICAgICB0aGlzLmNoYW5nZXMkLm5leHQobnVsbCk7XHJcbiAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmluaXQodGhpcy50cmVlTW9kZWwsIHRoaXMudHJlZU9wdGlvbnMpO1xyXG4gICB9XHJcblxyXG4gICAvKiogUmVuZGVycyBhIGJyYW5jaCBvZiB0aGUgdHJlZSBhbmQgYWxsIG9mIGl0cyBkZXNjZW5kYW50cyAqL1xyXG4gICBwdWJsaWMgcmVuZGVyQnJhbmNoKGhvc3Q6IFZpZXdDb250YWluZXJSZWYsIGJyYW5jaDogQnJhbmNoPGFueT4pIHtcclxuICAgICAgaWYgKHRoaXMudHJlZU1vZGVsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHJlZU1vZGVsIG5vdCBpbml0aWFsaXplZFwiKTtcclxuICAgICAgfVxyXG4gICAgICBob3N0LmNsZWFyKCk7XHJcbiAgICAgIGJyYW5jaC5jbGVhckNoaWxkcmVuKCk7XHJcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBicmFuY2guZGF0YT8ubm9kZXMgPz8gW10pIHtcclxuICAgICAgICAgY29uc3QgbmV3QnJhbmNoID0gbmV3IEJyYW5jaChub2RlKTtcclxuICAgICAgICAgYnJhbmNoLmFwcGVuZENoaWxkKG5ld0JyYW5jaCk7XHJcbiAgICAgICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IHRoaXMuY29tcG9uZW50Q3JlYXRvclNlcnZpY2UuYXBwZW5kQ29tcG9uZW50PExpbWJsZVRyZWVOb2RlQ29tcG9uZW50PihcclxuICAgICAgICAgICAgTGltYmxlVHJlZU5vZGVDb21wb25lbnQsXHJcbiAgICAgICAgICAgIGhvc3RcclxuICAgICAgICAgKTtcclxuICAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmJyYW5jaCA9IG5ld0JyYW5jaDtcclxuICAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLnBhcmVudEhvc3QgPSBob3N0O1xyXG4gICAgICAgICAvL1RoZSBMaW1ibGVUcmVlTm9kZUNvbXBvbmVudCB3aWxsIChpbmRpcmVjdGx5KSBjYWxsIHRoZSBgcmVuZGVyQnJhbmNoYCBtZXRob2Qgb2YgdGhpcyBzZXJ2aWNlIHRvIHJlbmRlclxyXG4gICAgICAgICAvL2l0cyBvd24gY2hpbGRyZW5cclxuICAgICAgfVxyXG4gICB9XHJcblxyXG4gICBwcml2YXRlIHByb2Nlc3NPcHRpb25zKFxyXG4gICAgICBvcHRpb25zOiBMaW1ibGVUcmVlT3B0aW9ucyA9IHt9LFxyXG4gICAgICBpdGVtc1BlclBhZ2U6IG51bWJlciA9IEluZmluaXR5LFxyXG4gICAgICBwYWdlOiBudW1iZXIgPSAxXHJcbiAgICk6IFByb2Nlc3NlZE9wdGlvbnMge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIG9wdGlvbnMubGlzdE1vZGUgPT09IHRydWUgJiZcclxuICAgICAgICAgb3B0aW9ucy5hbGxvd05lc3RpbmcgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICBvcHRpb25zLmFsbG93TmVzdGluZyAhPT0gZmFsc2VcclxuICAgICAgKSB7XHJcbiAgICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgICAgXCJUaGUgdmFsdWUgb2YgYGFsbG93TmVzdGluZ2Agd2lsbCBiZSBpZ25vcmVkOyBpdCBtdXN0IGJlIGZhbHNlIHdoZW4gYGxpc3RNb2RlYCBpcyB0cnVlXCJcclxuICAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCByZXN1bHQ6IFByb2Nlc3NlZE9wdGlvbnNCYXNlID0ge1xyXG4gICAgICAgICBkZWZhdWx0Q29tcG9uZW50OiBvcHRpb25zLmRlZmF1bHRDb21wb25lbnQsXHJcbiAgICAgICAgIGluZGVudDogb3B0aW9ucy5pbmRlbnQgPz8gSU5ERU5ULFxyXG4gICAgICAgICBhbGxvd05lc3Rpbmc6XHJcbiAgICAgICAgICAgIG9wdGlvbnMubGlzdE1vZGUgIT09IHRydWUgJiYgKG9wdGlvbnMuYWxsb3dOZXN0aW5nID8/IHRydWUpLFxyXG4gICAgICAgICBhbGxvd0RyYWdnaW5nOiBvcHRpb25zLmFsbG93RHJhZ2dpbmcgPz8gdHJ1ZSxcclxuICAgICAgICAgYWxsb3dEcm9wOiBvcHRpb25zLmFsbG93RHJvcCA/PyAoKCkgPT4gdHJ1ZSksXHJcbiAgICAgICAgIGxpc3RNb2RlOiBvcHRpb25zLmxpc3RNb2RlID8/IGZhbHNlLFxyXG4gICAgICAgICBpdGVtc1BlclBhZ2U6IG9wdGlvbnMubGlzdE1vZGUgPyBpdGVtc1BlclBhZ2UgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgIHBhZ2U6IG9wdGlvbnMubGlzdE1vZGUgPyBwYWdlIDogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcbiAgICAgIHJldHVybiByZXN1bHQgYXMgUHJvY2Vzc2VkT3B0aW9ucztcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSByZWJ1aWxkVHJlZURhdGEoKTogdm9pZCB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICAgdGhpcy5vcmlnaW5hbERhdGEgPT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICB0aGlzLnRyZWVEYXRhID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgdGhpcy50cmVlT3B0aW9ucyA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgIHRoaXMuaG9zdCA9PT0gdW5kZWZpbmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUcmVlIGRhdGEgbm90IGluaXRpYWxpemVkXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudHJlZURhdGEgPSBbXTtcclxuICAgICAgZm9yIChjb25zdCBicmFuY2ggb2YgdGhpcy50cmVlTW9kZWwuZ2V0Q2hpbGRyZW4oKSkge1xyXG4gICAgICAgICB0aGlzLnRyZWVEYXRhLnB1c2godGhpcy5yZWJ1aWxkQnJhbmNoKGJyYW5jaCkpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChcclxuICAgICAgICAgdGhpcy50cmVlT3B0aW9ucy5saXN0TW9kZSA9PT0gdHJ1ZSAmJlxyXG4gICAgICAgICB0aGlzLnRyZWVPcHRpb25zLml0ZW1zUGVyUGFnZSA8IEluZmluaXR5XHJcbiAgICAgICkge1xyXG4gICAgICAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSB0aGlzLnRyZWVPcHRpb25zLml0ZW1zUGVyUGFnZTtcclxuICAgICAgICAgY29uc3Qgc3RhcnQgPSBpdGVtc1BlclBhZ2UgKiAodGhpcy50cmVlT3B0aW9ucy5wYWdlIC0gMSk7XHJcbiAgICAgICAgIHRoaXMub3JpZ2luYWxEYXRhLnNwbGljZShzdGFydCwgaXRlbXNQZXJQYWdlLCAuLi50aGlzLnRyZWVEYXRhKTtcclxuICAgICAgICAgaWYgKHRoaXMudHJlZURhdGEubGVuZ3RoICE9PSBpdGVtc1BlclBhZ2UpIHtcclxuICAgICAgICAgICAgbGV0IGFjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgIHRoaXMudHJlZURhdGEubGVuZ3RoIDwgaXRlbXNQZXJQYWdlICYmXHJcbiAgICAgICAgICAgICAgIHN0YXJ0ICsgaXRlbXNQZXJQYWdlIDw9IHRoaXMub3JpZ2luYWxEYXRhLmxlbmd0aFxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgLy9UaGUgY3VycmVudCBwYWdlIGRvZXMgbm90IGhhdmUgZW5vdWdoIG5vZGVzLiBBZGQgc29tZSB0byB0aGUgdmlldyBmcm9tIHRoZSBuZXh0IHBhZ2UuXHJcbiAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gaXRlbXNQZXJQYWdlIC0gdGhpcy50cmVlRGF0YS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgIGZvciAoXHJcbiAgICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IGl0ZW1zUGVyUGFnZSAtIDE7XHJcbiAgICAgICAgICAgICAgICAgIGluZGV4IDwgaXRlbXNQZXJQYWdlICsgY291bnQgLSAxO1xyXG4gICAgICAgICAgICAgICAgICBpbmRleCsrXHJcbiAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBicmFuY2ggPSBuZXcgQnJhbmNoKHRoaXMub3JpZ2luYWxEYXRhW3N0YXJ0ICsgaW5kZXhdKTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy50cmVlTW9kZWwuYXBwZW5kQ2hpbGQoYnJhbmNoKTtcclxuICAgICAgICAgICAgICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gdGhpcy5jb21wb25lbnRDcmVhdG9yU2VydmljZS5hcHBlbmRDb21wb25lbnQ8TGltYmxlVHJlZU5vZGVDb21wb25lbnQ+KFxyXG4gICAgICAgICAgICAgICAgICAgICBMaW1ibGVUcmVlTm9kZUNvbXBvbmVudCxcclxuICAgICAgICAgICAgICAgICAgICAgdGhpcy5ob3N0XHJcbiAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5icmFuY2ggPSBicmFuY2g7XHJcbiAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5wYXJlbnRIb3N0ID0gdGhpcy5ob3N0O1xyXG4gICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgIGFjdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmVlRGF0YS5sZW5ndGggPiBpdGVtc1BlclBhZ2UpIHtcclxuICAgICAgICAgICAgICAgLy9UaGUgY3VycmVudCBwYWdlIGhhcyB0b28gbWFueSBub2Rlcy4gUmVtb3ZlIHNvbWUgb2YgdGhlbSBmcm9tIHRoZSB2aWV3LlxyXG4gICAgICAgICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMudHJlZURhdGEubGVuZ3RoIC0gaXRlbXNQZXJQYWdlO1xyXG4gICAgICAgICAgICAgICBmb3IgKFxyXG4gICAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSBpdGVtc1BlclBhZ2UgKyBjb3VudCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgIGluZGV4ID49IGl0ZW1zUGVyUGFnZTtcclxuICAgICAgICAgICAgICAgICAgaW5kZXgtLVxyXG4gICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy50cmVlTW9kZWwucmVtb3ZlQ2hpbGQoaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLmhvc3QucmVtb3ZlKGluZGV4KTtcclxuICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICBhY3Rpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChhY3Rpb24gPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgY29uc3QgZW5kID0gc3RhcnQgKyBpdGVtc1BlclBhZ2U7XHJcbiAgICAgICAgICAgICAgIHRoaXMudHJlZURhdGEgPSB0aGlzLm9yaWdpbmFsRGF0YS5zbGljZShzdGFydCwgZW5kKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIHRoaXMub3JpZ2luYWxEYXRhLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgIHRoaXMub3JpZ2luYWxEYXRhLnB1c2goLi4udGhpcy50cmVlRGF0YSk7XHJcbiAgICAgIH1cclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSByZWJ1aWxkQnJhbmNoKGJyYW5jaDogQnJhbmNoPGFueT4pOiBMaW1ibGVUcmVlTm9kZSB7XHJcbiAgICAgIGNvbnN0IHRlbXA6IExpbWJsZVRyZWVOb2RlID0gYnJhbmNoLmRhdGE7XHJcbiAgICAgIHRlbXAubm9kZXMgPSBbXTtcclxuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBicmFuY2guZ2V0Q2hpbGRyZW4oKSkge1xyXG4gICAgICAgICB0ZW1wLm5vZGVzLnB1c2godGhpcy5yZWJ1aWxkQnJhbmNoKGNoaWxkKSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHRlbXA7XHJcbiAgIH1cclxufVxyXG4iXX0=