@sunbird-cb/access-settings 0.0.1-cbrelease-4.8.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2022/lib/_common/access-control/access-control.component.mjs +561 -0
- package/esm2022/lib/_common/access-control/access-control.module.mjs +125 -0
- package/esm2022/lib/_common/dialogs/access-control-guide/access-control-guide.component.mjs +27 -0
- package/esm2022/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.mjs +27 -0
- package/esm2022/lib/_common/dialogs/entity-selections/entity-selections.component.mjs +371 -0
- package/esm2022/lib/_common/dialogs/invite-users/invite-users.component.mjs +116 -0
- package/esm2022/lib/_common/pagination/pagination.component.mjs +168 -0
- package/esm2022/lib/_constants/app.constants.mjs +6 -0
- package/esm2022/lib/_directives/drag-drop.directive.mjs +53 -0
- package/esm2022/lib/_models/access-control.model.mjs +31 -0
- package/esm2022/lib/_models/pagination.model.mjs +2 -0
- package/esm2022/lib/_services/access-control.service.mjs +195 -0
- package/esm2022/lib/_services/cadre-mapping.service.mjs +164 -0
- package/esm2022/lib/access-settings.component.mjs +13 -0
- package/esm2022/lib/access-settings.module.mjs +21 -0
- package/esm2022/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.mjs +391 -0
- package/esm2022/lib/components/list-table/list-table.component.mjs +148 -0
- package/esm2022/lib/components/snackbar/snackbar.component.mjs +19 -0
- package/esm2022/public-api.mjs +10 -0
- package/esm2022/sunbird-cb-access-settings.mjs +5 -0
- package/fesm2022/sunbird-cb-access-settings.mjs +2331 -0
- package/fesm2022/sunbird-cb-access-settings.mjs.map +1 -0
- package/index.d.ts +6 -0
- package/lib/_common/access-control/access-control.component.d.ts +71 -0
- package/lib/_common/access-control/access-control.component.d.ts.map +1 -0
- package/lib/_common/access-control/access-control.module.d.ts +36 -0
- package/lib/_common/access-control/access-control.module.d.ts.map +1 -0
- package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts +16 -0
- package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts.map +1 -0
- package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts +15 -0
- package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
- package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts +65 -0
- package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts.map +1 -0
- package/lib/_common/dialogs/invite-users/invite-users.component.d.ts +40 -0
- package/lib/_common/dialogs/invite-users/invite-users.component.d.ts.map +1 -0
- package/lib/_common/pagination/pagination.component.d.ts +31 -0
- package/lib/_common/pagination/pagination.component.d.ts.map +1 -0
- package/lib/_constants/app.constants.d.ts +6 -0
- package/lib/_constants/app.constants.d.ts.map +1 -0
- package/lib/_directives/drag-drop.directive.d.ts +12 -0
- package/lib/_directives/drag-drop.directive.d.ts.map +1 -0
- package/lib/_models/access-control.model.d.ts +106 -0
- package/lib/_models/access-control.model.d.ts.map +1 -0
- package/lib/_models/pagination.model.d.ts +6 -0
- package/lib/_models/pagination.model.d.ts.map +1 -0
- package/lib/_services/access-control.service.d.ts +72 -0
- package/lib/_services/access-control.service.d.ts.map +1 -0
- package/lib/_services/cadre-mapping.service.d.ts +71 -0
- package/lib/_services/cadre-mapping.service.d.ts.map +1 -0
- package/lib/access-settings.component.d.ts +9 -0
- package/lib/access-settings.component.d.ts.map +1 -0
- package/lib/access-settings.module.d.ts +12 -0
- package/lib/access-settings.module.d.ts.map +1 -0
- package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts +31 -0
- package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts.map +1 -0
- package/lib/components/list-table/list-table.component.d.ts +40 -0
- package/lib/components/list-table/list-table.component.d.ts.map +1 -0
- package/lib/components/snackbar/snackbar.component.d.ts +13 -0
- package/lib/components/snackbar/snackbar.component.d.ts.map +1 -0
- package/package.json +28 -0
- package/public-api.d.ts +7 -0
- package/public-api.d.ts.map +1 -0
- package/sunbird-cb-access-settings.d.ts.map +1 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { Component, inject } from "@angular/core";
|
|
2
|
+
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
|
|
3
|
+
import { FormControl } from "@angular/forms";
|
|
4
|
+
import { BATCH_RANGES } from "../../../_constants/app.constants";
|
|
5
|
+
import { NsAccessControlConfig } from "../../../_models/access-control.model";
|
|
6
|
+
import { Subject } from "rxjs";
|
|
7
|
+
import { takeUntil } from "rxjs/operators";
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/material/dialog";
|
|
10
|
+
import * as i2 from "../../../_services/access-control.service";
|
|
11
|
+
import * as i3 from "@angular/common";
|
|
12
|
+
import * as i4 from "@angular/material/legacy-radio";
|
|
13
|
+
import * as i5 from "@angular/material/icon";
|
|
14
|
+
import * as i6 from "@angular/material/legacy-checkbox";
|
|
15
|
+
import * as i7 from "@angular/material/legacy-form-field";
|
|
16
|
+
import * as i8 from "@angular/material/legacy-input";
|
|
17
|
+
import * as i9 from "@angular/forms";
|
|
18
|
+
import * as i10 from "@angular/material/legacy-button";
|
|
19
|
+
import * as i11 from "@angular/material/legacy-progress-spinner";
|
|
20
|
+
export class EntitySelectionsComponent {
|
|
21
|
+
constructor(dialogRef, accessControlService) {
|
|
22
|
+
this.dialogRef = dialogRef;
|
|
23
|
+
this.accessControlService = accessControlService;
|
|
24
|
+
this.destroy$ = new Subject();
|
|
25
|
+
this.isLoading = false;
|
|
26
|
+
this.searchControl = new FormControl("");
|
|
27
|
+
this.filterValue = "all";
|
|
28
|
+
this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#".split("");
|
|
29
|
+
this.dataList = [];
|
|
30
|
+
this.selectedData = [];
|
|
31
|
+
this.groupedEntityData = {};
|
|
32
|
+
this.selectionType = "";
|
|
33
|
+
this.selectionTypeEnum = NsAccessControlConfig.SelectionType;
|
|
34
|
+
this.radioSelections = [];
|
|
35
|
+
this.data = inject(MAT_DIALOG_DATA);
|
|
36
|
+
}
|
|
37
|
+
ngOnInit() {
|
|
38
|
+
// If data was passed to the dialog, initialize selections
|
|
39
|
+
this.accessControlCriteriaSelection = this.accessControlService.accessControlConfig().accessControlCriteriaSelection;
|
|
40
|
+
if (this.data) {
|
|
41
|
+
this.selectionType = this.data?.condition?.entity;
|
|
42
|
+
}
|
|
43
|
+
if (this.data && this.data.selected) {
|
|
44
|
+
this.selectedData = this.data.selected;
|
|
45
|
+
}
|
|
46
|
+
// Subscribe to search control changes
|
|
47
|
+
this.searchControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((query) => {
|
|
48
|
+
if (this.selectionType) {
|
|
49
|
+
switch (this.selectionType) {
|
|
50
|
+
case this.selectionTypeEnum.Service:
|
|
51
|
+
this.getServicesList(query);
|
|
52
|
+
break;
|
|
53
|
+
case this.selectionTypeEnum.Cadre:
|
|
54
|
+
this.getCadreList(query);
|
|
55
|
+
break;
|
|
56
|
+
case this.selectionTypeEnum.Batch:
|
|
57
|
+
this.getBatchList(query);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
this.initializeDisplay();
|
|
63
|
+
}
|
|
64
|
+
initializeDisplay() {
|
|
65
|
+
switch (this.selectionType) {
|
|
66
|
+
case NsAccessControlConfig.SelectionType.Organizations:
|
|
67
|
+
this.radioSelections = this.accessControlCriteriaSelection.organizationRadioSelection;
|
|
68
|
+
break;
|
|
69
|
+
case NsAccessControlConfig.SelectionType.Designation:
|
|
70
|
+
const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
|
|
71
|
+
if (selectionIds?.length) {
|
|
72
|
+
this.getDesignationsList("");
|
|
73
|
+
}
|
|
74
|
+
this.radioSelections = this.accessControlCriteriaSelection.designationRadioSelection;
|
|
75
|
+
break;
|
|
76
|
+
case NsAccessControlConfig.SelectionType.Service:
|
|
77
|
+
this.radioSelections = this.accessControlCriteriaSelection.servicesRadioSelection;
|
|
78
|
+
this.getServicesList(this.searchControl.value);
|
|
79
|
+
break;
|
|
80
|
+
case NsAccessControlConfig.SelectionType.Cadre:
|
|
81
|
+
this.radioSelections = [{ value: "all", label: "All" }];
|
|
82
|
+
this.getCadreList(this.searchControl.value);
|
|
83
|
+
break;
|
|
84
|
+
case NsAccessControlConfig.SelectionType.Batch:
|
|
85
|
+
this.radioSelections = [{ value: "all", label: "All" }];
|
|
86
|
+
this.getBatchList(this.searchControl.value);
|
|
87
|
+
break;
|
|
88
|
+
case NsAccessControlConfig.SelectionType.Group:
|
|
89
|
+
this.getGroupList();
|
|
90
|
+
break;
|
|
91
|
+
case NsAccessControlConfig.SelectionType.VerificationStatus:
|
|
92
|
+
this.getVerificationStatus();
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
onClose() {
|
|
97
|
+
this.dialogRef.close();
|
|
98
|
+
}
|
|
99
|
+
getSelectionValue(item) {
|
|
100
|
+
if (typeof item !== "object" || item === null) {
|
|
101
|
+
return item;
|
|
102
|
+
}
|
|
103
|
+
else if (this.selectionType === NsAccessControlConfig.SelectionType.Cadre ||
|
|
104
|
+
this.selectionType === NsAccessControlConfig.SelectionType.Service ||
|
|
105
|
+
this.selectionType === NsAccessControlConfig.SelectionType.Designation) {
|
|
106
|
+
return item?.name;
|
|
107
|
+
}
|
|
108
|
+
return item?.id || item?.identifier || item;
|
|
109
|
+
}
|
|
110
|
+
isSelected(item) {
|
|
111
|
+
const value = this.getSelectionValue(item);
|
|
112
|
+
return this.selectedData.includes(value);
|
|
113
|
+
}
|
|
114
|
+
toggleSelection(item) {
|
|
115
|
+
const value = this.getSelectionValue(item);
|
|
116
|
+
const index = this.selectedData.indexOf(value);
|
|
117
|
+
if (index > -1) {
|
|
118
|
+
this.selectedData.splice(index, 1);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
this.selectedData.push(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
onFilterChange(event) {
|
|
125
|
+
this.filterValue = event.value;
|
|
126
|
+
this.getFilteredEntityGrouped();
|
|
127
|
+
}
|
|
128
|
+
search() {
|
|
129
|
+
switch (this.selectionType) {
|
|
130
|
+
case NsAccessControlConfig.SelectionType.Designation:
|
|
131
|
+
this.getDesignationsList(this.searchControl.value);
|
|
132
|
+
break;
|
|
133
|
+
case NsAccessControlConfig.SelectionType.Organizations:
|
|
134
|
+
this.getOrganisationsList(this.searchControl.value);
|
|
135
|
+
break;
|
|
136
|
+
case NsAccessControlConfig.SelectionType.Service:
|
|
137
|
+
this.getServicesList(this.searchControl.value);
|
|
138
|
+
break;
|
|
139
|
+
case NsAccessControlConfig.SelectionType.Cadre:
|
|
140
|
+
this.getCadreList(this.searchControl.value);
|
|
141
|
+
break;
|
|
142
|
+
case NsAccessControlConfig.SelectionType.Batch:
|
|
143
|
+
this.getCadreList(this.searchControl.value);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
getFilteredEntityGrouped() {
|
|
148
|
+
let filtered = this.dataList;
|
|
149
|
+
// Filter by radio selection only
|
|
150
|
+
if (this.filterValue === "selected") {
|
|
151
|
+
filtered = filtered.filter(org => this.isSelected(org));
|
|
152
|
+
}
|
|
153
|
+
else if (this.filterValue === "notSelected") {
|
|
154
|
+
filtered = filtered.filter(org => !this.isSelected(org));
|
|
155
|
+
}
|
|
156
|
+
// For batch, group by range and chunk each range
|
|
157
|
+
if (this.selectionType === this.selectionTypeEnum.Batch) {
|
|
158
|
+
const batchGrouped = this.groupBatchByRange(filtered);
|
|
159
|
+
const chunked = {};
|
|
160
|
+
for (const key in batchGrouped) {
|
|
161
|
+
chunked[key] = this.chunkArray(batchGrouped[key], 8);
|
|
162
|
+
}
|
|
163
|
+
this.groupedEntityData = chunked;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// For all other types, group by letter and chunk each group
|
|
167
|
+
const grouped = {};
|
|
168
|
+
const temp = {};
|
|
169
|
+
for (const org of filtered) {
|
|
170
|
+
let entity = org?.channel || org?.name || org?.designation;
|
|
171
|
+
let letter = entity?.charAt(0)?.toUpperCase() || "#";
|
|
172
|
+
if (!/^[A-Z]$/.test(letter)) {
|
|
173
|
+
letter = "#";
|
|
174
|
+
}
|
|
175
|
+
if (!temp[letter])
|
|
176
|
+
temp[letter] = [];
|
|
177
|
+
temp[letter].push(org);
|
|
178
|
+
}
|
|
179
|
+
for (const letter in temp) {
|
|
180
|
+
grouped[letter] = this.chunkArray(temp[letter], 7);
|
|
181
|
+
}
|
|
182
|
+
this.groupedEntityData = grouped;
|
|
183
|
+
}
|
|
184
|
+
scrollToSection(letter) {
|
|
185
|
+
const section = document.getElementById(`section-${letter}`);
|
|
186
|
+
if (section) {
|
|
187
|
+
this.selectedCharacterRange = letter;
|
|
188
|
+
section.scrollIntoView({ behavior: "smooth", inline: "start" });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
updateAlphabet() {
|
|
192
|
+
const chars = new Set();
|
|
193
|
+
for (const data of this.dataList) {
|
|
194
|
+
let letter = "#";
|
|
195
|
+
const value = data?.channel || data?.name || data?.designation;
|
|
196
|
+
letter = value.charAt(0)?.toUpperCase() || "#";
|
|
197
|
+
if (!/^[A-Z]$/.test(letter)) {
|
|
198
|
+
letter = "#";
|
|
199
|
+
}
|
|
200
|
+
chars.add(letter);
|
|
201
|
+
}
|
|
202
|
+
const sorted = Array.from(chars)
|
|
203
|
+
.filter(c => c !== "#")
|
|
204
|
+
.sort();
|
|
205
|
+
if (chars.has("#"))
|
|
206
|
+
sorted.push("#");
|
|
207
|
+
this.alphabet = sorted;
|
|
208
|
+
}
|
|
209
|
+
get checkIfData() {
|
|
210
|
+
return ((this.groupedEntityData && Object.keys(this.groupedEntityData).length > 0) ||
|
|
211
|
+
(this.selectionType === NsAccessControlConfig.SelectionType.Group && this.dataList.length > 0) ||
|
|
212
|
+
(this.selectionType === NsAccessControlConfig.SelectionType.VerificationStatus && this.dataList.length > 0));
|
|
213
|
+
}
|
|
214
|
+
getOrganisationsList(query) {
|
|
215
|
+
this.isLoading = true;
|
|
216
|
+
this.accessControlService.fetchOrgList(query).subscribe({
|
|
217
|
+
next: response => {
|
|
218
|
+
if (response?.result && response?.result?.response?.content) {
|
|
219
|
+
this.dataList = response.result.response.content;
|
|
220
|
+
this.updateAlphabet();
|
|
221
|
+
this.getFilteredEntityGrouped();
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.dataList = [];
|
|
225
|
+
this.alphabet = [];
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
complete: () => {
|
|
229
|
+
this.isLoading = false;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
getDesignationsList(query) {
|
|
234
|
+
this.isLoading = true;
|
|
235
|
+
const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
|
|
236
|
+
if (selectionIds?.length) {
|
|
237
|
+
const categories = selectionIds.map((ele) => `${ele}_odcs_designation`);
|
|
238
|
+
this.accessControlService
|
|
239
|
+
.fetchDesignationsWithOrg(categories, query)
|
|
240
|
+
.pipe(takeUntil(this.destroy$))
|
|
241
|
+
.subscribe({
|
|
242
|
+
next: response => {
|
|
243
|
+
if (response?.result && response?.result?.Term) {
|
|
244
|
+
this.dataList = response?.result?.Term;
|
|
245
|
+
this.updateAlphabet();
|
|
246
|
+
this.getFilteredEntityGrouped();
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
this.dataList = [];
|
|
250
|
+
this.alphabet = [];
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
complete: () => {
|
|
254
|
+
this.isLoading = false;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.accessControlService
|
|
260
|
+
.fetchDesignation(query)
|
|
261
|
+
.pipe(takeUntil(this.destroy$))
|
|
262
|
+
.subscribe({
|
|
263
|
+
next: response => {
|
|
264
|
+
if (response?.result && response?.result?.result?.data) {
|
|
265
|
+
this.dataList = response?.result?.result?.data;
|
|
266
|
+
this.updateAlphabet();
|
|
267
|
+
this.getFilteredEntityGrouped();
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
this.dataList = [];
|
|
271
|
+
this.alphabet = [];
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
complete: () => {
|
|
275
|
+
this.isLoading = false;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
getServicesList(query) {
|
|
281
|
+
const baseList = this.accessControlService.holdServiceCadrebatch().service;
|
|
282
|
+
this.dataList = query ? baseList.filter(service => service.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
|
|
283
|
+
this.updateAlphabet();
|
|
284
|
+
this.getFilteredEntityGrouped();
|
|
285
|
+
}
|
|
286
|
+
getCadreList(query) {
|
|
287
|
+
const baseList = this.accessControlService.holdServiceCadrebatch().cadre;
|
|
288
|
+
this.dataList = query ? baseList.filter(cadre => cadre.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
|
|
289
|
+
this.updateAlphabet();
|
|
290
|
+
this.getFilteredEntityGrouped();
|
|
291
|
+
}
|
|
292
|
+
getBatchList(query) {
|
|
293
|
+
const baseList = this.accessControlService.holdServiceCadrebatch().batch;
|
|
294
|
+
this.dataList = query ? baseList.filter(batch => batch.toString().includes(query)) : baseList;
|
|
295
|
+
this.updateBatchRanges();
|
|
296
|
+
this.getFilteredEntityGrouped();
|
|
297
|
+
}
|
|
298
|
+
getGroupList() {
|
|
299
|
+
this.isLoading = true;
|
|
300
|
+
this.accessControlService
|
|
301
|
+
.fetchGroupsList()
|
|
302
|
+
.pipe(takeUntil(this.destroy$))
|
|
303
|
+
.subscribe({
|
|
304
|
+
next: (response) => {
|
|
305
|
+
if (response?.result && response?.result?.response) {
|
|
306
|
+
this.dataList = response.result.response;
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
complete: () => {
|
|
310
|
+
this.isLoading = false;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
getVerificationStatus() {
|
|
315
|
+
this.dataList = this.accessControlCriteriaSelection.verificationStatus;
|
|
316
|
+
}
|
|
317
|
+
updateBatchRanges() {
|
|
318
|
+
this.batchRanges = BATCH_RANGES.map(range => range.label);
|
|
319
|
+
}
|
|
320
|
+
groupBatchByRange(batchList) {
|
|
321
|
+
const grouped = {};
|
|
322
|
+
for (const range of BATCH_RANGES) {
|
|
323
|
+
grouped[range.label] = batchList.filter(year => year >= range.start && year <= range.end);
|
|
324
|
+
}
|
|
325
|
+
return grouped;
|
|
326
|
+
}
|
|
327
|
+
getModalTitle() {
|
|
328
|
+
switch (this.selectionType) {
|
|
329
|
+
case NsAccessControlConfig.SelectionType.Designation:
|
|
330
|
+
return "Select Designation";
|
|
331
|
+
case NsAccessControlConfig.SelectionType.Organizations:
|
|
332
|
+
return "Select Organisation";
|
|
333
|
+
case NsAccessControlConfig.SelectionType.Service:
|
|
334
|
+
return "Select Services";
|
|
335
|
+
case NsAccessControlConfig.SelectionType.Cadre:
|
|
336
|
+
return "Select Cadre";
|
|
337
|
+
case NsAccessControlConfig.SelectionType.Batch:
|
|
338
|
+
return "Select Batch";
|
|
339
|
+
case NsAccessControlConfig.SelectionType.Group:
|
|
340
|
+
return "Select Group";
|
|
341
|
+
case NsAccessControlConfig.SelectionType.VerificationStatus:
|
|
342
|
+
return "Verification Status";
|
|
343
|
+
}
|
|
344
|
+
return "";
|
|
345
|
+
}
|
|
346
|
+
applySelections() {
|
|
347
|
+
this.dialogRef.close({
|
|
348
|
+
rule: this.data.rule,
|
|
349
|
+
condition: this.data.condition,
|
|
350
|
+
selected: this.selectedData
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
chunkArray(array, chunkSize) {
|
|
354
|
+
const results = [];
|
|
355
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
356
|
+
results.push(array.slice(i, i + chunkSize));
|
|
357
|
+
}
|
|
358
|
+
return results;
|
|
359
|
+
}
|
|
360
|
+
ngOnDestroy() {
|
|
361
|
+
this.destroy$.next();
|
|
362
|
+
this.destroy$.complete();
|
|
363
|
+
}
|
|
364
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, deps: [{ token: i1.MatDialogRef }, { token: i2.AccessControlService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
365
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EntitySelectionsComponent, selector: "sb-uic-entity-selections", ngImport: i0, template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i4.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i6.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLegacyPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); }
|
|
366
|
+
}
|
|
367
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, decorators: [{
|
|
368
|
+
type: Component,
|
|
369
|
+
args: [{ selector: "sb-uic-entity-selections", template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"] }]
|
|
370
|
+
}], ctorParameters: function () { return [{ type: i1.MatDialogRef }, { type: i2.AccessControlService }]; } });
|
|
371
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXNlbGVjdGlvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL2FjY2Vzcy1zZXR0aW5ncy9zcmMvbGliL19jb21tb24vZGlhbG9ncy9lbnRpdHktc2VsZWN0aW9ucy9lbnRpdHktc2VsZWN0aW9ucy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJyYXJ5L3N1bmJpcmQtY2IvYWNjZXNzLXNldHRpbmdzL3NyYy9saWIvX2NvbW1vbi9kaWFsb2dzL2VudGl0eS1zZWxlY3Rpb25zL2VudGl0eS1zZWxlY3Rpb25zLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUVyRSxPQUFPLEVBQUUsZUFBZSxFQUFnQixNQUFNLDBCQUEwQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDakUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7Ozs7QUFPM0MsTUFBTSxPQUFPLHlCQUF5QjtJQW1CcEMsWUFBbUIsU0FBa0QsRUFBVSxvQkFBMEM7UUFBdEcsY0FBUyxHQUFULFNBQVMsQ0FBeUM7UUFBVSx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBbEJqSCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN2QyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGtCQUFhLEdBQUcsSUFBSSxXQUFXLENB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QVEsRUFBRSxDQUFDO0lBQzNCLENBQUM7K0dBN1hVLHlCQUF5QjttR0FBekIseUJBQXlCLGdFQ2R0QywrelBBa0xBOzs0RkRwS2EseUJBQXlCO2tCQUxyQyxTQUFTOytCQUNFLDBCQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5qZWN0LCBPbkluaXQsIE9uRGVzdHJveSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBBY2Nlc3NDb250cm9sU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9fc2VydmljZXMvYWNjZXNzLWNvbnRyb2wuc2VydmljZVwiO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2dSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nXCI7XG5pbXBvcnQgeyBGb3JtQ29udHJvbCB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgQkFUQ0hfUkFOR0VTIH0gZnJvbSBcIi4uLy4uLy4uL19jb25zdGFudHMvYXBwLmNvbnN0YW50c1wiO1xuaW1wb3J0IHsgTnNBY2Nlc3NDb250cm9sQ29uZmlnIH0gZnJvbSBcIi4uLy4uLy4uL19tb2RlbHMvYWNjZXNzLWNvbnRyb2wubW9kZWxcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJzYi11aWMtZW50aXR5LXNlbGVjdGlvbnNcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9lbnRpdHktc2VsZWN0aW9ucy5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vZW50aXR5LXNlbGVjdGlvbnMuY29tcG9uZW50LnNjc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgRW50aXR5U2VsZWN0aW9uc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIGlzTG9hZGluZyA9IGZhbHNlO1xuICBzZWFyY2hDb250cm9sID0gbmV3IEZvcm1Db250cm9sKFwiXCIpO1xuICBmaWx0ZXJWYWx1ZTogXCJhbGxcIiB8IFwic2VsZWN0ZWRcIiB8IFwibm90U2VsZWN0ZWRcIiA9IFwiYWxsXCI7XG4gIGFscGhhYmV0ID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiNcIi5zcGxpdChcIlwiKTtcblxuICBkYXRhTGlzdDogYW55W10gPSBbXTtcblxuICBzZWxlY3RlZERhdGE6IG51bWJlcltdID0gW107XG4gIGdyb3VwZWRFbnRpdHlEYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueVtdIH0gPSB7fTtcbiAgc2VsZWN0aW9uVHlwZSA9IFwiXCI7XG4gIHNlbGVjdGlvblR5cGVFbnVtID0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGU7XG4gIHJhZGlvU2VsZWN0aW9uczogeyB2YWx1ZTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xuICBiYXRjaFJhbmdlczogYW55O1xuICBzZWxlY3RlZENoYXJhY3RlclJhbmdlOiBzdHJpbmc7XG4gIGFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbiE6IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uO1xuXG4gIHB1YmxpYyByZWFkb25seSBkYXRhID0gaW5qZWN0PHsgcnVsZTogYW55OyBjb25kaXRpb246IGFueTsgc2VsZWN0ZWQ6IGFueVtdIH0+KE1BVF9ESUFMT0dfREFUQSk7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxFbnRpdHlTZWxlY3Rpb25zQ29tcG9uZW50PiwgcHJpdmF0ZSBhY2Nlc3NDb250cm9sU2VydmljZTogQWNjZXNzQ29udHJvbFNlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gSWYgZGF0YSB3YXMgcGFzc2VkIHRvIHRoZSBkaWFsb2csIGluaXRpYWxpemUgc2VsZWN0aW9uc1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uID0gdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5hY2Nlc3NDb250cm9sQ29uZmlnKCkuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uO1xuICAgIGlmICh0aGlzLmRhdGEpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uVHlwZSA9IHRoaXMuZGF0YT8uY29uZGl0aW9uPy5lbnRpdHk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhLnNlbGVjdGVkKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YSA9IHRoaXMuZGF0YS5zZWxlY3RlZDtcbiAgICB9XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gc2VhcmNoIGNvbnRyb2wgY2hhbmdlc1xuICAgIHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgocXVlcnk6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgICAgIGNhc2UgdGhpcy5zZWxlY3Rpb25UeXBlRW51bS5TZXJ2aWNlOlxuICAgICAgICAgICAgdGhpcy5nZXRTZXJ2aWNlc0xpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB0aGlzLnNlbGVjdGlvblR5cGVFbnVtLkNhZHJlOlxuICAgICAgICAgICAgdGhpcy5nZXRDYWRyZUxpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB0aGlzLnNlbGVjdGlvblR5cGVFbnVtLkJhdGNoOlxuICAgICAgICAgICAgdGhpcy5nZXRCYXRjaExpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZURpc3BsYXkoKTtcbiAgfVxuXG4gIGluaXRpYWxpemVEaXNwbGF5KCk6IHZvaWQge1xuICAgIHN3aXRjaCAodGhpcy5zZWxlY3Rpb25UeXBlKSB7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLk9yZ2FuaXphdGlvbnM6XG4gICAgICAgIHRoaXMucmFkaW9TZWxlY3Rpb25zID0gdGhpcy5hY2Nlc3NDb250cm9sQ3JpdGVyaWFTZWxlY3Rpb24ub3JnYW5pemF0aW9uUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5EZXNpZ25hdGlvbjpcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uSWRzID0gdGhpcy5kYXRhPy5ydWxlPy5jb25kaXRpb25zPy5maW5kKFxuICAgICAgICAgIChjOiBhbnkpID0+IGMuZW50aXR5ID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Pcmdhbml6YXRpb25zXG4gICAgICAgICk/LnNlbGVjdGlvbnM7XG4gICAgICAgIGlmIChzZWxlY3Rpb25JZHM/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuZ2V0RGVzaWduYXRpb25zTGlzdChcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJhZGlvU2VsZWN0aW9ucyA9IHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uLmRlc2lnbmF0aW9uUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlOlxuICAgICAgICB0aGlzLnJhZGlvU2VsZWN0aW9ucyA9IHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uLnNlcnZpY2VzUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0U2VydmljZXNMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZTpcbiAgICAgICAgdGhpcy5yYWRpb1NlbGVjdGlvbnMgPSBbeyB2YWx1ZTogXCJhbGxcIiwgbGFiZWw6IFwiQWxsXCIgfV07XG4gICAgICAgIHRoaXMuZ2V0Q2FkcmVMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5CYXRjaDpcbiAgICAgICAgdGhpcy5yYWRpb1NlbGVjdGlvbnMgPSBbeyB2YWx1ZTogXCJhbGxcIiwgbGFiZWw6IFwiQWxsXCIgfV07XG4gICAgICAgIHRoaXMuZ2V0QmF0Y2hMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Hcm91cDpcbiAgICAgICAgdGhpcy5nZXRHcm91cExpc3QoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1czpcbiAgICAgICAgdGhpcy5nZXRWZXJpZmljYXRpb25TdGF0dXMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWxlY3Rpb25WYWx1ZShpdGVtOiBhbnkpOiBhbnkge1xuICAgIGlmICh0eXBlb2YgaXRlbSAhPT0gXCJvYmplY3RcIiB8fCBpdGVtID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zZWxlY3Rpb25UeXBlID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZSB8fFxuICAgICAgdGhpcy5zZWxlY3Rpb25UeXBlID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlIHx8XG4gICAgICB0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkRlc2lnbmF0aW9uXG4gICAgKSB7XG4gICAgICByZXR1cm4gaXRlbT8ubmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXRlbT8uaWQgfHwgaXRlbT8uaWRlbnRpZmllciB8fCBpdGVtO1xuICB9XG5cbiAgaXNTZWxlY3RlZChpdGVtOiBhbnkpOiBib29sZWFuIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0U2VsZWN0aW9uVmFsdWUoaXRlbSk7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWREYXRhLmluY2x1ZGVzKHZhbHVlKTtcbiAgfVxuXG4gIHRvZ2dsZVNlbGVjdGlvbihpdGVtOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0U2VsZWN0aW9uVmFsdWUoaXRlbSk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnNlbGVjdGVkRGF0YS5pbmRleE9mKHZhbHVlKTtcblxuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YS5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBvbkZpbHRlckNoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXJWYWx1ZSA9IGV2ZW50LnZhbHVlO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBzZWFyY2goKTogdm9pZCB7XG4gICAgc3dpdGNoICh0aGlzLnNlbGVjdGlvblR5cGUpIHtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuRGVzaWduYXRpb246XG4gICAgICAgIHRoaXMuZ2V0RGVzaWduYXRpb25zTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9uczpcbiAgICAgICAgdGhpcy5nZXRPcmdhbmlzYXRpb25zTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuU2VydmljZTpcbiAgICAgICAgdGhpcy5nZXRTZXJ2aWNlc0xpc3QodGhpcy5zZWFyY2hDb250cm9sLnZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkNhZHJlOlxuICAgICAgICB0aGlzLmdldENhZHJlTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuQmF0Y2g6XG4gICAgICAgIHRoaXMuZ2V0Q2FkcmVMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpOiB2b2lkIHtcbiAgICBsZXQgZmlsdGVyZWQgPSB0aGlzLmRhdGFMaXN0O1xuXG4gICAgLy8gRmlsdGVyIGJ5IHJhZGlvIHNlbGVjdGlvbiBvbmx5XG4gICAgaWYgKHRoaXMuZmlsdGVyVmFsdWUgPT09IFwic2VsZWN0ZWRcIikge1xuICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIob3JnID0+IHRoaXMuaXNTZWxlY3RlZChvcmcpKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmlsdGVyVmFsdWUgPT09IFwibm90U2VsZWN0ZWRcIikge1xuICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIob3JnID0+ICF0aGlzLmlzU2VsZWN0ZWQob3JnKSk7XG4gICAgfVxuXG4gICAgLy8gRm9yIGJhdGNoLCBncm91cCBieSByYW5nZSBhbmQgY2h1bmsgZWFjaCByYW5nZVxuICAgIGlmICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IHRoaXMuc2VsZWN0aW9uVHlwZUVudW0uQmF0Y2gpIHtcbiAgICAgIGNvbnN0IGJhdGNoR3JvdXBlZCA9IHRoaXMuZ3JvdXBCYXRjaEJ5UmFuZ2UoZmlsdGVyZWQpO1xuICAgICAgY29uc3QgY2h1bmtlZDogeyBba2V5OiBzdHJpbmddOiBhbnlbXVtdIH0gPSB7fTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGJhdGNoR3JvdXBlZCkge1xuICAgICAgICBjaHVua2VkW2tleV0gPSB0aGlzLmNodW5rQXJyYXkoYmF0Y2hHcm91cGVkW2tleV0sIDgpO1xuICAgICAgfVxuICAgICAgdGhpcy5ncm91cGVkRW50aXR5RGF0YSA9IGNodW5rZWQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRm9yIGFsbCBvdGhlciB0eXBlcywgZ3JvdXAgYnkgbGV0dGVyIGFuZCBjaHVuayBlYWNoIGdyb3VwXG4gICAgY29uc3QgZ3JvdXBlZDogeyBba2V5OiBzdHJpbmddOiBhbnlbXVtdIH0gPSB7fTtcbiAgICBjb25zdCB0ZW1wOiB7IFtrZXk6IHN0cmluZ106IGFueVtdIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG9yZyBvZiBmaWx0ZXJlZCkge1xuICAgICAgbGV0IGVudGl0eSA9IG9yZz8uY2hhbm5lbCB8fCBvcmc/Lm5hbWUgfHwgb3JnPy5kZXNpZ25hdGlvbjtcbiAgICAgIGxldCBsZXR0ZXIgPSBlbnRpdHk/LmNoYXJBdCgwKT8udG9VcHBlckNhc2UoKSB8fCBcIiNcIjtcbiAgICAgIGlmICghL15bQS1aXSQvLnRlc3QobGV0dGVyKSkge1xuICAgICAgICBsZXR0ZXIgPSBcIiNcIjtcbiAgICAgIH1cbiAgICAgIGlmICghdGVtcFtsZXR0ZXJdKSB0ZW1wW2xldHRlcl0gPSBbXTtcbiAgICAgIHRlbXBbbGV0dGVyXS5wdXNoKG9yZyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgbGV0dGVyIGluIHRlbXApIHtcbiAgICAgIGdyb3VwZWRbbGV0dGVyXSA9IHRoaXMuY2h1bmtBcnJheSh0ZW1wW2xldHRlcl0sIDcpO1xuICAgIH1cbiAgICB0aGlzLmdyb3VwZWRFbnRpdHlEYXRhID0gZ3JvdXBlZDtcbiAgfVxuXG4gIHNjcm9sbFRvU2VjdGlvbihsZXR0ZXI6IHN0cmluZykge1xuICAgIGNvbnN0IHNlY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc2VjdGlvbi0ke2xldHRlcn1gKTtcbiAgICBpZiAoc2VjdGlvbikge1xuICAgICAgdGhpcy5zZWxlY3RlZENoYXJhY3RlclJhbmdlID0gbGV0dGVyO1xuICAgICAgc2VjdGlvbi5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBpbmxpbmU6IFwic3RhcnRcIiB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUFscGhhYmV0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNoYXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2YgdGhpcy5kYXRhTGlzdCkge1xuICAgICAgbGV0IGxldHRlciA9IFwiI1wiO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IGRhdGE/LmNoYW5uZWwgfHwgZGF0YT8ubmFtZSB8fCBkYXRhPy5kZXNpZ25hdGlvbjtcbiAgICAgIGxldHRlciA9IHZhbHVlLmNoYXJBdCgwKT8udG9VcHBlckNhc2UoKSB8fCBcIiNcIjtcblxuICAgICAgaWYgKCEvXltBLVpdJC8udGVzdChsZXR0ZXIpKSB7XG4gICAgICAgIGxldHRlciA9IFwiI1wiO1xuICAgICAgfVxuXG4gICAgICBjaGFycy5hZGQobGV0dGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3J0ZWQgPSBBcnJheS5mcm9tKGNoYXJzKVxuICAgICAgLmZpbHRlcihjID0+IGMgIT09IFwiI1wiKVxuICAgICAgLnNvcnQoKTtcbiAgICBpZiAoY2hhcnMuaGFzKFwiI1wiKSkgc29ydGVkLnB1c2goXCIjXCIpO1xuXG4gICAgdGhpcy5hbHBoYWJldCA9IHNvcnRlZDtcbiAgfVxuXG4gIGdldCBjaGVja0lmRGF0YSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMuZ3JvdXBlZEVudGl0eURhdGEgJiYgT2JqZWN0LmtleXModGhpcy5ncm91cGVkRW50aXR5RGF0YSkubGVuZ3RoID4gMCkgfHxcbiAgICAgICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkdyb3VwICYmIHRoaXMuZGF0YUxpc3QubGVuZ3RoID4gMCkgfHxcbiAgICAgICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1cyAmJiB0aGlzLmRhdGFMaXN0Lmxlbmd0aCA+IDApXG4gICAgKTtcbiAgfVxuXG4gIGdldE9yZ2FuaXNhdGlvbnNMaXN0KHF1ZXJ5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5mZXRjaE9yZ0xpc3QocXVlcnkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiByZXNwb25zZSA9PiB7XG4gICAgICAgIGlmIChyZXNwb25zZT8ucmVzdWx0ICYmIHJlc3BvbnNlPy5yZXN1bHQ/LnJlc3BvbnNlPy5jb250ZW50KSB7XG4gICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlLnJlc3VsdC5yZXNwb25zZS5jb250ZW50O1xuICAgICAgICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICAgICAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSBbXTtcbiAgICAgICAgICB0aGlzLmFscGhhYmV0ID0gW107XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0RGVzaWduYXRpb25zTGlzdChxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHNlbGVjdGlvbklkcyA9IHRoaXMuZGF0YT8ucnVsZT8uY29uZGl0aW9ucz8uZmluZCgoYzogYW55KSA9PiBjLmVudGl0eSA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9ucyk/LnNlbGVjdGlvbnM7XG4gICAgaWYgKHNlbGVjdGlvbklkcz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBjYXRlZ29yaWVzID0gc2VsZWN0aW9uSWRzLm1hcCgoZWxlOiBzdHJpbmcpID0+IGAke2VsZX1fb2Rjc19kZXNpZ25hdGlvbmApO1xuICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZVxuICAgICAgICAuZmV0Y2hEZXNpZ25hdGlvbnNXaXRoT3JnKGNhdGVnb3JpZXMsIHF1ZXJ5KVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6IHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZT8ucmVzdWx0ICYmIHJlc3BvbnNlPy5yZXN1bHQ/LlRlcm0pIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlPy5yZXN1bHQ/LlRlcm07XG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICAgICAgICAgICAgdGhpcy5nZXRGaWx0ZXJlZEVudGl0eUdyb3VwZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSBbXTtcbiAgICAgICAgICAgICAgdGhpcy5hbHBoYWJldCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZVxuICAgICAgICAuZmV0Y2hEZXNpZ25hdGlvbihxdWVyeSlcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2U/LnJlc3VsdCAmJiByZXNwb25zZT8ucmVzdWx0Py5yZXN1bHQ/LmRhdGEpIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlPy5yZXN1bHQ/LnJlc3VsdD8uZGF0YTtcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVBbHBoYWJldCgpO1xuICAgICAgICAgICAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmFscGhhYmV0ID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldFNlcnZpY2VzTGlzdChxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYmFzZUxpc3QgPSB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLmhvbGRTZXJ2aWNlQ2FkcmViYXRjaCgpLnNlcnZpY2U7XG4gICAgdGhpcy5kYXRhTGlzdCA9IHF1ZXJ5ID8gYmFzZUxpc3QuZmlsdGVyKHNlcnZpY2UgPT4gc2VydmljZS5uYW1lPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHF1ZXJ5LnRvTG93ZXJDYXNlKCkpKSA6IGJhc2VMaXN0O1xuICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICB9XG5cbiAgZ2V0Q2FkcmVMaXN0KHF1ZXJ5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBiYXNlTGlzdCA9IHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2UuaG9sZFNlcnZpY2VDYWRyZWJhdGNoKCkuY2FkcmU7XG4gICAgdGhpcy5kYXRhTGlzdCA9IHF1ZXJ5ID8gYmFzZUxpc3QuZmlsdGVyKGNhZHJlID0+IGNhZHJlLm5hbWU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSkpIDogYmFzZUxpc3Q7XG4gICAgdGhpcy51cGRhdGVBbHBoYWJldCgpO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBnZXRCYXRjaExpc3QocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGJhc2VMaXN0ID0gdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2goKS5iYXRjaDtcbiAgICB0aGlzLmRhdGFMaXN0ID0gcXVlcnkgPyBiYXNlTGlzdC5maWx0ZXIoYmF0Y2ggPT4gYmF0Y2gudG9TdHJpbmcoKS5pbmNsdWRlcyhxdWVyeSkpIDogYmFzZUxpc3Q7XG4gICAgdGhpcy51cGRhdGVCYXRjaFJhbmdlcygpO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBnZXRHcm91cExpc3QoKTogdm9pZCB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2VcbiAgICAgIC5mZXRjaEdyb3Vwc0xpc3QoKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlPy5yZXN1bHQgJiYgcmVzcG9uc2U/LnJlc3VsdD8ucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSByZXNwb25zZS5yZXN1bHQucmVzcG9uc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0VmVyaWZpY2F0aW9uU3RhdHVzKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YUxpc3QgPSB0aGlzLmFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbi52ZXJpZmljYXRpb25TdGF0dXM7XG4gIH1cblxuICB1cGRhdGVCYXRjaFJhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmJhdGNoUmFuZ2VzID0gQkFUQ0hfUkFOR0VTLm1hcChyYW5nZSA9PiByYW5nZS5sYWJlbCk7XG4gIH1cblxuICBncm91cEJhdGNoQnlSYW5nZShiYXRjaExpc3Q6IG51bWJlcltdKSB7XG4gICAgY29uc3QgZ3JvdXBlZDogeyBba2V5OiBzdHJpbmddOiBudW1iZXJbXSB9ID0ge307XG4gICAgZm9yIChjb25zdCByYW5nZSBvZiBCQVRDSF9SQU5HRVMpIHtcbiAgICAgIGdyb3VwZWRbcmFuZ2UubGFiZWxdID0gYmF0Y2hMaXN0LmZpbHRlcih5ZWFyID0+IHllYXIgPj0gcmFuZ2Uuc3RhcnQgJiYgeWVhciA8PSByYW5nZS5lbmQpO1xuICAgIH1cbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfVxuXG4gIGdldE1vZGFsVGl0bGUoKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5EZXNpZ25hdGlvbjpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IERlc2lnbmF0aW9uXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLk9yZ2FuaXphdGlvbnM6XG4gICAgICAgIHJldHVybiBcIlNlbGVjdCBPcmdhbmlzYXRpb25cIjtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuU2VydmljZTpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IFNlcnZpY2VzXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkNhZHJlOlxuICAgICAgICByZXR1cm4gXCJTZWxlY3QgQ2FkcmVcIjtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuQmF0Y2g6XG4gICAgICAgIHJldHVybiBcIlNlbGVjdCBCYXRjaFwiO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Hcm91cDpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IEdyb3VwXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1czpcbiAgICAgICAgcmV0dXJuIFwiVmVyaWZpY2F0aW9uIFN0YXR1c1wiO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuXG4gIGFwcGx5U2VsZWN0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSh7XG4gICAgICBydWxlOiB0aGlzLmRhdGEucnVsZSxcbiAgICAgIGNvbmRpdGlvbjogdGhpcy5kYXRhLmNvbmRpdGlvbixcbiAgICAgIHNlbGVjdGVkOiB0aGlzLnNlbGVjdGVkRGF0YVxuICAgIH0pO1xuICB9XG5cbiAgY2h1bmtBcnJheTxUPihhcnJheTogVFtdLCBjaHVua1NpemU6IG51bWJlcik6IFRbXVtdIHtcbiAgICBjb25zdCByZXN1bHRzOiBUW11bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpICs9IGNodW5rU2l6ZSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGFycmF5LnNsaWNlKGksIGkgKyBjaHVua1NpemUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBkaWFsb2ctaGVhZGluZyBpdGVtcy1jZW50ZXJcIj5cbiAgPGgyIG1hdC1kaWFsb2ctdGl0bGUgY2xhc3M9XCJtYi0wXCI+e3sgZ2V0TW9kYWxUaXRsZSgpIH19PC9oMj5cbiAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJjbG9zZS1idXR0b25cIiAoY2xpY2spPVwib25DbG9zZSgpXCI+XG4gICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgPC9idXR0b24+XG48L2Rpdj5cblxuPGRpdiBtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdJZj1cIlxuICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uRGVzaWduYXRpb24gfHxcbiAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlNlcnZpY2UgfHxcbiAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkNhZHJlIHx8XG4gICAgICBzZWxlY3Rpb25UeXBlID09PSBzZWxlY3Rpb25UeXBlRW51bS5CYXRjaCB8fFxuICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uT3JnYW5pemF0aW9uc1xuICAgIFwiPlxuICAgIDwhLS0gU2VhcmNoIEJveCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWNvbnRhaW5lciBmbGV4IGl0ZW1zLWNlbnRlciBnYXAtNFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1hdC1mdWxsLXJhZGl1cyBmbGV4LWdyb3dcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICA8bWF0LWljb24gbWF0UHJlZml4PnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgICAgPGlucHV0IG1hdElucHV0IHBsYWNlaG9sZGVyPVwiVHlwZSBoZXJlIHRvIHNlYXJjaC4uLlwiIFtmb3JtQ29udHJvbF09XCJzZWFyY2hDb250cm9sXCIgKGtleXVwLmVudGVyKT1cInNlYXJjaCgpXCIgLz5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtZmxhdC1idXR0b25cbiAgICAgICAgW2Rpc2FibGVkXT1cIiFzZWFyY2hDb250cm9sLnZhbHVlXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciByb3VuZGVkLWZ1bGwgbmV3LWJnLWNvbG9yIGZvbnQtYm9sZCB0ZXh0LXNtIHRleHQtd2hpdGUgc2VhcmNoLWJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJzZWFyY2goKVwiPlxuICAgICAgICBTZWFyY2hcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInAtNCBtdC0yXCI+XG4gICAgICA8IS0tIEZpbHRlciBPcHRpb25zIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGFMaXN0Lmxlbmd0aCAmJiB0aGlzLnNlbGVjdGlvblR5cGUgIT09IHNlbGVjdGlvblR5cGVFbnVtLkNhZHJlICYmIHRoaXMuc2VsZWN0aW9uVHlwZSAhPT0gc2VsZWN0aW9uVHlwZUVudW0uQmF0Y2hcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlci1vcHRpb25zXCI+XG4gICAgICAgICAgPG1hdC1yYWRpby1ncm91cCBbKG5nTW9kZWwpXT1cImZpbHRlclZhbHVlXCIgYXJpYS1sYWJlbD1cIkZpbHRlciBvcHRpb25zXCIgKGNoYW5nZSk9XCJvbkZpbHRlckNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJhZGlvU2VsZWN0aW9uc1wiPlxuICAgICAgICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvbiBbdmFsdWVdPVwiaXRlbT8udmFsdWVcIj57eyBpdGVtPy5sYWJlbCB9fTwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbWF0LXJhZGlvLWdyb3VwPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwib3JnLWNvbnRhaW5lclwiPlxuICAgICAgICA8IS0tIEEtWiBGaWx0ZXIgQmFyIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItbG9hZGVyIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LXNwaW5uZXI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoZWNrSWZEYXRhXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxwaGFiZXQtZmlsdGVyXCIgKm5nSWY9XCJ0aGlzLnNlbGVjdGlvblR5cGUgIT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxldHRlciBvZiBhbHBoYWJldDsgbGV0IGkgPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsZXR0ZXItYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzY3JvbGxUb1NlY3Rpb24obGV0dGVyKVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICdhY3RpdmUtcmFuZ2UtYnRuJzogc2VsZWN0ZWRDaGFyYWN0ZXJSYW5nZSA9PT0gbGV0dGVyXG4gICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICB7eyBsZXR0ZXIgfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGl2aWRlci1hcGxcIiAqbmdJZj1cIiFsYXN0XCI+PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxwaGFiZXQtZmlsdGVyXCIgKm5nSWY9XCJ0aGlzLnNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxldHRlciBvZiBiYXRjaFJhbmdlczsgbGV0IGkgPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyYW5nZS1idXR0b24gcHgtNFwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2Nyb2xsVG9TZWN0aW9uKGxldHRlcilcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAnYWN0aXZlLXJhbmdlLWJ0bic6IHNlbGVjdGVkQ2hhcmFjdGVyUmFuZ2UgPT09IGxldHRlclxuICAgICAgICAgICAgICAgICAgfVwiPlxuICAgICAgICAgICAgICAgICAge3sgbGV0dGVyIH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXItYXBsXCIgKm5nSWY9XCIhbGFzdFwiPjwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoZWNrSWZEYXRhOyBlbHNlIG5vRGF0YVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGdyb3VwZWRFbnRpdHlEYXRhIHwga2V5dmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3JnLWNvbHVtbiBwLTIgbXItNFwiIFthdHRyLmlkXT1cIidzZWN0aW9uLScgKyBncm91cC5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcmctbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmF0Y2gtcmFuZ2UtY29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJncm91cC52YWx1ZSAmJiBncm91cC52YWx1ZS5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBncm91cC52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmF0Y2gtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZW50aXR5IG9mIGNvbHVtblwiIGNsYXNzPVwib3JnLWNhcmQgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkRlc2lnbmF0aW9uIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uT3JnYW5pemF0aW9ucyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlNlcnZpY2UgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25UeXBlID09PSBzZWxlY3Rpb25UeXBlRW51bS5DYWRyZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImlzU2VsZWN0ZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3Rpb24oZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cImVudGl0eT8ubmFtZSB8fCBlbnRpdHk/LmRlc2lnbmF0aW9uIHx8IGVudGl0eT8uY2hhbm5lbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVudGl0eT8ubmFtZSB8fCBlbnRpdHk/LmRlc2lnbmF0aW9uIHx8IGVudGl0eT8uY2hhbm5lbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW2NoZWNrZWRdPVwiaXNTZWxlY3RlZChlbnRpdHkpXCIgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3Rpb24oZW50aXR5KVwiIFt0aXRsZV09XCJlbnRpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlbnRpdHkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9EYXRhPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vLWRhdGEgcC00IGZsZXggZmxleC1jb2x1bW4gaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9uby1ldmVudHMucG5nXCIgYWx0PVwibm8tZGF0YVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1ib2xkXCI+Tm8gaW5mb3JtYXRpb24gdG8gZGlzcGxheSB5ZXQ8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uR3JvdXBcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1sb2FkZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgPG1hdC1zcGlubmVyPjwvbWF0LXNwaW5uZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtMTYgaXRlbXMtY2VudGVyIHAtNCBvcHRpb25zLWNoZWNrYm94XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGRhdGFMaXN0XCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveCBbY2hlY2tlZF09XCJpc1NlbGVjdGVkKGdyb3VwKVwiIChjaGFuZ2UpPVwidG9nZ2xlU2VsZWN0aW9uKGdyb3VwKVwiIFt0aXRsZV09XCJncm91cFwiPlxuICAgICAgICAgICAge3sgZ3JvdXAgfX1cbiAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlZlcmlmaWNhdGlvblN0YXR1c1wiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGdhcC0xNiBpdGVtcy1jZW50ZXIgcC00IG9wdGlvbnMtY2hlY2tib3hcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGRhdGFMaXN0XCI+XG4gICAgICAgIDxtYXQtY2hlY2tib3ggW2NoZWNrZWRdPVwiaXNTZWxlY3RlZChncm91cClcIiAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdGlvbihncm91cClcIiBbdGl0bGVdPVwiZ3JvdXBcIj5cbiAgICAgICAgICB7eyBncm91cCB9fVxuICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bWF0LWRpYWxvZy1hY3Rpb25zPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hlY2tJZkRhdGFcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtNCBpdGVtcy1jZW50ZXIgbWwtYXV0byBtci0xIGFwcGx5LWJ1dHRvbi1jb250YWluZXIgbXktMlwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRleHQteHNcIj57eyBzZWxlY3RlZERhdGEubGVuZ3RoIH19IGl0ZW1zIHNlbGVjdGVkPC9kaXY+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1mbGF0LWJ1dHRvblxuICAgICAgICBbZGlzYWJsZWRdPVwic2VsZWN0ZWREYXRhLmxlbmd0aCA9PT0gMFwiXG4gICAgICAgIChjbGljayk9XCJhcHBseVNlbGVjdGlvbnMoKVwiXG4gICAgICAgIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1mdWxsIG5ldy1iZy1jb2xvciBmb250LWJvbGQgdGV4dC1zbSB0ZXh0LXdoaXRlIG10LTJcIj5cbiAgICAgICAgQXBwbHlcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuIl19
|