@ecodev/natural 62.1.2 → 63.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ecodev-natural-vanilla.mjs +1193 -0
- package/fesm2022/ecodev-natural-vanilla.mjs.map +1 -0
- package/fesm2022/ecodev-natural.mjs +436 -425
- package/fesm2022/ecodev-natural.mjs.map +1 -1
- package/lib/classes/network-activity.service.d.ts +54 -0
- package/lib/classes/validators.d.ts +1 -1
- package/lib/modules/columns-picker/columns-picker.component.d.ts +2 -2
- package/lib/modules/common/services/seo.provider.d.ts +2 -2
- package/lib/modules/dropdown-components/type-select/type-select.component.d.ts +1 -1
- package/lib/modules/file/abstract-file.d.ts +6 -3
- package/lib/modules/file/component/file.component.d.ts +2 -2
- package/lib/modules/file/file-drop.directive.d.ts +2 -3
- package/lib/modules/fixed-button-detail/fixed-button-detail.component.d.ts +2 -3
- package/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.d.ts +3 -3
- package/lib/modules/icon/icon.module.d.ts +2 -2
- package/lib/modules/panels/panels.service.d.ts +1 -2
- package/lib/modules/relations/relations.component.d.ts +3 -3
- package/lib/modules/search/dropdown-container/dropdown-container.component.d.ts +2 -3
- package/lib/modules/search/group/group.component.d.ts +2 -3
- package/lib/modules/search/input/input.component.d.ts +5 -5
- package/lib/modules/search/search/search.component.d.ts +2 -2
- package/lib/modules/select/abstract-select.component.d.ts +3 -3
- package/lib/modules/select/select/select.component.d.ts +1 -1
- package/lib/modules/sidenav/sidenav-container/sidenav-container.component.d.ts +1 -1
- package/lib/modules/table-button/table-button.component.d.ts +4 -2
- package/package.json +16 -14
- package/public-api.d.ts +1 -0
- package/src/lib/_natural.theme.scss +1 -2
- package/vanilla/index.d.ts +5 -0
- package/vanilla/package.json +3 -0
- package/vanilla/public-api.d.ts +11 -0
- package/vanilla/src/lib/classes/crypto.d.ts +8 -0
- package/vanilla/src/lib/classes/data-source.d.ts +32 -0
- package/vanilla/src/lib/classes/query-variable-manager-utils.d.ts +2 -0
- package/vanilla/src/lib/classes/query-variable-manager.d.ts +91 -0
- package/vanilla/src/lib/classes/signing.d.ts +7 -0
- package/vanilla/src/lib/classes/utility.d.ts +77 -0
- package/vanilla/src/lib/modules/search/classes/graphql-doctrine.types.d.ts +83 -0
- package/vanilla/src/lib/modules/search/classes/utils.d.ts +17 -0
- package/vanilla/src/lib/modules/search/types/dropdown-component.d.ts +20 -0
- package/vanilla/src/lib/modules/search/types/facet.d.ts +75 -0
- package/vanilla/src/lib/modules/search/types/values.d.ts +32 -0
- package/vanilla/src/lib/services/abstract-model.service.d.ts +244 -0
- package/vanilla/src/lib/services/debounce.service.d.ts +52 -0
- package/vanilla/src/lib/types/types.d.ts +100 -0
- package/esm2022/ecodev-natural.mjs +0 -5
- package/esm2022/lib/classes/abstract-detail.mjs +0 -229
- package/esm2022/lib/classes/abstract-editable-list.mjs +0 -99
- package/esm2022/lib/classes/abstract-list.mjs +0 -461
- package/esm2022/lib/classes/abstract-navigable-list.mjs +0 -133
- package/esm2022/lib/classes/apollo-utils.mjs +0 -59
- package/esm2022/lib/classes/crypto.mjs +0 -23
- package/esm2022/lib/classes/cumulative-changes.mjs +0 -50
- package/esm2022/lib/classes/data-source.mjs +0 -71
- package/esm2022/lib/classes/providers.mjs +0 -13
- package/esm2022/lib/classes/query-variable-manager-utils.mjs +0 -14
- package/esm2022/lib/classes/query-variable-manager.mjs +0 -172
- package/esm2022/lib/classes/rxjs.mjs +0 -54
- package/esm2022/lib/classes/signing.mjs +0 -38
- package/esm2022/lib/classes/tld.mjs +0 -1476
- package/esm2022/lib/classes/utility.mjs +0 -234
- package/esm2022/lib/classes/validators.mjs +0 -179
- package/esm2022/lib/directives/http-prefix.directive.mjs +0 -47
- package/esm2022/lib/modules/alert/alert.service.mjs +0 -53
- package/esm2022/lib/modules/alert/confirm.component.mjs +0 -16
- package/esm2022/lib/modules/alert/public-api.mjs +0 -6
- package/esm2022/lib/modules/avatar/component/avatar.component.mjs +0 -203
- package/esm2022/lib/modules/avatar/public-api.mjs +0 -6
- package/esm2022/lib/modules/avatar/service/avatar.service.mjs +0 -63
- package/esm2022/lib/modules/avatar/sources/gravatar.mjs +0 -29
- package/esm2022/lib/modules/avatar/sources/image.mjs +0 -13
- package/esm2022/lib/modules/avatar/sources/initials.mjs +0 -39
- package/esm2022/lib/modules/avatar/sources/source.mjs +0 -16
- package/esm2022/lib/modules/columns-picker/columns-picker.component.mjs +0 -145
- package/esm2022/lib/modules/columns-picker/public-api.mjs +0 -5
- package/esm2022/lib/modules/columns-picker/types.mjs +0 -2
- package/esm2022/lib/modules/common/directives/background-density.directive.mjs +0 -63
- package/esm2022/lib/modules/common/directives/linkable-tab.directive.mjs +0 -93
- package/esm2022/lib/modules/common/directives/src-density.directive.mjs +0 -72
- package/esm2022/lib/modules/common/pipes/capitalize.pipe.mjs +0 -24
- package/esm2022/lib/modules/common/pipes/ellipsis.pipe.mjs +0 -17
- package/esm2022/lib/modules/common/pipes/enum.pipe.mjs +0 -24
- package/esm2022/lib/modules/common/pipes/time-ago.pipe.mjs +0 -140
- package/esm2022/lib/modules/common/public-api.mjs +0 -14
- package/esm2022/lib/modules/common/services/memory-storage.mjs +0 -110
- package/esm2022/lib/modules/common/services/seo.provider.mjs +0 -23
- package/esm2022/lib/modules/common/services/seo.service.mjs +0 -235
- package/esm2022/lib/modules/detail-header/detail-header.component.mjs +0 -84
- package/esm2022/lib/modules/detail-header/public-api.mjs +0 -5
- package/esm2022/lib/modules/dialog-trigger/dialog-trigger.component.mjs +0 -72
- package/esm2022/lib/modules/dialog-trigger/public-api.mjs +0 -5
- package/esm2022/lib/modules/dropdown-components/abstract-association-select-component.directive.mjs +0 -100
- package/esm2022/lib/modules/dropdown-components/public-api.mjs +0 -14
- package/esm2022/lib/modules/dropdown-components/type-boolean/type-boolean.component.mjs +0 -39
- package/esm2022/lib/modules/dropdown-components/type-date/type-date.component.mjs +0 -173
- package/esm2022/lib/modules/dropdown-components/type-date-range/type-date-range.component.mjs +0 -134
- package/esm2022/lib/modules/dropdown-components/type-hierarchic-selector/type-hierarchic-selector.component.mjs +0 -80
- package/esm2022/lib/modules/dropdown-components/type-natural-select/type-natural-select.component.mjs +0 -48
- package/esm2022/lib/modules/dropdown-components/type-number/type-number.component.mjs +0 -110
- package/esm2022/lib/modules/dropdown-components/type-options/type-options.component.mjs +0 -64
- package/esm2022/lib/modules/dropdown-components/type-select/type-select.component.mjs +0 -175
- package/esm2022/lib/modules/dropdown-components/type-text/type-text.component.mjs +0 -62
- package/esm2022/lib/modules/dropdown-components/types.mjs +0 -41
- package/esm2022/lib/modules/dropdown-components/utils.mjs +0 -35
- package/esm2022/lib/modules/file/abstract-file.mjs +0 -230
- package/esm2022/lib/modules/file/component/file.component.mjs +0 -172
- package/esm2022/lib/modules/file/file-drop.directive.mjs +0 -111
- package/esm2022/lib/modules/file/file-select.directive.mjs +0 -26
- package/esm2022/lib/modules/file/file.service.mjs +0 -43
- package/esm2022/lib/modules/file/public-api.mjs +0 -9
- package/esm2022/lib/modules/file/types.mjs +0 -2
- package/esm2022/lib/modules/file/utils.mjs +0 -129
- package/esm2022/lib/modules/fixed-button/fixed-button.component.mjs +0 -30
- package/esm2022/lib/modules/fixed-button/public-api.mjs +0 -5
- package/esm2022/lib/modules/fixed-button-detail/fixed-button-detail.component.mjs +0 -56
- package/esm2022/lib/modules/fixed-button-detail/public-api.mjs +0 -5
- package/esm2022/lib/modules/hierarchic-selector/classes/flat-node.mjs +0 -18
- package/esm2022/lib/modules/hierarchic-selector/classes/hierarchic-configuration.mjs +0 -2
- package/esm2022/lib/modules/hierarchic-selector/classes/hierarchic-filters-configuration.mjs +0 -2
- package/esm2022/lib/modules/hierarchic-selector/classes/model-node.mjs +0 -14
- package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.mjs +0 -398
- package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.service.mjs +0 -243
- package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector-dialog/hierarchic-selector-dialog.component.mjs +0 -38
- package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector-dialog/hierarchic-selector-dialog.service.mjs +0 -22
- package/esm2022/lib/modules/hierarchic-selector/public-api.mjs +0 -10
- package/esm2022/lib/modules/icon/icon.directive.mjs +0 -96
- package/esm2022/lib/modules/icon/icon.module.mjs +0 -33
- package/esm2022/lib/modules/icon/public-api.mjs +0 -6
- package/esm2022/lib/modules/logger/error-handler.mjs +0 -87
- package/esm2022/lib/modules/logger/error.module.mjs +0 -22
- package/esm2022/lib/modules/logger/public-api.mjs +0 -6
- package/esm2022/lib/modules/matomo/matomo.service.mjs +0 -96
- package/esm2022/lib/modules/matomo/public-api.mjs +0 -5
- package/esm2022/lib/modules/panels/abstract-panel.mjs +0 -76
- package/esm2022/lib/modules/panels/fallback-if-no-opened-panels.urlmatcher.mjs +0 -12
- package/esm2022/lib/modules/panels/panels.component.mjs +0 -27
- package/esm2022/lib/modules/panels/panels.module.mjs +0 -10
- package/esm2022/lib/modules/panels/panels.service.mjs +0 -329
- package/esm2022/lib/modules/panels/panels.urlmatcher.mjs +0 -75
- package/esm2022/lib/modules/panels/public-api.mjs +0 -11
- package/esm2022/lib/modules/panels/types.mjs +0 -3
- package/esm2022/lib/modules/relations/public-api.mjs +0 -5
- package/esm2022/lib/modules/relations/relations.component.mjs +0 -254
- package/esm2022/lib/modules/search/classes/graphql-doctrine.mjs +0 -111
- package/esm2022/lib/modules/search/classes/graphql-doctrine.types.mjs +0 -14
- package/esm2022/lib/modules/search/classes/transformers.mjs +0 -142
- package/esm2022/lib/modules/search/classes/url.mjs +0 -53
- package/esm2022/lib/modules/search/classes/utils.mjs +0 -25
- package/esm2022/lib/modules/search/dropdown-container/dropdown-container-animations.mjs +0 -44
- package/esm2022/lib/modules/search/dropdown-container/dropdown-container.component.mjs +0 -87
- package/esm2022/lib/modules/search/dropdown-container/dropdown-ref.mjs +0 -24
- package/esm2022/lib/modules/search/dropdown-container/dropdown.service.mjs +0 -90
- package/esm2022/lib/modules/search/facet-selector/facet-selector.component.mjs +0 -45
- package/esm2022/lib/modules/search/group/group.component.mjs +0 -53
- package/esm2022/lib/modules/search/input/input.component.mjs +0 -365
- package/esm2022/lib/modules/search/public-api.mjs +0 -7
- package/esm2022/lib/modules/search/search/search.component.mjs +0 -102
- package/esm2022/lib/modules/search/types/dropdown-component.mjs +0 -2
- package/esm2022/lib/modules/search/types/facet.mjs +0 -2
- package/esm2022/lib/modules/search/types/values.mjs +0 -2
- package/esm2022/lib/modules/select/abstract-select.component.mjs +0 -232
- package/esm2022/lib/modules/select/public-api.mjs +0 -7
- package/esm2022/lib/modules/select/select/select.component.mjs +0 -310
- package/esm2022/lib/modules/select/select-enum/select-enum.component.mjs +0 -57
- package/esm2022/lib/modules/select/select-hierarchic/select-hierarchic.component.mjs +0 -155
- package/esm2022/lib/modules/sidenav/public-api.mjs +0 -9
- package/esm2022/lib/modules/sidenav/sidenav/sidenav.component.mjs +0 -15
- package/esm2022/lib/modules/sidenav/sidenav-container/sidenav-container.component.mjs +0 -90
- package/esm2022/lib/modules/sidenav/sidenav-content/sidenav-content.component.mjs +0 -11
- package/esm2022/lib/modules/sidenav/sidenav-stack.service.mjs +0 -50
- package/esm2022/lib/modules/sidenav/sidenav.service.mjs +0 -196
- package/esm2022/lib/modules/stamp/public-api.mjs +0 -5
- package/esm2022/lib/modules/stamp/stamp.component.mjs +0 -23
- package/esm2022/lib/modules/table-button/public-api.mjs +0 -5
- package/esm2022/lib/modules/table-button/table-button.component.mjs +0 -78
- package/esm2022/lib/services/abstract-model.service.mjs +0 -526
- package/esm2022/lib/services/debounce.service.mjs +0 -149
- package/esm2022/lib/services/enum.service.mjs +0 -64
- package/esm2022/lib/services/link-mutation.service.mjs +0 -154
- package/esm2022/lib/services/persistence.service.mjs +0 -115
- package/esm2022/lib/services/swiss-parsing-date-adapter.service.mjs +0 -63
- package/esm2022/lib/types/types.mjs +0 -2
- package/esm2022/public-api.mjs +0 -46
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
2
|
-
import { FlatTreeControl } from '@angular/cdk/tree';
|
|
3
|
-
import { Component, DestroyRef, EventEmitter, inject, Input, Output, } from '@angular/core';
|
|
4
|
-
import { MatTreeFlatDataSource, MatTreeFlattener, MatTreeModule } from '@angular/material/tree';
|
|
5
|
-
import { finalize } from 'rxjs/operators';
|
|
6
|
-
import { toGraphQLDoctrineFilter } from '../../search/classes/graphql-doctrine';
|
|
7
|
-
import { HierarchicFlatNode } from '../classes/flat-node';
|
|
8
|
-
import { NaturalHierarchicSelectorService } from './hierarchic-selector.service';
|
|
9
|
-
import { replaceObjectKeepingReference } from '../../../classes/utility';
|
|
10
|
-
import { MatChipsModule } from '@angular/material/chips';
|
|
11
|
-
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
12
|
-
import { NaturalIconDirective } from '../../icon/icon.directive';
|
|
13
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
14
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
15
|
-
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
16
|
-
import { CommonModule } from '@angular/common';
|
|
17
|
-
import { NaturalSearchComponent } from '../../search/search/search.component';
|
|
18
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
19
|
-
import * as i0 from "@angular/core";
|
|
20
|
-
import * as i1 from "@angular/common";
|
|
21
|
-
import * as i2 from "@angular/material/progress-spinner";
|
|
22
|
-
import * as i3 from "@angular/material/tree";
|
|
23
|
-
import * as i4 from "@angular/material/button";
|
|
24
|
-
import * as i5 from "@angular/material/icon";
|
|
25
|
-
import * as i6 from "@angular/material/checkbox";
|
|
26
|
-
import * as i7 from "@angular/material/chips";
|
|
27
|
-
export class NaturalHierarchicSelectorComponent {
|
|
28
|
-
destroyRef = inject(DestroyRef);
|
|
29
|
-
hierarchicSelectorService = inject(NaturalHierarchicSelectorService);
|
|
30
|
-
/**
|
|
31
|
-
* Function that receives a model and returns a string for display value
|
|
32
|
-
*/
|
|
33
|
-
displayWith;
|
|
34
|
-
/**
|
|
35
|
-
* Config for items and relations arrangement
|
|
36
|
-
*/
|
|
37
|
-
config;
|
|
38
|
-
/**
|
|
39
|
-
* If multiple or single item selection
|
|
40
|
-
*/
|
|
41
|
-
multiple = false;
|
|
42
|
-
/**
|
|
43
|
-
* Selected items
|
|
44
|
-
* Organized by key, containing each an array of selected items of same type
|
|
45
|
-
*/
|
|
46
|
-
selected = {};
|
|
47
|
-
/**
|
|
48
|
-
* Whether selectable elements can be unselected
|
|
49
|
-
*/
|
|
50
|
-
allowUnselect = true;
|
|
51
|
-
/**
|
|
52
|
-
* Filters that apply to each query
|
|
53
|
-
*/
|
|
54
|
-
filters;
|
|
55
|
-
/**
|
|
56
|
-
* Search facets
|
|
57
|
-
*/
|
|
58
|
-
searchFacets = [];
|
|
59
|
-
/**
|
|
60
|
-
* Selections to apply on natural-search on component initialisation
|
|
61
|
-
*/
|
|
62
|
-
searchSelections = [];
|
|
63
|
-
/**
|
|
64
|
-
* Emits when natural-search selections change
|
|
65
|
-
*/
|
|
66
|
-
searchSelectionChange = new EventEmitter();
|
|
67
|
-
/**
|
|
68
|
-
* Inner representation of selected @Input() to allow flat listing as mat-chip.
|
|
69
|
-
*/
|
|
70
|
-
selectedNodes = [];
|
|
71
|
-
/**
|
|
72
|
-
* Emits selection change
|
|
73
|
-
* Returns a Literal where selected models are organized by key
|
|
74
|
-
*/
|
|
75
|
-
selectionChange = new EventEmitter();
|
|
76
|
-
/**
|
|
77
|
-
* Controller for nodes selection
|
|
78
|
-
*/
|
|
79
|
-
flatNodesSelection;
|
|
80
|
-
treeControl;
|
|
81
|
-
treeFlattener;
|
|
82
|
-
dataSource;
|
|
83
|
-
loading = false;
|
|
84
|
-
/**
|
|
85
|
-
* Cache for transformed nodes
|
|
86
|
-
*/
|
|
87
|
-
flatNodeMap = new Map();
|
|
88
|
-
/**
|
|
89
|
-
* Angular OnChange implementation
|
|
90
|
-
*/
|
|
91
|
-
ngOnChanges(changes) {
|
|
92
|
-
if (changes.selected && !changes.selected.firstChange) {
|
|
93
|
-
this.updateInnerSelection(this.selected);
|
|
94
|
-
}
|
|
95
|
-
if (changes.filters && !changes.filters.firstChange) {
|
|
96
|
-
this.loadRoots();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Angular OnInit implementation
|
|
101
|
-
*/
|
|
102
|
-
ngOnInit() {
|
|
103
|
-
// Init tree checkbox selectors
|
|
104
|
-
this.flatNodesSelection = new SelectionModel(this.multiple);
|
|
105
|
-
// Tree controllers and manipulators
|
|
106
|
-
this.treeFlattener = new MatTreeFlattener(this.transformer(), this.getLevel(), this.isExpandable(), this.getChildren());
|
|
107
|
-
this.treeControl = new FlatTreeControl(this.getLevel(), this.isExpandable());
|
|
108
|
-
// The dataSource contains a nested ModelNodes list. Each ModelNode has a child attribute that returns an observable.
|
|
109
|
-
// The dataSource contains a flat representation of the nested ModelNodes that is generated by the treeFlattener related functions
|
|
110
|
-
this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
|
|
111
|
-
// Update dataSource when receiving new list -> we assign the whole tree
|
|
112
|
-
// The treeControl and treeFlattener will generate the displayed tree
|
|
113
|
-
this.hierarchicSelectorService.dataChange
|
|
114
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
115
|
-
.subscribe(data => (this.dataSource.data = data));
|
|
116
|
-
// Prevent empty screen on first load and init NaturalHierarchicSelectorService with inputted configuration
|
|
117
|
-
let variables;
|
|
118
|
-
if (this.searchSelections.some(s => s.length)) {
|
|
119
|
-
variables = { filter: toGraphQLDoctrineFilter(this.searchFacets, this.searchSelections) };
|
|
120
|
-
}
|
|
121
|
-
this.loadRoots(variables);
|
|
122
|
-
// OrganizedSelection into list usable by template
|
|
123
|
-
this.updateInnerSelection(this.selected);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Toggle selection of a FlatNode, considering if multiple selection is activated or not
|
|
127
|
-
*/
|
|
128
|
-
toggleFlatNode(flatNode) {
|
|
129
|
-
if (this.multiple) {
|
|
130
|
-
// Is multiple allowed, just toggle element
|
|
131
|
-
if (this.flatNodesSelection.isSelected(flatNode)) {
|
|
132
|
-
this.unselectFlatNode(flatNode);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
this.selectFlatNode(flatNode);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else if (!this.multiple) {
|
|
139
|
-
if (this.flatNodesSelection.isSelected(flatNode)) {
|
|
140
|
-
this.unselectSingleFlatNode();
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
// If not multiple, and we want to select an element, unselect everything before to keep a single selection
|
|
144
|
-
this.selectSingleFlatNode(flatNode);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* When unselecting an element from the mat-chips, it can be deep in the hierarchy, and the tree element may not exist...
|
|
150
|
-
* ... but we still need to remove the element from the mat-chips list.
|
|
151
|
-
*/
|
|
152
|
-
unselectModelNode(node) {
|
|
153
|
-
const flatNode = this.getFlatNode(node);
|
|
154
|
-
if (flatNode) {
|
|
155
|
-
this.unselectFlatNode(flatNode);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
// Remove from chips list only if no flatNode, because unselectFlatNode() already deals with it.
|
|
159
|
-
this.removeModelNode(node);
|
|
160
|
-
this.updateSelection(this.selectedNodes);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
isNodeTogglable(flatNode) {
|
|
164
|
-
if (this.isNodeSelected(flatNode.node)) {
|
|
165
|
-
return flatNode.deselectable;
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
return flatNode.selectable;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
getDisplayFn(config) {
|
|
172
|
-
if (config.displayWith) {
|
|
173
|
-
return config.displayWith;
|
|
174
|
-
}
|
|
175
|
-
if (this.displayWith) {
|
|
176
|
-
return this.displayWith;
|
|
177
|
-
}
|
|
178
|
-
return item => (item ? item.fullName || item.name : '');
|
|
179
|
-
}
|
|
180
|
-
loadChildren(flatNode) {
|
|
181
|
-
if (this.treeControl.isExpanded(flatNode)) {
|
|
182
|
-
this.hierarchicSelectorService.loadChildren(flatNode, this.filters);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Created to collapse all children when closing a parent, but not sure it's good.
|
|
187
|
-
*/
|
|
188
|
-
// public loadChildren(flatNode: HierarchicFlatNode) {
|
|
189
|
-
// if (this.treeControl.isExpanded(flatNode)) {
|
|
190
|
-
//
|
|
191
|
-
// const cachedFlatNode = this.getFlatNode(flatNode.node);
|
|
192
|
-
// if (cachedFlatNode) {
|
|
193
|
-
// this.hierarchicSelectorService.loadChildren(cachedFlatNode, this.filters);
|
|
194
|
-
//
|
|
195
|
-
// // Close children
|
|
196
|
-
// cachedFlatNode.node.children.forEach(child => {
|
|
197
|
-
// const childNode = this.getFlatNode(child);
|
|
198
|
-
// if (childNode) {
|
|
199
|
-
// this.treeControl.collapse(childNode);
|
|
200
|
-
// }
|
|
201
|
-
// });
|
|
202
|
-
// }
|
|
203
|
-
// }
|
|
204
|
-
// }
|
|
205
|
-
getChildren() {
|
|
206
|
-
return (node) => {
|
|
207
|
-
return node.childrenChange;
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Transforms a HierarchicModelNode into a FlatNode
|
|
212
|
-
*/
|
|
213
|
-
transformer() {
|
|
214
|
-
return (node, level) => {
|
|
215
|
-
return this.getOrCreateFlatNode(node, level);
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Return deep of the node in the tree
|
|
220
|
-
*/
|
|
221
|
-
getLevel() {
|
|
222
|
-
return (node) => {
|
|
223
|
-
return node.level;
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Is always expandable because we load on demand, we don't know if there are children yet
|
|
228
|
-
*/
|
|
229
|
-
isExpandable() {
|
|
230
|
-
return (node) => {
|
|
231
|
-
return node.expandable;
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
getOrCreateFlatNode(node, level) {
|
|
235
|
-
// Return FlatNode if exists
|
|
236
|
-
const flatNode = this.getFlatNode(node);
|
|
237
|
-
if (flatNode) {
|
|
238
|
-
return flatNode;
|
|
239
|
-
}
|
|
240
|
-
// Return new FlatNode
|
|
241
|
-
return this.createFlatNode(node, level);
|
|
242
|
-
}
|
|
243
|
-
search(selections) {
|
|
244
|
-
this.searchSelectionChange.emit(selections);
|
|
245
|
-
if (selections.some(s => s.length)) {
|
|
246
|
-
const variables = { filter: toGraphQLDoctrineFilter(this.searchFacets, selections) };
|
|
247
|
-
this.hierarchicSelectorService.search(variables, this.filters);
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
this.loadRoots();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
loadRoots(searchVariables) {
|
|
254
|
-
this.loading = true;
|
|
255
|
-
this.flatNodeMap = new Map();
|
|
256
|
-
this.hierarchicSelectorService
|
|
257
|
-
.init(this.config, this.filters, searchVariables || null)
|
|
258
|
-
.pipe(finalize(() => (this.loading = false)))
|
|
259
|
-
.subscribe();
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Sync inner selection (tree and mat-chips) according to selected input attribute
|
|
263
|
-
*/
|
|
264
|
-
updateInnerSelection(selected) {
|
|
265
|
-
// Transform an OrganizedModelSelection into a ModelNode list that is used in the selected zone of the component (see template)
|
|
266
|
-
this.selectedNodes = this.hierarchicSelectorService.fromOrganizedSelection(selected);
|
|
267
|
-
this.flatNodesSelection.clear();
|
|
268
|
-
for (const node of this.selectedNodes) {
|
|
269
|
-
const flatNode = this.getFlatNode(node);
|
|
270
|
-
if (flatNode) {
|
|
271
|
-
this.flatNodesSelection.select(flatNode);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Unselect a node, keeping the rest of the selected untouched
|
|
277
|
-
*/
|
|
278
|
-
unselectFlatNode(flatNode) {
|
|
279
|
-
this.flatNodesSelection.deselect(flatNode);
|
|
280
|
-
this.removeModelNode(flatNode.node);
|
|
281
|
-
this.updateSelection(this.selectedNodes);
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Remove a node from chip lists
|
|
285
|
-
*/
|
|
286
|
-
removeModelNode(node) {
|
|
287
|
-
const key = this.getMapKey(node.model);
|
|
288
|
-
const selectionIndex = this.selectedNodes.findIndex(n => this.getMapKey(n.model) === key);
|
|
289
|
-
this.selectedNodes.splice(selectionIndex, 1);
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Select a node, keeping th rest of the selected untouched
|
|
293
|
-
*/
|
|
294
|
-
selectFlatNode(flatNode) {
|
|
295
|
-
this.flatNodesSelection.select(flatNode);
|
|
296
|
-
this.selectedNodes.push(flatNode.node);
|
|
297
|
-
this.updateSelection(this.selectedNodes);
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Clear all selected and select the given node
|
|
301
|
-
*/
|
|
302
|
-
selectSingleFlatNode(flatNode) {
|
|
303
|
-
this.flatNodesSelection.clear();
|
|
304
|
-
this.flatNodesSelection.select(flatNode);
|
|
305
|
-
this.selectedNodes = [flatNode.node];
|
|
306
|
-
this.updateSelection(this.selectedNodes);
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Clear all selected and select the given node
|
|
310
|
-
*/
|
|
311
|
-
unselectSingleFlatNode() {
|
|
312
|
-
this.flatNodesSelection.clear();
|
|
313
|
-
this.selectedNodes = [];
|
|
314
|
-
this.updateSelection(this.selectedNodes);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Transform the given elements into the organized selection that is emitted to output
|
|
318
|
-
*/
|
|
319
|
-
updateSelection(selected) {
|
|
320
|
-
const organizedFlatNodesSelection = this.hierarchicSelectorService.toOrganizedSelection(selected);
|
|
321
|
-
replaceObjectKeepingReference(this.selected, organizedFlatNodesSelection);
|
|
322
|
-
this.selectionChange.emit(organizedFlatNodesSelection);
|
|
323
|
-
}
|
|
324
|
-
isNodeSelected(node) {
|
|
325
|
-
const key = this.getMapKey(node.model);
|
|
326
|
-
return this.selectedNodes.some(n => this.getMapKey(n.model) === key);
|
|
327
|
-
}
|
|
328
|
-
getFlatNode(node) {
|
|
329
|
-
const key = this.getMapKey(node.model);
|
|
330
|
-
return this.flatNodeMap.get(key) || null;
|
|
331
|
-
}
|
|
332
|
-
createFlatNode(node, level) {
|
|
333
|
-
const key = this.getMapKey(node.model);
|
|
334
|
-
const name = this.getDisplayFn(node.config)(node.model);
|
|
335
|
-
const expandable = false;
|
|
336
|
-
const isCustomSelectable = node.config.isSelectableCallback
|
|
337
|
-
? node.config.isSelectableCallback(node.model)
|
|
338
|
-
: true;
|
|
339
|
-
const isSelectable = !!node.config.selectableAtKey && isCustomSelectable;
|
|
340
|
-
const flatNode = new HierarchicFlatNode(node, name, level, expandable, isSelectable);
|
|
341
|
-
this.hierarchicSelectorService.countItems(flatNode, this.filters);
|
|
342
|
-
// Mark node as selected if needed (checks the selected processed input)
|
|
343
|
-
if (this.isNodeSelected(node)) {
|
|
344
|
-
if (!this.allowUnselect) {
|
|
345
|
-
flatNode.deselectable = false;
|
|
346
|
-
}
|
|
347
|
-
this.flatNodesSelection.select(flatNode);
|
|
348
|
-
}
|
|
349
|
-
// Cache FlatNode
|
|
350
|
-
this.flatNodeMap.set(key, flatNode);
|
|
351
|
-
return flatNode;
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Returns an identifier key for map cache
|
|
355
|
-
* As many object types can be used, this function considers typename and ID to return something like document-123
|
|
356
|
-
*/
|
|
357
|
-
getMapKey(model) {
|
|
358
|
-
return model.__typename + '-' + model.id;
|
|
359
|
-
}
|
|
360
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NaturalHierarchicSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
361
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: NaturalHierarchicSelectorComponent, isStandalone: true, selector: "natural-hierarchic-selector", inputs: { displayWith: "displayWith", config: "config", multiple: "multiple", selected: "selected", allowUnselect: "allowUnselect", filters: "filters", searchFacets: "searchFacets", searchSelections: "searchSelections" }, outputs: { searchSelectionChange: "searchSelectionChange", selectionChange: "selectionChange" }, providers: [NaturalHierarchicSelectorService], usesOnChanges: true, ngImport: i0, template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search (selectionChange)=\"search($event)\" [facets]=\"searchFacets\" [selections]=\"searchSelections\" />\n</div>\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner [diameter]=\"36\" mode=\"indeterminate\" style=\"margin: 10px\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" [ngClass]=\"{leaf: !node.expandable}\" matTreeNodePadding>\n @if (node.expandable) {\n <button\n (click)=\"loadChildren(node)\"\n [attr.aria-label]=\"'toggle ' + node.name\"\n mat-icon-button\n matTreeNodeToggle\n >\n @if (node.loading) {\n <mat-progress-spinner [diameter]=\"24\" [strokeWidth]=\"5\" mode=\"indeterminate\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n (change)=\"toggleFlatNode(node)\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n style=\"margin-right: 10px\"\n >\n @if (node.node.config.icon) {\n <mat-icon [naturalIcon]=\"node.node.config.icon\" style=\"margin-right: 10px\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option (removed)=\"unselectModelNode(node)\" [removable]=\"true\" [selectable]=\"false\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"], dependencies: [{ kind: "component", type: NaturalSearchComponent, selector: "natural-search", inputs: ["placeholder", "facets", "multipleGroups", "dropdownTitle", "selections"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTreeModule }, { kind: "directive", type: i3.MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: i3.MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "directive", type: i3.MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: i3.MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: i3.MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NaturalIconDirective, selector: "mat-icon[naturalIcon]", inputs: ["naturalIcon", "size"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i7.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i7.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: i7.MatChipRemove, selector: "[matChipRemove]" }] });
|
|
362
|
-
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NaturalHierarchicSelectorComponent, decorators: [{
|
|
364
|
-
type: Component,
|
|
365
|
-
args: [{ selector: 'natural-hierarchic-selector', providers: [NaturalHierarchicSelectorService], standalone: true, imports: [
|
|
366
|
-
NaturalSearchComponent,
|
|
367
|
-
CommonModule,
|
|
368
|
-
MatProgressSpinnerModule,
|
|
369
|
-
MatTreeModule,
|
|
370
|
-
MatButtonModule,
|
|
371
|
-
MatIconModule,
|
|
372
|
-
NaturalIconDirective,
|
|
373
|
-
MatCheckboxModule,
|
|
374
|
-
MatChipsModule,
|
|
375
|
-
], template: "<div [style.margin-bottom.px]=\"20\">\n <natural-search (selectionChange)=\"search($event)\" [facets]=\"searchFacets\" [selections]=\"searchSelections\" />\n</div>\n\n<div class=\"body\">\n @if (loading) {\n <mat-progress-spinner [diameter]=\"36\" mode=\"indeterminate\" style=\"margin: 10px\" />\n }\n\n <mat-tree [dataSource]=\"dataSource\" [treeControl]=\"treeControl\">\n <mat-tree-node *matTreeNodeDef=\"let node\" [ngClass]=\"{leaf: !node.expandable}\" matTreeNodePadding>\n @if (node.expandable) {\n <button\n (click)=\"loadChildren(node)\"\n [attr.aria-label]=\"'toggle ' + node.name\"\n mat-icon-button\n matTreeNodeToggle\n >\n @if (node.loading) {\n <mat-progress-spinner [diameter]=\"24\" [strokeWidth]=\"5\" mode=\"indeterminate\" />\n }\n @if (!node.loading) {\n <mat-icon [naturalIcon]=\"treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'\" />\n }\n </button>\n }\n\n <mat-checkbox\n (change)=\"toggleFlatNode(node)\"\n [checked]=\"flatNodesSelection.isSelected(node)\"\n [disabled]=\"!isNodeTogglable(node)\"\n style=\"margin-right: 10px\"\n >\n @if (node.node.config.icon) {\n <mat-icon [naturalIcon]=\"node.node.config.icon\" style=\"margin-right: 10px\" />\n }\n <span>{{ node.name }}</span>\n </mat-checkbox>\n </mat-tree-node>\n </mat-tree>\n\n <mat-chip-listbox aria-orientation=\"vertical\" class=\"mat-mdc-chip-set-stacked\">\n @for (node of selectedNodes; track node.model.id) {\n <mat-chip-option (removed)=\"unselectModelNode(node)\" [removable]=\"true\" [selectable]=\"false\">\n @if (node.config.icon) {\n <mat-icon matChipAvatar [naturalIcon]=\"node.config.icon\" />\n }\n {{ node.model.name || node.model.fullName }}\n <button matChipRemove>\n <mat-icon naturalIcon=\"cancel\" />\n </button>\n </mat-chip-option>\n } @empty {\n <p class=\"mat-body nat-padding-horizontal\" i18n>Aucune s\u00E9lection</p>\n }\n </mat-chip-listbox>\n</div>\n\n@if (!loading && !dataSource.data.length) {\n <div i18n>Aucun r\u00E9sultat</div>\n}\n", styles: [":host{display:block}:host ul,:host li{-webkit-margin-before:0;-webkit-margin-after:0;list-style-type:none}:host mat-icon{width:18px;height:18px;font-size:18px}:host .mat-tree-node.leaf{margin-left:48px}:host .body{display:flex;flex-direction:row;justify-content:space-between}:host .body mat-tree{flex:66}:host .body mat-chip-listbox{flex:33}:host mat-tree{flex-shrink:0}:host mat-chip-listbox{margin-left:10px}\n"] }]
|
|
376
|
-
}], propDecorators: { displayWith: [{
|
|
377
|
-
type: Input
|
|
378
|
-
}], config: [{
|
|
379
|
-
type: Input,
|
|
380
|
-
args: [{ required: true }]
|
|
381
|
-
}], multiple: [{
|
|
382
|
-
type: Input
|
|
383
|
-
}], selected: [{
|
|
384
|
-
type: Input
|
|
385
|
-
}], allowUnselect: [{
|
|
386
|
-
type: Input
|
|
387
|
-
}], filters: [{
|
|
388
|
-
type: Input
|
|
389
|
-
}], searchFacets: [{
|
|
390
|
-
type: Input
|
|
391
|
-
}], searchSelections: [{
|
|
392
|
-
type: Input
|
|
393
|
-
}], searchSelectionChange: [{
|
|
394
|
-
type: Output
|
|
395
|
-
}], selectionChange: [{
|
|
396
|
-
type: Output
|
|
397
|
-
}] } });
|
|
398
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGllcmFyY2hpYy1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uYXR1cmFsL3NyYy9saWIvbW9kdWxlcy9oaWVyYXJjaGljLXNlbGVjdG9yL2hpZXJhcmNoaWMtc2VsZWN0b3IvaGllcmFyY2hpYy1zZWxlY3Rvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uYXR1cmFsL3NyYy9saWIvbW9kdWxlcy9oaWVyYXJjaGljLXNlbGVjdG9yL2hpZXJhcmNoaWMtc2VsZWN0b3IvaGllcmFyY2hpYy1zZWxlY3Rvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDeEQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFDSCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUdMLE1BQU0sR0FFVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFOUYsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR3hDLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBRzlFLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBSXhELE9BQU8sRUFBQyxnQ0FBZ0MsRUFBMEIsTUFBTSwrQkFBK0IsQ0FBQztBQUN4RyxPQUFPLEVBQUMsNkJBQTZCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFDLGlCQUFpQixF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TUFBTTtzQkFBckMsS0FBSzt1QkFBQyxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUM7Z0JBS1AsUUFBUTtzQkFBdkIsS0FBSztnQkFNVSxRQUFRO3NCQUF2QixLQUFLO2dCQUtVLGFBQWE7c0JBQTVCLEtBQUs7Z0JBS1UsT0FBTztzQkFBdEIsS0FBSztnQkFLVSxZQUFZO3NCQUEzQixLQUFLO2dCQUtVLGdCQUFnQjtzQkFBL0IsS0FBSztnQkFLb0IscUJBQXFCO3NCQUE5QyxNQUFNO2dCQVdtQixlQUFlO3NCQUF4QyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTZWxlY3Rpb25Nb2RlbH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcbmltcG9ydCB7RmxhdFRyZWVDb250cm9sfSBmcm9tICdAYW5ndWxhci9jZGsvdHJlZSc7XG5pbXBvcnQge1xuICAgIENvbXBvbmVudCxcbiAgICBEZXN0cm95UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBpbmplY3QsXG4gICAgSW5wdXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge01hdFRyZWVGbGF0RGF0YVNvdXJjZSwgTWF0VHJlZUZsYXR0ZW5lciwgTWF0VHJlZU1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdHJlZSc7XG5pbXBvcnQge09ic2VydmFibGV9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtmaW5hbGl6ZX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtRdWVyeVZhcmlhYmxlc30gZnJvbSAnLi4vLi4vLi4vY2xhc3Nlcy9xdWVyeS12YXJpYWJsZS1tYW5hZ2VyJztcbmltcG9ydCB7TGl0ZXJhbH0gZnJvbSAnLi4vLi4vLi4vdHlwZXMvdHlwZXMnO1xuaW1wb3J0IHt0b0dyYXBoUUxEb2N0cmluZUZpbHRlcn0gZnJvbSAnLi4vLi4vc2VhcmNoL2NsYXNzZXMvZ3JhcGhxbC1kb2N0cmluZSc7XG5pbXBvcnQge05hdHVyYWxTZWFyY2hGYWNldHN9IGZyb20gJy4uLy4uL3NlYXJjaC90eXBlcy9mYWNldCc7XG5pbXBvcnQge05hdHVyYWxTZWFyY2hTZWxlY3Rpb25zfSBmcm9tICcuLi8uLi9zZWFyY2gvdHlwZXMvdmFsdWVzJztcbmltcG9ydCB7SGllcmFyY2hpY0ZsYXROb2RlfSBmcm9tICcuLi9jbGFzc2VzL2ZsYXQtbm9kZSc7XG5pbXBvcnQge05hdHVyYWxIaWVyYXJjaGljQ29uZmlndXJhdGlvbn0gZnJvbSAnLi4vY2xhc3Nlcy9oaWVyYXJjaGljLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHtIaWVyYXJjaGljRmlsdGVyc0NvbmZpZ3VyYXRpb259IGZyb20gJy4uL2NsYXNzZXMvaGllcmFyY2hpYy1maWx0ZXJzLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHtIaWVyYXJjaGljTW9kZWxOb2RlfSBmcm9tICcuLi9jbGFzc2VzL21vZGVsLW5vZGUnO1xuaW1wb3J0IHtOYXR1cmFsSGllcmFyY2hpY1NlbGVjdG9yU2VydmljZSwgT3JnYW5pemVkTW9kZWxTZWxlY3Rpb259IGZyb20gJy4vaGllcmFyY2hpYy1zZWxlY3Rvci5zZXJ2aWNlJztcbmltcG9ydCB7cmVwbGFjZU9iamVjdEtlZXBpbmdSZWZlcmVuY2V9IGZyb20gJy4uLy4uLy4uL2NsYXNzZXMvdXRpbGl0eSc7XG5pbXBvcnQge01hdENoaXBzTW9kdWxlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGlwcyc7XG5pbXBvcnQge01hdENoZWNrYm94TW9kdWxlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGVja2JveCc7XG5pbXBvcnQge05hdHVyYWxJY29uRGlyZWN0aXZlfSBmcm9tICcuLi8uLi9pY29uL2ljb24uZGlyZWN0aXZlJztcbmltcG9ydCB7TWF0SWNvbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQge01hdEJ1dHRvbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7TWF0UHJvZ3Jlc3NTcGlubmVyTW9kdWxlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wcm9ncmVzcy1zcGlubmVyJztcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtOYXR1cmFsU2VhcmNoQ29tcG9uZW50fSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoL3NlYXJjaC5jb21wb25lbnQnO1xuaW1wb3J0IHt0YWtlVW50aWxEZXN0cm95ZWR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduYXR1cmFsLWhpZXJhcmNoaWMtc2VsZWN0b3InLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9oaWVyYXJjaGljLXNlbGVjdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybDogJy4vaGllcmFyY2hpYy1zZWxlY3Rvci5jb21wb25lbnQuc2NzcycsXG4gICAgcHJvdmlkZXJzOiBbTmF0dXJhbEhpZXJhcmNoaWNTZWxlY3RvclNlcnZpY2VdLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW1xuICAgICAgICBOYXR1cmFsU2VhcmNoQ29tcG9uZW50LFxuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZSxcbiAgICAgICAgTWF0VHJlZU1vZHVsZSxcbiAgICAgICAgTWF0QnV0dG9uTW9kdWxlLFxuICAgICAgICBNYXRJY29uTW9kdWxlLFxuICAgICAgICBOYXR1cmFsSWNvbkRpcmVjdGl2ZSxcbiAgICAgICAgTWF0Q2hlY2tib3hNb2R1bGUsXG4gICAgICAgIE1hdENoaXBzTW9kdWxlLFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5hdHVyYWxIaWVyYXJjaGljU2VsZWN0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaGllcmFyY2hpY1NlbGVjdG9yU2VydmljZSA9IGluamVjdChOYXR1cmFsSGllcmFyY2hpY1NlbGVjdG9yU2VydmljZSk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0aGF0IHJlY2VpdmVzIGEgbW9kZWwgYW5kIHJldHVybnMgYSBzdHJpbmcgZm9yIGRpc3BsYXkgdmFsdWVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgZGlzcGxheVdpdGg/OiAoaXRlbTogYW55KSA9PiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDb25maWcgZm9yIGl0ZW1zIGFuZCByZWxhdGlvbnMgYXJyYW5nZW1lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoe3JlcXVpcmVkOiB0cnVlfSkgcHVibGljIGNvbmZpZyE6IE5hdHVyYWxIaWVyYXJjaGljQ29uZmlndXJhdGlvbltdO1xuXG4gICAgLyoqXG4gICAgICogSWYgbXVsdGlwbGUgb3Igc2luZ2xlIGl0ZW0gc2VsZWN0aW9uXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIG11bHRpcGxlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY3RlZCBpdGVtc1xuICAgICAqIE9yZ2FuaXplZCBieSBrZXksIGNvbnRhaW5pbmcgZWFjaCBhbiBhcnJheSBvZiBzZWxlY3RlZCBpdGVtcyBvZiBzYW1lIHR5cGVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc2VsZWN0ZWQ6IE9yZ2FuaXplZE1vZGVsU2VsZWN0aW9uID0ge307XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHNlbGVjdGFibGUgZWxlbWVudHMgY2FuIGJlIHVuc2VsZWN0ZWRcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgYWxsb3dVbnNlbGVjdCA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBGaWx0ZXJzIHRoYXQgYXBwbHkgdG8gZWFjaCBxdWVyeVxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBmaWx0ZXJzPzogSGllcmFyY2hpY0ZpbHRlcnNDb25maWd1cmF0aW9uIHwgbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmYWNldHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc2VhcmNoRmFjZXRzOiBOYXR1cmFsU2VhcmNoRmFjZXRzID0gW107XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY3Rpb25zIHRvIGFwcGx5IG9uIG5hdHVyYWwtc2VhcmNoIG9uIGNvbXBvbmVudCBpbml0aWFsaXNhdGlvblxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzZWFyY2hTZWxlY3Rpb25zOiBOYXR1cmFsU2VhcmNoU2VsZWN0aW9ucyA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgd2hlbiBuYXR1cmFsLXNlYXJjaCBzZWxlY3Rpb25zIGNoYW5nZVxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgcmVhZG9ubHkgc2VhcmNoU2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxOYXR1cmFsU2VhcmNoU2VsZWN0aW9ucz4oKTtcblxuICAgIC8qKlxuICAgICAqIElubmVyIHJlcHJlc2VudGF0aW9uIG9mIHNlbGVjdGVkIEBJbnB1dCgpIHRvIGFsbG93IGZsYXQgbGlzdGluZyBhcyBtYXQtY2hpcC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0ZWROb2RlczogSGllcmFyY2hpY01vZGVsTm9kZVtdID0gW107XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBzZWxlY3Rpb24gY2hhbmdlXG4gICAgICogUmV0dXJucyBhIExpdGVyYWwgd2hlcmUgc2VsZWN0ZWQgbW9kZWxzIGFyZSBvcmdhbml6ZWQgYnkga2V5XG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyByZWFkb25seSBzZWxlY3Rpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE9yZ2FuaXplZE1vZGVsU2VsZWN0aW9uPigpO1xuXG4gICAgLyoqXG4gICAgICogQ29udHJvbGxlciBmb3Igbm9kZXMgc2VsZWN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGZsYXROb2Rlc1NlbGVjdGlvbiE6IFNlbGVjdGlvbk1vZGVsPEhpZXJhcmNoaWNGbGF0Tm9kZT47XG5cbiAgICBwdWJsaWMgdHJlZUNvbnRyb2whOiBGbGF0VHJlZUNvbnRyb2w8SGllcmFyY2hpY0ZsYXROb2RlPjtcbiAgICBwdWJsaWMgdHJlZUZsYXR0ZW5lciE6IE1hdFRyZWVGbGF0dGVuZXI8SGllcmFyY2hpY01vZGVsTm9kZSwgSGllcmFyY2hpY0ZsYXROb2RlPjtcbiAgICBwdWJsaWMgZGF0YVNvdXJjZSE6IE1hdFRyZWVGbGF0RGF0YVNvdXJjZTxIaWVyYXJjaGljTW9kZWxOb2RlLCBIaWVyYXJjaGljRmxhdE5vZGU+O1xuXG4gICAgcHVibGljIGxvYWRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIENhY2hlIGZvciB0cmFuc2Zvcm1lZCBub2Rlc1xuICAgICAqL1xuICAgIHByaXZhdGUgZmxhdE5vZGVNYXA6IE1hcDxzdHJpbmcsIEhpZXJhcmNoaWNGbGF0Tm9kZT4gPSBuZXcgTWFwPHN0cmluZywgSGllcmFyY2hpY0ZsYXROb2RlPigpO1xuXG4gICAgLyoqXG4gICAgICogQW5ndWxhciBPbkNoYW5nZSBpbXBsZW1lbnRhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIGlmIChjaGFuZ2VzLnNlbGVjdGVkICYmICFjaGFuZ2VzLnNlbGVjdGVkLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUlubmVyU2VsZWN0aW9uKHRoaXMuc2VsZWN0ZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYW5nZXMuZmlsdGVycyAmJiAhY2hhbmdlcy5maWx0ZXJzLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRSb290cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW5ndWxhciBPbkluaXQgaW1wbGVtZW50YXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIC8vIEluaXQgdHJlZSBjaGVja2JveCBzZWxlY3RvcnNcbiAgICAgICAgdGhpcy5mbGF0Tm9kZXNTZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55Pih0aGlzLm11bHRpcGxlKTtcblxuICAgICAgICAvLyBUcmVlIGNvbnRyb2xsZXJzIGFuZCBtYW5pcHVsYXRvcnNcbiAgICAgICAgdGhpcy50cmVlRmxhdHRlbmVyID0gbmV3IE1hdFRyZWVGbGF0dGVuZXIoXG4gICAgICAgICAgICB0aGlzLnRyYW5zZm9ybWVyKCksXG4gICAgICAgICAgICB0aGlzLmdldExldmVsKCksXG4gICAgICAgICAgICB0aGlzLmlzRXhwYW5kYWJsZSgpLFxuICAgICAgICAgICAgdGhpcy5nZXRDaGlsZHJlbigpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnRyZWVDb250cm9sID0gbmV3IEZsYXRUcmVlQ29udHJvbDxIaWVyYXJjaGljRmxhdE5vZGU+KHRoaXMuZ2V0TGV2ZWwoKSwgdGhpcy5pc0V4cGFuZGFibGUoKSk7XG5cbiAgICAgICAgLy8gVGhlIGRhdGFTb3VyY2UgY29udGFpbnMgYSBuZXN0ZWQgTW9kZWxOb2RlcyBsaXN0LiBFYWNoIE1vZGVsTm9kZSBoYXMgYSBjaGlsZCBhdHRyaWJ1dGUgdGhhdCByZXR1cm5zIGFuIG9ic2VydmFibGUuXG4gICAgICAgIC8vIFRoZSBkYXRhU291cmNlIGNvbnRhaW5zIGEgZmxhdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbmVzdGVkIE1vZGVsTm9kZXMgdGhhdCBpcyBnZW5lcmF0ZWQgYnkgdGhlIHRyZWVGbGF0dGVuZXIgcmVsYXRlZCBmdW5jdGlvbnNcbiAgICAgICAgdGhpcy5kYXRhU291cmNlID0gbmV3IE1hdFRyZWVGbGF0RGF0YVNvdXJjZSh0aGlzLnRyZWVDb250cm9sLCB0aGlzLnRyZWVGbGF0dGVuZXIpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBkYXRhU291cmNlIHdoZW4gcmVjZWl2aW5nIG5ldyBsaXN0IC0+IHdlIGFzc2lnbiB0aGUgd2hvbGUgdHJlZVxuICAgICAgICAvLyBUaGUgdHJlZUNvbnRyb2wgYW5kIHRyZWVGbGF0dGVuZXIgd2lsbCBnZW5lcmF0ZSB0aGUgZGlzcGxheWVkIHRyZWVcbiAgICAgICAgdGhpcy5oaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlLmRhdGFDaGFuZ2VcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgICAgICAgLnN1YnNjcmliZShkYXRhID0+ICh0aGlzLmRhdGFTb3VyY2UuZGF0YSA9IGRhdGEpKTtcblxuICAgICAgICAvLyBQcmV2ZW50IGVtcHR5IHNjcmVlbiBvbiBmaXJzdCBsb2FkIGFuZCBpbml0IE5hdHVyYWxIaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlIHdpdGggaW5wdXR0ZWQgY29uZmlndXJhdGlvblxuICAgICAgICBsZXQgdmFyaWFibGVzO1xuICAgICAgICBpZiAodGhpcy5zZWFyY2hTZWxlY3Rpb25zLnNvbWUocyA9PiBzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgIHZhcmlhYmxlcyA9IHtmaWx0ZXI6IHRvR3JhcGhRTERvY3RyaW5lRmlsdGVyKHRoaXMuc2VhcmNoRmFjZXRzLCB0aGlzLnNlYXJjaFNlbGVjdGlvbnMpfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRSb290cyh2YXJpYWJsZXMpO1xuXG4gICAgICAgIC8vIE9yZ2FuaXplZFNlbGVjdGlvbiBpbnRvIGxpc3QgdXNhYmxlIGJ5IHRlbXBsYXRlXG4gICAgICAgIHRoaXMudXBkYXRlSW5uZXJTZWxlY3Rpb24odGhpcy5zZWxlY3RlZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHNlbGVjdGlvbiBvZiBhIEZsYXROb2RlLCBjb25zaWRlcmluZyBpZiBtdWx0aXBsZSBzZWxlY3Rpb24gaXMgYWN0aXZhdGVkIG9yIG5vdFxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGVGbGF0Tm9kZShmbGF0Tm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgICAvLyBJcyBtdWx0aXBsZSBhbGxvd2VkLCBqdXN0IHRvZ2dsZSBlbGVtZW50XG4gICAgICAgICAgICBpZiAodGhpcy5mbGF0Tm9kZXNTZWxlY3Rpb24uaXNTZWxlY3RlZChmbGF0Tm9kZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVuc2VsZWN0RmxhdE5vZGUoZmxhdE5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEZsYXROb2RlKGZsYXROb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5tdWx0aXBsZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZmxhdE5vZGVzU2VsZWN0aW9uLmlzU2VsZWN0ZWQoZmxhdE5vZGUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51bnNlbGVjdFNpbmdsZUZsYXROb2RlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIElmIG5vdCBtdWx0aXBsZSwgYW5kIHdlIHdhbnQgdG8gc2VsZWN0IGFuIGVsZW1lbnQsIHVuc2VsZWN0IGV2ZXJ5dGhpbmcgYmVmb3JlIHRvIGtlZXAgYSBzaW5nbGUgc2VsZWN0aW9uXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RTaW5nbGVGbGF0Tm9kZShmbGF0Tm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHVuc2VsZWN0aW5nIGFuIGVsZW1lbnQgZnJvbSB0aGUgbWF0LWNoaXBzLCBpdCBjYW4gYmUgZGVlcCBpbiB0aGUgaGllcmFyY2h5LCBhbmQgdGhlIHRyZWUgZWxlbWVudCBtYXkgbm90IGV4aXN0Li4uXG4gICAgICogLi4uIGJ1dCB3ZSBzdGlsbCBuZWVkIHRvIHJlbW92ZSB0aGUgZWxlbWVudCBmcm9tIHRoZSBtYXQtY2hpcHMgbGlzdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgdW5zZWxlY3RNb2RlbE5vZGUobm9kZTogSGllcmFyY2hpY01vZGVsTm9kZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBmbGF0Tm9kZSA9IHRoaXMuZ2V0RmxhdE5vZGUobm9kZSk7XG4gICAgICAgIGlmIChmbGF0Tm9kZSkge1xuICAgICAgICAgICAgdGhpcy51bnNlbGVjdEZsYXROb2RlKGZsYXROb2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNoaXBzIGxpc3Qgb25seSBpZiBubyBmbGF0Tm9kZSwgYmVjYXVzZSB1bnNlbGVjdEZsYXROb2RlKCkgYWxyZWFkeSBkZWFscyB3aXRoIGl0LlxuICAgICAgICAgICAgdGhpcy5yZW1vdmVNb2RlbE5vZGUobm9kZSk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbih0aGlzLnNlbGVjdGVkTm9kZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGlzTm9kZVRvZ2dsYWJsZShmbGF0Tm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmlzTm9kZVNlbGVjdGVkKGZsYXROb2RlLm5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmxhdE5vZGUuZGVzZWxlY3RhYmxlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZsYXROb2RlLnNlbGVjdGFibGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc3BsYXlGbihjb25maWc6IE5hdHVyYWxIaWVyYXJjaGljQ29uZmlndXJhdGlvbik6IChpdGVtOiBhbnkpID0+IHN0cmluZyB7XG4gICAgICAgIGlmIChjb25maWcuZGlzcGxheVdpdGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25maWcuZGlzcGxheVdpdGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kaXNwbGF5V2l0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheVdpdGg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaXRlbSA9PiAoaXRlbSA/IGl0ZW0uZnVsbE5hbWUgfHwgaXRlbS5uYW1lIDogJycpO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkQ2hpbGRyZW4oZmxhdE5vZGU6IEhpZXJhcmNoaWNGbGF0Tm9kZSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50cmVlQ29udHJvbC5pc0V4cGFuZGVkKGZsYXROb2RlKSkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlLmxvYWRDaGlsZHJlbihmbGF0Tm9kZSwgdGhpcy5maWx0ZXJzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZWQgdG8gY29sbGFwc2UgYWxsIGNoaWxkcmVuIHdoZW4gY2xvc2luZyBhIHBhcmVudCwgYnV0IG5vdCBzdXJlIGl0J3MgZ29vZC5cbiAgICAgKi9cbiAgICAvLyBwdWJsaWMgbG9hZENoaWxkcmVuKGZsYXROb2RlOiBIaWVyYXJjaGljRmxhdE5vZGUpIHtcbiAgICAvLyAgICAgaWYgKHRoaXMudHJlZUNvbnRyb2wuaXNFeHBhbmRlZChmbGF0Tm9kZSkpIHtcbiAgICAvL1xuICAgIC8vICAgICAgICAgY29uc3QgY2FjaGVkRmxhdE5vZGUgPSB0aGlzLmdldEZsYXROb2RlKGZsYXROb2RlLm5vZGUpO1xuICAgIC8vICAgICAgICAgaWYgKGNhY2hlZEZsYXROb2RlKSB7XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlLmxvYWRDaGlsZHJlbihjYWNoZWRGbGF0Tm9kZSwgdGhpcy5maWx0ZXJzKTtcbiAgICAvL1xuICAgIC8vICAgICAgICAgICAgIC8vIENsb3NlIGNoaWxkcmVuXG4gICAgLy8gICAgICAgICAgICAgY2FjaGVkRmxhdE5vZGUubm9kZS5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAvLyAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlID0gdGhpcy5nZXRGbGF0Tm9kZShjaGlsZCk7XG4gICAgLy8gICAgICAgICAgICAgICAgIGlmIChjaGlsZE5vZGUpIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJlZUNvbnRyb2wuY29sbGFwc2UoY2hpbGROb2RlKTtcbiAgICAvLyAgICAgICAgICAgICAgICAgfVxuICAgIC8vICAgICAgICAgICAgIH0pO1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICB9XG4gICAgLy8gfVxuXG4gICAgcHJpdmF0ZSBnZXRDaGlsZHJlbigpOiAobm9kZTogSGllcmFyY2hpY01vZGVsTm9kZSkgPT4gT2JzZXJ2YWJsZTxIaWVyYXJjaGljTW9kZWxOb2RlW10+IHtcbiAgICAgICAgcmV0dXJuIChub2RlOiBIaWVyYXJjaGljTW9kZWxOb2RlKTogT2JzZXJ2YWJsZTxIaWVyYXJjaGljTW9kZWxOb2RlW10+ID0+IHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmNoaWxkcmVuQ2hhbmdlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybXMgYSBIaWVyYXJjaGljTW9kZWxOb2RlIGludG8gYSBGbGF0Tm9kZVxuICAgICAqL1xuICAgIHByaXZhdGUgdHJhbnNmb3JtZXIoKTogKG5vZGU6IEhpZXJhcmNoaWNNb2RlbE5vZGUsIGxldmVsOiBudW1iZXIpID0+IEhpZXJhcmNoaWNGbGF0Tm9kZSB7XG4gICAgICAgIHJldHVybiAobm9kZTogSGllcmFyY2hpY01vZGVsTm9kZSwgbGV2ZWw6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JDcmVhdGVGbGF0Tm9kZShub2RlLCBsZXZlbCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIGRlZXAgb2YgdGhlIG5vZGUgaW4gdGhlIHRyZWVcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldExldmVsKCk6IChub2RlOiBIaWVyYXJjaGljRmxhdE5vZGUpID0+IG51bWJlciB7XG4gICAgICAgIHJldHVybiAobm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5sZXZlbDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJcyBhbHdheXMgZXhwYW5kYWJsZSBiZWNhdXNlIHdlIGxvYWQgb24gZGVtYW5kLCB3ZSBkb24ndCBrbm93IGlmIHRoZXJlIGFyZSBjaGlsZHJlbiB5ZXRcbiAgICAgKi9cbiAgICBwcml2YXRlIGlzRXhwYW5kYWJsZSgpOiAobm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKSA9PiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChub2RlOiBIaWVyYXJjaGljRmxhdE5vZGUpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmV4cGFuZGFibGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRPckNyZWF0ZUZsYXROb2RlKG5vZGU6IEhpZXJhcmNoaWNNb2RlbE5vZGUsIGxldmVsOiBudW1iZXIpOiBIaWVyYXJjaGljRmxhdE5vZGUge1xuICAgICAgICAvLyBSZXR1cm4gRmxhdE5vZGUgaWYgZXhpc3RzXG4gICAgICAgIGNvbnN0IGZsYXROb2RlID0gdGhpcy5nZXRGbGF0Tm9kZShub2RlKTtcbiAgICAgICAgaWYgKGZsYXROb2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmxhdE5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gbmV3IEZsYXROb2RlXG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUZsYXROb2RlKG5vZGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2VhcmNoKHNlbGVjdGlvbnM6IE5hdHVyYWxTZWFyY2hTZWxlY3Rpb25zKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VhcmNoU2VsZWN0aW9uQ2hhbmdlLmVtaXQoc2VsZWN0aW9ucyk7XG4gICAgICAgIGlmIChzZWxlY3Rpb25zLnNvbWUocyA9PiBzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhcmlhYmxlcyA9IHtmaWx0ZXI6IHRvR3JhcGhRTERvY3RyaW5lRmlsdGVyKHRoaXMuc2VhcmNoRmFjZXRzLCBzZWxlY3Rpb25zKX07XG4gICAgICAgICAgICB0aGlzLmhpZXJhcmNoaWNTZWxlY3RvclNlcnZpY2Uuc2VhcmNoKHZhcmlhYmxlcywgdGhpcy5maWx0ZXJzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9hZFJvb3RzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRSb290cyhzZWFyY2hWYXJpYWJsZXM/OiBRdWVyeVZhcmlhYmxlcyk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmZsYXROb2RlTWFwID0gbmV3IE1hcDxzdHJpbmcsIEhpZXJhcmNoaWNGbGF0Tm9kZT4oKTtcbiAgICAgICAgdGhpcy5oaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlXG4gICAgICAgICAgICAuaW5pdCh0aGlzLmNvbmZpZywgdGhpcy5maWx0ZXJzLCBzZWFyY2hWYXJpYWJsZXMgfHwgbnVsbClcbiAgICAgICAgICAgIC5waXBlKGZpbmFsaXplKCgpID0+ICh0aGlzLmxvYWRpbmcgPSBmYWxzZSkpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN5bmMgaW5uZXIgc2VsZWN0aW9uICh0cmVlIGFuZCBtYXQtY2hpcHMpIGFjY29yZGluZyB0byBzZWxlY3RlZCBpbnB1dCBhdHRyaWJ1dGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZUlubmVyU2VsZWN0aW9uKHNlbGVjdGVkOiBPcmdhbml6ZWRNb2RlbFNlbGVjdGlvbik6IHZvaWQge1xuICAgICAgICAvLyBUcmFuc2Zvcm0gYW4gT3JnYW5pemVkTW9kZWxTZWxlY3Rpb24gaW50byBhIE1vZGVsTm9kZSBsaXN0IHRoYXQgaXMgdXNlZCBpbiB0aGUgc2VsZWN0ZWQgem9uZSBvZiB0aGUgY29tcG9uZW50IChzZWUgdGVtcGxhdGUpXG4gICAgICAgIHRoaXMuc2VsZWN0ZWROb2RlcyA9IHRoaXMuaGllcmFyY2hpY1NlbGVjdG9yU2VydmljZS5mcm9tT3JnYW5pemVkU2VsZWN0aW9uKHNlbGVjdGVkKTtcblxuICAgICAgICB0aGlzLmZsYXROb2Rlc1NlbGVjdGlvbi5jbGVhcigpO1xuICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5zZWxlY3RlZE5vZGVzKSB7XG4gICAgICAgICAgICBjb25zdCBmbGF0Tm9kZSA9IHRoaXMuZ2V0RmxhdE5vZGUobm9kZSk7XG4gICAgICAgICAgICBpZiAoZmxhdE5vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZsYXROb2Rlc1NlbGVjdGlvbi5zZWxlY3QoZmxhdE5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5zZWxlY3QgYSBub2RlLCBrZWVwaW5nIHRoZSByZXN0IG9mIHRoZSBzZWxlY3RlZCB1bnRvdWNoZWRcbiAgICAgKi9cbiAgICBwcml2YXRlIHVuc2VsZWN0RmxhdE5vZGUoZmxhdE5vZGU6IEhpZXJhcmNoaWNGbGF0Tm9kZSk6IHZvaWQge1xuICAgICAgICB0aGlzLmZsYXROb2Rlc1NlbGVjdGlvbi5kZXNlbGVjdChmbGF0Tm9kZSk7XG4gICAgICAgIHRoaXMucmVtb3ZlTW9kZWxOb2RlKGZsYXROb2RlLm5vZGUpO1xuICAgICAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbih0aGlzLnNlbGVjdGVkTm9kZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIG5vZGUgZnJvbSBjaGlwIGxpc3RzXG4gICAgICovXG4gICAgcHJpdmF0ZSByZW1vdmVNb2RlbE5vZGUobm9kZTogSGllcmFyY2hpY01vZGVsTm9kZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldE1hcEtleShub2RlLm1vZGVsKTtcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uSW5kZXggPSB0aGlzLnNlbGVjdGVkTm9kZXMuZmluZEluZGV4KG4gPT4gdGhpcy5nZXRNYXBLZXkobi5tb2RlbCkgPT09IGtleSk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWROb2Rlcy5zcGxpY2Uoc2VsZWN0aW9uSW5kZXgsIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdCBhIG5vZGUsIGtlZXBpbmcgdGggcmVzdCBvZiB0aGUgc2VsZWN0ZWQgdW50b3VjaGVkXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZWxlY3RGbGF0Tm9kZShmbGF0Tm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZmxhdE5vZGVzU2VsZWN0aW9uLnNlbGVjdChmbGF0Tm9kZSk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWROb2Rlcy5wdXNoKGZsYXROb2RlLm5vZGUpO1xuICAgICAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbih0aGlzLnNlbGVjdGVkTm9kZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsZWFyIGFsbCBzZWxlY3RlZCBhbmQgc2VsZWN0IHRoZSBnaXZlbiBub2RlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZWxlY3RTaW5nbGVGbGF0Tm9kZShmbGF0Tm9kZTogSGllcmFyY2hpY0ZsYXROb2RlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZmxhdE5vZGVzU2VsZWN0aW9uLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuZmxhdE5vZGVzU2VsZWN0aW9uLnNlbGVjdChmbGF0Tm9kZSk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWROb2RlcyA9IFtmbGF0Tm9kZS5ub2RlXTtcbiAgICAgICAgdGhpcy51cGRhdGVTZWxlY3Rpb24odGhpcy5zZWxlY3RlZE5vZGVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgc2VsZWN0ZWQgYW5kIHNlbGVjdCB0aGUgZ2l2ZW4gbm9kZVxuICAgICAqL1xuICAgIHByaXZhdGUgdW5zZWxlY3RTaW5nbGVGbGF0Tm9kZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5mbGF0Tm9kZXNTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZE5vZGVzID0gW107XG4gICAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uKHRoaXMuc2VsZWN0ZWROb2Rlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtIHRoZSBnaXZlbiBlbGVtZW50cyBpbnRvIHRoZSBvcmdhbml6ZWQgc2VsZWN0aW9uIHRoYXQgaXMgZW1pdHRlZCB0byBvdXRwdXRcbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZVNlbGVjdGlvbihzZWxlY3RlZDogSGllcmFyY2hpY01vZGVsTm9kZVtdKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG9yZ2FuaXplZEZsYXROb2Rlc1NlbGVjdGlvbiA9IHRoaXMuaGllcmFyY2hpY1NlbGVjdG9yU2VydmljZS50b09yZ2FuaXplZFNlbGVjdGlvbihzZWxlY3RlZCk7XG4gICAgICAgIHJlcGxhY2VPYmplY3RLZWVwaW5nUmVmZXJlbmNlKHRoaXMuc2VsZWN0ZWQsIG9yZ2FuaXplZEZsYXROb2Rlc1NlbGVjdGlvbik7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQob3JnYW5pemVkRmxhdE5vZGVzU2VsZWN0aW9uKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTm9kZVNlbGVjdGVkKG5vZGU6IEhpZXJhcmNoaWNNb2RlbE5vZGUpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXRNYXBLZXkobm9kZS5tb2RlbCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWROb2Rlcy5zb21lKG4gPT4gdGhpcy5nZXRNYXBLZXkobi5tb2RlbCkgPT09IGtleSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRGbGF0Tm9kZShub2RlOiBIaWVyYXJjaGljTW9kZWxOb2RlKTogSGllcmFyY2hpY0ZsYXROb2RlIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0TWFwS2V5KG5vZGUubW9kZWwpO1xuICAgICAgICByZXR1cm4gdGhpcy5mbGF0Tm9kZU1hcC5nZXQoa2V5KSB8fCBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlRmxhdE5vZGUobm9kZTogSGllcmFyY2hpY01vZGVsTm9kZSwgbGV2ZWw6IG51bWJlcik6IEhpZXJhcmNoaWNGbGF0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0TWFwS2V5KG5vZGUubW9kZWwpO1xuICAgICAgICBjb25zdCBuYW1lID0gdGhpcy5nZXREaXNwbGF5Rm4obm9kZS5jb25maWcpKG5vZGUubW9kZWwpO1xuICAgICAgICBjb25zdCBleHBhbmRhYmxlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGlzQ3VzdG9tU2VsZWN0YWJsZSA9IG5vZGUuY29uZmlnLmlzU2VsZWN0YWJsZUNhbGxiYWNrXG4gICAgICAgICAgICA/IG5vZGUuY29uZmlnLmlzU2VsZWN0YWJsZUNhbGxiYWNrKG5vZGUubW9kZWwpXG4gICAgICAgICAgICA6IHRydWU7XG4gICAgICAgIGNvbnN0IGlzU2VsZWN0YWJsZSA9ICEhbm9kZS5jb25maWcuc2VsZWN0YWJsZUF0S2V5ICYmIGlzQ3VzdG9tU2VsZWN0YWJsZTtcblxuICAgICAgICBjb25zdCBmbGF0Tm9kZSA9IG5ldyBIaWVyYXJjaGljRmxhdE5vZGUobm9kZSwgbmFtZSwgbGV2ZWwsIGV4cGFuZGFibGUsIGlzU2VsZWN0YWJsZSk7XG5cbiAgICAgICAgdGhpcy5oaWVyYXJjaGljU2VsZWN0b3JTZXJ2aWNlLmNvdW50SXRlbXMoZmxhdE5vZGUsIHRoaXMuZmlsdGVycyk7XG5cbiAgICAgICAgLy8gTWFyayBub2RlIGFzIHNlbGVjdGVkIGlmIG5lZWRlZCAoY2hlY2tzIHRoZSBzZWxlY3RlZCBwcm9jZXNzZWQgaW5wdXQpXG4gICAgICAgIGlmICh0aGlzLmlzTm9kZVNlbGVjdGVkKG5vZGUpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dVbnNlbGVjdCkge1xuICAgICAgICAgICAgICAgIGZsYXROb2RlLmRlc2VsZWN0YWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mbGF0Tm9kZXNTZWxlY3Rpb24uc2VsZWN0KGZsYXROb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhY2hlIEZsYXROb2RlXG4gICAgICAgIHRoaXMuZmxhdE5vZGVNYXAuc2V0KGtleSwgZmxhdE5vZGUpO1xuXG4gICAgICAgIHJldHVybiBmbGF0Tm9kZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGlkZW50aWZpZXIga2V5IGZvciBtYXAgY2FjaGVcbiAgICAgKiBBcyBtYW55IG9iamVjdCB0eXBlcyBjYW4gYmUgdXNlZCwgdGhpcyBmdW5jdGlvbiBjb25zaWRlcnMgdHlwZW5hbWUgYW5kIElEIHRvIHJldHVybiBzb21ldGhpbmcgbGlrZSBkb2N1bWVudC0xMjNcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldE1hcEtleShtb2RlbDogTGl0ZXJhbCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBtb2RlbC5fX3R5cGVuYW1lICsgJy0nICsgbW9kZWwuaWQ7XG4gICAgfVxufVxuIiwiPGRpdiBbc3R5bGUubWFyZ2luLWJvdHRvbS5weF09XCIyMFwiPlxuICAgIDxuYXR1cmFsLXNlYXJjaCAoc2VsZWN0aW9uQ2hhbmdlKT1cInNlYXJjaCgkZXZlbnQpXCIgW2ZhY2V0c109XCJzZWFyY2hGYWNldHNcIiBbc2VsZWN0aW9uc109XCJzZWFyY2hTZWxlY3Rpb25zXCIgLz5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwiYm9keVwiPlxuICAgIEBpZiAobG9hZGluZykge1xuICAgICAgICA8bWF0LXByb2dyZXNzLXNwaW5uZXIgW2RpYW1ldGVyXT1cIjM2XCIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIiBzdHlsZT1cIm1hcmdpbjogMTBweFwiIC8+XG4gICAgfVxuXG4gICAgPG1hdC10cmVlIFtkYXRhU291cmNlXT1cImRhdGFTb3VyY2VcIiBbdHJlZUNvbnRyb2xdPVwidHJlZUNvbnRyb2xcIj5cbiAgICAgICAgPG1hdC10cmVlLW5vZGUgKm1hdFRyZWVOb2RlRGVmPVwibGV0IG5vZGVcIiBbbmdDbGFzc109XCJ7bGVhZjogIW5vZGUuZXhwYW5kYWJsZX1cIiBtYXRUcmVlTm9kZVBhZGRpbmc+XG4gICAgICAgICAgICBAaWYgKG5vZGUuZXhwYW5kYWJsZSkge1xuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImxvYWRDaGlsZHJlbihub2RlKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ3RvZ2dsZSAnICsgbm9kZS5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIG1hdFRyZWVOb2RlVG9nZ2xlXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKG5vZGUubG9hZGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1zcGlubmVyIFtkaWFtZXRlcl09XCIyNFwiIFtzdHJva2VXaWR0aF09XCI1XCIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIiAvPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoIW5vZGUubG9hZGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIFtuYXR1cmFsSWNvbl09XCJ0cmVlQ29udHJvbC5pc0V4cGFuZGVkKG5vZGUpID8gJ2V4cGFuZF9tb3JlJyA6ICdjaGV2cm9uX3JpZ2h0J1wiIC8+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlRmxhdE5vZGUobm9kZSlcIlxuICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImZsYXROb2Rlc1NlbGVjdGlvbi5pc1NlbGVjdGVkKG5vZGUpXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWlzTm9kZVRvZ2dsYWJsZShub2RlKVwiXG4gICAgICAgICAgICAgICAgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHhcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEBpZiAobm9kZS5ub2RlLmNvbmZpZy5pY29uKSB7XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBbbmF0dXJhbEljb25dPVwibm9kZS5ub2RlLmNvbmZpZy5pY29uXCIgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEwcHhcIiAvPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBub2RlLm5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgPC9tYXQtdHJlZS1ub2RlPlxuICAgIDwvbWF0LXRyZWU+XG5cbiAgICA8bWF0LWNoaXAtbGlzdGJveCBhcmlhLW9yaWVudGF0aW9uPVwidmVydGljYWxcIiBjbGFzcz1cIm1hdC1tZGMtY2hpcC1zZXQtc3RhY2tlZFwiPlxuICAgICAgICBAZm9yIChub2RlIG9mIHNlbGVjdGVkTm9kZXM7IHRyYWNrIG5vZGUubW9kZWwuaWQpIHtcbiAgICAgICAgICAgIDxtYXQtY2hpcC1vcHRpb24gKHJlbW92ZWQpPVwidW5zZWxlY3RNb2RlbE5vZGUobm9kZSlcIiBbcmVtb3ZhYmxlXT1cInRydWVcIiBbc2VsZWN0YWJsZV09XCJmYWxzZVwiPlxuICAgICAgICAgICAgICAgIEBpZiAobm9kZS5jb25maWcuaWNvbikge1xuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gbWF0Q2hpcEF2YXRhciBbbmF0dXJhbEljb25dPVwibm9kZS5jb25maWcuaWNvblwiIC8+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHt7IG5vZGUubW9kZWwubmFtZSB8fCBub2RlLm1vZGVsLmZ1bGxOYW1lIH19XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXRDaGlwUmVtb3ZlPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gbmF0dXJhbEljb249XCJjYW5jZWxcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9tYXQtY2hpcC1vcHRpb24+XG4gICAgICAgIH0gQGVtcHR5IHtcbiAgICAgICAgICAgIDxwIGNsYXNzPVwibWF0LWJvZHkgbmF0LXBhZGRpbmctaG9yaXpvbnRhbFwiIGkxOG4+QXVjdW5lIHPDqWxlY3Rpb248L3A+XG4gICAgICAgIH1cbiAgICA8L21hdC1jaGlwLWxpc3Rib3g+XG48L2Rpdj5cblxuQGlmICghbG9hZGluZyAmJiAhZGF0YVNvdXJjZS5kYXRhLmxlbmd0aCkge1xuICAgIDxkaXYgaTE4bj5BdWN1biByw6lzdWx0YXQ8L2Rpdj5cbn1cbiJdfQ==
|