@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.
Files changed (64) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/_common/access-control/access-control.component.mjs +561 -0
  3. package/esm2022/lib/_common/access-control/access-control.module.mjs +125 -0
  4. package/esm2022/lib/_common/dialogs/access-control-guide/access-control-guide.component.mjs +27 -0
  5. package/esm2022/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.mjs +27 -0
  6. package/esm2022/lib/_common/dialogs/entity-selections/entity-selections.component.mjs +371 -0
  7. package/esm2022/lib/_common/dialogs/invite-users/invite-users.component.mjs +116 -0
  8. package/esm2022/lib/_common/pagination/pagination.component.mjs +168 -0
  9. package/esm2022/lib/_constants/app.constants.mjs +6 -0
  10. package/esm2022/lib/_directives/drag-drop.directive.mjs +53 -0
  11. package/esm2022/lib/_models/access-control.model.mjs +31 -0
  12. package/esm2022/lib/_models/pagination.model.mjs +2 -0
  13. package/esm2022/lib/_services/access-control.service.mjs +195 -0
  14. package/esm2022/lib/_services/cadre-mapping.service.mjs +164 -0
  15. package/esm2022/lib/access-settings.component.mjs +13 -0
  16. package/esm2022/lib/access-settings.module.mjs +21 -0
  17. package/esm2022/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.mjs +391 -0
  18. package/esm2022/lib/components/list-table/list-table.component.mjs +148 -0
  19. package/esm2022/lib/components/snackbar/snackbar.component.mjs +19 -0
  20. package/esm2022/public-api.mjs +10 -0
  21. package/esm2022/sunbird-cb-access-settings.mjs +5 -0
  22. package/fesm2022/sunbird-cb-access-settings.mjs +2331 -0
  23. package/fesm2022/sunbird-cb-access-settings.mjs.map +1 -0
  24. package/index.d.ts +6 -0
  25. package/lib/_common/access-control/access-control.component.d.ts +71 -0
  26. package/lib/_common/access-control/access-control.component.d.ts.map +1 -0
  27. package/lib/_common/access-control/access-control.module.d.ts +36 -0
  28. package/lib/_common/access-control/access-control.module.d.ts.map +1 -0
  29. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts +16 -0
  30. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts.map +1 -0
  31. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts +15 -0
  32. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
  33. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts +65 -0
  34. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts.map +1 -0
  35. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts +40 -0
  36. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts.map +1 -0
  37. package/lib/_common/pagination/pagination.component.d.ts +31 -0
  38. package/lib/_common/pagination/pagination.component.d.ts.map +1 -0
  39. package/lib/_constants/app.constants.d.ts +6 -0
  40. package/lib/_constants/app.constants.d.ts.map +1 -0
  41. package/lib/_directives/drag-drop.directive.d.ts +12 -0
  42. package/lib/_directives/drag-drop.directive.d.ts.map +1 -0
  43. package/lib/_models/access-control.model.d.ts +106 -0
  44. package/lib/_models/access-control.model.d.ts.map +1 -0
  45. package/lib/_models/pagination.model.d.ts +6 -0
  46. package/lib/_models/pagination.model.d.ts.map +1 -0
  47. package/lib/_services/access-control.service.d.ts +72 -0
  48. package/lib/_services/access-control.service.d.ts.map +1 -0
  49. package/lib/_services/cadre-mapping.service.d.ts +71 -0
  50. package/lib/_services/cadre-mapping.service.d.ts.map +1 -0
  51. package/lib/access-settings.component.d.ts +9 -0
  52. package/lib/access-settings.component.d.ts.map +1 -0
  53. package/lib/access-settings.module.d.ts +12 -0
  54. package/lib/access-settings.module.d.ts.map +1 -0
  55. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts +31 -0
  56. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts.map +1 -0
  57. package/lib/components/list-table/list-table.component.d.ts +40 -0
  58. package/lib/components/list-table/list-table.component.d.ts.map +1 -0
  59. package/lib/components/snackbar/snackbar.component.d.ts +13 -0
  60. package/lib/components/snackbar/snackbar.component.d.ts.map +1 -0
  61. package/package.json +28 -0
  62. package/public-api.d.ts +7 -0
  63. package/public-api.d.ts.map +1 -0
  64. package/sunbird-cb-access-settings.d.ts.map +1 -0
@@ -0,0 +1,561 @@
1
+ import { Component, EventEmitter, Input, Output } from "@angular/core";
2
+ import { InviteUsersComponent } from "../dialogs/invite-users/invite-users.component";
3
+ import { NsAccessControlConfig } from "../../_models/access-control.model";
4
+ import { Validators } from "@angular/forms";
5
+ import { EntitySelectionsComponent } from "../dialogs/entity-selections/entity-selections.component";
6
+ import { v4 as uuidv4 } from "uuid";
7
+ import { SnackbarComponent } from "../../components/snackbar/snackbar.component";
8
+ import { ConfirmDialogComponent } from "../dialogs/confirm-dialog/confirm-dialog.component";
9
+ import { AccessControlGuideComponent } from "../dialogs/access-control-guide/access-control-guide.component";
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/material/dialog";
12
+ import * as i2 from "@angular/forms";
13
+ import * as i3 from "../../_services/access-control.service";
14
+ import * as i4 from "../../_services/cadre-mapping.service";
15
+ import * as i5 from "@angular/material/legacy-snack-bar";
16
+ import * as i6 from "@angular/common";
17
+ import * as i7 from "@angular/material/legacy-radio";
18
+ import * as i8 from "@angular/material/icon";
19
+ import * as i9 from "@angular/material/legacy-slide-toggle";
20
+ import * as i10 from "@angular/material/legacy-form-field";
21
+ import * as i11 from "@angular/material/legacy-select";
22
+ import * as i12 from "@angular/material/legacy-core";
23
+ import * as i13 from "@angular/material/expansion";
24
+ import * as i14 from "@angular/material/legacy-button";
25
+ import * as i15 from "@angular/material/legacy-progress-spinner";
26
+ import * as i16 from "@angular/material/tooltip";
27
+ export class AccessControlComponent {
28
+ constructor(dialog, fb, accessControlService, cadreMappingService, snackbar) {
29
+ this.dialog = dialog;
30
+ this.fb = fb;
31
+ this.accessControlService = accessControlService;
32
+ this.cadreMappingService = cadreMappingService;
33
+ this.snackbar = snackbar;
34
+ this.contentId = "";
35
+ this.accessControlData = new EventEmitter();
36
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
37
+ this.ACCESS_TYPE_ENUM = NsAccessControlConfig.IAccessTypes;
38
+ this.isLoading = false;
39
+ this.isVisibilityEnabled = false;
40
+ this.filterCriteria = false;
41
+ this.defaultConditionRelationship = "AND";
42
+ this.defaultUserGroupRelationship = "OR";
43
+ this.isSaveFltrBtnDisabled = false;
44
+ this.isApplyBtnDisabled = false;
45
+ this.isApplying = false;
46
+ this.isSaving = false;
47
+ }
48
+ ngOnInit() {
49
+ this.initForm();
50
+ this.getAccessControl();
51
+ this.accessControlService.accessControlConfig.set(this.config);
52
+ this.accessControlCriteriaSelection = this.config?.accessControlCriteriaSelection;
53
+ this.usersTableConfig = this.config?.usersTableConfig;
54
+ if (!this.contentId) {
55
+ this.callSnackbar("Content id is required", "error");
56
+ }
57
+ if (this.content) {
58
+ if (this.content?.status === "Draft") {
59
+ this.isApplyBtnDisabled = true;
60
+ }
61
+ if (this.content?.status === "Live") {
62
+ this.isSaveFltrBtnDisabled = true;
63
+ }
64
+ if (this.content?.accessSettingsEnabled) {
65
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
66
+ }
67
+ else {
68
+ if (this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.ALL_USERS) {
69
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
70
+ }
71
+ else if (this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC ||
72
+ this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
73
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ fetchCadreConfigData() {
79
+ this.isLoading = true;
80
+ this.accessControlService.fetchCadreConfig().subscribe({
81
+ next: (response) => {
82
+ if (response?.result && response?.result?.response && Object.keys(response?.result?.response)?.length) {
83
+ this.cadreConfigData = response.result.response?.value;
84
+ this.cadreMappingService.initialize(this.cadreConfigData);
85
+ this.accessControlService.holdServiceCadrebatch.set({
86
+ service: this.cadreMappingService.getAllServices(),
87
+ batch: this.cadreMappingService.getAllBatchYears(),
88
+ cadre: this.cadreMappingService.getAllCadres()
89
+ });
90
+ }
91
+ },
92
+ complete: () => {
93
+ this.isLoading = false;
94
+ }
95
+ });
96
+ }
97
+ initForm() {
98
+ this.accessControlForm = this.fb.group({
99
+ userGroup: this.fb.array([])
100
+ });
101
+ }
102
+ get userGroup() {
103
+ return this.accessControlForm.get("userGroup");
104
+ }
105
+ ruleConditions(ruleIndex) {
106
+ return this.userGroup.at(ruleIndex).get("conditions");
107
+ }
108
+ onAccessTypeChange(event) {
109
+ if (!this.cadreConfigData) {
110
+ this.fetchCadreConfigData();
111
+ }
112
+ if (event.value === NsAccessControlConfig.IAccessTypes.Public) {
113
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
114
+ width: "470px",
115
+ data: { type: "confirm-access-type" }
116
+ });
117
+ dialogRef.afterClosed().subscribe(result => {
118
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
119
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
120
+ this.updateContentAccessSetting();
121
+ }
122
+ else {
123
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
124
+ }
125
+ });
126
+ }
127
+ else {
128
+ this.updateContentAccessSetting();
129
+ }
130
+ if (event.value === NsAccessControlConfig.IAccessTypes.Custom) {
131
+ this.isVisibilityEnabled = false;
132
+ }
133
+ }
134
+ addUserGroup() {
135
+ const ruleGroup = this.fb.group({
136
+ id: [uuidv4()],
137
+ name: [`User Group ${this.userGroup.length + 1}`],
138
+ description: [`Description for UserGroup ${this.userGroup.length + 1}`],
139
+ conditions: this.fb.array([this.createConditionGroup(uuidv4(), this.userGroup.length - 1)])
140
+ });
141
+ this.userGroup.push(ruleGroup);
142
+ }
143
+ addCondition(userGroupIndex) {
144
+ const conditions = this.ruleConditions(userGroupIndex);
145
+ const accessSetting = this.content?.accessSetting;
146
+ // Check if organization/users already exists based on access setting
147
+ if (accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC || accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
148
+ const entityType = accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC
149
+ ? NsAccessControlConfig.SelectionType.Organizations
150
+ : NsAccessControlConfig.SelectionType.Users;
151
+ const existingEntity = conditions.controls.some(ctrl => ctrl.get("entity")?.value === entityType);
152
+ if (existingEntity) {
153
+ this.callSnackbar(`${entityType.toUpperCase()} is already added in this user group`, "error");
154
+ return;
155
+ }
156
+ }
157
+ // Check if the last condition's selections are empty
158
+ if (conditions.length > 0) {
159
+ const lastCondition = conditions.at(conditions.length - 1);
160
+ const selections = lastCondition.get("selections")?.value || [];
161
+ if (selections.length === 0) {
162
+ this.callSnackbar("Please select a value for the current condition before adding another one.", "error");
163
+ return;
164
+ }
165
+ }
166
+ conditions.push(this.createConditionGroup(uuidv4(), userGroupIndex));
167
+ }
168
+ createConditionGroup(id, userGroupIndex) {
169
+ let entity = "";
170
+ const accessSetting = this.content?.accessSetting;
171
+ if (accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC || accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
172
+ entity =
173
+ accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC
174
+ ? NsAccessControlConfig.SelectionType.Organizations
175
+ : NsAccessControlConfig.SelectionType.Users;
176
+ this.accessControlCriteriaSelection.optionsEntity.forEach((ele) => {
177
+ ele.disabled = ele.value !== entity;
178
+ });
179
+ }
180
+ return this.fb.group({
181
+ id: [id],
182
+ entity: [entity, Validators.required],
183
+ conditionType: [{ value: "is", disabled: true }, Validators.required],
184
+ selections: [[]]
185
+ });
186
+ }
187
+ onEntityChange(userGroupIndex, conditionIndex) {
188
+ const conditions = this.ruleConditions(userGroupIndex);
189
+ const condition = conditions.at(conditionIndex);
190
+ const selectedEntity = condition?.get("entity")?.value;
191
+ // Check if the same entity is already selected in another condition of this user group
192
+ const isDuplicate = conditions.controls.some((ctrl, index) => {
193
+ return index !== conditionIndex && ctrl.get("entity")?.value === selectedEntity;
194
+ });
195
+ if (isDuplicate) {
196
+ this.callSnackbar(`${selectedEntity?.toUpperCase()} is already selected in this user group`, "error");
197
+ condition.get("entity")?.setValue("");
198
+ return;
199
+ }
200
+ if (condition?.value?.selections?.length) {
201
+ condition.get("selections")?.setValue([]);
202
+ }
203
+ }
204
+ getAvailableEntities(userGroupIndex, currentConditionIndex) {
205
+ const conditions = this.ruleConditions(userGroupIndex);
206
+ const selectedEntities = conditions.controls
207
+ .map((ctrl, idx) => (idx !== currentConditionIndex ? ctrl.get("entity")?.value : null))
208
+ .filter(e => !!e);
209
+ return this.accessControlCriteriaSelection?.optionsEntity.filter(option => !selectedEntities.includes(option.value));
210
+ }
211
+ removeUserGroup(index) {
212
+ const group = this.userGroup.at(index);
213
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
214
+ width: "470px",
215
+ data: { additionalData: group?.value?.name, type: "delete" }
216
+ });
217
+ dialogRef.afterClosed().subscribe(result => {
218
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
219
+ this.userGroup.removeAt(index);
220
+ }
221
+ });
222
+ }
223
+ resetUserGroup(index) {
224
+ const group = this.userGroup.at(index);
225
+ if (group) {
226
+ group.get("name")?.setValue(`User Group ${index + 1}`);
227
+ group.get("description")?.setValue(`Description for UserGroup ${index + 1}`);
228
+ const conditions = group.get("conditions");
229
+ for (let i = 0; i < conditions.length; i++) {
230
+ const id = conditions.at(i).get("id")?.value;
231
+ conditions.setControl(i, this.createConditionGroup(id, index));
232
+ }
233
+ }
234
+ }
235
+ removeCondition(userGroupIndex, conditionIndex) {
236
+ const conditions = this.ruleConditions(userGroupIndex);
237
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
238
+ width: "470px",
239
+ data: { additionalData: "this condition", type: "delete" }
240
+ });
241
+ dialogRef.afterClosed().subscribe(result => {
242
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
243
+ conditions.removeAt(conditionIndex);
244
+ }
245
+ });
246
+ }
247
+ resetCondition(userGroupIndex, conditionIndex) {
248
+ const conditions = this.ruleConditions(userGroupIndex);
249
+ const condition = conditions.at(conditionIndex);
250
+ if (condition) {
251
+ const id = condition.get("id")?.value || uuidv4();
252
+ conditions.setControl(conditionIndex, this.createConditionGroup(id, userGroupIndex));
253
+ }
254
+ }
255
+ manageSelections(condition, rule, userGroupIndex) {
256
+ switch (condition.value.entity) {
257
+ case NsAccessControlConfig.SelectionType.Users:
258
+ this.openInviteUserDialog(condition?.value, rule?.value);
259
+ break;
260
+ case NsAccessControlConfig.SelectionType.Organizations:
261
+ case NsAccessControlConfig.SelectionType.Designation:
262
+ case NsAccessControlConfig.SelectionType.Service:
263
+ case NsAccessControlConfig.SelectionType.Cadre:
264
+ case NsAccessControlConfig.SelectionType.Batch:
265
+ case NsAccessControlConfig.SelectionType.Group:
266
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
267
+ this.processCadreConfigMapping(userGroupIndex);
268
+ this.openSelectionDialog(rule?.value, condition?.value);
269
+ break;
270
+ default:
271
+ console.warn("Unsupported entity type:", condition.value.entity);
272
+ }
273
+ }
274
+ openSelectionDialog(rule, condition) {
275
+ const originalSelections = [...(condition.selections || [])];
276
+ const dialogRef = this.dialog.open(EntitySelectionsComponent, {
277
+ width: "1032px",
278
+ data: { rule: rule, condition: condition, selected: condition.selections }
279
+ });
280
+ dialogRef.afterClosed().subscribe(result => {
281
+ if (result) {
282
+ // Find the rule FormGroup in the FormArray
283
+ const ruleIndex = this.userGroup.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.rule.id);
284
+ if (ruleIndex !== -1) {
285
+ const ruleGroup = this.userGroup.at(ruleIndex);
286
+ const conditions = ruleGroup.get("conditions");
287
+ const conditionIndex = conditions.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.condition.id);
288
+ if (conditionIndex !== -1) {
289
+ const conditionGroup = conditions.at(conditionIndex);
290
+ conditionGroup.get("selections")?.setValue(result.selected);
291
+ if (condition.entity === NsAccessControlConfig.SelectionType.Organizations &&
292
+ !this.areSelectionsEqual(originalSelections, result.selected)) {
293
+ const designationCondition = conditions.controls.find(ctrl => ctrl.get("entity")?.value === NsAccessControlConfig.SelectionType.Designation);
294
+ if (designationCondition) {
295
+ designationCondition.get("selections")?.setValue([]);
296
+ }
297
+ }
298
+ this.processCadreConfigMapping(ruleIndex);
299
+ }
300
+ }
301
+ }
302
+ });
303
+ }
304
+ areSelectionsEqual(content_1, content_2) {
305
+ if (content_1.length !== content_2.length)
306
+ return false;
307
+ return content_1.every(item => content_2.includes(item));
308
+ }
309
+ processCadreConfigMapping(userGroupIndex) {
310
+ const ruleGroup = this.userGroup.at(userGroupIndex);
311
+ const conditionValue = ruleGroup.get("conditions").value;
312
+ if (conditionValue && conditionValue.length) {
313
+ const services = conditionValue.find((ele) => ele.entity === "service");
314
+ const cadre = conditionValue.find((ele) => ele.entity === "cadre");
315
+ const batch = conditionValue.find((ele) => ele.entity === "batch");
316
+ const serviceSelections = services?.selections || [];
317
+ const cadreSelections = cadre?.selections || [];
318
+ const batchSelections = batch?.selections || [];
319
+ // Case 1: Only service selected
320
+ if (serviceSelections?.length && !cadreSelections?.length && !batchSelections?.length) {
321
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
322
+ ...prev,
323
+ service: this.cadreMappingService.getAllServices(),
324
+ cadre: this.cadreMappingService.getCadresByServices(serviceSelections),
325
+ batch: this.cadreMappingService.getBatchYearsByServices(serviceSelections)
326
+ }));
327
+ }
328
+ // Case 2: Only cadre selected
329
+ else if (!serviceSelections?.length && cadreSelections?.length && !batchSelections?.length) {
330
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
331
+ ...prev,
332
+ cadre: this.cadreMappingService.getAllCadres(),
333
+ service: this.cadreMappingService.getServicesByCadres(cadreSelections),
334
+ batch: this.cadreMappingService.getBatchYearsByServices(cadreSelections)
335
+ }));
336
+ }
337
+ // Case 3: Only batch selected
338
+ else if (!serviceSelections?.length && !cadreSelections?.length && batchSelections?.length) {
339
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
340
+ ...prev,
341
+ batch: this.cadreMappingService.getAllBatchYears(),
342
+ service: this.cadreMappingService.getServicesByBatchYears(batchSelections),
343
+ cadre: this.cadreMappingService.getCadresByBatchYears(batchSelections)
344
+ }));
345
+ }
346
+ // Case 4: Service and Cadre selected
347
+ else if (serviceSelections?.length && cadreSelections?.length && !batchSelections?.length) {
348
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
349
+ ...prev,
350
+ service: this.cadreMappingService.getServicesByCadres(cadreSelections),
351
+ cadre: this.cadreMappingService.getCadresByServices(serviceSelections),
352
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
353
+ }));
354
+ }
355
+ // Case 5: Service and Batch selected
356
+ else if (serviceSelections?.length && !cadreSelections?.length && batchSelections?.length) {
357
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
358
+ ...prev,
359
+ cadre: this.cadreMappingService.getCadresByServicesAndBatch(serviceSelections, batchSelections),
360
+ service: this.cadreMappingService.getServicesByCadresAndBatch(cadreSelections, batchSelections),
361
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
362
+ }));
363
+ }
364
+ // Case 6: Cadre and Batch selected
365
+ else if (!serviceSelections?.length && cadreSelections?.length && batchSelections?.length) {
366
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
367
+ ...prev,
368
+ service: this.cadreMappingService.getServicesByCadresAndBatch(cadreSelections, batchSelections),
369
+ cadre: this.cadreMappingService.getCadresByServicesAndBatch(serviceSelections, batchSelections),
370
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
371
+ }));
372
+ }
373
+ else {
374
+ this.accessControlService.holdServiceCadrebatch.set({
375
+ service: this.cadreMappingService.getAllServices(),
376
+ batch: this.cadreMappingService.getAllBatchYears(),
377
+ cadre: this.cadreMappingService.getAllCadres()
378
+ });
379
+ }
380
+ }
381
+ }
382
+ openInviteUserDialog(condition, rule) {
383
+ const dialogRef = this.dialog.open(InviteUsersComponent, {
384
+ width: "1090px",
385
+ data: { condition: condition, rule: rule, selected: condition.selections }
386
+ });
387
+ dialogRef.afterClosed().subscribe(result => {
388
+ if (result) {
389
+ // Find the rule FormGroup in the FormArray
390
+ const ruleIndex = this.userGroup.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.rule.id);
391
+ if (ruleIndex !== -1) {
392
+ const ruleGroup = this.userGroup.at(ruleIndex);
393
+ const conditions = ruleGroup.get("conditions");
394
+ const conditionIndex = conditions.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.condition.id);
395
+ if (conditionIndex !== -1) {
396
+ const conditionGroup = conditions.at(conditionIndex);
397
+ // const userIds = result.selected && result.selected.map((user: any) => user?.userId);
398
+ conditionGroup.get("selections")?.setValue(result.selected);
399
+ }
400
+ }
401
+ }
402
+ });
403
+ }
404
+ callSnackbar(message, type) {
405
+ if (type === "success") {
406
+ this.snackbar.openFromComponent(SnackbarComponent, {
407
+ data: { message: message, type: "success" },
408
+ duration: 3000,
409
+ panelClass: "course-success-snackbar"
410
+ });
411
+ }
412
+ else if (type === "error") {
413
+ this.snackbar.openFromComponent(SnackbarComponent, {
414
+ data: { message: message, type: "error" },
415
+ duration: 3000,
416
+ panelClass: "course-error-snackbar"
417
+ });
418
+ }
419
+ }
420
+ async applyAccessControlValue() {
421
+ if (this.content?.status === "Draft")
422
+ this.isSaving = true;
423
+ else if (this.content?.status === "Live")
424
+ this.isApplying = true;
425
+ const payload = await this.processRequestCreation();
426
+ this.accessControlService.applyUserGroupAccessControl(payload).subscribe({
427
+ next: response => {
428
+ if (response?.result && response?.result?.accessControl) {
429
+ this.accessControlData.emit({ userGroup: response.result.accessControl?.userGroup, accessType: this.accessType });
430
+ this.callSnackbar("Access Control saved successfully", "success");
431
+ }
432
+ else {
433
+ this.callSnackbar("Could not save access control, Please try again.", "error");
434
+ }
435
+ if (this.content?.status === "Draft")
436
+ this.isSaving = false;
437
+ else if (this.content?.status === "Live")
438
+ this.isApplying = false;
439
+ },
440
+ error: () => {
441
+ this.callSnackbar("Could not save access control, Please try again.", "error");
442
+ if (this.content?.status === "Draft")
443
+ this.isSaving = false;
444
+ else if (this.content?.status === "Live")
445
+ this.isApplying = false;
446
+ }
447
+ });
448
+ }
449
+ processRequestCreation() {
450
+ return new Promise((resolve, reject) => {
451
+ try {
452
+ const data = this.accessControlForm.value;
453
+ const userGroups = data.userGroup.map((group) => ({
454
+ userGroupName: group.name,
455
+ userGroupCriteriaList: group.conditions.map((condition) => {
456
+ let criteriaValue;
457
+ if (condition?.entity === NsAccessControlConfig.SelectionType.Users && condition?.selected?.length && condition?.selected[0]?.userId) {
458
+ const userIds = condition.selected?.map((user) => user?.userId) || [];
459
+ criteriaValue = userIds;
460
+ }
461
+ else {
462
+ criteriaValue = condition.selections?.map(String) || [];
463
+ }
464
+ return {
465
+ criteriaKey: condition.entity,
466
+ criteriaValue
467
+ };
468
+ })
469
+ }));
470
+ const requestPayload = {
471
+ contentId: this.contentId,
472
+ accessControl: {
473
+ version: 1,
474
+ userGroups
475
+ }
476
+ };
477
+ resolve(requestPayload);
478
+ }
479
+ catch (error) {
480
+ reject(error);
481
+ }
482
+ });
483
+ }
484
+ openInstructonsDialog() {
485
+ this.dialog.open(AccessControlGuideComponent, {
486
+ width: "960px"
487
+ });
488
+ }
489
+ async getAccessControl() {
490
+ const response = await this.accessControlService
491
+ .fetchUserGroupAccessControl(this.contentId)
492
+ .toPromise()
493
+ .catch(() => {
494
+ this.accessControlData.emit({ userGroup: this.accessControlForm.value?.userGroup, accessType: this.accessType });
495
+ });
496
+ if (response?.result?.accessControl) {
497
+ this.processAccessControlResult(response.result.accessControl);
498
+ this.accessControlData.emit({ userGroup: response.result.accessControl?.userGroup, accessType: this.accessType });
499
+ }
500
+ }
501
+ processAccessControlResult(accessControl) {
502
+ if (!accessControl?.userGroups?.length)
503
+ return;
504
+ while (this.userGroup.length) {
505
+ this.userGroup.removeAt(0);
506
+ }
507
+ accessControl.userGroups.forEach((group) => {
508
+ const conditions = this.fb.array([]);
509
+ group.userGroupCriteriaList.forEach((criteria) => {
510
+ const condition = this.createConditionGroup(uuidv4(), this.userGroup.length);
511
+ // Map API keys to form entity values
512
+ const entityMap = {
513
+ rootOrgId: NsAccessControlConfig.SelectionType.Organizations,
514
+ user: NsAccessControlConfig.SelectionType.Users,
515
+ group: NsAccessControlConfig.SelectionType.Group,
516
+ designation: NsAccessControlConfig.SelectionType.Designation,
517
+ profilestatus: NsAccessControlConfig.SelectionType.VerificationStatus,
518
+ Cadre: NsAccessControlConfig.SelectionType.Cadre,
519
+ service: NsAccessControlConfig.SelectionType.Service,
520
+ batch: NsAccessControlConfig.SelectionType.Batch
521
+ };
522
+ // Set the form values
523
+ condition.patchValue({
524
+ entity: entityMap[criteria.criteriaKey] || criteria.criteriaKey,
525
+ selections: criteria.criteriaValue
526
+ });
527
+ conditions.push(condition);
528
+ });
529
+ const ruleGroup = this.fb.group({
530
+ id: [group.userGroupId || uuidv4()],
531
+ name: [group.userGroupName],
532
+ description: [`Description for ${group.userGroupName}`],
533
+ conditions: conditions
534
+ });
535
+ this.userGroup.push(ruleGroup);
536
+ });
537
+ if (!this.cadreConfigData) {
538
+ this.fetchCadreConfigData();
539
+ }
540
+ }
541
+ async updateContentAccessSetting() {
542
+ const accessTypeBoolean = this.accessType === NsAccessControlConfig.IAccessTypes.Public ? false : true;
543
+ const request = this.accessControlService.createRequestContent(this.content, accessTypeBoolean);
544
+ await this.accessControlService.updateContentV3(request, this.contentId).toPromise();
545
+ }
546
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlComponent, deps: [{ token: i1.MatDialog }, { token: i2.FormBuilder }, { token: i3.AccessControlService }, { token: i4.CadreMappingService }, { token: i5.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
547
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AccessControlComponent, selector: "sb-uic-access-control", inputs: { config: "config", contentId: "contentId", content: "content" }, outputs: { accessControlData: "accessControlData" }, ngImport: i0, template: "<div class=\"py-4 px-10\">\n <div class=\"p-4 as-container\">\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xl font-bold primary-text-color\">Access Control</span>\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-sm primary-text-color cursor-pointer\" (click)=\"openInstructonsDialog()\">How to use access control?</span>\n <img src=\"/assets/icons/support-i.svg\" alt=\"support i\" class=\"img-icon-24\" />\n </div>\n </div>\n <div class=\"light-grey-border p-4 mt-4\">\n <mat-radio-group [(ngModel)]=\"accessType\" (change)=\"onAccessTypeChange($event)\">\n <div class=\"radio-container flex gap-5 mb-4\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.accessTypes\">\n <mat-radio-button [value]=\"item.value\">\n <div class=\"flex gap-2 items-center\">\n <span>{{ item?.name }}</span>\n <mat-icon svgIcon=\"info-outline\" [matTooltip]=\"item?.tooltip\"></mat-icon>\n </div>\n </mat-radio-button>\n </ng-container>\n </div>\n </mat-radio-group>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Public\">\n <div class=\"info-container\">\n <label class=\"text-sm\">This event will be visible to all Karmayogis.</label>\n </div>\n </ng-container>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Custom\">\n <div class=\"visibiliy-container light-grey-border p-4\">\n <div class=\"flex justify-between items-center\">\n <span class=\"text-lg font-bold\">Visibility</span>\n <mat-slide-toggle [(ngModel)]=\"isVisibilityEnabled\"></mat-slide-toggle>\n </div>\n <ng-container *ngIf=\"!isVisibilityEnabled\">\n <label class=\"text-sm\">Karmayogis will NOT be able to search and view the description page of the event.</label>\n </ng-container>\n <ng-container *ngIf=\"isVisibilityEnabled\">\n <label class=\"text-sm\"\n >Karmayogis will be able to search and view the description page of the event but will not able to enroll if Karmayogi do not satisfy the\n conditions defined in the access control below.</label\n >\n </ng-container>\n </div>\n <!-- <div class=\"flex justify-between items-center mt-4 mb-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"filterCriteria = !filterCriteria\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Filter criteria</span>\n <mat-icon class=\"primary-text-color\">{{ filterCriteria ? \"visibility_on\" : \"visibility_off\" }}</mat-icon>\n </div>\n </button>\n </div> -->\n\n <ng-container *ngIf=\"filterCriteria\">\n <div class=\"filter-criteria-container light-grey-border p-4 mt-4 flex flex-middle justify-between mb-4\">\n <div class=\"info\">\n <span class=\"text-sm\">Define the conditions that Karmayogis must satisfy to enroll in the event.</span>\n </div>\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Refresh</span>\n <mat-icon class=\"primary-text-color\">refresh</mat-icon>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"accessControlForm && userGroup?.length > 0 && !isLoading\">\n <form [formGroup]=\"accessControlForm\">\n <mat-accordion class=\"example-headers-align access-usergroup-accordion mt-3\" multi=\"true\">\n <ng-container formArrayName=\"userGroup\" *ngFor=\"let rule of userGroup?.controls; let i = index; let ruleLast = last\">\n <ng-container [formGroupName]=\"i\">\n <mat-expansion-panel class=\"access-usergroup-panel\" expanded>\n <mat-expansion-panel-header>\n <mat-panel-title class=\"items-center\">\n <span class=\"text-sm\">{{ rule.get(\"name\")?.value }}</span>\n </mat-panel-title>\n <mat-panel-description class=\"justify-end items-center\" (click)=\"$event.stopPropagation()\">\n <button mat-icon-button aria-label=\"delete user group\" (click)=\"removeUserGroup(i)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh user group\" (click)=\"resetUserGroup(i)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngIf=\"rule.get('conditions') as conditionsArray\">\n <div [formArrayName]=\"'conditions'\">\n <ng-container *ngFor=\"let condition of conditionsArray?.controls; let j = index; let conditionlast = last\">\n <div class=\"condition-selection mt-2\" [formGroupName]=\"j\">\n <div class=\"select-condition-text mb-3 mt-4\">Select Condition {{ i + 1 + \".\" + (j + 1) }}</div>\n <div class=\"selections-options grid grid-cols-5 gap-4\">\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"entity\" (selectionChange)=\"onEntityChange(i, j)\">\n <ng-container *ngFor=\"let item of getAvailableEntities(i, j)\">\n <mat-option [value]=\"item?.value\" [disabled]=\"item?.disabled\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"conditionType\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.optionsConditions\">\n <mat-option [value]=\"item?.value\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"action-manage-selection\">\n <button\n mat-flat-button\n (click)=\"manageSelections(condition, rule, i)\"\n [disabled]=\"!condition.get('entity').value || !condition.get('conditionType').value\"\n class=\"rounded-full new-bg-color text-white mt-2 flex items-center gap-2\">\n <mat-icon svgIcon=\"svg_search\" class=\"mr-2\"></mat-icon>\n <span class=\"font-bold text-sm\">Manage Selections</span>\n </button>\n </div>\n <div class=\"action-options-selected\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners mt-2\" type=\"button\">\n <div class=\"flex gap-2 flex-middle mt-2\">\n <span class=\"text-m color-gr underline\">{{ condition.get(\"selections\").value.length }} items selected</span>\n </div>\n </button>\n </div>\n <div class=\"action-more-options flex justify-end\">\n <div class=\"flex gap-4\">\n <button mat-icon-button aria-label=\"delete condition\" class=\"mt-2 ml-auto\" (click)=\"removeCondition(i, j)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh condition\" class=\"mt-2 ml-auto\" (click)=\"resetCondition(i, j)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"and-or mat-full-radius\" *ngIf=\"conditionsArray?.length > 1 && !conditionlast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultConditionRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"action-add-condition\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addCondition(i)\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add Condition</span>\n </div>\n </button>\n </div>\n </mat-expansion-panel>\n <div class=\"and-or mat-full-radius\" *ngIf=\"userGroup.length > 1 && !ruleLast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultUserGroupRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </ng-container>\n </mat-accordion>\n </form>\n </ng-container>\n\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=\"text-center mb-6 mt-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addUserGroup()\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add User Group</span>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"userGroup?.length > 0\">\n <div class=\"action-save flex justify-center items-center gap-4\">\n <!-- Save Filter Button -->\n <button\n mat-flat-button\n class=\"flex rounded-full px-4 py-2 mat-btn-outline font-bold text-sm items-center gap-2\"\n [disabled]=\"isSaveFltrBtnDisabled || isSaving\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isSaving\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Save Filter</span>\n </button>\n\n <!-- Apply Button -->\n <button\n mat-flat-button\n [disabled]=\"isApplyBtnDisabled || isApplying\"\n class=\"flex items-center rounded-full px-4 py-2 new-bg-color font-bold text-sm text-white gap-2\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isApplying\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Apply</span>\n </button>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".as-container{border:1px solid #1b4ca1;border-radius:10px}.filter-criteria-container{background:#fff8ef}.access-rules-panel{background:#e8edf6!important;border-radius:4px;margin-bottom:10px;box-shadow:none!important}::ng-deep .mat-expansion-panel-body{background:#fff!important}.more-menu-icon{font-size:16px;height:16px;width:16px}.selections-options .mat-full-radius ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline{border-radius:12px!important;border:1px solid rgba(0,0,0,.1607843137)}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-end{border-radius:0 12px 12px 0!important}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-start{border-radius:12px 0 0 12px!important;flex-grow:1}.selections-options .mat-full-radius ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.mt-2{margin-top:.5rem!important}.action-manage-selection mat-icon{font-size:18px;height:28px;width:16px}.action-manage-selection button{padding:4px 16px}.color-gr{background:#1b4ca1}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-end{border:none!important}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-start{border:none!important}.and-or ::ng-deep .mat-select-value{color:#1b4ca1!important;font-family:Montserrat;font-weight:600;font-size:16px}.and-or ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.w-max-100{max-width:100px}.mat-expansion-panel-header.mat-expanded{height:50px!important}.mat-expansion-panel-header{background:#e8edf6}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:none!important;border:1px solid rgba(0,0,0,.0784313725)}.mr-1{margin-right:.25rem!important}::ng-deep .mat-menu-panel{border:1px solid rgba(0,0,0,.2);border-radius:12px}::ng-deep .mat-menu-content:not(:empty){padding-top:0!important;padding-bottom:0!important}:host ::ng-deep .mdc-dialog .mdc-dialog__content{padding:0 24px 24px!important}.select-condition-text{font-family:Lato;font-weight:400;font-size:12px;color:#666}::ng-deep .mat-select-panel{max-height:340px!important}.radio-container mat-icon{width:16px;height:16px;font-size:0px}.img-icon-24{width:24px;height:24px}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i7.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatLegacySlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i10.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i11.MatLegacySelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i12.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i13.MatAccordion, selector: "mat-accordion", inputs: ["multi", "hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i13.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i13.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "directive", type: i13.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i13.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.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: i15.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i16.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] }); }
548
+ }
549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlComponent, decorators: [{
550
+ type: Component,
551
+ args: [{ selector: "sb-uic-access-control", template: "<div class=\"py-4 px-10\">\n <div class=\"p-4 as-container\">\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xl font-bold primary-text-color\">Access Control</span>\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-sm primary-text-color cursor-pointer\" (click)=\"openInstructonsDialog()\">How to use access control?</span>\n <img src=\"/assets/icons/support-i.svg\" alt=\"support i\" class=\"img-icon-24\" />\n </div>\n </div>\n <div class=\"light-grey-border p-4 mt-4\">\n <mat-radio-group [(ngModel)]=\"accessType\" (change)=\"onAccessTypeChange($event)\">\n <div class=\"radio-container flex gap-5 mb-4\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.accessTypes\">\n <mat-radio-button [value]=\"item.value\">\n <div class=\"flex gap-2 items-center\">\n <span>{{ item?.name }}</span>\n <mat-icon svgIcon=\"info-outline\" [matTooltip]=\"item?.tooltip\"></mat-icon>\n </div>\n </mat-radio-button>\n </ng-container>\n </div>\n </mat-radio-group>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Public\">\n <div class=\"info-container\">\n <label class=\"text-sm\">This event will be visible to all Karmayogis.</label>\n </div>\n </ng-container>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Custom\">\n <div class=\"visibiliy-container light-grey-border p-4\">\n <div class=\"flex justify-between items-center\">\n <span class=\"text-lg font-bold\">Visibility</span>\n <mat-slide-toggle [(ngModel)]=\"isVisibilityEnabled\"></mat-slide-toggle>\n </div>\n <ng-container *ngIf=\"!isVisibilityEnabled\">\n <label class=\"text-sm\">Karmayogis will NOT be able to search and view the description page of the event.</label>\n </ng-container>\n <ng-container *ngIf=\"isVisibilityEnabled\">\n <label class=\"text-sm\"\n >Karmayogis will be able to search and view the description page of the event but will not able to enroll if Karmayogi do not satisfy the\n conditions defined in the access control below.</label\n >\n </ng-container>\n </div>\n <!-- <div class=\"flex justify-between items-center mt-4 mb-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"filterCriteria = !filterCriteria\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Filter criteria</span>\n <mat-icon class=\"primary-text-color\">{{ filterCriteria ? \"visibility_on\" : \"visibility_off\" }}</mat-icon>\n </div>\n </button>\n </div> -->\n\n <ng-container *ngIf=\"filterCriteria\">\n <div class=\"filter-criteria-container light-grey-border p-4 mt-4 flex flex-middle justify-between mb-4\">\n <div class=\"info\">\n <span class=\"text-sm\">Define the conditions that Karmayogis must satisfy to enroll in the event.</span>\n </div>\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Refresh</span>\n <mat-icon class=\"primary-text-color\">refresh</mat-icon>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"accessControlForm && userGroup?.length > 0 && !isLoading\">\n <form [formGroup]=\"accessControlForm\">\n <mat-accordion class=\"example-headers-align access-usergroup-accordion mt-3\" multi=\"true\">\n <ng-container formArrayName=\"userGroup\" *ngFor=\"let rule of userGroup?.controls; let i = index; let ruleLast = last\">\n <ng-container [formGroupName]=\"i\">\n <mat-expansion-panel class=\"access-usergroup-panel\" expanded>\n <mat-expansion-panel-header>\n <mat-panel-title class=\"items-center\">\n <span class=\"text-sm\">{{ rule.get(\"name\")?.value }}</span>\n </mat-panel-title>\n <mat-panel-description class=\"justify-end items-center\" (click)=\"$event.stopPropagation()\">\n <button mat-icon-button aria-label=\"delete user group\" (click)=\"removeUserGroup(i)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh user group\" (click)=\"resetUserGroup(i)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngIf=\"rule.get('conditions') as conditionsArray\">\n <div [formArrayName]=\"'conditions'\">\n <ng-container *ngFor=\"let condition of conditionsArray?.controls; let j = index; let conditionlast = last\">\n <div class=\"condition-selection mt-2\" [formGroupName]=\"j\">\n <div class=\"select-condition-text mb-3 mt-4\">Select Condition {{ i + 1 + \".\" + (j + 1) }}</div>\n <div class=\"selections-options grid grid-cols-5 gap-4\">\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"entity\" (selectionChange)=\"onEntityChange(i, j)\">\n <ng-container *ngFor=\"let item of getAvailableEntities(i, j)\">\n <mat-option [value]=\"item?.value\" [disabled]=\"item?.disabled\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"conditionType\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.optionsConditions\">\n <mat-option [value]=\"item?.value\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"action-manage-selection\">\n <button\n mat-flat-button\n (click)=\"manageSelections(condition, rule, i)\"\n [disabled]=\"!condition.get('entity').value || !condition.get('conditionType').value\"\n class=\"rounded-full new-bg-color text-white mt-2 flex items-center gap-2\">\n <mat-icon svgIcon=\"svg_search\" class=\"mr-2\"></mat-icon>\n <span class=\"font-bold text-sm\">Manage Selections</span>\n </button>\n </div>\n <div class=\"action-options-selected\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners mt-2\" type=\"button\">\n <div class=\"flex gap-2 flex-middle mt-2\">\n <span class=\"text-m color-gr underline\">{{ condition.get(\"selections\").value.length }} items selected</span>\n </div>\n </button>\n </div>\n <div class=\"action-more-options flex justify-end\">\n <div class=\"flex gap-4\">\n <button mat-icon-button aria-label=\"delete condition\" class=\"mt-2 ml-auto\" (click)=\"removeCondition(i, j)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh condition\" class=\"mt-2 ml-auto\" (click)=\"resetCondition(i, j)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"and-or mat-full-radius\" *ngIf=\"conditionsArray?.length > 1 && !conditionlast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultConditionRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"action-add-condition\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addCondition(i)\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add Condition</span>\n </div>\n </button>\n </div>\n </mat-expansion-panel>\n <div class=\"and-or mat-full-radius\" *ngIf=\"userGroup.length > 1 && !ruleLast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultUserGroupRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </ng-container>\n </mat-accordion>\n </form>\n </ng-container>\n\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=\"text-center mb-6 mt-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addUserGroup()\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add User Group</span>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"userGroup?.length > 0\">\n <div class=\"action-save flex justify-center items-center gap-4\">\n <!-- Save Filter Button -->\n <button\n mat-flat-button\n class=\"flex rounded-full px-4 py-2 mat-btn-outline font-bold text-sm items-center gap-2\"\n [disabled]=\"isSaveFltrBtnDisabled || isSaving\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isSaving\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Save Filter</span>\n </button>\n\n <!-- Apply Button -->\n <button\n mat-flat-button\n [disabled]=\"isApplyBtnDisabled || isApplying\"\n class=\"flex items-center rounded-full px-4 py-2 new-bg-color font-bold text-sm text-white gap-2\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isApplying\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Apply</span>\n </button>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".as-container{border:1px solid #1b4ca1;border-radius:10px}.filter-criteria-container{background:#fff8ef}.access-rules-panel{background:#e8edf6!important;border-radius:4px;margin-bottom:10px;box-shadow:none!important}::ng-deep .mat-expansion-panel-body{background:#fff!important}.more-menu-icon{font-size:16px;height:16px;width:16px}.selections-options .mat-full-radius ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline{border-radius:12px!important;border:1px solid rgba(0,0,0,.1607843137)}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-end{border-radius:0 12px 12px 0!important}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-start{border-radius:12px 0 0 12px!important;flex-grow:1}.selections-options .mat-full-radius ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.mt-2{margin-top:.5rem!important}.action-manage-selection mat-icon{font-size:18px;height:28px;width:16px}.action-manage-selection button{padding:4px 16px}.color-gr{background:#1b4ca1}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-end{border:none!important}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-start{border:none!important}.and-or ::ng-deep .mat-select-value{color:#1b4ca1!important;font-family:Montserrat;font-weight:600;font-size:16px}.and-or ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.w-max-100{max-width:100px}.mat-expansion-panel-header.mat-expanded{height:50px!important}.mat-expansion-panel-header{background:#e8edf6}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:none!important;border:1px solid rgba(0,0,0,.0784313725)}.mr-1{margin-right:.25rem!important}::ng-deep .mat-menu-panel{border:1px solid rgba(0,0,0,.2);border-radius:12px}::ng-deep .mat-menu-content:not(:empty){padding-top:0!important;padding-bottom:0!important}:host ::ng-deep .mdc-dialog .mdc-dialog__content{padding:0 24px 24px!important}.select-condition-text{font-family:Lato;font-weight:400;font-size:12px;color:#666}::ng-deep .mat-select-panel{max-height:340px!important}.radio-container mat-icon{width:16px;height:16px;font-size:0px}.img-icon-24{width:24px;height:24px}\n"] }]
552
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i2.FormBuilder }, { type: i3.AccessControlService }, { type: i4.CadreMappingService }, { type: i5.MatLegacySnackBar }]; }, propDecorators: { config: [{
553
+ type: Input
554
+ }], contentId: [{
555
+ type: Input
556
+ }], content: [{
557
+ type: Input
558
+ }], accessControlData: [{
559
+ type: Output
560
+ }] } });
561
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL2FjY2Vzcy1zZXR0aW5ncy9zcmMvbGliL19jb21tb24vYWNjZXNzLWNvbnRyb2wvYWNjZXNzLWNvbnRyb2wuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL2FjY2Vzcy1zZXR0aW5ncy9zcmMvbGliL19jb21tb24vYWNjZXNzLWNvbnRyb2wvYWNjZXNzLWNvbnRyb2wuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUvRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUN0RixPQUFPLEVBQXFCLHFCQUFxQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDOUYsT0FBTyxFQUFxQyxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUvRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwwREFBMEQsQ0FBQztBQUNyRyxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVwQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUVqRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUM1RixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxnRUFBZ0UsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTzdHLE1BQU0sT0FBTyxzQkFBc0I7SUEwQmpDLFlBQ1UsTUFBaUIsRUFDakIsRUFBZSxFQUNmLG9CQUEwQyxFQUMxQyxtQkFBd0MsRUFDeEMsUUFBcUI7UUFKckIsV0FBTSxHQUFOLE1BQU0s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Q0FBQzsrR0F6a0JVLHNCQUFzQjttR0FBdEIsc0JBQXNCLDRMQ25CbkMscXlaQXdOQTs7NEZEck1hLHNCQUFzQjtrQkFMbEMsU0FBUzsrQkFDRSx1QkFBdUI7K05BS3hCLE1BQU07c0JBQWQsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFFSSxpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE1hdERpYWxvZyB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2dcIjtcbmltcG9ydCB7IEludml0ZVVzZXJzQ29tcG9uZW50IH0gZnJvbSBcIi4uL2RpYWxvZ3MvaW52aXRlLXVzZXJzL2ludml0ZS11c2Vycy5jb21wb25lbnRcIjtcbmltcG9ydCB7IElVc2VyR3JvdXBSZXF1ZXN0LCBOc0FjY2Vzc0NvbnRyb2xDb25maWcgfSBmcm9tIFwiLi4vLi4vX21vZGVscy9hY2Nlc3MtY29udHJvbC5tb2RlbFwiO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUFycmF5LCBWYWxpZGF0b3JzIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBBY2Nlc3NDb250cm9sU2VydmljZSB9IGZyb20gXCIuLi8uLi9fc2VydmljZXMvYWNjZXNzLWNvbnRyb2wuc2VydmljZVwiO1xuaW1wb3J0IHsgRW50aXR5U2VsZWN0aW9uc0NvbXBvbmVudCB9IGZyb20gXCIuLi9kaWFsb2dzL2VudGl0eS1zZWxlY3Rpb25zL2VudGl0eS1zZWxlY3Rpb25zLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB7IENhZHJlTWFwcGluZ1NlcnZpY2UgfSBmcm9tIFwiLi4vLi4vX3NlcnZpY2VzL2NhZHJlLW1hcHBpbmcuc2VydmljZVwiO1xuaW1wb3J0IHsgU25hY2tiYXJDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50cy9zbmFja2Jhci9zbmFja2Jhci5jb21wb25lbnRcIjtcbmltcG9ydCB7IE1hdExlZ2FjeVNuYWNrQmFyIGFzIE1hdFNuYWNrQmFyIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXJcIjtcbmltcG9ydCB7IENvbmZpcm1EaWFsb2dDb21wb25lbnQgfSBmcm9tIFwiLi4vZGlhbG9ncy9jb25maXJtLWRpYWxvZy9jb25maXJtLWRpYWxvZy5jb21wb25lbnRcIjtcbmltcG9ydCB7IEFjY2Vzc0NvbnRyb2xHdWlkZUNvbXBvbmVudCB9IGZyb20gXCIuLi9kaWFsb2dzL2FjY2Vzcy1jb250cm9sLWd1aWRlL2FjY2Vzcy1jb250cm9sLWd1aWRlLmNvbXBvbmVudFwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwic2ItdWljLWFjY2Vzcy1jb250cm9sXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vYWNjZXNzLWNvbnRyb2wuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2FjY2Vzcy1jb250cm9sLmNvbXBvbmVudC5zY3NzXCJdXG59KVxuZXhwb3J0IGNsYXNzIEFjY2Vzc0NvbnRyb2xDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBjb25maWchOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc0NvbnRyb2xDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRlbnRJZDogc3RyaW5nID0gXCJcIjtcbiAgQElucHV0KCkgY29udGVudDogYW55O1xuXG4gIEBPdXRwdXQoKSBhY2Nlc3NDb250cm9sRGF0YTogRXZlbnRFbWl0dGVyPHsgdXNlckdyb3VwOiBhbnlbXTsgYWNjZXNzVHlwZTogc3RyaW5nIH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGFjY2Vzc1R5cGU6IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JVHlwZUFjY2Vzc1R5cGUgPSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1R5cGVzLlB1YmxpYztcbiAgQUNDRVNTX1RZUEVfRU5VTSA9IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzVHlwZXM7XG5cbiAgaXNMb2FkaW5nID0gZmFsc2U7XG4gIGlzVmlzaWJpbGl0eUVuYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgZmlsdGVyQ3JpdGVyaWE6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBkZWZhdWx0Q29uZGl0aW9uUmVsYXRpb25zaGlwOiBzdHJpbmcgPSBcIkFORFwiO1xuICBkZWZhdWx0VXNlckdyb3VwUmVsYXRpb25zaGlwOiBzdHJpbmcgPSBcIk9SXCI7XG5cbiAgYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uITogTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NDb250cm9sQ3JpdGVyaWFTZWxlY3Rpb247XG4gIHVzZXJzVGFibGVDb25maWc6IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JVGFibGVDb25maWc7XG4gIGFjY2Vzc0NvbnRyb2xGb3JtITogRm9ybUdyb3VwO1xuXG4gIGNhZHJlQ29uZmlnRGF0YTogYW55O1xuICBpc1NhdmVGbHRyQnRuRGlzYWJsZWQgPSBmYWxzZTtcbiAgaXNBcHBseUJ0bkRpc2FibGVkID0gZmFsc2U7XG4gIGlzQXBwbHlpbmcgPSBmYWxzZTtcbiAgaXNTYXZpbmcgPSBmYWxzZTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGFjY2Vzc0NvbnRyb2xTZXJ2aWNlOiBBY2Nlc3NDb250cm9sU2VydmljZSxcbiAgICBwcml2YXRlIGNhZHJlTWFwcGluZ1NlcnZpY2U6IENhZHJlTWFwcGluZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBzbmFja2JhcjogTWF0U25hY2tCYXJcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgICB0aGlzLmdldEFjY2Vzc0NvbnRyb2woKTtcbiAgICB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLmFjY2Vzc0NvbnRyb2xDb25maWcuc2V0KHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbiA9IHRoaXMuY29uZmlnPy5hY2Nlc3NDb250cm9sQ3JpdGVyaWFTZWxlY3Rpb247XG5cbiAgICB0aGlzLnVzZXJzVGFibGVDb25maWcgPSB0aGlzLmNvbmZpZz8udXNlcnNUYWJsZUNvbmZpZztcblxuICAgIGlmICghdGhpcy5jb250ZW50SWQpIHtcbiAgICAgIHRoaXMuY2FsbFNuYWNrYmFyKFwiQ29udGVudCBpZCBpcyByZXF1aXJlZFwiLCBcImVycm9yXCIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnQ/LnN0YXR1cyA9PT0gXCJEcmFmdFwiKSB7XG4gICAgICAgIHRoaXMuaXNBcHBseUJ0bkRpc2FibGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmNvbnRlbnQ/LnN0YXR1cyA9PT0gXCJMaXZlXCIpIHtcbiAgICAgICAgdGhpcy5pc1NhdmVGbHRyQnRuRGlzYWJsZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jb250ZW50Py5hY2Nlc3NTZXR0aW5nc0VuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUeXBlID0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NUeXBlcy5DdXN0b207XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5jb250ZW50Py5hY2Nlc3NTZXR0aW5nID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1NldHRpbmcuQUxMX1VTRVJTKSB7XG4gICAgICAgICAgdGhpcy5hY2Nlc3NUeXBlID0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NUeXBlcy5QdWJsaWM7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgdGhpcy5jb250ZW50Py5hY2Nlc3NTZXR0aW5nID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1NldHRpbmcuTURPX1NQRUNJRklDIHx8XG4gICAgICAgICAgdGhpcy5jb250ZW50Py5hY2Nlc3NTZXR0aW5nID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1NldHRpbmcuQ1VTVE9NRV9VU0VSXG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuYWNjZXNzVHlwZSA9IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzVHlwZXMuQ3VzdG9tO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZmV0Y2hDYWRyZUNvbmZpZ0RhdGEoKTogdm9pZCB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2UuZmV0Y2hDYWRyZUNvbmZpZygpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICBpZiAocmVzcG9uc2U/LnJlc3VsdCAmJiByZXNwb25zZT8ucmVzdWx0Py5yZXNwb25zZSAmJiBPYmplY3Qua2V5cyhyZXNwb25zZT8ucmVzdWx0Py5yZXNwb25zZSk/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuY2FkcmVDb25maWdEYXRhID0gcmVzcG9uc2UucmVzdWx0LnJlc3BvbnNlPy52YWx1ZTtcbiAgICAgICAgICB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuaW5pdGlhbGl6ZSh0aGlzLmNhZHJlQ29uZmlnRGF0YSk7XG4gICAgICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2guc2V0KHtcbiAgICAgICAgICAgIHNlcnZpY2U6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRBbGxTZXJ2aWNlcygpLFxuICAgICAgICAgICAgYmF0Y2g6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRBbGxCYXRjaFllYXJzKCksXG4gICAgICAgICAgICBjYWRyZTogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldEFsbENhZHJlcygpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaW5pdEZvcm0oKSB7XG4gICAgdGhpcy5hY2Nlc3NDb250cm9sRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgdXNlckdyb3VwOiB0aGlzLmZiLmFycmF5KFtdKVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHVzZXJHcm91cCgpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmFjY2Vzc0NvbnRyb2xGb3JtLmdldChcInVzZXJHcm91cFwiKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBydWxlQ29uZGl0aW9ucyhydWxlSW5kZXg6IG51bWJlcik6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMudXNlckdyb3VwLmF0KHJ1bGVJbmRleCkuZ2V0KFwiY29uZGl0aW9uc1wiKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBvbkFjY2Vzc1R5cGVDaGFuZ2UoZXZlbnQ6IGFueSkge1xuICAgIGlmICghdGhpcy5jYWRyZUNvbmZpZ0RhdGEpIHtcbiAgICAgIHRoaXMuZmV0Y2hDYWRyZUNvbmZpZ0RhdGEoKTtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudmFsdWUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzVHlwZXMuUHVibGljKSB7XG4gICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKENvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgd2lkdGg6IFwiNDcwcHhcIixcbiAgICAgICAgZGF0YTogeyB0eXBlOiBcImNvbmZpcm0tYWNjZXNzLXR5cGVcIiB9XG4gICAgICB9KTtcbiAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWN0aW9ucy5Db25maXJtKSB7XG4gICAgICAgICAgdGhpcy5hY2Nlc3NUeXBlID0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NUeXBlcy5QdWJsaWM7XG4gICAgICAgICAgdGhpcy51cGRhdGVDb250ZW50QWNjZXNzU2V0dGluZygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYWNjZXNzVHlwZSA9IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzVHlwZXMuQ3VzdG9tO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVDb250ZW50QWNjZXNzU2V0dGluZygpO1xuICAgIH1cblxuICAgIGlmIChldmVudC52YWx1ZSA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NUeXBlcy5DdXN0b20pIHtcbiAgICAgIHRoaXMuaXNWaXNpYmlsaXR5RW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGFkZFVzZXJHcm91cCgpIHtcbiAgICBjb25zdCBydWxlR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGlkOiBbdXVpZHY0KCldLFxuICAgICAgbmFtZTogW2BVc2VyIEdyb3VwICR7dGhpcy51c2VyR3JvdXAubGVuZ3RoICsgMX1gXSxcbiAgICAgIGRlc2NyaXB0aW9uOiBbYERlc2NyaXB0aW9uIGZvciBVc2VyR3JvdXAgJHt0aGlzLnVzZXJHcm91cC5sZW5ndGggKyAxfWBdLFxuICAgICAgY29uZGl0aW9uczogdGhpcy5mYi5hcnJheShbdGhpcy5jcmVhdGVDb25kaXRpb25Hcm91cCh1dWlkdjQoKSwgdGhpcy51c2VyR3JvdXAubGVuZ3RoIC0gMSldKVxuICAgIH0pO1xuXG4gICAgdGhpcy51c2VyR3JvdXAucHVzaChydWxlR3JvdXApO1xuICB9XG5cbiAgYWRkQ29uZGl0aW9uKHVzZXJHcm91cEluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gdGhpcy5ydWxlQ29uZGl0aW9ucyh1c2VyR3JvdXBJbmRleCk7XG4gICAgY29uc3QgYWNjZXNzU2V0dGluZyA9IHRoaXMuY29udGVudD8uYWNjZXNzU2V0dGluZztcblxuICAgIC8vIENoZWNrIGlmIG9yZ2FuaXphdGlvbi91c2VycyBhbHJlYWR5IGV4aXN0cyBiYXNlZCBvbiBhY2Nlc3Mgc2V0dGluZ1xuICAgIGlmIChhY2Nlc3NTZXR0aW5nID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1NldHRpbmcuTURPX1NQRUNJRklDIHx8IGFjY2Vzc1NldHRpbmcgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzU2V0dGluZy5DVVNUT01FX1VTRVIpIHtcbiAgICAgIGNvbnN0IGVudGl0eVR5cGUgPVxuICAgICAgICBhY2Nlc3NTZXR0aW5nID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1NldHRpbmcuTURPX1NQRUNJRklDXG4gICAgICAgICAgPyBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Pcmdhbml6YXRpb25zXG4gICAgICAgICAgOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Vc2VycztcbiAgICAgIGNvbnN0IGV4aXN0aW5nRW50aXR5ID0gY29uZGl0aW9ucy5jb250cm9scy5zb21lKGN0cmwgPT4gY3RybC5nZXQoXCJlbnRpdHlcIik/LnZhbHVlID09PSBlbnRpdHlUeXBlKTtcblxuICAgICAgaWYgKGV4aXN0aW5nRW50aXR5KSB7XG4gICAgICAgIHRoaXMuY2FsbFNuYWNrYmFyKGAke2VudGl0eVR5cGUudG9VcHBlckNhc2UoKX0gaXMgYWxyZWFkeSBhZGRlZCBpbiB0aGlzIHVzZXIgZ3JvdXBgLCBcImVycm9yXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGxhc3QgY29uZGl0aW9uJ3Mgc2VsZWN0aW9ucyBhcmUgZW1wdHlcbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBsYXN0Q29uZGl0aW9uID0gY29uZGl0aW9ucy5hdChjb25kaXRpb25zLmxlbmd0aCAtIDEpO1xuICAgICAgY29uc3Qgc2VsZWN0aW9ucyA9IGxhc3RDb25kaXRpb24uZ2V0KFwic2VsZWN0aW9uc1wiKT8udmFsdWUgfHwgW107XG4gICAgICBpZiAoc2VsZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5jYWxsU25hY2tiYXIoXCJQbGVhc2Ugc2VsZWN0IGEgdmFsdWUgZm9yIHRoZSBjdXJyZW50IGNvbmRpdGlvbiBiZWZvcmUgYWRkaW5nIGFub3RoZXIgb25lLlwiLCBcImVycm9yXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uZGl0aW9ucy5wdXNoKHRoaXMuY3JlYXRlQ29uZGl0aW9uR3JvdXAodXVpZHY0KCksIHVzZXJHcm91cEluZGV4KSk7XG4gIH1cblxuICBjcmVhdGVDb25kaXRpb25Hcm91cChpZDogbnVtYmVyLCB1c2VyR3JvdXBJbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICBsZXQgZW50aXR5ID0gXCJcIjtcbiAgICBjb25zdCBhY2Nlc3NTZXR0aW5nID0gdGhpcy5jb250ZW50Py5hY2Nlc3NTZXR0aW5nO1xuXG4gICAgaWYgKGFjY2Vzc1NldHRpbmcgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzU2V0dGluZy5NRE9fU1BFQ0lGSUMgfHwgYWNjZXNzU2V0dGluZyA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NTZXR0aW5nLkNVU1RPTUVfVVNFUikge1xuICAgICAgZW50aXR5ID1cbiAgICAgICAgYWNjZXNzU2V0dGluZyA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLklBY2Nlc3NTZXR0aW5nLk1ET19TUEVDSUZJQ1xuICAgICAgICAgID8gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9uc1xuICAgICAgICAgIDogTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuVXNlcnM7XG4gICAgICB0aGlzLmFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbi5vcHRpb25zRW50aXR5LmZvckVhY2goKGVsZTogTnNBY2Nlc3NDb250cm9sQ29uZmlnLklPcHRpb25zRW50aXR5KSA9PiB7XG4gICAgICAgIGVsZS5kaXNhYmxlZCA9IGVsZS52YWx1ZSAhPT0gZW50aXR5O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgaWQ6IFtpZF0sXG4gICAgICBlbnRpdHk6IFtlbnRpdHksIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgY29uZGl0aW9uVHlwZTogW3sgdmFsdWU6IFwiaXNcIiwgZGlzYWJsZWQ6IHRydWUgfSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBzZWxlY3Rpb25zOiBbW11dXG4gICAgfSk7XG4gIH1cblxuICBvbkVudGl0eUNoYW5nZSh1c2VyR3JvdXBJbmRleDogbnVtYmVyLCBjb25kaXRpb25JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMucnVsZUNvbmRpdGlvbnModXNlckdyb3VwSW5kZXgpO1xuICAgIGNvbnN0IGNvbmRpdGlvbiA9IGNvbmRpdGlvbnMuYXQoY29uZGl0aW9uSW5kZXgpO1xuICAgIGNvbnN0IHNlbGVjdGVkRW50aXR5ID0gY29uZGl0aW9uPy5nZXQoXCJlbnRpdHlcIik/LnZhbHVlO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHNhbWUgZW50aXR5IGlzIGFscmVhZHkgc2VsZWN0ZWQgaW4gYW5vdGhlciBjb25kaXRpb24gb2YgdGhpcyB1c2VyIGdyb3VwXG4gICAgY29uc3QgaXNEdXBsaWNhdGUgPSBjb25kaXRpb25zLmNvbnRyb2xzLnNvbWUoKGN0cmwsIGluZGV4KSA9PiB7XG4gICAgICByZXR1cm4gaW5kZXggIT09IGNvbmRpdGlvbkluZGV4ICYmIGN0cmwuZ2V0KFwiZW50aXR5XCIpPy52YWx1ZSA9PT0gc2VsZWN0ZWRFbnRpdHk7XG4gICAgfSk7XG5cbiAgICBpZiAoaXNEdXBsaWNhdGUpIHtcbiAgICAgIHRoaXMuY2FsbFNuYWNrYmFyKGAke3NlbGVjdGVkRW50aXR5Py50b1VwcGVyQ2FzZSgpfSBpcyBhbHJlYWR5IHNlbGVjdGVkIGluIHRoaXMgdXNlciBncm91cGAsIFwiZXJyb3JcIik7XG4gICAgICBjb25kaXRpb24uZ2V0KFwiZW50aXR5XCIpPy5zZXRWYWx1ZShcIlwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29uZGl0aW9uPy52YWx1ZT8uc2VsZWN0aW9ucz8ubGVuZ3RoKSB7XG4gICAgICBjb25kaXRpb24uZ2V0KFwic2VsZWN0aW9uc1wiKT8uc2V0VmFsdWUoW10pO1xuICAgIH1cbiAgfVxuXG4gIGdldEF2YWlsYWJsZUVudGl0aWVzKHVzZXJHcm91cEluZGV4OiBudW1iZXIsIGN1cnJlbnRDb25kaXRpb25JbmRleDogbnVtYmVyKTogeyB2YWx1ZTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMucnVsZUNvbmRpdGlvbnModXNlckdyb3VwSW5kZXgpO1xuICAgIGNvbnN0IHNlbGVjdGVkRW50aXRpZXMgPSBjb25kaXRpb25zLmNvbnRyb2xzXG4gICAgICAubWFwKChjdHJsLCBpZHgpID0+IChpZHggIT09IGN1cnJlbnRDb25kaXRpb25JbmRleCA/IGN0cmwuZ2V0KFwiZW50aXR5XCIpPy52YWx1ZSA6IG51bGwpKVxuICAgICAgLmZpbHRlcihlID0+ICEhZSk7XG4gICAgcmV0dXJuIHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uPy5vcHRpb25zRW50aXR5LmZpbHRlcihvcHRpb24gPT4gIXNlbGVjdGVkRW50aXRpZXMuaW5jbHVkZXMob3B0aW9uLnZhbHVlKSk7XG4gIH1cblxuICByZW1vdmVVc2VyR3JvdXAoaW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IGdyb3VwID0gdGhpcy51c2VyR3JvdXAuYXQoaW5kZXgpO1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgd2lkdGg6IFwiNDcwcHhcIixcbiAgICAgIGRhdGE6IHsgYWRkaXRpb25hbERhdGE6IGdyb3VwPy52YWx1ZT8ubmFtZSwgdHlwZTogXCJkZWxldGVcIiB9XG4gICAgfSk7XG4gICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWN0aW9ucy5Db25maXJtKSB7XG4gICAgICAgIHRoaXMudXNlckdyb3VwLnJlbW92ZUF0KGluZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJlc2V0VXNlckdyb3VwKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBncm91cCA9IHRoaXMudXNlckdyb3VwLmF0KGluZGV4KTtcbiAgICBpZiAoZ3JvdXApIHtcbiAgICAgIGdyb3VwLmdldChcIm5hbWVcIik/LnNldFZhbHVlKGBVc2VyIEdyb3VwICR7aW5kZXggKyAxfWApO1xuICAgICAgZ3JvdXAuZ2V0KFwiZGVzY3JpcHRpb25cIik/LnNldFZhbHVlKGBEZXNjcmlwdGlvbiBmb3IgVXNlckdyb3VwICR7aW5kZXggKyAxfWApO1xuICAgICAgY29uc3QgY29uZGl0aW9ucyA9IGdyb3VwLmdldChcImNvbmRpdGlvbnNcIikgYXMgRm9ybUFycmF5O1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25kaXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGlkID0gY29uZGl0aW9ucy5hdChpKS5nZXQoXCJpZFwiKT8udmFsdWU7XG4gICAgICAgIGNvbmRpdGlvbnMuc2V0Q29udHJvbChpLCB0aGlzLmNyZWF0ZUNvbmRpdGlvbkdyb3VwKGlkLCBpbmRleCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUNvbmRpdGlvbih1c2VyR3JvdXBJbmRleDogbnVtYmVyLCBjb25kaXRpb25JbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHRoaXMucnVsZUNvbmRpdGlvbnModXNlckdyb3VwSW5kZXgpO1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgd2lkdGg6IFwiNDcwcHhcIixcbiAgICAgIGRhdGE6IHsgYWRkaXRpb25hbERhdGE6IFwidGhpcyBjb25kaXRpb25cIiwgdHlwZTogXCJkZWxldGVcIiB9XG4gICAgfSk7XG4gICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWN0aW9ucy5Db25maXJtKSB7XG4gICAgICAgIGNvbmRpdGlvbnMucmVtb3ZlQXQoY29uZGl0aW9uSW5kZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmVzZXRDb25kaXRpb24odXNlckdyb3VwSW5kZXg6IG51bWJlciwgY29uZGl0aW9uSW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLnJ1bGVDb25kaXRpb25zKHVzZXJHcm91cEluZGV4KTtcbiAgICBjb25zdCBjb25kaXRpb24gPSBjb25kaXRpb25zLmF0KGNvbmRpdGlvbkluZGV4KTtcbiAgICBpZiAoY29uZGl0aW9uKSB7XG4gICAgICBjb25zdCBpZCA9IGNvbmRpdGlvbi5nZXQoXCJpZFwiKT8udmFsdWUgfHwgdXVpZHY0KCk7XG4gICAgICBjb25kaXRpb25zLnNldENvbnRyb2woY29uZGl0aW9uSW5kZXgsIHRoaXMuY3JlYXRlQ29uZGl0aW9uR3JvdXAoaWQsIHVzZXJHcm91cEluZGV4KSk7XG4gICAgfVxuICB9XG5cbiAgbWFuYWdlU2VsZWN0aW9ucyhjb25kaXRpb246IGFueSwgcnVsZTogYW55LCB1c2VyR3JvdXBJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgc3dpdGNoIChjb25kaXRpb24udmFsdWUuZW50aXR5KSB7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlVzZXJzOlxuICAgICAgICB0aGlzLm9wZW5JbnZpdGVVc2VyRGlhbG9nKGNvbmRpdGlvbj8udmFsdWUsIHJ1bGU/LnZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLk9yZ2FuaXphdGlvbnM6XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkRlc2lnbmF0aW9uOlxuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlOlxuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZTpcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuQmF0Y2g6XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkdyb3VwOlxuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5WZXJpZmljYXRpb25TdGF0dXM6XG4gICAgICAgIHRoaXMucHJvY2Vzc0NhZHJlQ29uZmlnTWFwcGluZyh1c2VyR3JvdXBJbmRleCk7XG4gICAgICAgIHRoaXMub3BlblNlbGVjdGlvbkRpYWxvZyhydWxlPy52YWx1ZSwgY29uZGl0aW9uPy52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS53YXJuKFwiVW5zdXBwb3J0ZWQgZW50aXR5IHR5cGU6XCIsIGNvbmRpdGlvbi52YWx1ZS5lbnRpdHkpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5TZWxlY3Rpb25EaWFsb2cocnVsZTogYW55LCBjb25kaXRpb246IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IG9yaWdpbmFsU2VsZWN0aW9ucyA9IFsuLi4oY29uZGl0aW9uLnNlbGVjdGlvbnMgfHwgW10pXTtcblxuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oRW50aXR5U2VsZWN0aW9uc0NvbXBvbmVudCwge1xuICAgICAgd2lkdGg6IFwiMTAzMnB4XCIsXG4gICAgICBkYXRhOiB7IHJ1bGU6IHJ1bGUsIGNvbmRpdGlvbjogY29uZGl0aW9uLCBzZWxlY3RlZDogY29uZGl0aW9uLnNlbGVjdGlvbnMgfVxuICAgIH0pO1xuXG4gICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIEZpbmQgdGhlIHJ1bGUgRm9ybUdyb3VwIGluIHRoZSBGb3JtQXJyYXlcbiAgICAgICAgY29uc3QgcnVsZUluZGV4ID0gdGhpcy51c2VyR3JvdXAuY29udHJvbHMuZmluZEluZGV4KChjdHJsOiBhbnkpID0+IGN0cmwuZ2V0KFwiaWRcIik/LnZhbHVlID09PSByZXN1bHQucnVsZS5pZCk7XG4gICAgICAgIGlmIChydWxlSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgY29uc3QgcnVsZUdyb3VwID0gdGhpcy51c2VyR3JvdXAuYXQocnVsZUluZGV4KTtcbiAgICAgICAgICBjb25zdCBjb25kaXRpb25zID0gcnVsZUdyb3VwLmdldChcImNvbmRpdGlvbnNcIikgYXMgRm9ybUFycmF5O1xuICAgICAgICAgIGNvbnN0IGNvbmRpdGlvbkluZGV4ID0gY29uZGl0aW9ucy5jb250cm9scy5maW5kSW5kZXgoKGN0cmw6IGFueSkgPT4gY3RybC5nZXQoXCJpZFwiKT8udmFsdWUgPT09IHJlc3VsdC5jb25kaXRpb24uaWQpO1xuXG4gICAgICAgICAgaWYgKGNvbmRpdGlvbkluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgY29uZGl0aW9uR3JvdXAgPSBjb25kaXRpb25zLmF0KGNvbmRpdGlvbkluZGV4KTtcbiAgICAgICAgICAgIGNvbmRpdGlvbkdyb3VwLmdldChcInNlbGVjdGlvbnNcIik/LnNldFZhbHVlKHJlc3VsdC5zZWxlY3RlZCk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgY29uZGl0aW9uLmVudGl0eSA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9ucyAmJlxuICAgICAgICAgICAgICAhdGhpcy5hcmVTZWxlY3Rpb25zRXF1YWwob3JpZ2luYWxTZWxlY3Rpb25zLCByZXN1bHQuc2VsZWN0ZWQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVzaWduYXRpb25Db25kaXRpb24gPSBjb25kaXRpb25zLmNvbnRyb2xzLmZpbmQoXG4gICAgICAgICAgICAgICAgY3RybCA9PiBjdHJsLmdldChcImVudGl0eVwiKT8udmFsdWUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkRlc2lnbmF0aW9uXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgaWYgKGRlc2lnbmF0aW9uQ29uZGl0aW9uKSB7XG4gICAgICAgICAgICAgICAgZGVzaWduYXRpb25Db25kaXRpb24uZ2V0KFwic2VsZWN0aW9uc1wiKT8uc2V0VmFsdWUoW10pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc0NhZHJlQ29uZmlnTWFwcGluZyhydWxlSW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhcmVTZWxlY3Rpb25zRXF1YWwoY29udGVudF8xOiBhbnlbXSwgY29udGVudF8yOiBhbnlbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChjb250ZW50XzEubGVuZ3RoICE9PSBjb250ZW50XzIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGNvbnRlbnRfMS5ldmVyeShpdGVtID0+IGNvbnRlbnRfMi5pbmNsdWRlcyhpdGVtKSk7XG4gIH1cblxuICBwcm9jZXNzQ2FkcmVDb25maWdNYXBwaW5nKHVzZXJHcm91cEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBydWxlR3JvdXAgPSB0aGlzLnVzZXJHcm91cC5hdCh1c2VyR3JvdXBJbmRleCk7XG4gICAgY29uc3QgY29uZGl0aW9uVmFsdWUgPSBydWxlR3JvdXAuZ2V0KFwiY29uZGl0aW9uc1wiKS52YWx1ZTtcbiAgICBpZiAoY29uZGl0aW9uVmFsdWUgJiYgY29uZGl0aW9uVmFsdWUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzZXJ2aWNlcyA9IGNvbmRpdGlvblZhbHVlLmZpbmQoKGVsZTogYW55KSA9PiBlbGUuZW50aXR5ID09PSBcInNlcnZpY2VcIik7XG4gICAgICBjb25zdCBjYWRyZSA9IGNvbmRpdGlvblZhbHVlLmZpbmQoKGVsZTogYW55KSA9PiBlbGUuZW50aXR5ID09PSBcImNhZHJlXCIpO1xuICAgICAgY29uc3QgYmF0Y2ggPSBjb25kaXRpb25WYWx1ZS5maW5kKChlbGU6IGFueSkgPT4gZWxlLmVudGl0eSA9PT0gXCJiYXRjaFwiKTtcbiAgICAgIGNvbnN0IHNlcnZpY2VTZWxlY3Rpb25zID0gc2VydmljZXM/LnNlbGVjdGlvbnMgfHwgW107XG4gICAgICBjb25zdCBjYWRyZVNlbGVjdGlvbnMgPSBjYWRyZT8uc2VsZWN0aW9ucyB8fCBbXTtcbiAgICAgIGNvbnN0IGJhdGNoU2VsZWN0aW9ucyA9IGJhdGNoPy5zZWxlY3Rpb25zIHx8IFtdO1xuICAgICAgLy8gQ2FzZSAxOiBPbmx5IHNlcnZpY2Ugc2VsZWN0ZWRcbiAgICAgIGlmIChzZXJ2aWNlU2VsZWN0aW9ucz8ubGVuZ3RoICYmICFjYWRyZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiAhYmF0Y2hTZWxlY3Rpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2gudXBkYXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIHNlcnZpY2U6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRBbGxTZXJ2aWNlcygpLFxuICAgICAgICAgIGNhZHJlOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0Q2FkcmVzQnlTZXJ2aWNlcyhzZXJ2aWNlU2VsZWN0aW9ucyksXG4gICAgICAgICAgYmF0Y2g6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRCYXRjaFllYXJzQnlTZXJ2aWNlcyhzZXJ2aWNlU2VsZWN0aW9ucylcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgICAgLy8gQ2FzZSAyOiBPbmx5IGNhZHJlIHNlbGVjdGVkXG4gICAgICBlbHNlIGlmICghc2VydmljZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiBjYWRyZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiAhYmF0Y2hTZWxlY3Rpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2gudXBkYXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIGNhZHJlOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0QWxsQ2FkcmVzKCksXG4gICAgICAgICAgc2VydmljZTogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldFNlcnZpY2VzQnlDYWRyZXMoY2FkcmVTZWxlY3Rpb25zKSxcbiAgICAgICAgICBiYXRjaDogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldEJhdGNoWWVhcnNCeVNlcnZpY2VzKGNhZHJlU2VsZWN0aW9ucylcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgICAgLy8gQ2FzZSAzOiBPbmx5IGJhdGNoIHNlbGVjdGVkXG4gICAgICBlbHNlIGlmICghc2VydmljZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiAhY2FkcmVTZWxlY3Rpb25zPy5sZW5ndGggJiYgYmF0Y2hTZWxlY3Rpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2gudXBkYXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIGJhdGNoOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0QWxsQmF0Y2hZZWFycygpLFxuICAgICAgICAgIHNlcnZpY2U6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRTZXJ2aWNlc0J5QmF0Y2hZZWFycyhiYXRjaFNlbGVjdGlvbnMpLFxuICAgICAgICAgIGNhZHJlOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0Q2FkcmVzQnlCYXRjaFllYXJzKGJhdGNoU2VsZWN0aW9ucylcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgICAgLy8gQ2FzZSA0OiBTZXJ2aWNlIGFuZCBDYWRyZSBzZWxlY3RlZFxuICAgICAgZWxzZSBpZiAoc2VydmljZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiBjYWRyZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiAhYmF0Y2hTZWxlY3Rpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2gudXBkYXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIHNlcnZpY2U6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRTZXJ2aWNlc0J5Q2FkcmVzKGNhZHJlU2VsZWN0aW9ucyksXG4gICAgICAgICAgY2FkcmU6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRDYWRyZXNCeVNlcnZpY2VzKHNlcnZpY2VTZWxlY3Rpb25zKSxcbiAgICAgICAgICBiYXRjaDogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldEJhdGNoWWVhcnNCeVNlcnZpY2VzQW5kQ2FkcmVzKHNlcnZpY2VTZWxlY3Rpb25zLCBjYWRyZVNlbGVjdGlvbnMpXG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICAgIC8vIENhc2UgNTogU2VydmljZSBhbmQgQmF0Y2ggc2VsZWN0ZWRcbiAgICAgIGVsc2UgaWYgKHNlcnZpY2VTZWxlY3Rpb25zPy5sZW5ndGggJiYgIWNhZHJlU2VsZWN0aW9ucz8ubGVuZ3RoICYmIGJhdGNoU2VsZWN0aW9ucz8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2UuaG9sZFNlcnZpY2VDYWRyZWJhdGNoLnVwZGF0ZShwcmV2ID0+ICh7XG4gICAgICAgICAgLi4ucHJldixcbiAgICAgICAgICBjYWRyZTogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldENhZHJlc0J5U2VydmljZXNBbmRCYXRjaChzZXJ2aWNlU2VsZWN0aW9ucywgYmF0Y2hTZWxlY3Rpb25zKSxcbiAgICAgICAgICBzZXJ2aWNlOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0U2VydmljZXNCeUNhZHJlc0FuZEJhdGNoKGNhZHJlU2VsZWN0aW9ucywgYmF0Y2hTZWxlY3Rpb25zKSxcbiAgICAgICAgICBiYXRjaDogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldEJhdGNoWWVhcnNCeVNlcnZpY2VzQW5kQ2FkcmVzKHNlcnZpY2VTZWxlY3Rpb25zLCBjYWRyZVNlbGVjdGlvbnMpXG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICAgIC8vIENhc2UgNjogQ2FkcmUgYW5kIEJhdGNoIHNlbGVjdGVkXG4gICAgICBlbHNlIGlmICghc2VydmljZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiBjYWRyZVNlbGVjdGlvbnM/Lmxlbmd0aCAmJiBiYXRjaFNlbGVjdGlvbnM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLmhvbGRTZXJ2aWNlQ2FkcmViYXRjaC51cGRhdGUocHJldiA9PiAoe1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgICAgc2VydmljZTogdGhpcy5jYWRyZU1hcHBpbmdTZXJ2aWNlLmdldFNlcnZpY2VzQnlDYWRyZXNBbmRCYXRjaChjYWRyZVNlbGVjdGlvbnMsIGJhdGNoU2VsZWN0aW9ucyksXG4gICAgICAgICAgY2FkcmU6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRDYWRyZXNCeVNlcnZpY2VzQW5kQmF0Y2goc2VydmljZVNlbGVjdGlvbnMsIGJhdGNoU2VsZWN0aW9ucyksXG4gICAgICAgICAgYmF0Y2g6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRCYXRjaFllYXJzQnlTZXJ2aWNlc0FuZENhZHJlcyhzZXJ2aWNlU2VsZWN0aW9ucywgY2FkcmVTZWxlY3Rpb25zKVxuICAgICAgICB9KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLmhvbGRTZXJ2aWNlQ2FkcmViYXRjaC5zZXQoe1xuICAgICAgICAgIHNlcnZpY2U6IHRoaXMuY2FkcmVNYXBwaW5nU2VydmljZS5nZXRBbGxTZXJ2aWNlcygpLFxuICAgICAgICAgIGJhdGNoOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0QWxsQmF0Y2hZZWFycygpLFxuICAgICAgICAgIGNhZHJlOiB0aGlzLmNhZHJlTWFwcGluZ1NlcnZpY2UuZ2V0QWxsQ2FkcmVzKClcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb3Blbkludml0ZVVzZXJEaWFsb2coY29uZGl0aW9uOiBhbnksIHJ1bGU6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oSW52aXRlVXNlcnNDb21wb25lbnQsIHtcbiAgICAgIHdpZHRoOiBcIjEwOTBweFwiLFxuICAgICAgZGF0YTogeyBjb25kaXRpb246IGNvbmRpdGlvbiwgcnVsZTogcnVsZSwgc2VsZWN0ZWQ6IGNvbmRpdGlvbi5zZWxlY3Rpb25zIH1cbiAgICB9KTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAvLyBGaW5kIHRoZSBydWxlIEZvcm1Hcm91cCBpbiB0aGUgRm9ybUFycmF5XG4gICAgICAgIGNvbnN0IHJ1bGVJbmRleCA9IHRoaXMudXNlckdyb3VwLmNvbnRyb2xzLmZpbmRJbmRleCgoY3RybDogYW55KSA9PiBjdHJsLmdldChcImlkXCIpPy52YWx1ZSA9PT0gcmVzdWx0LnJ1bGUuaWQpO1xuICAgICAgICBpZiAocnVsZUluZGV4ICE9PSAtMSkge1xuICAgICAgICAgIGNvbnN0IHJ1bGVHcm91cCA9IHRoaXMudXNlckdyb3VwLmF0KHJ1bGVJbmRleCk7XG4gICAgICAgICAgY29uc3QgY29uZGl0aW9ucyA9IHJ1bGVHcm91cC5nZXQoXCJjb25kaXRpb25zXCIpIGFzIEZvcm1BcnJheTtcbiAgICAgICAgICBjb25zdCBjb25kaXRpb25JbmRleCA9IGNvbmRpdGlvbnMuY29udHJvbHMuZmluZEluZGV4KChjdHJsOiBhbnkpID0+IGN0cmwuZ2V0KFwiaWRcIik/LnZhbHVlID09PSByZXN1bHQuY29uZGl0aW9uLmlkKTtcbiAgICAgICAgICBpZiAoY29uZGl0aW9uSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBjb25kaXRpb25Hcm91cCA9IGNvbmRpdGlvbnMuYXQoY29uZGl0aW9uSW5kZXgpO1xuICAgICAgICAgICAgLy8gY29uc3QgdXNlcklkcyA9IHJlc3VsdC5zZWxlY3RlZCAmJiByZXN1bHQuc2VsZWN0ZWQubWFwKCh1c2VyOiBhbnkpID0+IHVzZXI/LnVzZXJJZCk7XG4gICAgICAgICAgICBjb25kaXRpb25Hcm91cC5nZXQoXCJzZWxlY3Rpb25zXCIpPy5zZXRWYWx1ZShyZXN1bHQuc2VsZWN0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgY2FsbFNuYWNrYmFyKG1lc3NhZ2U6IHN0cmluZywgdHlwZTogXCJzdWNjZXNzXCIgfCBcImVycm9yXCIpOiB2b2lkIHtcbiAgICBpZiAodHlwZSA9PT0gXCJzdWNjZXNzXCIpIHtcbiAgICAgIHRoaXMuc25hY2tiYXIub3BlbkZyb21Db21wb25lbnQoU25hY2tiYXJDb21wb25lbnQsIHtcbiAgICAgICAgZGF0YTogeyBtZXNzYWdlOiBtZXNzYWdlLCB0eXBlOiBcInN1Y2Nlc3NcIiB9LFxuICAgICAgICBkdXJhdGlvbjogMzAwMCxcbiAgICAgICAgcGFuZWxDbGFzczogXCJjb3Vyc2Utc3VjY2Vzcy1zbmFja2JhclwiXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgdGhpcy5zbmFja2Jhci5vcGVuRnJvbUNvbXBvbmVudChTbmFja2JhckNvbXBvbmVudCwge1xuICAgICAgICBkYXRhOiB7IG1lc3NhZ2U6IG1lc3NhZ2UsIHR5cGU6IFwiZXJyb3JcIiB9LFxuICAgICAgICBkdXJhdGlvbjogMzAwMCxcbiAgICAgICAgcGFuZWxDbGFzczogXCJjb3Vyc2UtZXJyb3Itc25hY2tiYXJcIlxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYXBwbHlBY2Nlc3NDb250cm9sVmFsdWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY29udGVudD8uc3RhdHVzID09PSBcIkRyYWZ0XCIpIHRoaXMuaXNTYXZpbmcgPSB0cnVlO1xuICAgIGVsc2UgaWYgKHRoaXMuY29udGVudD8uc3RhdHVzID09PSBcIkxpdmVcIikgdGhpcy5pc0FwcGx5aW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgdGhpcy5wcm9jZXNzUmVxdWVzdENyZWF0aW9uKCk7XG4gICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5hcHBseVVzZXJHcm91cEFjY2Vzc0NvbnRyb2wocGF5bG9hZCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKHJlc3BvbnNlPy5yZXN1bHQgJiYgcmVzcG9uc2U/LnJlc3VsdD8uYWNjZXNzQ29udHJvbCkge1xuICAgICAgICAgIHRoaXMuYWNjZXNzQ29udHJvbERhdGEuZW1pdCh7IHVzZXJHcm91cDogcmVzcG9uc2UucmVzdWx0LmFjY2Vzc0NvbnRyb2w/LnVzZXJHcm91cCwgYWNjZXNzVHlwZTogdGhpcy5hY2Nlc3NUeXBlIH0pO1xuICAgICAgICAgIHRoaXMuY2FsbFNuYWNrYmFyKFwiQWNjZXNzIENvbnRyb2wgc2F2ZWQgc3VjY2Vzc2Z1bGx5XCIsIFwic3VjY2Vzc1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbGxTbmFja2JhcihcIkNvdWxkIG5vdCBzYXZlIGFjY2VzcyBjb250cm9sLCBQbGVhc2UgdHJ5IGFnYWluLlwiLCBcImVycm9yXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29udGVudD8uc3RhdHVzID09PSBcIkRyYWZ0XCIpIHRoaXMuaXNTYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodGhpcy5jb250ZW50Py5zdGF0dXMgPT09IFwiTGl2ZVwiKSB0aGlzLmlzQXBwbHlpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNhbGxTbmFja2JhcihcIkNvdWxkIG5vdCBzYXZlIGFjY2VzcyBjb250cm9sLCBQbGVhc2UgdHJ5IGFnYWluLlwiLCBcImVycm9yXCIpO1xuICAgICAgICBpZiAodGhpcy5jb250ZW50Py5zdGF0dXMgPT09IFwiRHJhZnRcIikgdGhpcy5pc1NhdmluZyA9IGZhbHNlO1xuICAgICAgICBlbHNlIGlmICh0aGlzLmNvbnRlbnQ/LnN0YXR1cyA9PT0gXCJMaXZlXCIpIHRoaXMuaXNBcHBseWluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJvY2Vzc1JlcXVlc3RDcmVhdGlvbigpOiBQcm9taXNlPElVc2VyR3JvdXBSZXF1ZXN0PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmFjY2Vzc0NvbnRyb2xGb3JtLnZhbHVlO1xuXG4gICAgICAgIGNvbnN0IHVzZXJHcm91cHMgPSBkYXRhLnVzZXJHcm91cC5tYXAoKGdyb3VwOiBhbnkpID0+ICh7XG4gICAgICAgICAgdXNlckdyb3VwTmFtZTogZ3JvdXAubmFtZSxcbiAgICAgICAgICB1c2VyR3JvdXBDcml0ZXJpYUxpc3Q6IGdyb3VwLmNvbmRpdGlvbnMubWFwKChjb25kaXRpb246IGFueSkgPT4ge1xuICAgICAgICAgICAgbGV0IGNyaXRlcmlhVmFsdWU6IHN0cmluZ1tdO1xuXG4gICAgICAgICAgICBpZiAoY29uZGl0aW9uPy5lbnRpdHkgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlVzZXJzICYmIGNvbmRpdGlvbj8uc2VsZWN0ZWQ/Lmxlbmd0aCAmJiBjb25kaXRpb24/LnNlbGVjdGVkWzBdPy51c2VySWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdXNlcklkcyA9IGNvbmRpdGlvbi5zZWxlY3RlZD8ubWFwKCh1c2VyOiBhbnkpID0+IHVzZXI/LnVzZXJJZCkgfHwgW107XG4gICAgICAgICAgICAgIGNyaXRlcmlhVmFsdWUgPSB1c2VySWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3JpdGVyaWFWYWx1ZSA9IGNvbmRpdGlvbi5zZWxlY3Rpb25zPy5tYXAoU3RyaW5nKSB8fCBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgY3JpdGVyaWFLZXk6IGNvbmRpdGlvbi5lbnRpdHksXG4gICAgICAgICAgICAgIGNyaXRlcmlhVmFsdWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSlcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RQYXlsb2FkOiBJVXNlckdyb3VwUmVxdWVzdCA9IHtcbiAgICAgICAgICBjb250ZW50SWQ6IHRoaXMuY29udGVudElkLFxuICAgICAgICAgIGFjY2Vzc0NvbnRyb2w6IHtcbiAgICAgICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgICAgICB1c2VyR3JvdXBzXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHJlc29sdmUocmVxdWVzdFBheWxvYWQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG9wZW5JbnN0cnVjdG9uc0RpYWxvZygpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZy5vcGVuKEFjY2Vzc0NvbnRyb2xHdWlkZUNvbXBvbmVudCwge1xuICAgICAgd2lkdGg6IFwiOTYwcHhcIlxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZ2V0QWNjZXNzQ29udHJvbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2VcbiAgICAgIC5mZXRjaFVzZXJHcm91cEFjY2Vzc0NvbnRyb2wodGhpcy5jb250ZW50SWQpXG4gICAgICAudG9Qcm9taXNlKClcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWNjZXNzQ29udHJvbERhdGEuZW1pdCh7IHVzZXJHcm91cDogdGhpcy5hY2Nlc3NDb250cm9sRm9ybS52YWx1ZT8udXNlckdyb3VwLCBhY2Nlc3NUeXBlOiB0aGlzLmFjY2Vzc1R5cGUgfSk7XG4gICAgICB9KTtcbiAgICBpZiAocmVzcG9uc2U/LnJlc3VsdD8uYWNjZXNzQ29udHJvbCkge1xuICAgICAgdGhpcy5wcm9jZXNzQWNjZXNzQ29udHJvbFJlc3VsdChyZXNwb25zZS5yZXN1bHQuYWNjZXNzQ29udHJvbCk7XG4gICAgICB0aGlzLmFjY2Vzc0NvbnRyb2xEYXRhLmVtaXQoeyB1c2VyR3JvdXA6IHJlc3BvbnNlLnJlc3VsdC5hY2Nlc3NDb250cm9sPy51c2VyR3JvdXAsIGFjY2Vzc1R5cGU6IHRoaXMuYWNjZXNzVHlwZSB9KTtcbiAgICB9XG4gIH1cblxuICBwcm9jZXNzQWNjZXNzQ29udHJvbFJlc3VsdChhY2Nlc3NDb250cm9sOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoIWFjY2Vzc0NvbnRyb2w/LnVzZXJHcm91cHM/Lmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgd2hpbGUgKHRoaXMudXNlckdyb3VwLmxlbmd0aCkge1xuICAgICAgdGhpcy51c2VyR3JvdXAucmVtb3ZlQXQoMCk7XG4gICAgfVxuXG4gICAgYWNjZXNzQ29udHJvbC51c2VyR3JvdXBzLmZvckVhY2goKGdyb3VwOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IGNvbmRpdGlvbnMgPSB0aGlzLmZiLmFycmF5KFtdKSBhcyBhbnk7XG5cbiAgICAgIGdyb3VwLnVzZXJHcm91cENyaXRlcmlhTGlzdC5mb3JFYWNoKChjcml0ZXJpYTogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuY3JlYXRlQ29uZGl0aW9uR3JvdXAodXVpZHY0KCksIHRoaXMudXNlckdyb3VwLmxlbmd0aCk7XG5cbiAgICAgICAgLy8gTWFwIEFQSSBrZXlzIHRvIGZvcm0gZW50aXR5IHZhbHVlc1xuICAgICAgICBjb25zdCBlbnRpdHlNYXA6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgcm9vdE9yZ0lkOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Pcmdhbml6YXRpb25zLFxuICAgICAgICAgIHVzZXI6IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlVzZXJzLFxuICAgICAgICAgIGdyb3VwOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Hcm91cCxcbiAgICAgICAgICBkZXNpZ25hdGlvbjogTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuRGVzaWduYXRpb24sXG4gICAgICAgICAgcHJvZmlsZXN0YXR1czogTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuVmVyaWZpY2F0aW9uU3RhdHVzLFxuICAgICAgICAgIENhZHJlOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZSxcbiAgICAgICAgICBzZXJ2aWNlOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlLFxuICAgICAgICAgIGJhdGNoOiBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5CYXRjaFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB0aGUgZm9ybSB2YWx1ZXNcbiAgICAgICAgY29uZGl0aW9uLnBhdGNoVmFsdWUoe1xuICAgICAgICAgIGVudGl0eTogZW50aXR5TWFwW2NyaXRlcmlhLmNyaXRlcmlhS2V5XSB8fCBjcml0ZXJpYS5jcml0ZXJpYUtleSxcbiAgICAgICAgICBzZWxlY3Rpb25zOiBjcml0ZXJpYS5jcml0ZXJpYVZhbHVlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbmRpdGlvbnMucHVzaChjb25kaXRpb24pO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJ1bGVHcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICBpZDogW2dyb3VwLnVzZXJHcm91cElkIHx8IHV1aWR2NCgpXSxcbiAgICAgICAgbmFtZTogW2dyb3VwLnVzZXJHcm91cE5hbWVdLFxuICAgICAgICBkZXNjcmlwdGlvbjogW2BEZXNjcmlwdGlvbiBmb3IgJHtncm91cC51c2VyR3JvdXBOYW1lfWBdLFxuICAgICAgICBjb25kaXRpb25zOiBjb25kaXRpb25zXG4gICAgICB9KTtcblxuICAgICAgdGhpcy51c2VyR3JvdXAucHVzaChydWxlR3JvdXApO1xuICAgIH0pO1xuXG4gICAgaWYgKCF0aGlzLmNhZHJlQ29uZmlnRGF0YSkge1xuICAgICAgdGhpcy5mZXRjaENhZHJlQ29uZmlnRGF0YSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUNvbnRlbnRBY2Nlc3NTZXR0aW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFjY2Vzc1R5cGVCb29sZWFuID0gdGhpcy5hY2Nlc3NUeXBlID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuSUFjY2Vzc1R5cGVzLlB1YmxpYyA/IGZhbHNlIDogdHJ1ZTtcbiAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5jcmVhdGVSZXF1ZXN0Q29udGVudCh0aGlzLmNvbnRlbnQsIGFjY2Vzc1R5cGVCb29sZWFuKTtcbiAgICBhd2FpdCB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLnVwZGF0ZUNvbnRlbnRWMyhyZXF1ZXN0LCB0aGlzLmNvbnRlbnRJZCkudG9Qcm9taXNlKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJweS00IHB4LTEwXCI+XG4gIDxkaXYgY2xhc3M9XCJwLTQgYXMtY29udGFpbmVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXhsIGZvbnQtYm9sZCBwcmltYXJ5LXRleHQtY29sb3JcIj5BY2Nlc3MgQ29udHJvbDwvc3Bhbj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGdhcC0yIGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc20gcHJpbWFyeS10ZXh0LWNvbG9yIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cIm9wZW5JbnN0cnVjdG9uc0RpYWxvZygpXCI+SG93IHRvIHVzZSBhY2Nlc3MgY29udHJvbD88L3NwYW4+XG4gICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9zdXBwb3J0LWkuc3ZnXCIgYWx0PVwic3VwcG9ydCBpXCIgY2xhc3M9XCJpbWctaWNvbi0yNFwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibGlnaHQtZ3JleS1ib3JkZXIgcC00IG10LTRcIj5cbiAgICAgIDxtYXQtcmFkaW8tZ3JvdXAgWyhuZ01vZGVsKV09XCJhY2Nlc3NUeXBlXCIgKGNoYW5nZSk9XCJvbkFjY2Vzc1R5cGVDaGFuZ2UoJGV2ZW50KVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmFkaW8tY29udGFpbmVyIGZsZXggZ2FwLTUgbWItNFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uPy5hY2Nlc3NUeXBlc1wiPlxuICAgICAgICAgICAgPG1hdC1yYWRpby1idXR0b24gW3ZhbHVlXT1cIml0ZW0udmFsdWVcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTIgaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgaXRlbT8ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImluZm8tb3V0bGluZVwiIFttYXRUb29sdGlwXT1cIml0ZW0/LnRvb2x0aXBcIj48L21hdC1pY29uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L21hdC1yYWRpby1ncm91cD5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY2Nlc3NUeXBlID09PSBBQ0NFU1NfVFlQRV9FTlVNLlB1YmxpY1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5mby1jb250YWluZXJcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCI+VGhpcyBldmVudCB3aWxsIGJlIHZpc2libGUgdG8gYWxsIEthcm1heW9naXMuPC9sYWJlbD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY2Nlc3NUeXBlID09PSBBQ0NFU1NfVFlQRV9FTlVNLkN1c3RvbVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidmlzaWJpbGl5LWNvbnRhaW5lciBsaWdodC1ncmV5LWJvcmRlciBwLTRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW4gaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbGcgZm9udC1ib2xkXCI+VmlzaWJpbGl0eTwvc3Bhbj5cbiAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlIFsobmdNb2RlbCldPVwiaXNWaXNpYmlsaXR5RW5hYmxlZFwiPjwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVmlzaWJpbGl0eUVuYWJsZWRcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIj5LYXJtYXlvZ2lzIHdpbGwgTk9UIGJlIGFibGUgdG8gc2VhcmNoIGFuZCB2aWV3IHRoZSBkZXNjcmlwdGlvbiBwYWdlIG9mIHRoZSBldmVudC48L2xhYmVsPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1Zpc2liaWxpdHlFbmFibGVkXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCJcbiAgICAgICAgICAgICAgPkthcm1heW9naXMgd2lsbCBiZSBhYmxlIHRvIHNlYXJjaCBhbmQgdmlldyB0aGUgZGVzY3JpcHRpb24gcGFnZSBvZiB0aGUgZXZlbnQgYnV0IHdpbGwgbm90IGFibGUgdG8gZW5yb2xsIGlmIEthcm1heW9naSBkbyBub3Qgc2F0aXNmeSB0aGVcbiAgICAgICAgICAgICAgY29uZGl0aW9ucyBkZWZpbmVkIGluIHRoZSBhY2Nlc3MgY29udHJvbCBiZWxvdy48L2xhYmVsXG4gICAgICAgICAgICA+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXIgbXQtNCBtYi00XCI+XG4gICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNsYXNzPVwibmV3LXNlY29uZGFyeS1idXR0b24tbm8tYm9yZGVyIGJ1dHRvbi13aXRoLWNvcm5lcnNcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImZpbHRlckNyaXRlcmlhID0gIWZpbHRlckNyaXRlcmlhXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtMiBmbGV4LW1pZGRsZVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbVwiPkZpbHRlciBjcml0ZXJpYTwvc3Bhbj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwicHJpbWFyeS10ZXh0LWNvbG9yXCI+e3sgZmlsdGVyQ3JpdGVyaWEgPyBcInZpc2liaWxpdHlfb25cIiA6IFwidmlzaWJpbGl0eV9vZmZcIiB9fTwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+IC0tPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaWx0ZXJDcml0ZXJpYVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXItY3JpdGVyaWEtY29udGFpbmVyIGxpZ2h0LWdyZXktYm9yZGVyIHAtNCBtdC00IGZsZXggZmxleC1taWRkbGUganVzdGlmeS1iZXR3ZWVuIG1iLTRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbmZvXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zbVwiPkRlZmluZSB0aGUgY29uZGl0aW9ucyB0aGF0IEthcm1heW9naXMgbXVzdCBzYXRpc2Z5IHRvIGVucm9sbCBpbiB0aGUgZXZlbnQuPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY2xhc3M9XCJuZXctc2Vjb25kYXJ5LWJ1dHRvbi1uby1ib3JkZXIgYnV0dG9uLXdpdGgtY29ybmVyc1wiIHR5cGU9XCJidXR0b25cIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTIgZmxleC1taWRkbGVcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbVwiPlJlZnJlc2g8L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwicHJpbWFyeS10ZXh0LWNvbG9yXCI+cmVmcmVzaDwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY2Nlc3NDb250cm9sRm9ybSAmJiB1c2VyR3JvdXA/Lmxlbmd0aCA+IDAgJiYgIWlzTG9hZGluZ1wiPlxuICAgICAgICAgIDxmb3JtIFtmb3JtR3JvdXBdPVwiYWNjZXNzQ29udHJvbEZvcm1cIj5cbiAgICAgICAgICAgIDxtYXQtYWNjb3JkaW9uIGNsYXNzPVwiZXhhbXBsZS1oZWFkZXJzLWFsaWduIGFjY2Vzcy11c2VyZ3JvdXAtYWNjb3JkaW9uIG10LTNcIiBtdWx0aT1cInRydWVcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBmb3JtQXJyYXlOYW1lPVwidXNlckdyb3VwXCIgKm5nRm9yPVwibGV0IHJ1bGUgb2YgdXNlckdyb3VwPy5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgbGV0IHJ1bGVMYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwgY2xhc3M9XCJhY2Nlc3MtdXNlcmdyb3VwLXBhbmVsXCIgZXhwYW5kZWQ+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LXBhbmVsLXRpdGxlIGNsYXNzPVwiaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtc21cIj57eyBydWxlLmdldChcIm5hbWVcIik/LnZhbHVlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXBhbmVsLXRpdGxlPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtZGVzY3JpcHRpb24gY2xhc3M9XCJqdXN0aWZ5LWVuZCBpdGVtcy1jZW50ZXJcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBhcmlhLWxhYmVsPVwiZGVsZXRlIHVzZXIgZ3JvdXBcIiAoY2xpY2spPVwicmVtb3ZlVXNlckdyb3VwKGkpXCIgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGFyaWEtbGFiZWw9XCJyZWZyZXNoIHVzZXIgZ3JvdXBcIiAoY2xpY2spPVwicmVzZXRVc2VyR3JvdXAoaSlcIiB0aXRsZT1cIlJlZnJlc2hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnJlZnJlc2g8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJydWxlLmdldCgnY29uZGl0aW9ucycpIGFzIGNvbmRpdGlvbnNBcnJheVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW2Zvcm1BcnJheU5hbWVdPVwiJ2NvbmRpdGlvbnMnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb25kaXRpb24gb2YgY29uZGl0aW9uc0FycmF5Py5jb250cm9sczsgbGV0IGogPSBpbmRleDsgbGV0IGNvbmRpdGlvbmxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25kaXRpb24tc2VsZWN0aW9uIG10LTJcIiBbZm9ybUdyb3VwTmFtZV09XCJqXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdC1jb25kaXRpb24tdGV4dCBtYi0zIG10LTRcIj5TZWxlY3QgQ29uZGl0aW9uIHt7IGkgKyAxICsgXCIuXCIgKyAoaiArIDEpIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdGlvbnMtb3B0aW9ucyBncmlkIGdyaWQtY29scy01IGdhcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWZ1bGwtcmFkaXVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwidy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgcGxhY2Vob2xkZXI9XCJTZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJlbnRpdHlcIiAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uRW50aXR5Q2hhbmdlKGksIGopXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGdldEF2YWlsYWJsZUVudGl0aWVzKGksIGopXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJpdGVtPy52YWx1ZVwiIFtkaXNhYmxlZF09XCJpdGVtPy5kaXNhYmxlZFwiPnt7IGl0ZW0/LmxhYmVsIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWZ1bGwtcmFkaXVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIGNsYXNzPVwidy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgcGxhY2Vob2xkZXI9XCJTZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJjb25kaXRpb25UeXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbj8ub3B0aW9uc0NvbmRpdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIml0ZW0/LnZhbHVlXCI+e3sgaXRlbT8ubGFiZWwgfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tbWFuYWdlLXNlbGVjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0LWZsYXQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1hbmFnZVNlbGVjdGlvbnMoY29uZGl0aW9uLCBydWxlLCBpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFjb25kaXRpb24uZ2V0KCdlbnRpdHknKS52YWx1ZSB8fCAhY29uZGl0aW9uLmdldCgnY29uZGl0aW9uVHlwZScpLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJvdW5kZWQtZnVsbCBuZXctYmctY29sb3IgdGV4dC13aGl0ZSBtdC0yIGZsZXggaXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJzdmdfc2VhcmNoXCIgY2xhc3M9XCJtci0yXCI+PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtYm9sZCB0ZXh0LXNtXCI+TWFuYWdlIFNlbGVjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLW9wdGlvbnMtc2VsZWN0ZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNsYXNzPVwibmV3LXNlY29uZGFyeS1idXR0b24tbm8tYm9yZGVyIGJ1dHRvbi13aXRoLWNvcm5lcnMgbXQtMlwiIHR5cGU9XCJidXR0b25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtMiBmbGV4LW1pZGRsZSBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbSBjb2xvci1nciB1bmRlcmxpbmVcIj57eyBjb25kaXRpb24uZ2V0KFwic2VsZWN0aW9uc1wiKS52YWx1ZS5sZW5ndGggfX0gaXRlbXMgc2VsZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLW1vcmUtb3B0aW9ucyBmbGV4IGp1c3RpZnktZW5kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGdhcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gYXJpYS1sYWJlbD1cImRlbGV0ZSBjb25kaXRpb25cIiBjbGFzcz1cIm10LTIgbWwtYXV0b1wiIChjbGljayk9XCJyZW1vdmVDb25kaXRpb24oaSwgailcIiB0aXRsZT1cIkRlbGV0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gYXJpYS1sYWJlbD1cInJlZnJlc2ggY29uZGl0aW9uXCIgY2xhc3M9XCJtdC0yIG1sLWF1dG9cIiAoY2xpY2spPVwicmVzZXRDb25kaXRpb24oaSwgailcIiB0aXRsZT1cIlJlZnJlc2hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5yZWZyZXNoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbmQtb3IgbWF0LWZ1bGwtcmFkaXVzXCIgKm5nSWY9XCJjb25kaXRpb25zQXJyYXk/Lmxlbmd0aCA+IDEgJiYgIWNvbmRpdGlvbmxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInctbWF4LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgcGxhY2Vob2xkZXI9XCJTZWxlY3RcIiBbKHZhbHVlKV09XCJkZWZhdWx0Q29uZGl0aW9uUmVsYXRpb25zaGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCInQU5EJ1wiPkFORDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIidPUidcIj5PUjwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1hZGQtY29uZGl0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNsYXNzPVwibmV3LXNlY29uZGFyeS1idXR0b24tbm8tYm9yZGVyIGJ1dHRvbi13aXRoLWNvcm5lcnNcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFkZENvbmRpdGlvbihpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTIgZmxleC1taWRkbGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwicHJpbWFyeS10ZXh0LWNvbG9yXCI+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW1cIj5BZGQgQ29uZGl0aW9uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFuZC1vciBtYXQtZnVsbC1yYWRpdXNcIiAqbmdJZj1cInVzZXJHcm91cC5sZW5ndGggPiAxICYmICFydWxlTGFzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cInctbWF4LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IHBsYWNlaG9sZGVyPVwiU2VsZWN0XCIgWyh2YWx1ZSldPVwiZGVmYXVsdFVzZXJHcm91cFJlbGF0aW9uc2hpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIidBTkQnXCI+QU5EPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIidPUidcIj5PUjwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L21hdC1hY2NvcmRpb24+XG4gICAgICAgICAgPC9mb3JtPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItbG9hZGVyIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LXNwaW5uZXI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0xvYWRpbmdcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgbWItNiBtdC00XCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gY2xhc3M9XCJuZXctc2Vjb25kYXJ5LWJ1dHRvbi1uby1ib3JkZXIgYnV0dG9uLXdpdGgtY29ybmVyc1wiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWRkVXNlckdyb3VwKClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTIgZmxleC1taWRkbGVcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJwcmltYXJ5LXRleHQtY29sb3JcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tXCI+QWRkIFVzZXIgR3JvdXA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ1c2VyR3JvdXA/Lmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLXNhdmUgZmxleCBqdXN0aWZ5LWNlbnRlciBpdGVtcy1jZW50ZXIgZ2FwLTRcIj5cbiAgICAgICAgICAgIDwhLS0gU2F2ZSBGaWx0ZXIgQnV0dG9uIC0tPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXQtZmxhdC1idXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IHJvdW5kZWQtZnVsbCBweC00IHB5LTIgbWF0LWJ0bi1vdXRsaW5lIGZvbnQtYm9sZCB0ZXh0LXNtIGl0ZW1zLWNlbnRlciBnYXAtMlwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc1NhdmVGbHRyQnRuRGlzYWJsZWQgfHwgaXNTYXZpbmdcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlBY2Nlc3NDb250cm9sVmFsdWUoKVwiPlxuICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJpc1NhdmluZ1wiIGRpYW1ldGVyPVwiMThcIiBzdHJva2VXaWR0aD1cIjNcIiBjbGFzcz1cIiFpbmxpbmUgIW0tMCBtci0yXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgPHNwYW4+U2F2ZSBGaWx0ZXI8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgPCEtLSBBcHBseSBCdXR0b24gLS0+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG1hdC1mbGF0LWJ1dHRvblxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNBcHBseUJ0bkRpc2FibGVkIHx8IGlzQXBwbHlpbmdcIlxuICAgICAgICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHJvdW5kZWQtZnVsbCBweC00IHB5LTIgbmV3LWJnLWNvbG9yIGZvbnQtYm9sZCB0ZXh0LXNtIHRleHQtd2hpdGUgZ2FwLTJcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlBY2Nlc3NDb250cm9sVmFsdWUoKVwiPlxuICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJpc0FwcGx5aW5nXCIgZGlhbWV0ZXI9XCIxOFwiIHN0cm9rZVdpZHRoPVwiM1wiIGNsYXNzPVwiIWlubGluZSAhbS0wIG1yLTJcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICA8c3Bhbj5BcHBseTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19