@limble/limble-tree 0.13.0 → 1.0.0-alpha.1

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 (159) hide show
  1. package/README.md +22 -129
  2. package/esm2020/lib/components/branch/branch.component.mjs +87 -0
  3. package/esm2020/lib/components/dropzone/dropzone.component.mjs +35 -0
  4. package/esm2020/lib/components/host-component.interface.mjs +2 -0
  5. package/esm2020/lib/components/node-component.interface.mjs +2 -0
  6. package/esm2020/lib/components/root/root.component.mjs +37 -0
  7. package/esm2020/lib/core/branch-options.interface.mjs +2 -0
  8. package/esm2020/lib/core/configuration/configuration.mjs +17 -0
  9. package/esm2020/lib/core/configuration/tree-options.interface.mjs +2 -0
  10. package/esm2020/lib/core/index.mjs +6 -0
  11. package/esm2020/lib/core/relationship.interface.mjs +2 -0
  12. package/esm2020/lib/core/tree-branch/tree-branch.mjs +246 -0
  13. package/esm2020/lib/core/tree-node-base.mjs +68 -0
  14. package/esm2020/lib/core/tree-root/tree-root.mjs +69 -0
  15. package/esm2020/lib/core/tree-service/tree.service.mjs +19 -0
  16. package/esm2020/lib/errors/index.mjs +2 -0
  17. package/esm2020/lib/errors/tree-error.mjs +3 -0
  18. package/esm2020/lib/events/drag/drag-end-event.mjs +28 -0
  19. package/esm2020/lib/events/drag/drag-start-event.mjs +12 -0
  20. package/esm2020/lib/events/drag/drop-event.mjs +20 -0
  21. package/esm2020/lib/events/drag/index.mjs +4 -0
  22. package/esm2020/lib/events/index.mjs +3 -0
  23. package/esm2020/lib/events/relational/graft-event.mjs +24 -0
  24. package/esm2020/lib/events/relational/index.mjs +4 -0
  25. package/esm2020/lib/events/relational/prune-event.mjs +24 -0
  26. package/esm2020/lib/events/relational/relational-tree-event.interface.mjs +2 -0
  27. package/esm2020/lib/extras/collapse/collapse.mjs +33 -0
  28. package/esm2020/lib/extras/collapse/collapse.module.mjs +15 -0
  29. package/esm2020/lib/extras/collapse/collapse.service.mjs +20 -0
  30. package/esm2020/lib/extras/collapse/index.mjs +3 -0
  31. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.mjs +89 -0
  32. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.module.mjs +19 -0
  33. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.service.mjs +28 -0
  34. package/esm2020/lib/extras/drag-and-drop/drag-state.mjs +47 -0
  35. package/esm2020/lib/extras/drag-and-drop/draggable.directive.mjs +30 -0
  36. package/esm2020/lib/extras/drag-and-drop/dragover-no-change-detect.mjs +40 -0
  37. package/esm2020/lib/extras/drag-and-drop/dropzone-renderer.mjs +176 -0
  38. package/esm2020/lib/extras/drag-and-drop/index.mjs +5 -0
  39. package/esm2020/lib/legacy/index.mjs +7 -0
  40. package/esm2020/lib/legacy/legacy-component-obj.interface.mjs +2 -0
  41. package/esm2020/lib/legacy/legacy-tree-data.interface.mjs +2 -0
  42. package/esm2020/lib/legacy/legacy-tree-options.interface.mjs +2 -0
  43. package/esm2020/lib/legacy/legacy-tree.mjs +74 -0
  44. package/esm2020/lib/legacy/limble-tree-legacy.module.mjs +20 -0
  45. package/esm2020/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +78 -0
  46. package/esm2020/lib/limble-tree.module.mjs +21 -47
  47. package/esm2020/lib/structure/branchable.interface.mjs +2 -0
  48. package/esm2020/lib/structure/container-tree-node.interface.mjs +2 -0
  49. package/esm2020/lib/structure/content-container.interface.mjs +2 -0
  50. package/esm2020/lib/structure/event-conduit.interface.mjs +2 -0
  51. package/esm2020/lib/structure/graftable.interface.mjs +2 -0
  52. package/esm2020/lib/structure/index.mjs +12 -0
  53. package/esm2020/lib/structure/tree-branch-node.interface.mjs +2 -0
  54. package/esm2020/lib/structure/tree-event.interface.mjs +2 -0
  55. package/esm2020/lib/structure/tree-node.interface.mjs +2 -0
  56. package/esm2020/lib/structure/tree-plot.mjs +2 -0
  57. package/esm2020/lib/structure/tree-relationship.interface.mjs +2 -0
  58. package/esm2020/lib/structure/tree-root.node.interface.mjs +2 -0
  59. package/esm2020/limble-limble-tree.mjs +4 -4
  60. package/esm2020/public-api.mjs +12 -6
  61. package/esm2020/shared/assert.mjs +7 -0
  62. package/fesm2015/limble-limble-tree.mjs +1280 -2226
  63. package/fesm2015/limble-limble-tree.mjs.map +1 -1
  64. package/fesm2020/limble-limble-tree.mjs +1270 -2132
  65. package/fesm2020/limble-limble-tree.mjs.map +1 -1
  66. package/index.d.ts +5 -5
  67. package/lib/components/branch/branch.component.d.ts +26 -0
  68. package/lib/components/dropzone/dropzone.component.d.ts +13 -0
  69. package/lib/components/host-component.interface.d.ts +6 -0
  70. package/lib/components/node-component.interface.d.ts +5 -0
  71. package/lib/components/root/root.component.d.ts +14 -0
  72. package/lib/core/branch-options.interface.d.ts +14 -0
  73. package/lib/core/configuration/configuration.d.ts +11 -0
  74. package/lib/core/configuration/tree-options.interface.d.ts +35 -0
  75. package/lib/core/index.d.ts +5 -0
  76. package/lib/core/relationship.interface.d.ts +6 -0
  77. package/lib/core/tree-branch/tree-branch.d.ts +44 -0
  78. package/lib/core/tree-node-base.d.ts +26 -0
  79. package/lib/core/tree-root/tree-root.d.ts +28 -0
  80. package/lib/core/tree-service/tree.service.d.ts +9 -0
  81. package/lib/errors/index.d.ts +1 -0
  82. package/lib/errors/tree-error.d.ts +2 -0
  83. package/lib/events/drag/drag-end-event.d.ts +25 -0
  84. package/lib/events/drag/drag-start-event.d.ts +8 -0
  85. package/lib/events/drag/drop-event.d.ts +16 -0
  86. package/lib/events/drag/index.d.ts +3 -0
  87. package/lib/events/index.d.ts +2 -0
  88. package/lib/events/relational/graft-event.d.ts +15 -0
  89. package/lib/events/relational/index.d.ts +3 -0
  90. package/lib/events/relational/prune-event.d.ts +15 -0
  91. package/lib/events/relational/relational-tree-event.interface.d.ts +6 -0
  92. package/lib/extras/collapse/collapse.d.ts +11 -0
  93. package/lib/extras/collapse/collapse.module.d.ts +6 -0
  94. package/lib/extras/collapse/collapse.service.d.ts +9 -0
  95. package/lib/extras/collapse/index.d.ts +2 -0
  96. package/lib/extras/drag-and-drop/drag-and-drop.d.ts +17 -0
  97. package/lib/extras/drag-and-drop/drag-and-drop.module.d.ts +8 -0
  98. package/lib/extras/drag-and-drop/drag-and-drop.service.d.ts +16 -0
  99. package/lib/extras/drag-and-drop/drag-state.d.ts +23 -0
  100. package/lib/extras/drag-and-drop/draggable.directive.d.ts +12 -0
  101. package/lib/{custom-event-bindings/dragover-no-change-detect.directive.d.ts → extras/drag-and-drop/dragover-no-change-detect.d.ts} +14 -14
  102. package/lib/extras/drag-and-drop/dropzone-renderer.d.ts +28 -0
  103. package/lib/extras/drag-and-drop/index.d.ts +4 -0
  104. package/lib/legacy/index.d.ts +6 -0
  105. package/lib/legacy/legacy-component-obj.interface.d.ts +13 -0
  106. package/lib/legacy/legacy-tree-data.interface.d.ts +18 -0
  107. package/lib/legacy/legacy-tree-options.interface.d.ts +34 -0
  108. package/lib/legacy/legacy-tree.d.ts +14 -0
  109. package/lib/legacy/limble-tree-legacy.module.d.ts +8 -0
  110. package/lib/legacy/limble-tree-root/limble-tree-root.component.d.ts +28 -0
  111. package/lib/limble-tree.module.d.ts +9 -14
  112. package/lib/structure/branchable.interface.d.ts +5 -0
  113. package/lib/structure/container-tree-node.interface.d.ts +3 -0
  114. package/lib/structure/content-container.interface.d.ts +3 -0
  115. package/lib/structure/event-conduit.interface.d.ts +6 -0
  116. package/lib/structure/graftable.interface.d.ts +6 -0
  117. package/lib/structure/index.d.ts +11 -0
  118. package/lib/structure/tree-branch-node.interface.d.ts +5 -0
  119. package/lib/structure/tree-event.interface.d.ts +5 -0
  120. package/lib/structure/tree-node.interface.d.ts +9 -0
  121. package/lib/structure/tree-plot.d.ts +1 -0
  122. package/lib/structure/tree-relationship.interface.d.ts +7 -0
  123. package/lib/structure/tree-root.node.interface.d.ts +2 -0
  124. package/package.json +6 -14
  125. package/public-api.d.ts +8 -3
  126. package/shared/assert.d.ts +1 -0
  127. package/esm2020/lib/classes/Branch.mjs +0 -153
  128. package/esm2020/lib/classes/DropZone.mjs +0 -71
  129. package/esm2020/lib/classes/DropZoneLocation.mjs +0 -16
  130. package/esm2020/lib/custom-event-bindings/dragleave-no-change-detect.directive.mjs +0 -33
  131. package/esm2020/lib/custom-event-bindings/dragover-no-change-detect.directive.mjs +0 -39
  132. package/esm2020/lib/drop-zone/drop-zone.component.mjs +0 -75
  133. package/esm2020/lib/limble-tree-branch/limble-tree-branch.component.mjs +0 -110
  134. package/esm2020/lib/limble-tree-node/limble-tree-node.component.mjs +0 -467
  135. package/esm2020/lib/limble-tree-placeholder/limble-tree-placeholder.component.mjs +0 -70
  136. package/esm2020/lib/limble-tree-root/drop-zone.service.mjs +0 -376
  137. package/esm2020/lib/limble-tree-root/limble-tree-root.component.mjs +0 -172
  138. package/esm2020/lib/limble-tree-root/tree-construction-status.service.mjs +0 -33
  139. package/esm2020/lib/limble-tree-root/tree.service.mjs +0 -297
  140. package/esm2020/lib/singletons/component-creator.service.mjs +0 -19
  141. package/esm2020/lib/singletons/drag-state.service.mjs +0 -63
  142. package/esm2020/lib/singletons/global-events.service.mjs +0 -136
  143. package/esm2020/lib/util.mjs +0 -74
  144. package/lib/classes/Branch.d.ts +0 -26
  145. package/lib/classes/DropZone.d.ts +0 -27
  146. package/lib/classes/DropZoneLocation.d.ts +0 -9
  147. package/lib/custom-event-bindings/dragleave-no-change-detect.directive.d.ts +0 -13
  148. package/lib/drop-zone/drop-zone.component.d.ts +0 -18
  149. package/lib/limble-tree-branch/limble-tree-branch.component.d.ts +0 -28
  150. package/lib/limble-tree-node/limble-tree-node.component.d.ts +0 -53
  151. package/lib/limble-tree-placeholder/limble-tree-placeholder.component.d.ts +0 -21
  152. package/lib/limble-tree-root/drop-zone.service.d.ts +0 -62
  153. package/lib/limble-tree-root/limble-tree-root.component.d.ts +0 -37
  154. package/lib/limble-tree-root/tree-construction-status.service.d.ts +0 -15
  155. package/lib/limble-tree-root/tree.service.d.ts +0 -132
  156. package/lib/singletons/component-creator.service.d.ts +0 -9
  157. package/lib/singletons/drag-state.service.d.ts +0 -35
  158. package/lib/singletons/global-events.service.d.ts +0 -13
  159. package/lib/util.d.ts +0 -13
@@ -1,70 +0,0 @@
1
- import { ChangeDetectionStrategy, Component } from "@angular/core";
2
- import { DropZone } from "../classes/DropZone";
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "../limble-tree-root/drop-zone.service";
5
- import * as i2 from "../limble-tree-root/tree.service";
6
- import * as i3 from "../limble-tree-root/tree-construction-status.service";
7
- import * as i4 from "../drop-zone/drop-zone.component";
8
- import * as i5 from "../custom-event-bindings/dragover-no-change-detect.directive";
9
- export class LimbleTreePlaceholderComponent {
10
- constructor(dropZoneService, changeDetectorRef, treeService, treeConstructionStatus) {
11
- this.dropZoneService = dropZoneService;
12
- this.changeDetectorRef = changeDetectorRef;
13
- this.treeService = treeService;
14
- this.treeConstructionStatus = treeConstructionStatus;
15
- this.treeConstructionStatus.constructing();
16
- //This logic is very similar to what the lifecycle hooks of this component do.
17
- //We use this subscription because sometimes we can't wait for the lifecycle hooks:
18
- //Specifically, the drop zone registration and deregistration sometimes can't happen
19
- //asynchronously without causing bugs. So we handle it synchronously here as well.
20
- this.placeholderSubscription = this.treeService.placeholder$.subscribe((value) => {
21
- if (this.dropZone === undefined) {
22
- return;
23
- }
24
- this.dropZoneService.removeDropZone(this.dropZone);
25
- if (value === true) {
26
- this.dropZoneService.addDropZone(this.dropZone);
27
- this.dropZone.setHost(this.treeService.host);
28
- }
29
- });
30
- }
31
- ngOnInit() {
32
- this.dropZone = new DropZone([], 0);
33
- this.dropZoneService.addDropZone(this.dropZone);
34
- }
35
- ngAfterViewInit() {
36
- if (this.dropZone === undefined) {
37
- throw new Error("placeholder drop zone is not defined");
38
- }
39
- this.dropZone.setHost(this.treeService.host);
40
- this.treeConstructionStatus.doneConstructing();
41
- this.changeDetectorRef.detectChanges();
42
- }
43
- dragoverHandler() {
44
- if (this.dropZone === undefined) {
45
- return;
46
- }
47
- this.dropZoneService.showDropZoneFamily(this.dropZone);
48
- }
49
- ngOnDestroy() {
50
- this.placeholderSubscription.unsubscribe();
51
- if (this.dropZone === undefined) {
52
- throw new Error("could not remove placeholder drop zone");
53
- }
54
- this.dropZoneService.removeDropZone(this.dropZone);
55
- }
56
- }
57
- LimbleTreePlaceholderComponent.ɵfac = function LimbleTreePlaceholderComponent_Factory(t) { return new (t || LimbleTreePlaceholderComponent)(i0.ɵɵdirectiveInject(i1.DropZoneService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i2.TreeService), i0.ɵɵdirectiveInject(i3.TreeConstructionStatus)); };
58
- LimbleTreePlaceholderComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LimbleTreePlaceholderComponent, selectors: [["limble-tree-placeholder"]], decls: 2, vars: 1, consts: [[3, "dropZone"], [1, "placeholder", 3, "dragoverNoChangeDetect"]], template: function LimbleTreePlaceholderComponent_Template(rf, ctx) { if (rf & 1) {
59
- i0.ɵɵelement(0, "drop-zone", 0);
60
- i0.ɵɵelementStart(1, "div", 1);
61
- i0.ɵɵlistener("dragoverNoChangeDetect", function LimbleTreePlaceholderComponent_Template_div_dragoverNoChangeDetect_1_listener() { return ctx.dragoverHandler(); });
62
- i0.ɵɵelementEnd();
63
- } if (rf & 2) {
64
- i0.ɵɵproperty("dropZone", ctx.dropZone);
65
- } }, dependencies: [i4.DropZoneComponent, i5.DragoverNoChangeDetectDirective], styles: [".placeholder[_ngcontent-%COMP%]{width:100%;height:20px}"], changeDetection: 0 });
66
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LimbleTreePlaceholderComponent, [{
67
- type: Component,
68
- args: [{ selector: "limble-tree-placeholder", changeDetection: ChangeDetectionStrategy.OnPush, template: "<drop-zone [dropZone]=\"dropZone\"></drop-zone>\n<div class=\"placeholder\" (dragoverNoChangeDetect)=\"dragoverHandler()\"></div>\n", styles: [".placeholder{width:100%;height:20px}\n"] }]
69
- }], function () { return [{ type: i1.DropZoneService }, { type: i0.ChangeDetectorRef }, { type: i2.TreeService }, { type: i3.TreeConstructionStatus }]; }, null); })();
70
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltYmxlLXRyZWUtcGxhY2Vob2xkZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbGltYmxlLXRyZWUvc3JjL2xpYi9saW1ibGUtdHJlZS1wbGFjZWhvbGRlci9saW1ibGUtdHJlZS1wbGFjZWhvbGRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLXBsYWNlaG9sZGVyL2xpbWJsZS10cmVlLXBsYWNlaG9sZGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFSix1QkFBdUIsRUFFdkIsU0FBUyxFQUdYLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7OztBQVcvQyxNQUFNLE9BQU8sOEJBQThCO0lBS3hDLFlBQ29CLGVBQWdDLEVBQ2hDLGlCQUFvQyxFQUNwQyxXQUF3QixFQUN4QixzQkFBOEM7UUFIOUMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUUvRCxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDM0MsOEVBQThFO1FBQzlFLG1GQUFtRjtRQUNuRixvRkFBb0Y7UUFDcEYsa0ZBQWtGO1FBQ2xGLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQ25FLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDUCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFO2dCQUM5QixPQUFPO2FBQ1Q7WUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkQsSUFBSSxLQUFLLEtBQUssSUFBSSxFQUFFO2dCQUNqQixJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDL0M7UUFDSixDQUFDLENBQ0gsQ0FBQztJQUNMLENBQUM7SUFFTSxRQUFRO1FBQ1osSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFTSxlQUFlO1FBQ25CLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUU7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsc0JBQXNCLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVNLGVBQWU7UUFDbkIsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRTtZQUM5QixPQUFPO1NBQ1Q7UUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU0sV0FBVztRQUNmLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQztTQUM1RDtRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN0RCxDQUFDOzs0R0F6RFMsOEJBQThCO2lGQUE5Qiw4QkFBOEI7UUNwQjNDLCtCQUE2QztRQUM3Qyw4QkFBc0U7UUFBN0MsMElBQTBCLHFCQUFpQixJQUFDO1FBQUMsaUJBQU07O1FBRGpFLHVDQUFxQjs7dUZEb0JuQiw4QkFBOEI7Y0FOMUMsU0FBUzsyQkFDRyx5QkFBeUIsbUJBR2xCLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgQWZ0ZXJWaWV3SW5pdCxcbiAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICBDb21wb25lbnQsXG4gICBPbkRlc3Ryb3ksXG4gICBPbkluaXRcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBEcm9wWm9uZSB9IGZyb20gXCIuLi9jbGFzc2VzL0Ryb3Bab25lXCI7XG5pbXBvcnQgeyBEcm9wWm9uZVNlcnZpY2UgfSBmcm9tIFwiLi4vbGltYmxlLXRyZWUtcm9vdC9kcm9wLXpvbmUuc2VydmljZVwiO1xuaW1wb3J0IHsgVHJlZUNvbnN0cnVjdGlvblN0YXR1cyB9IGZyb20gXCIuLi9saW1ibGUtdHJlZS1yb290L3RyZWUtY29uc3RydWN0aW9uLXN0YXR1cy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBUcmVlU2VydmljZSB9IGZyb20gXCIuLi9saW1ibGUtdHJlZS1yb290L3RyZWUuc2VydmljZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgIHNlbGVjdG9yOiBcImxpbWJsZS10cmVlLXBsYWNlaG9sZGVyXCIsXG4gICB0ZW1wbGF0ZVVybDogXCIuL2xpbWJsZS10cmVlLXBsYWNlaG9sZGVyLmNvbXBvbmVudC5odG1sXCIsXG4gICBzdHlsZVVybHM6IFtcIi4vbGltYmxlLXRyZWUtcGxhY2Vob2xkZXIuY29tcG9uZW50LnNjc3NcIl0sXG4gICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBMaW1ibGVUcmVlUGxhY2Vob2xkZXJDb21wb25lbnRcbiAgIGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgcHVibGljIGRyb3Bab25lOiBEcm9wWm9uZSB8IHVuZGVmaW5lZDtcbiAgIHByaXZhdGUgcmVhZG9ubHkgcGxhY2Vob2xkZXJTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcm9wWm9uZVNlcnZpY2U6IERyb3Bab25lU2VydmljZSxcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgcHJpdmF0ZSByZWFkb25seSB0cmVlU2VydmljZTogVHJlZVNlcnZpY2UsXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVDb25zdHJ1Y3Rpb25TdGF0dXM6IFRyZWVDb25zdHJ1Y3Rpb25TdGF0dXNcbiAgICkge1xuICAgICAgdGhpcy50cmVlQ29uc3RydWN0aW9uU3RhdHVzLmNvbnN0cnVjdGluZygpO1xuICAgICAgLy9UaGlzIGxvZ2ljIGlzIHZlcnkgc2ltaWxhciB0byB3aGF0IHRoZSBsaWZlY3ljbGUgaG9va3Mgb2YgdGhpcyBjb21wb25lbnQgZG8uXG4gICAgICAvL1dlIHVzZSB0aGlzIHN1YnNjcmlwdGlvbiBiZWNhdXNlIHNvbWV0aW1lcyB3ZSBjYW4ndCB3YWl0IGZvciB0aGUgbGlmZWN5Y2xlIGhvb2tzOlxuICAgICAgLy9TcGVjaWZpY2FsbHksIHRoZSBkcm9wIHpvbmUgcmVnaXN0cmF0aW9uIGFuZCBkZXJlZ2lzdHJhdGlvbiBzb21ldGltZXMgY2FuJ3QgaGFwcGVuXG4gICAgICAvL2FzeW5jaHJvbm91c2x5IHdpdGhvdXQgY2F1c2luZyBidWdzLiBTbyB3ZSBoYW5kbGUgaXQgc3luY2hyb25vdXNseSBoZXJlIGFzIHdlbGwuXG4gICAgICB0aGlzLnBsYWNlaG9sZGVyU3Vic2NyaXB0aW9uID0gdGhpcy50cmVlU2VydmljZS5wbGFjZWhvbGRlciQuc3Vic2NyaWJlKFxuICAgICAgICAgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5kcm9wWm9uZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5yZW1vdmVEcm9wWm9uZSh0aGlzLmRyb3Bab25lKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2UuYWRkRHJvcFpvbmUodGhpcy5kcm9wWm9uZSk7XG4gICAgICAgICAgICAgICB0aGlzLmRyb3Bab25lLnNldEhvc3QodGhpcy50cmVlU2VydmljZS5ob3N0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICk7XG4gICB9XG5cbiAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgIHRoaXMuZHJvcFpvbmUgPSBuZXcgRHJvcFpvbmUoW10sIDApO1xuICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2UuYWRkRHJvcFpvbmUodGhpcy5kcm9wWm9uZSk7XG4gICB9XG5cbiAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICBpZiAodGhpcy5kcm9wWm9uZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwbGFjZWhvbGRlciBkcm9wIHpvbmUgaXMgbm90IGRlZmluZWRcIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRyb3Bab25lLnNldEhvc3QodGhpcy50cmVlU2VydmljZS5ob3N0KTtcbiAgICAgIHRoaXMudHJlZUNvbnN0cnVjdGlvblN0YXR1cy5kb25lQ29uc3RydWN0aW5nKCk7XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgIH1cblxuICAgcHVibGljIGRyYWdvdmVySGFuZGxlcigpIHtcbiAgICAgIGlmICh0aGlzLmRyb3Bab25lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLnNob3dEcm9wWm9uZUZhbWlseSh0aGlzLmRyb3Bab25lKTtcbiAgIH1cblxuICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgdGhpcy5wbGFjZWhvbGRlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgaWYgKHRoaXMuZHJvcFpvbmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY291bGQgbm90IHJlbW92ZSBwbGFjZWhvbGRlciBkcm9wIHpvbmVcIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5yZW1vdmVEcm9wWm9uZSh0aGlzLmRyb3Bab25lKTtcbiAgIH1cbn1cbiIsIjxkcm9wLXpvbmUgW2Ryb3Bab25lXT1cImRyb3Bab25lXCI+PC9kcm9wLXpvbmU+XG48ZGl2IGNsYXNzPVwicGxhY2Vob2xkZXJcIiAoZHJhZ292ZXJOb0NoYW5nZURldGVjdCk9XCJkcmFnb3ZlckhhbmRsZXIoKVwiPjwvZGl2PlxuIl19
@@ -1,376 +0,0 @@
1
- import { Injectable } from "@angular/core";
2
- import { arraysAreEqual, isNestingAllowed } from "../util";
3
- import { DropZone } from "../classes/DropZone";
4
- import { DropZoneLocation } from "../classes/DropZoneLocation";
5
- import { Subject } from "rxjs";
6
- import { debounce, filter, tap } from "rxjs/operators";
7
- import * as i0 from "@angular/core";
8
- import * as i1 from "../singletons/drag-state.service";
9
- import * as i2 from "./tree-construction-status.service";
10
- function sortFamily(memberA, memberB) {
11
- const aCoordinates = memberA.getFullInsertCoordinates();
12
- const bCoordinates = memberB.getFullInsertCoordinates();
13
- if (aCoordinates.length > bCoordinates.length) {
14
- return -1;
15
- }
16
- if (aCoordinates.length < bCoordinates.length) {
17
- return 1;
18
- }
19
- return 0;
20
- }
21
- export class DropZoneService {
22
- constructor(dragStateService, treeConstructionStatus) {
23
- this.dragStateService = dragStateService;
24
- this.dropZoneArchive = new Set();
25
- this.dropZoneInventory = [];
26
- this.dropZoneFamilies = [];
27
- this.visibleFamily = null;
28
- this.activeDropZone = null;
29
- this.tempFamilies = [];
30
- this.setActiveDropZone(null);
31
- let treeIsStable = false;
32
- const treeIsStable$ = treeConstructionStatus.stable$.pipe(tap((value) => {
33
- treeIsStable = value;
34
- }), filter((value) => value === true));
35
- this.update$ = new Subject();
36
- this.update$
37
- .pipe(debounce(() => {
38
- if (treeIsStable === true) {
39
- //If tree is stable, continue right away
40
- return Promise.resolve();
41
- }
42
- //If tree is not stable, wait for it to become so.
43
- return treeIsStable$;
44
- }))
45
- .subscribe(() => {
46
- setTimeout(() => {
47
- this.updateDropZones();
48
- });
49
- });
50
- }
51
- addDropZone(newDropZone) {
52
- this.dropZoneArchive.add(newDropZone);
53
- }
54
- /** hides all drop zones */
55
- clearVisibleZones() {
56
- if (this.visibleFamily !== null) {
57
- for (const member of this.visibleFamily.members) {
58
- member.isVisible(false);
59
- }
60
- this.visibleFamily = null;
61
- }
62
- this.setActiveDropZone(null);
63
- }
64
- getActiveDropZone() {
65
- return this.activeDropZone;
66
- }
67
- getDropZone(coordinates) {
68
- const parent = [...coordinates];
69
- parent.pop();
70
- const index = coordinates[coordinates.length - 1];
71
- const location = new DropZoneLocation(parent, index);
72
- return this.dropZoneInventory.find((dropZone) => DropZone.dropZoneLocationsAreEqual(dropZone, location));
73
- }
74
- init(tree, treeOptions) {
75
- this.tree = tree;
76
- this.treeOptions = treeOptions;
77
- this.update();
78
- }
79
- removeDropZone(dropZone) {
80
- this.dropZoneArchive.delete(dropZone);
81
- }
82
- /** hides all drop zones, deletes all the family assignments,
83
- * and empties the dropZoneInventory
84
- */
85
- reset() {
86
- this.clearVisibleZones();
87
- this.dropZoneFamilies.length = 0;
88
- this.dropZoneInventory.length = 0;
89
- }
90
- /**
91
- * Restores the service to its initial state: hides all drop zones,
92
- * deletes all the family assignments, and empties the dropZoneInventory
93
- * and dropZoneArchive.
94
- */
95
- restart() {
96
- this.reset();
97
- this.dropZoneArchive.clear();
98
- }
99
- restoreFamilies() {
100
- if (this.tempFamilies.length === 2) {
101
- this.dropZoneFamilies.pop();
102
- this.dropZoneFamilies.push(this.tempFamilies[0]);
103
- for (const member of this.tempFamilies[0].members) {
104
- member.setFamily(this.tempFamilies[0]);
105
- }
106
- if (this.tempFamilies[1] !== null) {
107
- this.dropZoneFamilies.push(this.tempFamilies[1]);
108
- for (const member of this.tempFamilies[1].members) {
109
- member.setFamily(this.tempFamilies[1]);
110
- }
111
- }
112
- this.tempFamilies = [];
113
- }
114
- }
115
- /**
116
- * Shows the drop zone family of the drop zone indicated by `coordinates`.
117
- */
118
- showDropZoneFamily(
119
- /** Note: this drop zone may not exist in the dropZoneInventory; we have to search the inventory based on its location */
120
- dropZone, options = { joinFamilies: false, activateLowestInsteadOfFounder: false }) {
121
- if (this.activeDropZone !== null &&
122
- DropZone.dropZoneLocationsAreEqual(this.activeDropZone, dropZone)) {
123
- //Already showing the family with the appropriate active drop zone
124
- return;
125
- }
126
- if (this.visibleFamily !== null || this.activeDropZone !== null) {
127
- this.clearVisibleZones();
128
- }
129
- const target = this.dropZoneInventory.find((zone) => DropZone.dropZoneLocationsAreEqual(zone, dropZone));
130
- if (target === undefined) {
131
- throw new Error(`Could not find drop zone to show. location: ${JSON.stringify(dropZone.getLocation())}`);
132
- }
133
- const family = target.getFamily();
134
- if (options.joinFamilies === true) {
135
- const location1 = dropZone.getLocation();
136
- const location2 = new DropZoneLocation([...location1.parentCoordinates], location1.insertIndex + 1);
137
- const target2 = this.dropZoneInventory.find((zone) => DropZone.dropZoneLocationsAreEqual(zone, location2));
138
- if (target2 === undefined) {
139
- throw new Error("Could not find drop zone to show");
140
- }
141
- const family2 = target2.getFamily();
142
- if (family === undefined || family2 === undefined) {
143
- throw new Error("No family");
144
- }
145
- const newFamily = {
146
- founder: family.founder,
147
- members: [...family.members]
148
- };
149
- this.showDropZone(family.founder, true);
150
- for (const member of family.members.sort(sortFamily)) {
151
- member.setFamily(newFamily);
152
- if (member !== family.founder) {
153
- if (this.activeDropZone === null) {
154
- //Failed to activate a zone so far, so activate this one instead
155
- this.showDropZone(member, true);
156
- }
157
- else {
158
- this.showDropZone(member);
159
- }
160
- }
161
- }
162
- for (const member of family2.members) {
163
- member.setFamily(newFamily);
164
- if (member.getLocation().parentCoordinates.length <
165
- target2.getLocation().parentCoordinates.length) {
166
- newFamily.members.push(member);
167
- this.showDropZone(member);
168
- }
169
- }
170
- //Temporarily store the old families
171
- this.tempFamilies = [family, family2];
172
- //Remove the old families
173
- const familyIndex = this.dropZoneFamilies.indexOf(family);
174
- this.dropZoneFamilies.splice(familyIndex, 1);
175
- const family2Index = this.dropZoneFamilies.indexOf(family2);
176
- this.dropZoneFamilies.splice(family2Index, 1);
177
- //Add the new family
178
- this.dropZoneFamilies.push(newFamily);
179
- this.visibleFamily = newFamily;
180
- }
181
- else {
182
- if (family === undefined) {
183
- throw new Error("No family");
184
- }
185
- this.visibleFamily = family;
186
- this.showDropZone(family.founder, true);
187
- if (family.members.length > 1) {
188
- for (const member of family.members.sort(sortFamily)) {
189
- if (member !== family.founder) {
190
- if (this.activeDropZone === null) {
191
- //Failed to activate a zone so far, so activate this one instead
192
- this.showDropZone(member, true);
193
- }
194
- else {
195
- this.showDropZone(member);
196
- }
197
- }
198
- }
199
- }
200
- }
201
- if (options.activateLowestInsteadOfFounder === true &&
202
- this.visibleFamily.members.length > 1) {
203
- const lowestMember = [...this.visibleFamily.members]
204
- .sort(sortFamily)
205
- .pop();
206
- if (lowestMember === undefined) {
207
- throw new Error("Could not get lowest member");
208
- }
209
- this.swapActiveDropZone(lowestMember);
210
- }
211
- }
212
- swapActiveDropZone(newActiveDropZone) {
213
- if (this.visibleFamily === null) {
214
- throw new Error("No visible family available for swapping");
215
- }
216
- const index = this.visibleFamily.members.findIndex((dropZone) => dropZone === newActiveDropZone);
217
- if (index === -1) {
218
- throw new Error("failed to swap active drop zone");
219
- }
220
- this.setActiveDropZone(newActiveDropZone);
221
- }
222
- update() {
223
- this.update$.next(null);
224
- }
225
- assignFamilies() {
226
- const orphanZones = [...this.dropZoneInventory];
227
- const deepestMembers = orphanZones
228
- .filter((zone) => {
229
- const location = zone.getLocation();
230
- return (location.insertIndex === 0 &&
231
- location.parentCoordinates.length > 0);
232
- })
233
- .sort((valueA, valueB) => {
234
- const aCoordinates = valueA.getFullInsertCoordinates();
235
- const bCoordinates = valueB.getFullInsertCoordinates();
236
- const length = Math.max(aCoordinates.length, bCoordinates.length);
237
- for (let index = 0; index < length; index++) {
238
- if ((aCoordinates[index] ?? -1) > (bCoordinates[index] ?? -1)) {
239
- return -1;
240
- }
241
- else if ((aCoordinates[index] ?? -1) < (bCoordinates[index] ?? -1)) {
242
- return 1;
243
- }
244
- }
245
- return 0;
246
- });
247
- for (const dropZone of deepestMembers) {
248
- if (!orphanZones.includes(dropZone)) {
249
- continue;
250
- }
251
- const family = {
252
- founder: dropZone,
253
- members: []
254
- };
255
- dropZone.setFamily(family);
256
- //See if there are any orphans that belong to this family and claim them.
257
- const cursor = [...dropZone.getFullInsertCoordinates()];
258
- while (cursor.length > 0) {
259
- const familyMemberIndex = orphanZones.findIndex((zone) => arraysAreEqual(zone.getFullInsertCoordinates(), cursor));
260
- if (familyMemberIndex !== -1) {
261
- const familyMember = orphanZones.splice(familyMemberIndex, 1)[0];
262
- family.members.push(familyMember);
263
- familyMember.setFamily(family);
264
- }
265
- cursor.pop();
266
- cursor[cursor.length - 1]++;
267
- }
268
- this.dropZoneFamilies.push(family);
269
- }
270
- for (const dropZone of orphanZones.filter((zone) => zone.getFullInsertCoordinates().length === 1)) {
271
- const family = {
272
- founder: dropZone,
273
- members: [dropZone]
274
- };
275
- dropZone.setFamily(family);
276
- this.dropZoneFamilies.push(family);
277
- orphanZones.splice(orphanZones.indexOf(dropZone), 1);
278
- }
279
- if (orphanZones.length !== 0) {
280
- let orphans = "";
281
- for (const zone of orphanZones) {
282
- orphans += `${JSON.stringify(zone.getLocation())}, `;
283
- }
284
- orphans = orphans.slice(0, orphans.length - 2);
285
- throw new Error(`Some zones were not assigned to a family. The orphan zones have the following locations: ${orphans}`);
286
- }
287
- }
288
- buildInventory() {
289
- //We do this funky string array because it is faster than doing direct array comparisons
290
- const inventoryCoordinates = [];
291
- for (const dropZone of this.dropZoneArchive) {
292
- const coordinates = dropZone.getFullInsertCoordinates().join(",");
293
- if (inventoryCoordinates.includes(coordinates)) {
294
- dropZone.isRendered(false);
295
- }
296
- else {
297
- this.dropZoneInventory.push(dropZone);
298
- inventoryCoordinates.push(coordinates);
299
- dropZone.isRendered(true);
300
- }
301
- }
302
- }
303
- setActiveDropZone(dropZone) {
304
- if (this.activeDropZone !== null) {
305
- this.activeDropZone.isActive(false);
306
- }
307
- this.activeDropZone = dropZone;
308
- if (this.activeDropZone !== null &&
309
- this.dragStateService.getState() !== "droppable") {
310
- this.dragStateService.droppable();
311
- }
312
- else if (this.activeDropZone === null &&
313
- this.dragStateService.getState() === "droppable") {
314
- this.dragStateService.notDroppable();
315
- }
316
- if (this.activeDropZone !== null) {
317
- this.activeDropZone.isActive(true);
318
- }
319
- }
320
- showDropZone(dropZone, active = false) {
321
- if (this.tree === undefined) {
322
- throw new Error("DropZoneService not initialized");
323
- }
324
- if (!this.zoneIsAllowed(dropZone)) {
325
- //User settings indicate to skip this drop zone
326
- return false;
327
- }
328
- const parent = this.tree.findByCoordinates(dropZone.getLocation().parentCoordinates);
329
- if (parent === undefined) {
330
- throw new Error("Bad family member");
331
- }
332
- dropZone.isVisible(true);
333
- if (active === true) {
334
- this.setActiveDropZone(dropZone);
335
- }
336
- return true;
337
- }
338
- updateDropZones() {
339
- this.reset();
340
- this.buildInventory();
341
- this.assignFamilies();
342
- }
343
- zoneIsAllowed(dropZone) {
344
- if (this.treeOptions === undefined || this.tree === undefined) {
345
- throw new Error("dropZoneService not initialized");
346
- }
347
- const data = this.dragStateService.getData();
348
- if (data === undefined) {
349
- throw new Error("Can't get dragged node");
350
- }
351
- const parentCoordinates = dropZone.getLocation().parentCoordinates;
352
- const dropZoneParent = this.tree.findByCoordinates(parentCoordinates);
353
- if (dropZoneParent === undefined) {
354
- throw new Error("Could not get drop zone parent");
355
- }
356
- if (parentCoordinates.length > 0 &&
357
- !isNestingAllowed(this.treeOptions, dropZoneParent.data)) {
358
- return false;
359
- }
360
- const dropZoneIndex = dropZone.getLocation().insertIndex;
361
- if (dropZoneIndex === undefined) {
362
- throw new Error("Could not get drop zone index");
363
- }
364
- const draggedNode = data.branch;
365
- if (!this.treeOptions.allowDrop(draggedNode.data, dropZoneParent.data, dropZoneIndex)) {
366
- return false;
367
- }
368
- return true;
369
- }
370
- }
371
- DropZoneService.ɵfac = function DropZoneService_Factory(t) { return new (t || DropZoneService)(i0.ɵɵinject(i1.DragStateService), i0.ɵɵinject(i2.TreeConstructionStatus)); };
372
- DropZoneService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: DropZoneService, factory: DropZoneService.ɵfac });
373
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DropZoneService, [{
374
- type: Injectable
375
- }], function () { return [{ type: i1.DragStateService }, { type: i2.TreeConstructionStatus }]; }, null); })();
376
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC16b25lLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLXJvb3QvZHJvcC16b25lLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUkzQyxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzNELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRS9CLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBU3ZELFNBQVMsVUFBVSxDQUFDLE9BQWlCLEVBQUUsT0FBaUI7SUFDckQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixFQUFFLENBQUM7SUFDeEQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixFQUFFLENBQUM7SUFDeEQsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUU7UUFDNUMsT0FBTyxDQUFDLENBQUMsQ0FBQztLQUNaO0lBQ0QsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUU7UUFDNUMsT0FBTyxDQUFDLENBQUM7S0FDWDtJQUNELE9BQU8sQ0FBQyxDQUFDO0FBQ1osQ0FBQztBQUdELE1BQU0sT0FBTyxlQUFlO0lBYXpCLFlBQ29CLGdCQUFrQyxFQUNuRCxzQkFBOEM7UUFEN0IscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUduRCxJQUFJLENBQUMsZUFBZSxHQUFHLElB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IkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEJyYW5jaCwgQnJhbmNoQ29vcmRpbmF0ZXMgfSBmcm9tIFwiLi4vY2xhc3Nlcy9CcmFuY2hcIjtcbmltcG9ydCB7IERyYWdTdGF0ZVNlcnZpY2UgfSBmcm9tIFwiLi4vc2luZ2xldG9ucy9kcmFnLXN0YXRlLnNlcnZpY2VcIjtcbmltcG9ydCB0eXBlIHsgTGltYmxlVHJlZU5vZGUsIFByb2Nlc3NlZE9wdGlvbnMgfSBmcm9tIFwiLi90cmVlLnNlcnZpY2VcIjtcbmltcG9ydCB7IGFycmF5c0FyZUVxdWFsLCBpc05lc3RpbmdBbGxvd2VkIH0gZnJvbSBcIi4uL3V0aWxcIjtcbmltcG9ydCB7IERyb3Bab25lIH0gZnJvbSBcIi4uL2NsYXNzZXMvRHJvcFpvbmVcIjtcbmltcG9ydCB7IERyb3Bab25lTG9jYXRpb24gfSBmcm9tIFwiLi4vY2xhc3Nlcy9Ecm9wWm9uZUxvY2F0aW9uXCI7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IFRyZWVDb25zdHJ1Y3Rpb25TdGF0dXMgfSBmcm9tIFwiLi90cmVlLWNvbnN0cnVjdGlvbi1zdGF0dXMuc2VydmljZVwiO1xuaW1wb3J0IHsgZGVib3VuY2UsIGZpbHRlciwgdGFwIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRHJvcFpvbmVGYW1pbHkge1xuICAgLyoqIFRoZSBkZWVwZXN0IG1lbWJlciBvZiB0aGUgZmFtaWx5ICovXG4gICBmb3VuZGVyOiBEcm9wWm9uZTtcbiAgIC8qKiBBbGwgdGhlIGRyb3Agem9uZXMgdGhhdCBiZWxvbmcgdG8gdGhpcyBmYW1pbHkgKi9cbiAgIG1lbWJlcnM6IEFycmF5PERyb3Bab25lPjtcbn1cblxuZnVuY3Rpb24gc29ydEZhbWlseShtZW1iZXJBOiBEcm9wWm9uZSwgbWVtYmVyQjogRHJvcFpvbmUpIHtcbiAgIGNvbnN0IGFDb29yZGluYXRlcyA9IG1lbWJlckEuZ2V0RnVsbEluc2VydENvb3JkaW5hdGVzKCk7XG4gICBjb25zdCBiQ29vcmRpbmF0ZXMgPSBtZW1iZXJCLmdldEZ1bGxJbnNlcnRDb29yZGluYXRlcygpO1xuICAgaWYgKGFDb29yZGluYXRlcy5sZW5ndGggPiBiQ29vcmRpbmF0ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICB9XG4gICBpZiAoYUNvb3JkaW5hdGVzLmxlbmd0aCA8IGJDb29yZGluYXRlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAxO1xuICAgfVxuICAgcmV0dXJuIDA7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEcm9wWm9uZVNlcnZpY2Uge1xuICAgcHJpdmF0ZSByZWFkb25seSBkcm9wWm9uZUFyY2hpdmU6IFNldDxEcm9wWm9uZT47XG4gICBwcml2YXRlIHJlYWRvbmx5IGRyb3Bab25lSW52ZW50b3J5OiBBcnJheTxEcm9wWm9uZT47XG4gICBwcml2YXRlIHJlYWRvbmx5IGRyb3Bab25lRmFtaWxpZXM6IEFycmF5PERyb3Bab25lRmFtaWx5PjtcbiAgIHByaXZhdGUgdmlzaWJsZUZhbWlseTogRHJvcFpvbmVGYW1pbHkgfCBudWxsO1xuICAgcHJpdmF0ZSBhY3RpdmVEcm9wWm9uZTogRHJvcFpvbmUgfCBudWxsO1xuICAgcHJpdmF0ZSB0cmVlOiBCcmFuY2g8YW55PiB8IHVuZGVmaW5lZDtcbiAgIHByaXZhdGUgdHJlZU9wdGlvbnM6IFByb2Nlc3NlZE9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICBwcml2YXRlIHRlbXBGYW1pbGllczpcbiAgICAgIHwgcmVhZG9ubHkgW0Ryb3Bab25lRmFtaWx5LCBEcm9wWm9uZUZhbWlseSB8IG51bGxdXG4gICAgICB8IHJlYWRvbmx5IFtdO1xuICAgcHJpdmF0ZSByZWFkb25seSB1cGRhdGUkOiBTdWJqZWN0PG51bGw+O1xuXG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgZHJhZ1N0YXRlU2VydmljZTogRHJhZ1N0YXRlU2VydmljZSxcbiAgICAgIHRyZWVDb25zdHJ1Y3Rpb25TdGF0dXM6IFRyZWVDb25zdHJ1Y3Rpb25TdGF0dXNcbiAgICkge1xuICAgICAgdGhpcy5kcm9wWm9uZUFyY2hpdmUgPSBuZXcgU2V0KCk7XG4gICAgICB0aGlzLmRyb3Bab25lSW52ZW50b3J5ID0gW107XG4gICAgICB0aGlzLmRyb3Bab25lRmFtaWxpZXMgPSBbXTtcbiAgICAgIHRoaXMudmlzaWJsZUZhbWlseSA9IG51bGw7XG4gICAgICB0aGlzLmFjdGl2ZURyb3Bab25lID0gbnVsbDtcbiAgICAgIHRoaXMudGVtcEZhbWlsaWVzID0gW107XG4gICAgICB0aGlzLnNldEFjdGl2ZURyb3Bab25lKG51bGwpO1xuICAgICAgbGV0IHRyZWVJc1N0YWJsZSA9IGZhbHNlO1xuICAgICAgY29uc3QgdHJlZUlzU3RhYmxlJCA9IHRyZWVDb25zdHJ1Y3Rpb25TdGF0dXMuc3RhYmxlJC5waXBlKFxuICAgICAgICAgdGFwKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdHJlZUlzU3RhYmxlID0gdmFsdWU7XG4gICAgICAgICB9KSxcbiAgICAgICAgIGZpbHRlcigodmFsdWUpID0+IHZhbHVlID09PSB0cnVlKVxuICAgICAgKTtcbiAgICAgIHRoaXMudXBkYXRlJCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICB0aGlzLnVwZGF0ZSRcbiAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgZGVib3VuY2UoKCkgPT4ge1xuICAgICAgICAgICAgICAgaWYgKHRyZWVJc1N0YWJsZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgLy9JZiB0cmVlIGlzIHN0YWJsZSwgY29udGludWUgcmlnaHQgYXdheVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgLy9JZiB0cmVlIGlzIG5vdCBzdGFibGUsIHdhaXQgZm9yIGl0IHRvIGJlY29tZSBzby5cbiAgICAgICAgICAgICAgIHJldHVybiB0cmVlSXNTdGFibGUkO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgIClcbiAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURyb3Bab25lcygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICB9KTtcbiAgIH1cblxuICAgcHVibGljIGFkZERyb3Bab25lKG5ld0Ryb3Bab25lOiBEcm9wWm9uZSk6IHZvaWQge1xuICAgICAgdGhpcy5kcm9wWm9uZUFyY2hpdmUuYWRkKG5ld0Ryb3Bab25lKTtcbiAgIH1cblxuICAgLyoqIGhpZGVzIGFsbCBkcm9wIHpvbmVzICovXG4gICBwdWJsaWMgY2xlYXJWaXNpYmxlWm9uZXMoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy52aXNpYmxlRmFtaWx5ICE9PSBudWxsKSB7XG4gICAgICAgICBmb3IgKGNvbnN0IG1lbWJlciBvZiB0aGlzLnZpc2libGVGYW1pbHkubWVtYmVycykge1xuICAgICAgICAgICAgbWVtYmVyLmlzVmlzaWJsZShmYWxzZSk7XG4gICAgICAgICB9XG4gICAgICAgICB0aGlzLnZpc2libGVGYW1pbHkgPSBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRBY3RpdmVEcm9wWm9uZShudWxsKTtcbiAgIH1cblxuICAgcHVibGljIGdldEFjdGl2ZURyb3Bab25lKCk6IERyb3Bab25lU2VydmljZVtcImFjdGl2ZURyb3Bab25lXCJdIHtcbiAgICAgIHJldHVybiB0aGlzLmFjdGl2ZURyb3Bab25lO1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0RHJvcFpvbmUoY29vcmRpbmF0ZXM6IEJyYW5jaENvb3JkaW5hdGVzKTogRHJvcFpvbmUgfCB1bmRlZmluZWQge1xuICAgICAgY29uc3QgcGFyZW50ID0gWy4uLmNvb3JkaW5hdGVzXTtcbiAgICAgIHBhcmVudC5wb3AoKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gY29vcmRpbmF0ZXNbY29vcmRpbmF0ZXMubGVuZ3RoIC0gMV07XG4gICAgICBjb25zdCBsb2NhdGlvbiA9IG5ldyBEcm9wWm9uZUxvY2F0aW9uKHBhcmVudCwgaW5kZXgpO1xuICAgICAgcmV0dXJuIHRoaXMuZHJvcFpvbmVJbnZlbnRvcnkuZmluZCgoZHJvcFpvbmUpID0+XG4gICAgICAgICBEcm9wWm9uZS5kcm9wWm9uZUxvY2F0aW9uc0FyZUVxdWFsKGRyb3Bab25lLCBsb2NhdGlvbilcbiAgICAgICk7XG4gICB9XG5cbiAgIHB1YmxpYyBpbml0KHRyZWU6IEJyYW5jaDxhbnk+LCB0cmVlT3B0aW9uczogUHJvY2Vzc2VkT3B0aW9ucyk6IHZvaWQge1xuICAgICAgdGhpcy50cmVlID0gdHJlZTtcbiAgICAgIHRoaXMudHJlZU9wdGlvbnMgPSB0cmVlT3B0aW9ucztcbiAgICAgIHRoaXMudXBkYXRlKCk7XG4gICB9XG5cbiAgIHB1YmxpYyByZW1vdmVEcm9wWm9uZShkcm9wWm9uZTogRHJvcFpvbmUpIHtcbiAgICAgIHRoaXMuZHJvcFpvbmVBcmNoaXZlLmRlbGV0ZShkcm9wWm9uZSk7XG4gICB9XG5cbiAgIC8qKiBoaWRlcyBhbGwgZHJvcCB6b25lcywgZGVsZXRlcyBhbGwgdGhlIGZhbWlseSBhc3NpZ25tZW50cyxcbiAgICAqIGFuZCBlbXB0aWVzIHRoZSBkcm9wWm9uZUludmVudG9yeVxuICAgICovXG4gICBwdWJsaWMgcmVzZXQoKTogdm9pZCB7XG4gICAgICB0aGlzLmNsZWFyVmlzaWJsZVpvbmVzKCk7XG4gICAgICB0aGlzLmRyb3Bab25lRmFtaWxpZXMubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuZHJvcFpvbmVJbnZlbnRvcnkubGVuZ3RoID0gMDtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZXN0b3JlcyB0aGUgc2VydmljZSB0byBpdHMgaW5pdGlhbCBzdGF0ZTogaGlkZXMgYWxsIGRyb3Agem9uZXMsXG4gICAgKiBkZWxldGVzIGFsbCB0aGUgZmFtaWx5IGFzc2lnbm1lbnRzLCBhbmQgZW1wdGllcyB0aGUgZHJvcFpvbmVJbnZlbnRvcnlcbiAgICAqIGFuZCBkcm9wWm9uZUFyY2hpdmUuXG4gICAgKi9cbiAgIHB1YmxpYyByZXN0YXJ0KCk6IHZvaWQge1xuICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgdGhpcy5kcm9wWm9uZUFyY2hpdmUuY2xlYXIoKTtcbiAgIH1cblxuICAgcHVibGljIHJlc3RvcmVGYW1pbGllcygpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLnRlbXBGYW1pbGllcy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVGYW1pbGllcy5wb3AoKTtcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVGYW1pbGllcy5wdXNoKHRoaXMudGVtcEZhbWlsaWVzWzBdKTtcbiAgICAgICAgIGZvciAoY29uc3QgbWVtYmVyIG9mIHRoaXMudGVtcEZhbWlsaWVzWzBdLm1lbWJlcnMpIHtcbiAgICAgICAgICAgIG1lbWJlci5zZXRGYW1pbHkodGhpcy50ZW1wRmFtaWxpZXNbMF0pO1xuICAgICAgICAgfVxuICAgICAgICAgaWYgKHRoaXMudGVtcEZhbWlsaWVzWzFdICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmRyb3Bab25lRmFtaWxpZXMucHVzaCh0aGlzLnRlbXBGYW1pbGllc1sxXSk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1lbWJlciBvZiB0aGlzLnRlbXBGYW1pbGllc1sxXS5tZW1iZXJzKSB7XG4gICAgICAgICAgICAgICBtZW1iZXIuc2V0RmFtaWx5KHRoaXMudGVtcEZhbWlsaWVzWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICAgIHRoaXMudGVtcEZhbWlsaWVzID0gW107XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKlxuICAgICogU2hvd3MgdGhlIGRyb3Agem9uZSBmYW1pbHkgb2YgdGhlIGRyb3Agem9uZSBpbmRpY2F0ZWQgYnkgYGNvb3JkaW5hdGVzYC5cbiAgICAqL1xuICAgcHVibGljIHNob3dEcm9wWm9uZUZhbWlseShcbiAgICAgIC8qKiBOb3RlOiB0aGlzIGRyb3Agem9uZSBtYXkgbm90IGV4aXN0IGluIHRoZSBkcm9wWm9uZUludmVudG9yeTsgd2UgaGF2ZSB0byBzZWFyY2ggdGhlIGludmVudG9yeSBiYXNlZCBvbiBpdHMgbG9jYXRpb24gKi9cbiAgICAgIGRyb3Bab25lOiBEcm9wWm9uZSxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgIGpvaW5GYW1pbGllcz86IGJvb2xlYW47XG4gICAgICAgICBhY3RpdmF0ZUxvd2VzdEluc3RlYWRPZkZvdW5kZXI/OiBib29sZWFuO1xuICAgICAgfSA9IHsgam9pbkZhbWlsaWVzOiBmYWxzZSwgYWN0aXZhdGVMb3dlc3RJbnN0ZWFkT2ZGb3VuZGVyOiBmYWxzZSB9XG4gICApOiB2b2lkIHtcbiAgICAgIGlmIChcbiAgICAgICAgIHRoaXMuYWN0aXZlRHJvcFpvbmUgIT09IG51bGwgJiZcbiAgICAgICAgIERyb3Bab25lLmRyb3Bab25lTG9jYXRpb25zQXJlRXF1YWwodGhpcy5hY3RpdmVEcm9wWm9uZSwgZHJvcFpvbmUpXG4gICAgICApIHtcbiAgICAgICAgIC8vQWxyZWFkeSBzaG93aW5nIHRoZSBmYW1pbHkgd2l0aCB0aGUgYXBwcm9wcmlhdGUgYWN0aXZlIGRyb3Agem9uZVxuICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudmlzaWJsZUZhbWlseSAhPT0gbnVsbCB8fCB0aGlzLmFjdGl2ZURyb3Bab25lICE9PSBudWxsKSB7XG4gICAgICAgICB0aGlzLmNsZWFyVmlzaWJsZVpvbmVzKCk7XG4gICAgICB9XG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmRyb3Bab25lSW52ZW50b3J5LmZpbmQoKHpvbmUpID0+XG4gICAgICAgICBEcm9wWm9uZS5kcm9wWm9uZUxvY2F0aW9uc0FyZUVxdWFsKHpvbmUsIGRyb3Bab25lKVxuICAgICAgKTtcbiAgICAgIGlmICh0YXJnZXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBmaW5kIGRyb3Agem9uZSB0byBzaG93LiBsb2NhdGlvbjogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgIGRyb3Bab25lLmdldExvY2F0aW9uKClcbiAgICAgICAgICAgICl9YFxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZhbWlseSA9IHRhcmdldC5nZXRGYW1pbHkoKTtcbiAgICAgIGlmIChvcHRpb25zLmpvaW5GYW1pbGllcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgY29uc3QgbG9jYXRpb24xID0gZHJvcFpvbmUuZ2V0TG9jYXRpb24oKTtcbiAgICAgICAgIGNvbnN0IGxvY2F0aW9uMiA9IG5ldyBEcm9wWm9uZUxvY2F0aW9uKFxuICAgICAgICAgICAgWy4uLmxvY2F0aW9uMS5wYXJlbnRDb29yZGluYXRlc10sXG4gICAgICAgICAgICBsb2NhdGlvbjEuaW5zZXJ0SW5kZXggKyAxXG4gICAgICAgICApO1xuICAgICAgICAgY29uc3QgdGFyZ2V0MiA9IHRoaXMuZHJvcFpvbmVJbnZlbnRvcnkuZmluZCgoem9uZSkgPT5cbiAgICAgICAgICAgIERyb3Bab25lLmRyb3Bab25lTG9jYXRpb25zQXJlRXF1YWwoem9uZSwgbG9jYXRpb24yKVxuICAgICAgICAgKTtcbiAgICAgICAgIGlmICh0YXJnZXQyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGRyb3Agem9uZSB0byBzaG93XCIpO1xuICAgICAgICAgfVxuICAgICAgICAgY29uc3QgZmFtaWx5MiA9IHRhcmdldDIuZ2V0RmFtaWx5KCk7XG4gICAgICAgICBpZiAoZmFtaWx5ID09PSB1bmRlZmluZWQgfHwgZmFtaWx5MiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBmYW1pbHlcIik7XG4gICAgICAgICB9XG4gICAgICAgICBjb25zdCBuZXdGYW1pbHkgPSB7XG4gICAgICAgICAgICBmb3VuZGVyOiBmYW1pbHkuZm91bmRlcixcbiAgICAgICAgICAgIG1lbWJlcnM6IFsuLi5mYW1pbHkubWVtYmVyc11cbiAgICAgICAgIH07XG4gICAgICAgICB0aGlzLnNob3dEcm9wWm9uZShmYW1pbHkuZm91bmRlciwgdHJ1ZSk7XG4gICAgICAgICBmb3IgKGNvbnN0IG1lbWJlciBvZiBmYW1pbHkubWVtYmVycy5zb3J0KHNvcnRGYW1pbHkpKSB7XG4gICAgICAgICAgICBtZW1iZXIuc2V0RmFtaWx5KG5ld0ZhbWlseSk7XG4gICAgICAgICAgICBpZiAobWVtYmVyICE9PSBmYW1pbHkuZm91bmRlcikge1xuICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlRHJvcFpvbmUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIC8vRmFpbGVkIHRvIGFjdGl2YXRlIGEgem9uZSBzbyBmYXIsIHNvIGFjdGl2YXRlIHRoaXMgb25lIGluc3RlYWRcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Ryb3Bab25lKG1lbWJlciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5zaG93RHJvcFpvbmUobWVtYmVyKTtcbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICAgIGZvciAoY29uc3QgbWVtYmVyIG9mIGZhbWlseTIubWVtYmVycykge1xuICAgICAgICAgICAgbWVtYmVyLnNldEZhbWlseShuZXdGYW1pbHkpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgbWVtYmVyLmdldExvY2F0aW9uKCkucGFyZW50Q29vcmRpbmF0ZXMubGVuZ3RoIDxcbiAgICAgICAgICAgICAgIHRhcmdldDIuZ2V0TG9jYXRpb24oKS5wYXJlbnRDb29yZGluYXRlcy5sZW5ndGhcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgbmV3RmFtaWx5Lm1lbWJlcnMucHVzaChtZW1iZXIpO1xuICAgICAgICAgICAgICAgdGhpcy5zaG93RHJvcFpvbmUobWVtYmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgICAgIC8vVGVtcG9yYXJpbHkgc3RvcmUgdGhlIG9sZCBmYW1pbGllc1xuICAgICAgICAgdGhpcy50ZW1wRmFtaWxpZXMgPSBbZmFtaWx5LCBmYW1pbHkyXTtcbiAgICAgICAgIC8vUmVtb3ZlIHRoZSBvbGQgZmFtaWxpZXNcbiAgICAgICAgIGNvbnN0IGZhbWlseUluZGV4ID0gdGhpcy5kcm9wWm9uZUZhbWlsaWVzLmluZGV4T2YoZmFtaWx5KTtcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVGYW1pbGllcy5zcGxpY2UoZmFtaWx5SW5kZXgsIDEpO1xuICAgICAgICAgY29uc3QgZmFtaWx5MkluZGV4ID0gdGhpcy5kcm9wWm9uZUZhbWlsaWVzLmluZGV4T2YoZmFtaWx5Mik7XG4gICAgICAgICB0aGlzLmRyb3Bab25lRmFtaWxpZXMuc3BsaWNlKGZhbWlseTJJbmRleCwgMSk7XG4gICAgICAgICAvL0FkZCB0aGUgbmV3IGZhbWlseVxuICAgICAgICAgdGhpcy5kcm9wWm9uZUZhbWlsaWVzLnB1c2gobmV3RmFtaWx5KTtcbiAgICAgICAgIHRoaXMudmlzaWJsZUZhbWlseSA9IG5ld0ZhbWlseTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICBpZiAoZmFtaWx5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGZhbWlseVwiKTtcbiAgICAgICAgIH1cbiAgICAgICAgIHRoaXMudmlzaWJsZUZhbWlseSA9IGZhbWlseTtcbiAgICAgICAgIHRoaXMuc2hvd0Ryb3Bab25lKGZhbWlseS5mb3VuZGVyLCB0cnVlKTtcbiAgICAgICAgIGlmIChmYW1pbHkubWVtYmVycy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1lbWJlciBvZiBmYW1pbHkubWVtYmVycy5zb3J0KHNvcnRGYW1pbHkpKSB7XG4gICAgICAgICAgICAgICBpZiAobWVtYmVyICE9PSBmYW1pbHkuZm91bmRlcikge1xuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlRHJvcFpvbmUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgIC8vRmFpbGVkIHRvIGFjdGl2YXRlIGEgem9uZSBzbyBmYXIsIHNvIGFjdGl2YXRlIHRoaXMgb25lIGluc3RlYWRcbiAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Ryb3Bab25lKG1lbWJlciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93RHJvcFpvbmUobWVtYmVyKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIG9wdGlvbnMuYWN0aXZhdGVMb3dlc3RJbnN0ZWFkT2ZGb3VuZGVyID09PSB0cnVlICYmXG4gICAgICAgICB0aGlzLnZpc2libGVGYW1pbHkubWVtYmVycy5sZW5ndGggPiAxXG4gICAgICApIHtcbiAgICAgICAgIGNvbnN0IGxvd2VzdE1lbWJlciA9IFsuLi50aGlzLnZpc2libGVGYW1pbHkubWVtYmVyc11cbiAgICAgICAgICAgIC5zb3J0KHNvcnRGYW1pbHkpXG4gICAgICAgICAgICAucG9wKCk7XG4gICAgICAgICBpZiAobG93ZXN0TWVtYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBnZXQgbG93ZXN0IG1lbWJlclwiKTtcbiAgICAgICAgIH1cbiAgICAgICAgIHRoaXMuc3dhcEFjdGl2ZURyb3Bab25lKGxvd2VzdE1lbWJlcik7XG4gICAgICB9XG4gICB9XG5cbiAgIHB1YmxpYyBzd2FwQWN0aXZlRHJvcFpvbmUobmV3QWN0aXZlRHJvcFpvbmU6IERyb3Bab25lKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy52aXNpYmxlRmFtaWx5ID09PSBudWxsKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyB2aXNpYmxlIGZhbWlseSBhdmFpbGFibGUgZm9yIHN3YXBwaW5nXCIpO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnZpc2libGVGYW1pbHkubWVtYmVycy5maW5kSW5kZXgoXG4gICAgICAgICAoZHJvcFpvbmUpID0+IGRyb3Bab25lID09PSBuZXdBY3RpdmVEcm9wWm9uZVxuICAgICAgKTtcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImZhaWxlZCB0byBzd2FwIGFjdGl2ZSBkcm9wIHpvbmVcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldEFjdGl2ZURyb3Bab25lKG5ld0FjdGl2ZURyb3Bab25lKTtcbiAgIH1cblxuICAgcHVibGljIHVwZGF0ZSgpOiB2b2lkIHtcbiAgICAgIHRoaXMudXBkYXRlJC5uZXh0KG51bGwpO1xuICAgfVxuXG4gICBwcml2YXRlIGFzc2lnbkZhbWlsaWVzKCk6IHZvaWQge1xuICAgICAgY29uc3Qgb3JwaGFuWm9uZXMgPSBbLi4udGhpcy5kcm9wWm9uZUludmVudG9yeV07XG4gICAgICBjb25zdCBkZWVwZXN0TWVtYmVycyA9IG9ycGhhblpvbmVzXG4gICAgICAgICAuZmlsdGVyKCh6b25lKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsb2NhdGlvbiA9IHpvbmUuZ2V0TG9jYXRpb24oKTtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICBsb2NhdGlvbi5pbnNlcnRJbmRleCA9PT0gMCAmJlxuICAgICAgICAgICAgICAgbG9jYXRpb24ucGFyZW50Q29vcmRpbmF0ZXMubGVuZ3RoID4gMFxuICAgICAgICAgICAgKTtcbiAgICAgICAgIH0pXG4gICAgICAgICAuc29ydCgodmFsdWVBLCB2YWx1ZUIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFDb29yZGluYXRlcyA9IHZhbHVlQS5nZXRGdWxsSW5zZXJ0Q29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgIGNvbnN0IGJDb29yZGluYXRlcyA9IHZhbHVlQi5nZXRGdWxsSW5zZXJ0Q29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWF4KGFDb29yZGluYXRlcy5sZW5ndGgsIGJDb29yZGluYXRlcy5sZW5ndGgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICAgaWYgKChhQ29vcmRpbmF0ZXNbaW5kZXhdID8/IC0xKSA+IChiQ29vcmRpbmF0ZXNbaW5kZXhdID8/IC0xKSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAgIChhQ29vcmRpbmF0ZXNbaW5kZXhdID8/IC0xKSA8IChiQ29vcmRpbmF0ZXNbaW5kZXhdID8/IC0xKVxuICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgfSk7XG4gICAgICBmb3IgKGNvbnN0IGRyb3Bab25lIG9mIGRlZXBlc3RNZW1iZXJzKSB7XG4gICAgICAgICBpZiAoIW9ycGhhblpvbmVzLmluY2x1ZGVzKGRyb3Bab25lKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICB9XG4gICAgICAgICBjb25zdCBmYW1pbHk6IERyb3Bab25lRmFtaWx5ID0ge1xuICAgICAgICAgICAgZm91bmRlcjogZHJvcFpvbmUsXG4gICAgICAgICAgICBtZW1iZXJzOiBbXVxuICAgICAgICAgfTtcbiAgICAgICAgIGRyb3Bab25lLnNldEZhbWlseShmYW1pbHkpO1xuICAgICAgICAgLy9TZWUgaWYgdGhlcmUgYXJlIGFueSBvcnBoYW5zIHRoYXQgYmVsb25nIHRvIHRoaXMgZmFtaWx5IGFuZCBjbGFpbSB0aGVtLlxuICAgICAgICAgY29uc3QgY3Vyc29yID0gWy4uLmRyb3Bab25lLmdldEZ1bGxJbnNlcnRDb29yZGluYXRlcygpXTtcbiAgICAgICAgIHdoaWxlIChjdXJzb3IubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZmFtaWx5TWVtYmVySW5kZXggPSBvcnBoYW5ab25lcy5maW5kSW5kZXgoKHpvbmUpID0+XG4gICAgICAgICAgICAgICBhcnJheXNBcmVFcXVhbCh6b25lLmdldEZ1bGxJbnNlcnRDb29yZGluYXRlcygpLCBjdXJzb3IpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGZhbWlseU1lbWJlckluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgY29uc3QgZmFtaWx5TWVtYmVyID0gb3JwaGFuWm9uZXMuc3BsaWNlKGZhbWlseU1lbWJlckluZGV4LCAxKVswXTtcbiAgICAgICAgICAgICAgIGZhbWlseS5tZW1iZXJzLnB1c2goZmFtaWx5TWVtYmVyKTtcbiAgICAgICAgICAgICAgIGZhbWlseU1lbWJlci5zZXRGYW1pbHkoZmFtaWx5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnNvci5wb3AoKTtcbiAgICAgICAgICAgIGN1cnNvcltjdXJzb3IubGVuZ3RoIC0gMV0rKztcbiAgICAgICAgIH1cbiAgICAgICAgIHRoaXMuZHJvcFpvbmVGYW1pbGllcy5wdXNoKGZhbWlseSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGRyb3Bab25lIG9mIG9ycGhhblpvbmVzLmZpbHRlcihcbiAgICAgICAgICh6b25lKSA9PiB6b25lLmdldEZ1bGxJbnNlcnRDb29yZGluYXRlcygpLmxlbmd0aCA9PT0gMVxuICAgICAgKSkge1xuICAgICAgICAgY29uc3QgZmFtaWx5OiBEcm9wWm9uZUZhbWlseSA9IHtcbiAgICAgICAgICAgIGZvdW5kZXI6IGRyb3Bab25lLFxuICAgICAgICAgICAgbWVtYmVyczogW2Ryb3Bab25lXVxuICAgICAgICAgfTtcbiAgICAgICAgIGRyb3Bab25lLnNldEZhbWlseShmYW1pbHkpO1xuICAgICAgICAgdGhpcy5kcm9wWm9uZUZhbWlsaWVzLnB1c2goZmFtaWx5KTtcbiAgICAgICAgIG9ycGhhblpvbmVzLnNwbGljZShvcnBoYW5ab25lcy5pbmRleE9mKGRyb3Bab25lKSwgMSk7XG4gICAgICB9XG4gICAgICBpZiAob3JwaGFuWm9uZXMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICBsZXQgb3JwaGFucyA9IFwiXCI7XG4gICAgICAgICBmb3IgKGNvbnN0IHpvbmUgb2Ygb3JwaGFuWm9uZXMpIHtcbiAgICAgICAgICAgIG9ycGhhbnMgKz0gYCR7SlNPTi5zdHJpbmdpZnkoem9uZS5nZXRMb2NhdGlvbigpKX0sIGA7XG4gICAgICAgICB9XG4gICAgICAgICBvcnBoYW5zID0gb3JwaGFucy5zbGljZSgwLCBvcnBoYW5zLmxlbmd0aCAtIDIpO1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFNvbWUgem9uZXMgd2VyZSBub3QgYXNzaWduZWQgdG8gYSBmYW1pbHkuIFRoZSBvcnBoYW4gem9uZXMgaGF2ZSB0aGUgZm9sbG93aW5nIGxvY2F0aW9uczogJHtvcnBoYW5zfWBcbiAgICAgICAgICk7XG4gICAgICB9XG4gICB9XG5cbiAgIHByaXZhdGUgYnVpbGRJbnZlbnRvcnkoKSB7XG4gICAgICAvL1dlIGRvIHRoaXMgZnVua3kgc3RyaW5nIGFycmF5IGJlY2F1c2UgaXQgaXMgZmFzdGVyIHRoYW4gZG9pbmcgZGlyZWN0IGFycmF5IGNvbXBhcmlzb25zXG4gICAgICBjb25zdCBpbnZlbnRvcnlDb29yZGluYXRlczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuICAgICAgZm9yIChjb25zdCBkcm9wWm9uZSBvZiB0aGlzLmRyb3Bab25lQXJjaGl2ZSkge1xuICAgICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBkcm9wWm9uZS5nZXRGdWxsSW5zZXJ0Q29vcmRpbmF0ZXMoKS5qb2luKFwiLFwiKTtcbiAgICAgICAgIGlmIChpbnZlbnRvcnlDb29yZGluYXRlcy5pbmNsdWRlcyhjb29yZGluYXRlcykpIHtcbiAgICAgICAgICAgIGRyb3Bab25lLmlzUmVuZGVyZWQoZmFsc2UpO1xuICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZHJvcFpvbmVJbnZlbnRvcnkucHVzaChkcm9wWm9uZSk7XG4gICAgICAgICAgICBpbnZlbnRvcnlDb29yZGluYXRlcy5wdXNoKGNvb3JkaW5hdGVzKTtcbiAgICAgICAgICAgIGRyb3Bab25lLmlzUmVuZGVyZWQodHJ1ZSk7XG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIHByaXZhdGUgc2V0QWN0aXZlRHJvcFpvbmUoZHJvcFpvbmU6IERyb3Bab25lIHwgbnVsbCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuYWN0aXZlRHJvcFpvbmUgIT09IG51bGwpIHtcbiAgICAgICAgIHRoaXMuYWN0aXZlRHJvcFpvbmUuaXNBY3RpdmUoZmFsc2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmVEcm9wWm9uZSA9IGRyb3Bab25lO1xuICAgICAgaWYgKFxuICAgICAgICAgdGhpcy5hY3RpdmVEcm9wWm9uZSAhPT0gbnVsbCAmJlxuICAgICAgICAgdGhpcy5kcmFnU3RhdGVTZXJ2aWNlLmdldFN0YXRlKCkgIT09IFwiZHJvcHBhYmxlXCJcbiAgICAgICkge1xuICAgICAgICAgdGhpcy5kcmFnU3RhdGVTZXJ2aWNlLmRyb3BwYWJsZSgpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgIHRoaXMuYWN0aXZlRHJvcFpvbmUgPT09IG51bGwgJiZcbiAgICAgICAgIHRoaXMuZHJhZ1N0YXRlU2VydmljZS5nZXRTdGF0ZSgpID09PSBcImRyb3BwYWJsZVwiXG4gICAgICApIHtcbiAgICAgICAgIHRoaXMuZHJhZ1N0YXRlU2VydmljZS5ub3REcm9wcGFibGUoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjdGl2ZURyb3Bab25lICE9PSBudWxsKSB7XG4gICAgICAgICB0aGlzLmFjdGl2ZURyb3Bab25lLmlzQWN0aXZlKHRydWUpO1xuICAgICAgfVxuICAgfVxuXG4gICBwcml2YXRlIHNob3dEcm9wWm9uZShkcm9wWm9uZTogRHJvcFpvbmUsIGFjdGl2ZSA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgICBpZiAodGhpcy50cmVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRyb3Bab25lU2VydmljZSBub3QgaW5pdGlhbGl6ZWRcIik7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuem9uZUlzQWxsb3dlZChkcm9wWm9uZSkpIHtcbiAgICAgICAgIC8vVXNlciBzZXR0aW5ncyBpbmRpY2F0ZSB0byBza2lwIHRoaXMgZHJvcCB6b25lXG4gICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLnRyZWUuZmluZEJ5Q29vcmRpbmF0ZXMoXG4gICAgICAgICBkcm9wWm9uZS5nZXRMb2NhdGlvbigpLnBhcmVudENvb3JkaW5hdGVzXG4gICAgICApO1xuICAgICAgaWYgKHBhcmVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCYWQgZmFtaWx5IG1lbWJlclwiKTtcbiAgICAgIH1cbiAgICAgIGRyb3Bab25lLmlzVmlzaWJsZSh0cnVlKTtcbiAgICAgIGlmIChhY3RpdmUgPT09IHRydWUpIHtcbiAgICAgICAgIHRoaXMuc2V0QWN0aXZlRHJvcFpvbmUoZHJvcFpvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICB9XG5cbiAgIHByaXZhdGUgdXBkYXRlRHJvcFpvbmVzKCk6IHZvaWQge1xuICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgdGhpcy5idWlsZEludmVudG9yeSgpO1xuICAgICAgdGhpcy5hc3NpZ25GYW1pbGllcygpO1xuICAgfVxuXG4gICBwcml2YXRlIHpvbmVJc0FsbG93ZWQoZHJvcFpvbmU6IERyb3Bab25lKTogYm9vbGVhbiB7XG4gICAgICBpZiAodGhpcy50cmVlT3B0aW9ucyA9PT0gdW5kZWZpbmVkIHx8IHRoaXMudHJlZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkcm9wWm9uZVNlcnZpY2Ugbm90IGluaXRpYWxpemVkXCIpO1xuICAgICAgfVxuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZHJhZ1N0YXRlU2VydmljZS5nZXREYXRhKCk7XG4gICAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBnZXQgZHJhZ2dlZCBub2RlXCIpO1xuICAgICAgfVxuICAgICAgY29uc3QgcGFyZW50Q29vcmRpbmF0ZXMgPSBkcm9wWm9uZS5nZXRMb2NhdGlvbigpLnBhcmVudENvb3JkaW5hdGVzO1xuICAgICAgY29uc3QgZHJvcFpvbmVQYXJlbnQgPSB0aGlzLnRyZWUuZmluZEJ5Q29vcmRpbmF0ZXMocGFyZW50Q29vcmRpbmF0ZXMpO1xuICAgICAgaWYgKGRyb3Bab25lUGFyZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBnZXQgZHJvcCB6b25lIHBhcmVudFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIHBhcmVudENvb3JkaW5hdGVzLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICFpc05lc3RpbmdBbGxvd2VkKFxuICAgICAgICAgICAgdGhpcy50cmVlT3B0aW9ucyxcbiAgICAgICAgICAgIGRyb3Bab25lUGFyZW50LmRhdGEgYXMgTGltYmxlVHJlZU5vZGVcbiAgICAgICAgIClcbiAgICAgICkge1xuICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgZHJvcFpvbmVJbmRleCA9IGRyb3Bab25lLmdldExvY2F0aW9uKCkuaW5zZXJ0SW5kZXg7XG4gICAgICBpZiAoZHJvcFpvbmVJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZ2V0IGRyb3Agem9uZSBpbmRleFwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRyYWdnZWROb2RlID0gZGF0YS5icmFuY2g7XG4gICAgICBpZiAoXG4gICAgICAgICAhdGhpcy50cmVlT3B0aW9ucy5hbGxvd0Ryb3AoXG4gICAgICAgICAgICBkcmFnZ2VkTm9kZS5kYXRhLFxuICAgICAgICAgICAgZHJvcFpvbmVQYXJlbnQuZGF0YSBhcyBMaW1ibGVUcmVlTm9kZSxcbiAgICAgICAgICAgIGRyb3Bab25lSW5kZXhcbiAgICAgICAgIClcbiAgICAgICkge1xuICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICB9XG59XG4iXX0=