@cqa-lib/cqa-ui 1.1.175 → 1.1.177

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 (39) hide show
  1. package/esm2020/lib/compare-runs/compare-runs.component.mjs +1 -1
  2. package/esm2020/lib/dynamic-select/dynamic-select-field.component.mjs +3 -3
  3. package/esm2020/lib/execution-screen/db-query-execution-item/db-query-execution-item.component.mjs +70 -5
  4. package/esm2020/lib/execution-screen/db-verification-step/db-verification-step.component.mjs +15 -3
  5. package/esm2020/lib/iterations-loop/iterations-loop.component.mjs +1 -1
  6. package/esm2020/lib/step-builder/step-builder-action/step-builder-action.component.mjs +29 -9
  7. package/esm2020/lib/step-builder/step-builder-condition/step-builder-condition.component.mjs +330 -0
  8. package/esm2020/lib/step-builder/step-builder-database/step-builder-database.component.mjs +205 -0
  9. package/esm2020/lib/table/dynamic-table/dynamic-table.component.mjs +35 -3
  10. package/esm2020/lib/templates/table-template.component.mjs +7 -4
  11. package/esm2020/lib/test-case-details/custom-edit-step/custom-edit-step-data.mjs +5 -0
  12. package/esm2020/lib/test-case-details/custom-edit-step/custom-edit-step-ref.mjs +32 -0
  13. package/esm2020/lib/test-case-details/custom-edit-step/custom-edit-step.component.mjs +71 -0
  14. package/esm2020/lib/test-case-details/custom-edit-step/custom-edit-step.service.mjs +97 -0
  15. package/esm2020/lib/test-case-details/normal-step/normal-step.component.mjs +59 -9
  16. package/esm2020/lib/ui-kit.module.mjs +18 -3
  17. package/esm2020/lib/utils/tw-overlay-container.mjs +6 -3
  18. package/esm2020/public-api.mjs +7 -1
  19. package/fesm2015/cqa-lib-cqa-ui.mjs +939 -34
  20. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  21. package/fesm2020/cqa-lib-cqa-ui.mjs +926 -34
  22. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  23. package/lib/dynamic-select/dynamic-select-field.component.d.ts +1 -0
  24. package/lib/execution-screen/db-query-execution-item/db-query-execution-item.component.d.ts +18 -3
  25. package/lib/execution-screen/db-verification-step/db-verification-step.component.d.ts +7 -1
  26. package/lib/step-builder/step-builder-action/step-builder-action.component.d.ts +2 -1
  27. package/lib/step-builder/step-builder-condition/step-builder-condition.component.d.ts +61 -0
  28. package/lib/step-builder/step-builder-database/step-builder-database.component.d.ts +61 -0
  29. package/lib/table/dynamic-table/dynamic-table.component.d.ts +7 -1
  30. package/lib/templates/table-template.component.d.ts +6 -1
  31. package/lib/test-case-details/custom-edit-step/custom-edit-step-data.d.ts +8 -0
  32. package/lib/test-case-details/custom-edit-step/custom-edit-step-ref.d.ts +13 -0
  33. package/lib/test-case-details/custom-edit-step/custom-edit-step.component.d.ts +25 -0
  34. package/lib/test-case-details/custom-edit-step/custom-edit-step.service.d.ts +23 -0
  35. package/lib/test-case-details/normal-step/normal-step.component.d.ts +9 -0
  36. package/lib/ui-kit.module.d.ts +26 -23
  37. package/package.json +1 -1
  38. package/public-api.d.ts +6 -0
  39. package/styles.css +1 -1
@@ -0,0 +1,330 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { FormControl, Validators } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ import * as i2 from "../../dynamic-select/dynamic-select-field.component";
6
+ import * as i3 from "../../button/button.component";
7
+ import * as i4 from "../../custom-input/custom-input.component";
8
+ import * as i5 from "@angular/material/slide-toggle";
9
+ import * as i6 from "@angular/common";
10
+ export class StepBuilderConditionComponent {
11
+ constructor(fb) {
12
+ this.fb = fb;
13
+ /** Options for operator dropdown */
14
+ this.operatorOptions = [
15
+ { id: 'equals', value: 'equals', name: 'equals', label: 'equals' },
16
+ { id: 'not_equals', value: 'not_equals', name: 'not equals', label: 'not equals' },
17
+ { id: 'contains', value: 'contains', name: 'contains', label: 'contains' },
18
+ { id: 'not_contains', value: 'not_contains', name: 'not contains', label: 'not contains' },
19
+ { id: 'greater_than', value: 'greater_than', name: 'greater than', label: 'greater than' },
20
+ { id: 'less_than', value: 'less_than', name: 'less than', label: 'less than' }
21
+ ];
22
+ /** List of action templates to display in value dropdown */
23
+ this.conditionTemplates = [];
24
+ /** Function to handle variable processing or custom logic. Can be passed from parent component. */
25
+ this.setConditionTemplateVariables = () => { return []; };
26
+ /** Emit when step is created */
27
+ this.createStep = new EventEmitter();
28
+ /** Emit when cancelled */
29
+ this.cancelled = new EventEmitter();
30
+ this.includeElse = false;
31
+ // Cache for value configs to avoid recreating on every change detection
32
+ this.valueConfigCache = null;
33
+ // Track selected templates and their variables for each condition row
34
+ this.selectedTemplates = new Map();
35
+ this.conditionTemplateVariables = new Map();
36
+ this.conditionVariablesForms = new Map();
37
+ this.conditionForm = this.fb.group({
38
+ conditions: this.fb.array([]),
39
+ includeElse: [false]
40
+ });
41
+ }
42
+ ngOnInit() {
43
+ // Add initial condition row
44
+ this.addCondition("CONDITION_IF");
45
+ // Initialize value config cache
46
+ this.updateValueConfigCache();
47
+ }
48
+ ngOnChanges(changes) {
49
+ // Regenerate value config cache when conditionTemplates changes
50
+ if (changes['conditionTemplates'] && !changes['conditionTemplates'].firstChange) {
51
+ this.updateValueConfigCache();
52
+ }
53
+ }
54
+ get conditionsFormArray() {
55
+ return this.conditionForm.get('conditions');
56
+ }
57
+ addCondition(conditionType) {
58
+ const conditionGroup = this.fb.group({
59
+ field: [conditionType, Validators.required],
60
+ operator: ['equals', Validators.required],
61
+ value: [null, Validators.required],
62
+ description: [''],
63
+ metadata: [''],
64
+ });
65
+ const index = this.conditionsFormArray.length;
66
+ this.conditionsFormArray.push(conditionGroup);
67
+ // Initialize variables form for this condition
68
+ this.conditionVariablesForms.set(index, this.fb.group({}));
69
+ }
70
+ removeCondition(index) {
71
+ if (this.conditionsFormArray.length > 1) {
72
+ this.conditionsFormArray.removeAt(index);
73
+ // Clean up associated data
74
+ this.selectedTemplates.delete(index);
75
+ this.conditionTemplateVariables.delete(index);
76
+ this.conditionVariablesForms.delete(index);
77
+ // Reindex remaining conditions
78
+ this.reindexConditionData(index);
79
+ }
80
+ }
81
+ reindexConditionData(removedIndex) {
82
+ // Create new maps with reindexed data
83
+ const newSelectedTemplates = new Map();
84
+ const newTemplateVariables = new Map();
85
+ const newVariablesForms = new Map();
86
+ this.selectedTemplates.forEach((template, oldIndex) => {
87
+ if (oldIndex < removedIndex) {
88
+ newSelectedTemplates.set(oldIndex, template);
89
+ }
90
+ else if (oldIndex > removedIndex) {
91
+ newSelectedTemplates.set(oldIndex - 1, template);
92
+ }
93
+ });
94
+ this.conditionTemplateVariables.forEach((variables, oldIndex) => {
95
+ if (oldIndex < removedIndex) {
96
+ newTemplateVariables.set(oldIndex, variables);
97
+ }
98
+ else if (oldIndex > removedIndex) {
99
+ newTemplateVariables.set(oldIndex - 1, variables);
100
+ }
101
+ });
102
+ this.conditionVariablesForms.forEach((form, oldIndex) => {
103
+ if (oldIndex < removedIndex) {
104
+ newVariablesForms.set(oldIndex, form);
105
+ }
106
+ else if (oldIndex > removedIndex) {
107
+ newVariablesForms.set(oldIndex - 1, form);
108
+ }
109
+ });
110
+ this.selectedTemplates = newSelectedTemplates;
111
+ this.conditionTemplateVariables = newTemplateVariables;
112
+ this.conditionVariablesForms = newVariablesForms;
113
+ }
114
+ getOperatorConfig(index) {
115
+ return {
116
+ key: 'operator',
117
+ placeholder: 'Select operator',
118
+ multiple: false,
119
+ searchable: false,
120
+ options: this.operatorOptions
121
+ };
122
+ }
123
+ updateValueConfigCache() {
124
+ // Convert ActionTemplate[] to SelectOption[]
125
+ const templateOptions = (this.conditionTemplates || []).map(template => ({
126
+ id: template.id?.toString() || template.displayName || '',
127
+ value: template.id?.toString() || template.displayName || '',
128
+ name: template.htmlGrammar || template.naturalText || '',
129
+ label: template.htmlGrammar || template.naturalText || ''
130
+ }));
131
+ this.valueConfigCache = {
132
+ key: 'value',
133
+ placeholder: 'Select Template',
134
+ multiple: false,
135
+ searchable: true,
136
+ displayLabelAsInnerHtml: true,
137
+ options: templateOptions
138
+ };
139
+ }
140
+ getValueConfig(index) {
141
+ // Return cached config to avoid recreating options on every change detection
142
+ if (!this.valueConfigCache) {
143
+ this.updateValueConfigCache();
144
+ }
145
+ // Create a new config object with the onChange handler for this specific index
146
+ // This ensures each condition row has its own handler while sharing the base config
147
+ return {
148
+ ...this.valueConfigCache,
149
+ onChange: (value) => {
150
+ this.onTemplateValueChange(index, value);
151
+ }
152
+ };
153
+ }
154
+ onTemplateValueChange(index, templateId) {
155
+ // Find the selected template
156
+ const selectedTemplate = this.conditionTemplates.find(t => (t.id?.toString() === templateId) || (t.displayName === templateId));
157
+ if (selectedTemplate && this.setConditionTemplateVariables) {
158
+ // Store selected template
159
+ this.selectedTemplates.set(index, selectedTemplate);
160
+ // Get template variables using the provided function
161
+ const variables = this.setConditionTemplateVariables(selectedTemplate);
162
+ this.conditionTemplateVariables.set(index, variables);
163
+ // Build form for template variables
164
+ this.buildConditionVariablesForm(index, variables);
165
+ }
166
+ else {
167
+ // Clear template and variables if no template selected
168
+ this.selectedTemplates.delete(index);
169
+ this.conditionTemplateVariables.delete(index);
170
+ const form = this.conditionVariablesForms.get(index);
171
+ if (form) {
172
+ Object.keys(form.controls).forEach(key => {
173
+ form.removeControl(key);
174
+ });
175
+ }
176
+ }
177
+ }
178
+ buildConditionVariablesForm(index, variables) {
179
+ let form = this.conditionVariablesForms.get(index);
180
+ if (!form) {
181
+ form = this.fb.group({});
182
+ this.conditionVariablesForms.set(index, form);
183
+ }
184
+ // Ensure form is not undefined
185
+ if (!form) {
186
+ return;
187
+ }
188
+ // Clear existing form controls
189
+ Object.keys(form.controls).forEach(key => {
190
+ form.removeControl(key);
191
+ });
192
+ // Add form controls for each variable
193
+ variables.forEach(variable => {
194
+ // Handle boolean variables - use boolean value, others use string
195
+ const defaultValue = variable.type === 'boolean'
196
+ ? (variable.value === true || variable.value === 'true' || variable.value === 1)
197
+ : (variable.value || '');
198
+ form.addControl(variable.name, new FormControl(defaultValue));
199
+ });
200
+ }
201
+ getConditionTemplateVariables(index) {
202
+ return this.conditionTemplateVariables.get(index) || [];
203
+ }
204
+ getConditionVariablesForm(index) {
205
+ let form = this.conditionVariablesForms.get(index);
206
+ if (!form) {
207
+ form = this.fb.group({});
208
+ this.conditionVariablesForms.set(index, form);
209
+ }
210
+ return form;
211
+ }
212
+ getSelectedTemplate(index) {
213
+ return this.selectedTemplates.get(index) || null;
214
+ }
215
+ getSelectConfigForVariable(index, variable) {
216
+ const options = (variable.options || []).map((opt) => ({
217
+ id: opt,
218
+ value: opt,
219
+ name: opt,
220
+ label: opt
221
+ }));
222
+ return {
223
+ key: variable.name,
224
+ placeholder: `Select ${variable.label}`,
225
+ multiple: false,
226
+ searchable: false,
227
+ options: options,
228
+ onChange: (value) => {
229
+ this.onConditionVariableValueChange(index, variable.name, value);
230
+ }
231
+ };
232
+ }
233
+ onConditionVariableValueChange(conditionIndex, variableName, value) {
234
+ // Update the variable in templateVariables array
235
+ const variables = this.conditionTemplateVariables.get(conditionIndex) || [];
236
+ const variable = variables.find(v => v.name === variableName);
237
+ if (variable) {
238
+ variable.value = value;
239
+ }
240
+ // Also update form control
241
+ const form = this.conditionVariablesForms.get(conditionIndex);
242
+ if (form && form.get(variableName)) {
243
+ form.get(variableName)?.setValue(value);
244
+ }
245
+ }
246
+ onConditionVariableInputChange(conditionIndex, variableName, value) {
247
+ // Update the variable in templateVariables array
248
+ const variables = this.conditionTemplateVariables.get(conditionIndex) || [];
249
+ const variable = variables.find(v => v.name === variableName);
250
+ if (variable) {
251
+ variable.value = value;
252
+ }
253
+ // Also update form control
254
+ const form = this.conditionVariablesForms.get(conditionIndex);
255
+ if (form && form.get(variableName)) {
256
+ form.get(variableName)?.setValue(value);
257
+ }
258
+ }
259
+ onConditionVariableBooleanChange(conditionIndex, variableName, value) {
260
+ // Update the variable in templateVariables array
261
+ const variables = this.conditionTemplateVariables.get(conditionIndex) || [];
262
+ const variable = variables.find(v => v.name === variableName);
263
+ if (variable) {
264
+ variable.value = value;
265
+ }
266
+ // Also update form control
267
+ const form = this.conditionVariablesForms.get(conditionIndex);
268
+ if (form) {
269
+ if (form.get(variableName)) {
270
+ form.get(variableName)?.setValue(value);
271
+ }
272
+ else {
273
+ // Create form control if it doesn't exist
274
+ form.addControl(variableName, new FormControl(value));
275
+ }
276
+ }
277
+ }
278
+ getConditionFormGroup(index) {
279
+ return this.conditionsFormArray.at(index);
280
+ }
281
+ onIncludeElseChange(checked) {
282
+ this.includeElse = checked;
283
+ this.conditionForm.patchValue({ includeElse: checked });
284
+ }
285
+ onCancel() {
286
+ this.cancelled.emit();
287
+ }
288
+ onCreateStep() {
289
+ if (this.conditionForm.valid) {
290
+ const formValue = this.conditionForm.value;
291
+ const stepData = {
292
+ conditions: formValue.conditions.map((cond, index) => {
293
+ // Find the ActionTemplate object from the stored ID/value
294
+ const templateId = cond.value;
295
+ const selectedTemplate = this.conditionTemplates.find(t => (t.id?.toString() === templateId) || (t.displayName === templateId)) || this.selectedTemplates.get(index);
296
+ // Get template variables for this condition
297
+ const templateVariables = this.conditionTemplateVariables.get(index) || [];
298
+ return {
299
+ field: cond.field,
300
+ operator: cond.operator,
301
+ value: selectedTemplate || null,
302
+ templateVariables: templateVariables,
303
+ description: cond.description || '',
304
+ metadata: cond.metadata || ''
305
+ };
306
+ }),
307
+ includeElse: formValue.includeElse || false
308
+ };
309
+ console.log('stepData', stepData);
310
+ this.createStep.emit(stepData);
311
+ }
312
+ }
313
+ }
314
+ StepBuilderConditionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderConditionComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
315
+ StepBuilderConditionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderConditionComponent, selector: "cqa-step-builder-condition", inputs: { operatorOptions: "operatorOptions", conditionTemplates: "conditionTemplates", setConditionTemplateVariables: "setConditionTemplateVariables" }, outputs: { createStep: "createStep", cancelled: "cancelled" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index\">\n <div\n *ngIf=\"getConditionFormGroup(i).get('field')?.value === 'CONDITION_IF' || getConditionFormGroup(i).get('field')?.value === 'CONDITION_ELSE_IF'\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{getConditionFormGroup(i).get('field')?.value === 'CONDITION_IF' ? 'IF' :\n getConditionFormGroup(i).get('field')?.value === 'CONDITION_ELSE_IF' ? 'ELSE IF' : 'ELSE'}}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\">\n <!-- Template Grammar Display -->\n <!-- <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"getSelectedTemplate(i)?.htmlGrammar || getSelectedTemplate(i)?.naturalText || ''\">\n </div> -->\n\n \n <!-- Description and Metadata Inputs -->\n <div class=\"cqa-flex cqa-flex cqa-gap-x-4 cqa-mb-4\" style=\"flex-wrap: wrap;\">\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter description'\"\n [value]=\"getConditionFormGroup(i).get('description')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"getConditionFormGroup(i).get('description')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Metadata -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter metadata'\"\n [value]=\"getConditionFormGroup(i).get('metadata')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"getConditionFormGroup(i).get('metadata')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n\n <!-- Template Variables Form Fields -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4\" style=\"flex-wrap: wrap;\">\n <ng-container *ngFor=\"let variable of getConditionTemplateVariables(i)\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle\n [checked]=\"getConditionVariablesForm(i).get(variable.name)?.value || variable.value || false\"\n (change)=\"onConditionVariableBooleanChange(i, variable.name, $event.checked)\"\n color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n \n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Dropdown for select variables -->\n <ng-container *ngIf=\"variable.name === 'type' || variable.name === 'scrollTo' || variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getConditionVariablesForm(i)\"\n [config]=\"getSelectConfigForVariable(i, variable)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <!-- Text Input for other variables -->\n <ng-container *ngIf=\"variable.name !== 'type' && variable.name !== 'scrollTo' && !variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input\n [placeholder]=\"'Text Input'\"\n [value]=\"variable.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"onConditionVariableInputChange(i, variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Add Condition Button -->\n <div class=\"cqa-border-2 cqa-border-dashed cqa-border-gray-300 cqa-rounded-lg cqa-p-1 cqa-mt-3\">\n <cqa-button\n variant=\"text\"\n icon=\"add\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n [text]=\"'Add Condition'\"\n (clicked)=\"addCondition('CONDITION_ELSE_IF')\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Include ELSE Branch Section -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-6 cqa-p-3 cqa-bg-gray-50 cqa-rounded-lg\">\n <div class=\"cqa-flex cqa-flex-col\">\n <h3 class=\"cqa-text-[14px] cqa-font-semibold cqa-text-gray-900 cqa-mb-1\">\n Include ELSE branch\n </h3>\n <p class=\"cqa-text-[12px] cqa-text-gray-600\">\n Execute alternative steps when condition is not met.\n </p>\n </div>\n <mat-slide-toggle [checked]=\"includeElse\" (change)=\"onIncludeElseChange($event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>", components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore"] }, { type: i3.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i4.CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i5.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], directives: [{ type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
316
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderConditionComponent, decorators: [{
317
+ type: Component,
318
+ args: [{ selector: 'cqa-step-builder-condition', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index\">\n <div\n *ngIf=\"getConditionFormGroup(i).get('field')?.value === 'CONDITION_IF' || getConditionFormGroup(i).get('field')?.value === 'CONDITION_ELSE_IF'\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{getConditionFormGroup(i).get('field')?.value === 'CONDITION_IF' ? 'IF' :\n getConditionFormGroup(i).get('field')?.value === 'CONDITION_ELSE_IF' ? 'ELSE IF' : 'ELSE'}}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\">\n <!-- Template Grammar Display -->\n <!-- <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"getSelectedTemplate(i)?.htmlGrammar || getSelectedTemplate(i)?.naturalText || ''\">\n </div> -->\n\n \n <!-- Description and Metadata Inputs -->\n <div class=\"cqa-flex cqa-flex cqa-gap-x-4 cqa-mb-4\" style=\"flex-wrap: wrap;\">\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter description'\"\n [value]=\"getConditionFormGroup(i).get('description')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"getConditionFormGroup(i).get('description')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Metadata -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter metadata'\"\n [value]=\"getConditionFormGroup(i).get('metadata')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"getConditionFormGroup(i).get('metadata')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n\n <!-- Template Variables Form Fields -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4\" style=\"flex-wrap: wrap;\">\n <ng-container *ngFor=\"let variable of getConditionTemplateVariables(i)\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle\n [checked]=\"getConditionVariablesForm(i).get(variable.name)?.value || variable.value || false\"\n (change)=\"onConditionVariableBooleanChange(i, variable.name, $event.checked)\"\n color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n \n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Dropdown for select variables -->\n <ng-container *ngIf=\"variable.name === 'type' || variable.name === 'scrollTo' || variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getConditionVariablesForm(i)\"\n [config]=\"getSelectConfigForVariable(i, variable)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <!-- Text Input for other variables -->\n <ng-container *ngIf=\"variable.name !== 'type' && variable.name !== 'scrollTo' && !variable.options\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input\n [placeholder]=\"'Text Input'\"\n [value]=\"variable.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"onConditionVariableInputChange(i, variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Add Condition Button -->\n <div class=\"cqa-border-2 cqa-border-dashed cqa-border-gray-300 cqa-rounded-lg cqa-p-1 cqa-mt-3\">\n <cqa-button\n variant=\"text\"\n icon=\"add\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n [text]=\"'Add Condition'\"\n (clicked)=\"addCondition('CONDITION_ELSE_IF')\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Include ELSE Branch Section -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-6 cqa-p-3 cqa-bg-gray-50 cqa-rounded-lg\">\n <div class=\"cqa-flex cqa-flex-col\">\n <h3 class=\"cqa-text-[14px] cqa-font-semibold cqa-text-gray-900 cqa-mb-1\">\n Include ELSE branch\n </h3>\n <p class=\"cqa-text-[12px] cqa-text-gray-600\">\n Execute alternative steps when condition is not met.\n </p>\n </div>\n <mat-slide-toggle [checked]=\"includeElse\" (change)=\"onIncludeElseChange($event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>", styles: [] }]
319
+ }], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { operatorOptions: [{
320
+ type: Input
321
+ }], conditionTemplates: [{
322
+ type: Input
323
+ }], setConditionTemplateVariables: [{
324
+ type: Input
325
+ }], createStep: [{
326
+ type: Output
327
+ }], cancelled: [{
328
+ type: Output
329
+ }] } });
330
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1idWlsZGVyLWNvbmRpdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3N0ZXAtYnVpbGRlci9zdGVwLWJ1aWxkZXItY29uZGl0aW9uL3N0ZXAtYnVpbGRlci1jb25kaXRpb24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zdGVwLWJ1aWxkZXIvc3RlcC1idWlsZGVyLWNvbmRpdGlvbi9zdGVwLWJ1aWxkZXItY29uZGl0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQW9DLE1BQU0sZUFBZSxDQUFDO0FBQ3pHLE9BQU8sRUFBcUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7OztBQXdCNUYsTUFBTSxPQUFPLDZCQUE2QjtJQWlDeEMsWUFBb0IsRUFBZTtRQUFmLE9BQUUsR0FBRixFQUFFLENBQWE7UUFoQ25DLG9DQUFvQztRQUMzQixvQkFBZSxHQUFtQjtZQUN6QyxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7WUFDbEUsRUFBRSxFQUFFLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFO1lBQ2xGLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRTtZQUMxRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUU7WUFDMUYsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFO1lBQzFGLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRTtTQUMvRSxDQUFDO1FBRUYsNERBQTREO1FBQ25ELHVCQUFrQixHQUFxQixFQUFFLENBQUM7UUFDbkQsbUdBQW1HO1FBQzFGLGtDQUE2QixHQUF1QyxHQUFHLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQSxDQUFBLENBQUMsQ0FBQztRQUVoRyxnQ0FBZ0M7UUFDdEIsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFxQixDQUFDO1FBRTdELDBCQUEwQjtRQUNoQixjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUcvQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUU3Qix3RUFBd0U7UUFDaEUscUJBQWdCLEdBQW9DLElBQUksQ0FBQztRQUVqRSxzRUFBc0U7UUFDOUQsc0JBQWlCLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDM0QsK0JBQTBCLEdBQXVCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDM0QsNEJBQXVCLEdBQTJCLElBQUksR0FBRyxFQUFFLENBQUM7UUFHbEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNqQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdCLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQztTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLDRCQUE0QjtRQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2xDLGdDQUFnQztRQUNoQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLGdFQUFnRTtRQUNoRSxJQUFJLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUMsV0FBVyxFQUFFO1lBQy9FLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztJQUVELElBQUksbUJBQW1CO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFjLENBQUM7SUFDM0QsQ0FBQztJQUVELFlBQVksQ0FBQyxhQUFxQjtRQUNoQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNuQyxLQUFLLEVBQUUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUMzQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUN6QyxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUNsQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDakIsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQ2YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztRQUM5QyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRTlDLCtDQUErQztRQUMvQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxlQUFlLENBQUMsS0FBYTtRQUMzQixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekMsMkJBQTJCO1lBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLCtCQUErQjtZQUMvQixJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbEM7SUFDSCxDQUFDO0lBRU8sb0JBQW9CLENBQUMsWUFBb0I7UUFDL0Msc0NBQXNDO1FBQ3RDLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLEVBQTBCLENBQUM7UUFDL0QsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBaUIsQ0FBQztRQUN0RCxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO1FBRXZELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDcEQsSUFBSSxRQUFRLEdBQUcsWUFBWSxFQUFFO2dCQUMzQixvQkFBb0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQzlDO2lCQUFNLElBQUksUUFBUSxHQUFHLFlBQVksRUFBRTtnQkFDbEMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDbEQ7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDOUQsSUFBSSxRQUFRLEdBQUcsWUFBWSxFQUFFO2dCQUMzQixvQkFBb0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQy9DO2lCQUFNLElBQUksUUFBUSxHQUFHLFlBQVksRUFBRTtnQkFDbEMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDbkQ7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDdEQsSUFBSSxRQUFRLEdBQUcsWUFBWSxFQUFFO2dCQUMzQixpQkFBaUIsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ3ZDO2lCQUFNLElBQUksUUFBUSxHQUFHLFlBQVksRUFBRTtnQkFDbEMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDM0M7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQztRQUM5QyxJQUFJLENBQUMsMEJBQTBCLEdBQUcsb0JBQW9CLENBQUM7UUFDdkQsSUFBSSxDQUFDLHVCQUF1QixHQUFHLGlCQUFpQixDQUFDO0lBQ25ELENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxLQUFhO1FBQzdCLE9BQU87WUFDTCxHQUFHLEVBQUUsVUFBVTtZQUNmLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsUUFBUSxFQUFFLEtBQUs7WUFDZixVQUFVLEVBQUUsS0FBSztZQUNqQixPQUFPLEVBQUUsSUFBSSxDQUFDLGVBQWU7U0FDOUIsQ0FBQztJQUNKLENBQUM7SUFFTyxzQkFBc0I7UUFDNUIsNkNBQTZDO1FBQzdDLE1BQU0sZUFBZSxHQUFtQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLEVBQUUsRUFBRSxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLFFBQVEsQ0FBQyxXQUFXLElBQUksRUFBRTtZQUN6RCxLQUFLLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxRQUFRLENBQUMsV0FBVyxJQUFJLEVBQUU7WUFDNUQsSUFBSSxFQUFFLFFBQVEsQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLFdBQVcsSUFBSSxFQUFFO1lBQ3hELEtBQUssRUFBRSxRQUFRLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxXQUFXLElBQUksRUFBRTtTQUMxRCxDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksQ0FBQyxnQkFBZ0IsR0FBRztZQUN0QixHQUFHLEVBQUUsT0FBTztZQUNaLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsUUFBUSxFQUFFLEtBQUs7WUFDZixVQUFVLEVBQUUsSUFBSTtZQUNoQix1QkFBdUIsRUFBRSxJQUFJO1lBQzdCLE9BQU8sRUFBRSxlQUFlO1NBQ3pCLENBQUM7SUFDSixDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQWE7UUFDMUIsNkVBQTZFO1FBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDMUIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7U0FDL0I7UUFFRCwrRUFBK0U7UUFDL0Usb0ZBQW9GO1FBQ3BGLE9BQU87WUFDTCxHQUFHLElBQUksQ0FBQyxnQkFBaUI7WUFDekIsUUFBUSxFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7Z0JBQ3ZCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0MsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQscUJBQXFCLENBQUMsS0FBYSxFQUFFLFVBQWU7UUFDbEQsNkJBQTZCO1FBQzdCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FDbkQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLFVBQVUsQ0FBQyxDQUN6RSxDQUFDO1FBRUYsSUFBSSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsNkJBQTZCLEVBQUU7WUFDMUQsMEJBQTBCO1lBQzFCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFcEQscURBQXFEO1lBQ3JELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3RELG9DQUFvQztZQUNwQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3BEO2FBQU07WUFDTCx1REFBdUQ7WUFDdkQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckQsSUFBSSxJQUFJLEVBQUU7Z0JBQ1IsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUN2QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMxQixDQUFDLENBQUMsQ0FBQzthQUNKO1NBQ0Y7SUFDSCxDQUFDO0lBRU8sMkJBQTJCLENBQUMsS0FBYSxFQUFFLFNBQWdCO1FBQ2pFLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNULElBQUksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztTQUMvQztRQUVELCtCQUErQjtRQUMvQixJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1QsT0FBTztTQUNSO1FBRUQsK0JBQStCO1FBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN2QyxJQUFLLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBRUgsc0NBQXNDO1FBQ3RDLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDM0Isa0VBQWtFO1lBQ2xFLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEtBQUssU0FBUztnQkFDOUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssS0FBSyxJQUFJLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxNQUFNLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUM7Z0JBQ2hGLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7WUFDM0IsSUFBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsNkJBQTZCLENBQUMsS0FBYTtRQUN6QyxPQUFPLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFELENBQUM7SUFFRCx5QkFBeUIsQ0FBQyxLQUFhO1FBQ3JDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNULElBQUksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztTQUMvQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELG1CQUFtQixDQUFDLEtBQWE7UUFDL0IsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQztJQUNuRCxDQUFDO0lBRUQsMEJBQTBCLENBQUMsS0FBYSxFQUFFLFFBQWE7UUFDckQsTUFBTSxPQUFPLEdBQW1CLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDN0UsRUFBRSxFQUFFLEdBQUc7WUFDUCxLQUFLLEVBQUUsR0FBRztZQUNWLElBQUksRUFBRSxHQUFHO1lBQ1QsS0FBSyxFQUFFLEdBQUc7U0FDWCxDQUFDLENBQUMsQ0FBQztRQUVKLE9BQU87WUFDTCxHQUFHLEVBQUUsUUFBUSxDQUFDLElBQUk7WUFDbEIsV0FBVyxFQUFFLFVBQVUsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUN2QyxRQUFRLEVBQUUsS0FBSztZQUNmLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLFFBQVEsRUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO2dCQUN2QixJQUFJLENBQUMsOEJBQThCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkUsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsOEJBQThCLENBQUMsY0FBc0IsRUFBRSxZQUFvQixFQUFFLEtBQVU7UUFDckYsaURBQWlEO1FBQ2pELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzVFLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxDQUFDO1FBQzlELElBQUksUUFBUSxFQUFFO1lBQ1osUUFBUSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7U0FDeEI7UUFDRCwyQkFBMkI7UUFDM0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM5RCxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQ2xDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3pDO0lBQ0gsQ0FBQztJQUVELDhCQUE4QixDQUFDLGNBQXNCLEVBQUUsWUFBb0IsRUFBRSxLQUFVO1FBQ3JGLGlEQUFpRDtRQUNqRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM1RSxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQztRQUM5RCxJQUFJLFFBQVEsRUFBRTtZQUNaLFFBQVEsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1NBQ3hCO1FBQ0QsMkJBQTJCO1FBQzNCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDOUQsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QztJQUNILENBQUM7SUFFRCxnQ0FBZ0MsQ0FBQyxjQUFzQixFQUFFLFlBQW9CLEVBQUUsS0FBYztRQUMzRixpREFBaUQ7UUFDakQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUUsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssWUFBWSxDQUFDLENBQUM7UUFDOUQsSUFBSSxRQUFRLEVBQUU7WUFDWixRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztTQUN4QjtRQUNELDJCQUEyQjtRQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlELElBQUksSUFBSSxFQUFFO1lBQ1IsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN6QztpQkFBTTtnQkFDTCwwQ0FBMEM7Z0JBQzFDLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDdkQ7U0FDRjtJQUNILENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxLQUFhO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQWMsQ0FBQztJQUN6RCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsT0FBZ0I7UUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFO1lBQzVCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDO1lBQzNDLE1BQU0sUUFBUSxHQUFzQjtnQkFDbEMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBUyxFQUFFLEtBQWEsRUFBRSxFQUFFO29CQUNoRSwwREFBMEQ7b0JBQzFELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQzlCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FDbkQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLFVBQVUsQ0FBQyxDQUN6RSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBRXZDLDRDQUE0QztvQkFDNUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFFM0UsT0FBTzt3QkFDTCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7d0JBQ2pCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTt3QkFDdkIsS0FBSyxFQUFFLGdCQUFnQixJQUFJLElBQUk7d0JBQy9CLGlCQUFpQixFQUFFLGlCQUFpQjt3QkFDcEMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksRUFBRTt3QkFDbkMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTtxQkFDOUIsQ0FBQztnQkFDSixDQUFDLENBQUM7Z0JBQ0YsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXLElBQUksS0FBSzthQUM1QyxDQUFDO1lBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDaEM7SUFDSCxDQUFDOzswSEExVlUsNkJBQTZCOzhHQUE3Qiw2QkFBNkIseVZDekIxQyxreFNBdUxNOzJGRDlKTyw2QkFBNkI7a0JBTnpDLFNBQVM7K0JBQ0UsNEJBQTRCLFFBR2hDLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRTtrR0FJckIsZUFBZTtzQkFBdkIsS0FBSztnQkFVRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBRUcsNkJBQTZCO3NCQUFyQyxLQUFLO2dCQUdJLFVBQVU7c0JBQW5CLE1BQU07Z0JBR0csU0FBUztzQkFBbEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUFycmF5LCBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBGb3JtQ29udHJvbCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcbmltcG9ydCB7IEFjdGlvblRlbXBsYXRlIH0gZnJvbSAnLi4vc3RlcC1idWlsZGVyLWFjdGlvbi9zdGVwLWJ1aWxkZXItYWN0aW9uLmNvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZGl0aW9uUm93IHtcbiAgZmllbGQ6IHN0cmluZztcbiAgb3BlcmF0b3I6IHN0cmluZztcbiAgdmFsdWU6IEFjdGlvblRlbXBsYXRlO1xuICB0ZW1wbGF0ZVZhcmlhYmxlcz86IGFueVtdO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgbWV0YWRhdGE/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZGl0aW9uRm9ybURhdGEge1xuICBjb25kaXRpb25zOiBDb25kaXRpb25Sb3dbXTtcbiAgaW5jbHVkZUVsc2U6IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NxYS1zdGVwLWJ1aWxkZXItY29uZGl0aW9uJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3N0ZXAtYnVpbGRlci1jb25kaXRpb24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFtdLFxuICBob3N0OiB7IGNsYXNzOiAnY3FhLXVpLXJvb3QnIH1cbn0pXG5leHBvcnQgY2xhc3MgU3RlcEJ1aWxkZXJDb25kaXRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIC8qKiBPcHRpb25zIGZvciBvcGVyYXRvciBkcm9wZG93biAqL1xuICBASW5wdXQoKSBvcGVyYXRvck9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW1xuICAgIHsgaWQ6ICdlcXVhbHMnLCB2YWx1ZTogJ2VxdWFscycsIG5hbWU6ICdlcXVhbHMnLCBsYWJlbDogJ2VxdWFscycgfSxcbiAgICB7IGlkOiAnbm90X2VxdWFscycsIHZhbHVlOiAnbm90X2VxdWFscycsIG5hbWU6ICdub3QgZXF1YWxzJywgbGFiZWw6ICdub3QgZXF1YWxzJyB9LFxuICAgIHsgaWQ6ICdjb250YWlucycsIHZhbHVlOiAnY29udGFpbnMnLCBuYW1lOiAnY29udGFpbnMnLCBsYWJlbDogJ2NvbnRhaW5zJyB9LFxuICAgIHsgaWQ6ICdub3RfY29udGFpbnMnLCB2YWx1ZTogJ25vdF9jb250YWlucycsIG5hbWU6ICdub3QgY29udGFpbnMnLCBsYWJlbDogJ25vdCBjb250YWlucycgfSxcbiAgICB7IGlkOiAnZ3JlYXRlcl90aGFuJywgdmFsdWU6ICdncmVhdGVyX3RoYW4nLCBuYW1lOiAnZ3JlYXRlciB0aGFuJywgbGFiZWw6ICdncmVhdGVyIHRoYW4nIH0sXG4gICAgeyBpZDogJ2xlc3NfdGhhbicsIHZhbHVlOiAnbGVzc190aGFuJywgbmFtZTogJ2xlc3MgdGhhbicsIGxhYmVsOiAnbGVzcyB0aGFuJyB9XG4gIF07XG5cbiAgLyoqIExpc3Qgb2YgYWN0aW9uIHRlbXBsYXRlcyB0byBkaXNwbGF5IGluIHZhbHVlIGRyb3Bkb3duICovXG4gIEBJbnB1dCgpIGNvbmRpdGlvblRlbXBsYXRlczogQWN0aW9uVGVtcGxhdGVbXSA9IFtdO1xuICAvKiogRnVuY3Rpb24gdG8gaGFuZGxlIHZhcmlhYmxlIHByb2Nlc3Npbmcgb3IgY3VzdG9tIGxvZ2ljLiBDYW4gYmUgcGFzc2VkIGZyb20gcGFyZW50IGNvbXBvbmVudC4gKi9cbiAgQElucHV0KCkgc2V0Q29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXM6ICh2YXJpYWJsZXM6IEFjdGlvblRlbXBsYXRlKSA9PiBhbnkgPSAoKSA9PiB7IHJldHVybiBbXX07XG5cbiAgLyoqIEVtaXQgd2hlbiBzdGVwIGlzIGNyZWF0ZWQgKi9cbiAgQE91dHB1dCgpIGNyZWF0ZVN0ZXAgPSBuZXcgRXZlbnRFbWl0dGVyPENvbmRpdGlvbkZvcm1EYXRhPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gY2FuY2VsbGVkICovXG4gIEBPdXRwdXQoKSBjYW5jZWxsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uZGl0aW9uRm9ybTogRm9ybUdyb3VwO1xuICBpbmNsdWRlRWxzZTogYm9vbGVhbiA9IGZhbHNlO1xuICBcbiAgLy8gQ2FjaGUgZm9yIHZhbHVlIGNvbmZpZ3MgdG8gYXZvaWQgcmVjcmVhdGluZyBvbiBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uXG4gIHByaXZhdGUgdmFsdWVDb25maWdDYWNoZTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIFxuICAvLyBUcmFjayBzZWxlY3RlZCB0ZW1wbGF0ZXMgYW5kIHRoZWlyIHZhcmlhYmxlcyBmb3IgZWFjaCBjb25kaXRpb24gcm93XG4gIHByaXZhdGUgc2VsZWN0ZWRUZW1wbGF0ZXM6IE1hcDxudW1iZXIsIEFjdGlvblRlbXBsYXRlPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBjb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlczogTWFwPG51bWJlciwgYW55W10+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGNvbmRpdGlvblZhcmlhYmxlc0Zvcm1zOiBNYXA8bnVtYmVyLCBGb3JtR3JvdXA+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyKSB7XG4gICAgdGhpcy5jb25kaXRpb25Gb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBjb25kaXRpb25zOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIGluY2x1ZGVFbHNlOiBbZmFsc2VdXG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBBZGQgaW5pdGlhbCBjb25kaXRpb24gcm93XG4gICAgdGhpcy5hZGRDb25kaXRpb24oXCJDT05ESVRJT05fSUZcIik7XG4gICAgLy8gSW5pdGlhbGl6ZSB2YWx1ZSBjb25maWcgY2FjaGVcbiAgICB0aGlzLnVwZGF0ZVZhbHVlQ29uZmlnQ2FjaGUoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBSZWdlbmVyYXRlIHZhbHVlIGNvbmZpZyBjYWNoZSB3aGVuIGNvbmRpdGlvblRlbXBsYXRlcyBjaGFuZ2VzXG4gICAgaWYgKGNoYW5nZXNbJ2NvbmRpdGlvblRlbXBsYXRlcyddICYmICFjaGFuZ2VzWydjb25kaXRpb25UZW1wbGF0ZXMnXS5maXJzdENoYW5nZSkge1xuICAgICAgdGhpcy51cGRhdGVWYWx1ZUNvbmZpZ0NhY2hlKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbmRpdGlvbnNGb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5jb25kaXRpb25Gb3JtLmdldCgnY29uZGl0aW9ucycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGFkZENvbmRpdGlvbihjb25kaXRpb25UeXBlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb25kaXRpb25Hcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgZmllbGQ6IFtjb25kaXRpb25UeXBlLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIG9wZXJhdG9yOiBbJ2VxdWFscycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmFsdWU6IFtudWxsLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSwgLy8gV2lsbCBzdG9yZSB0ZW1wbGF0ZSBJRCwgdGhlbiBtYXAgdG8gQWN0aW9uVGVtcGxhdGVcbiAgICAgIGRlc2NyaXB0aW9uOiBbJyddLFxuICAgICAgbWV0YWRhdGE6IFsnJ10sXG4gICAgfSk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmNvbmRpdGlvbnNGb3JtQXJyYXkubGVuZ3RoO1xuICAgIHRoaXMuY29uZGl0aW9uc0Zvcm1BcnJheS5wdXNoKGNvbmRpdGlvbkdyb3VwKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIHZhcmlhYmxlcyBmb3JtIGZvciB0aGlzIGNvbmRpdGlvblxuICAgIHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuc2V0KGluZGV4LCB0aGlzLmZiLmdyb3VwKHt9KSk7XG4gIH1cblxuICByZW1vdmVDb25kaXRpb24oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmRpdGlvbnNGb3JtQXJyYXkubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5jb25kaXRpb25zRm9ybUFycmF5LnJlbW92ZUF0KGluZGV4KTtcbiAgICAgIC8vIENsZWFuIHVwIGFzc29jaWF0ZWQgZGF0YVxuICAgICAgdGhpcy5zZWxlY3RlZFRlbXBsYXRlcy5kZWxldGUoaW5kZXgpO1xuICAgICAgdGhpcy5jb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlcy5kZWxldGUoaW5kZXgpO1xuICAgICAgdGhpcy5jb25kaXRpb25WYXJpYWJsZXNGb3Jtcy5kZWxldGUoaW5kZXgpO1xuICAgICAgXG4gICAgICAvLyBSZWluZGV4IHJlbWFpbmluZyBjb25kaXRpb25zXG4gICAgICB0aGlzLnJlaW5kZXhDb25kaXRpb25EYXRhKGluZGV4KTtcbiAgICB9XG4gIH1cbiAgXG4gIHByaXZhdGUgcmVpbmRleENvbmRpdGlvbkRhdGEocmVtb3ZlZEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBDcmVhdGUgbmV3IG1hcHMgd2l0aCByZWluZGV4ZWQgZGF0YVxuICAgIGNvbnN0IG5ld1NlbGVjdGVkVGVtcGxhdGVzID0gbmV3IE1hcDxudW1iZXIsIEFjdGlvblRlbXBsYXRlPigpO1xuICAgIGNvbnN0IG5ld1RlbXBsYXRlVmFyaWFibGVzID0gbmV3IE1hcDxudW1iZXIsIGFueVtdPigpO1xuICAgIGNvbnN0IG5ld1ZhcmlhYmxlc0Zvcm1zID0gbmV3IE1hcDxudW1iZXIsIEZvcm1Hcm91cD4oKTtcbiAgICBcbiAgICB0aGlzLnNlbGVjdGVkVGVtcGxhdGVzLmZvckVhY2goKHRlbXBsYXRlLCBvbGRJbmRleCkgPT4ge1xuICAgICAgaWYgKG9sZEluZGV4IDwgcmVtb3ZlZEluZGV4KSB7XG4gICAgICAgIG5ld1NlbGVjdGVkVGVtcGxhdGVzLnNldChvbGRJbmRleCwgdGVtcGxhdGUpO1xuICAgICAgfSBlbHNlIGlmIChvbGRJbmRleCA+IHJlbW92ZWRJbmRleCkge1xuICAgICAgICBuZXdTZWxlY3RlZFRlbXBsYXRlcy5zZXQob2xkSW5kZXggLSAxLCB0ZW1wbGF0ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgdGhpcy5jb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlcy5mb3JFYWNoKCh2YXJpYWJsZXMsIG9sZEluZGV4KSA9PiB7XG4gICAgICBpZiAob2xkSW5kZXggPCByZW1vdmVkSW5kZXgpIHtcbiAgICAgICAgbmV3VGVtcGxhdGVWYXJpYWJsZXMuc2V0KG9sZEluZGV4LCB2YXJpYWJsZXMpO1xuICAgICAgfSBlbHNlIGlmIChvbGRJbmRleCA+IHJlbW92ZWRJbmRleCkge1xuICAgICAgICBuZXdUZW1wbGF0ZVZhcmlhYmxlcy5zZXQob2xkSW5kZXggLSAxLCB2YXJpYWJsZXMpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuZm9yRWFjaCgoZm9ybSwgb2xkSW5kZXgpID0+IHtcbiAgICAgIGlmIChvbGRJbmRleCA8IHJlbW92ZWRJbmRleCkge1xuICAgICAgICBuZXdWYXJpYWJsZXNGb3Jtcy5zZXQob2xkSW5kZXgsIGZvcm0pO1xuICAgICAgfSBlbHNlIGlmIChvbGRJbmRleCA+IHJlbW92ZWRJbmRleCkge1xuICAgICAgICBuZXdWYXJpYWJsZXNGb3Jtcy5zZXQob2xkSW5kZXggLSAxLCBmb3JtKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICB0aGlzLnNlbGVjdGVkVGVtcGxhdGVzID0gbmV3U2VsZWN0ZWRUZW1wbGF0ZXM7XG4gICAgdGhpcy5jb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlcyA9IG5ld1RlbXBsYXRlVmFyaWFibGVzO1xuICAgIHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMgPSBuZXdWYXJpYWJsZXNGb3JtcztcbiAgfVxuXG4gIGdldE9wZXJhdG9yQ29uZmlnKGluZGV4OiBudW1iZXIpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBrZXk6ICdvcGVyYXRvcicsXG4gICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBvcGVyYXRvcicsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgIG9wdGlvbnM6IHRoaXMub3BlcmF0b3JPcHRpb25zXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlVmFsdWVDb25maWdDYWNoZSgpOiB2b2lkIHtcbiAgICAvLyBDb252ZXJ0IEFjdGlvblRlbXBsYXRlW10gdG8gU2VsZWN0T3B0aW9uW11cbiAgICBjb25zdCB0ZW1wbGF0ZU9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gKHRoaXMuY29uZGl0aW9uVGVtcGxhdGVzIHx8IFtdKS5tYXAodGVtcGxhdGUgPT4gKHtcbiAgICAgIGlkOiB0ZW1wbGF0ZS5pZD8udG9TdHJpbmcoKSB8fCB0ZW1wbGF0ZS5kaXNwbGF5TmFtZSB8fCAnJyxcbiAgICAgIHZhbHVlOiB0ZW1wbGF0ZS5pZD8udG9TdHJpbmcoKSB8fCB0ZW1wbGF0ZS5kaXNwbGF5TmFtZSB8fCAnJyxcbiAgICAgIG5hbWU6IHRlbXBsYXRlLmh0bWxHcmFtbWFyIHx8IHRlbXBsYXRlLm5hdHVyYWxUZXh0IHx8ICcnLFxuICAgICAgbGFiZWw6IHRlbXBsYXRlLmh0bWxHcmFtbWFyIHx8IHRlbXBsYXRlLm5hdHVyYWxUZXh0IHx8ICcnXG4gICAgfSkpO1xuXG4gICAgdGhpcy52YWx1ZUNvbmZpZ0NhY2hlID0ge1xuICAgICAga2V5OiAndmFsdWUnLFxuICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgVGVtcGxhdGUnLFxuICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgIGRpc3BsYXlMYWJlbEFzSW5uZXJIdG1sOiB0cnVlLFxuICAgICAgb3B0aW9uczogdGVtcGxhdGVPcHRpb25zXG4gICAgfTtcbiAgfVxuXG4gIGdldFZhbHVlQ29uZmlnKGluZGV4OiBudW1iZXIpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIC8vIFJldHVybiBjYWNoZWQgY29uZmlnIHRvIGF2b2lkIHJlY3JlYXRpbmcgb3B0aW9ucyBvbiBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgaWYgKCF0aGlzLnZhbHVlQ29uZmlnQ2FjaGUpIHtcbiAgICAgIHRoaXMudXBkYXRlVmFsdWVDb25maWdDYWNoZSgpO1xuICAgIH1cbiAgICBcbiAgICAvLyBDcmVhdGUgYSBuZXcgY29uZmlnIG9iamVjdCB3aXRoIHRoZSBvbkNoYW5nZSBoYW5kbGVyIGZvciB0aGlzIHNwZWNpZmljIGluZGV4XG4gICAgLy8gVGhpcyBlbnN1cmVzIGVhY2ggY29uZGl0aW9uIHJvdyBoYXMgaXRzIG93biBoYW5kbGVyIHdoaWxlIHNoYXJpbmcgdGhlIGJhc2UgY29uZmlnXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMudmFsdWVDb25maWdDYWNoZSEsXG4gICAgICBvbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5vblRlbXBsYXRlVmFsdWVDaGFuZ2UoaW5kZXgsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIFxuICBvblRlbXBsYXRlVmFsdWVDaGFuZ2UoaW5kZXg6IG51bWJlciwgdGVtcGxhdGVJZDogYW55KTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgc2VsZWN0ZWQgdGVtcGxhdGVcbiAgICBjb25zdCBzZWxlY3RlZFRlbXBsYXRlID0gdGhpcy5jb25kaXRpb25UZW1wbGF0ZXMuZmluZChcbiAgICAgIHQgPT4gKHQuaWQ/LnRvU3RyaW5nKCkgPT09IHRlbXBsYXRlSWQpIHx8ICh0LmRpc3BsYXlOYW1lID09PSB0ZW1wbGF0ZUlkKVxuICAgICk7XG4gICAgXG4gICAgaWYgKHNlbGVjdGVkVGVtcGxhdGUgJiYgdGhpcy5zZXRDb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlcykge1xuICAgICAgLy8gU3RvcmUgc2VsZWN0ZWQgdGVtcGxhdGVcbiAgICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZXMuc2V0KGluZGV4LCBzZWxlY3RlZFRlbXBsYXRlKTtcbiAgICAgIFxuICAgICAgLy8gR2V0IHRlbXBsYXRlIHZhcmlhYmxlcyB1c2luZyB0aGUgcHJvdmlkZWQgZnVuY3Rpb25cbiAgICAgIGNvbnN0IHZhcmlhYmxlcyA9IHRoaXMuc2V0Q29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMoc2VsZWN0ZWRUZW1wbGF0ZSk7XG4gICAgICB0aGlzLmNvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzLnNldChpbmRleCwgdmFyaWFibGVzKTtcbiAgICAgIC8vIEJ1aWxkIGZvcm0gZm9yIHRlbXBsYXRlIHZhcmlhYmxlc1xuICAgICAgdGhpcy5idWlsZENvbmRpdGlvblZhcmlhYmxlc0Zvcm0oaW5kZXgsIHZhcmlhYmxlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENsZWFyIHRlbXBsYXRlIGFuZCB2YXJpYWJsZXMgaWYgbm8gdGVtcGxhdGUgc2VsZWN0ZWRcbiAgICAgIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZXMuZGVsZXRlKGluZGV4KTtcbiAgICAgIHRoaXMuY29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMuZGVsZXRlKGluZGV4KTtcbiAgICAgIGNvbnN0IGZvcm0gPSB0aGlzLmNvbmRpdGlvblZhcmlhYmxlc0Zvcm1zLmdldChpbmRleCk7XG4gICAgICBpZiAoZm9ybSkge1xuICAgICAgICBPYmplY3Qua2V5cyhmb3JtLmNvbnRyb2xzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgZm9ybS5yZW1vdmVDb250cm9sKGtleSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBcbiAgcHJpdmF0ZSBidWlsZENvbmRpdGlvblZhcmlhYmxlc0Zvcm0oaW5kZXg6IG51bWJlciwgdmFyaWFibGVzOiBhbnlbXSk6IHZvaWQge1xuICAgIGxldCBmb3JtID0gdGhpcy5jb25kaXRpb25WYXJpYWJsZXNGb3Jtcy5nZXQoaW5kZXgpO1xuICAgIGlmICghZm9ybSkge1xuICAgICAgZm9ybSA9IHRoaXMuZmIuZ3JvdXAoe30pO1xuICAgICAgdGhpcy5jb25kaXRpb25WYXJpYWJsZXNGb3Jtcy5zZXQoaW5kZXgsIGZvcm0pO1xuICAgIH1cbiAgICBcbiAgICAvLyBFbnN1cmUgZm9ybSBpcyBub3QgdW5kZWZpbmVkXG4gICAgaWYgKCFmb3JtKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIC8vIENsZWFyIGV4aXN0aW5nIGZvcm0gY29udHJvbHNcbiAgICBPYmplY3Qua2V5cyhmb3JtLmNvbnRyb2xzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBmb3JtIS5yZW1vdmVDb250cm9sKGtleSk7XG4gICAgfSk7XG4gICAgXG4gICAgLy8gQWRkIGZvcm0gY29udHJvbHMgZm9yIGVhY2ggdmFyaWFibGVcbiAgICB2YXJpYWJsZXMuZm9yRWFjaCh2YXJpYWJsZSA9PiB7XG4gICAgICAvLyBIYW5kbGUgYm9vbGVhbiB2YXJpYWJsZXMgLSB1c2UgYm9vbGVhbiB2YWx1ZSwgb3RoZXJzIHVzZSBzdHJpbmdcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHZhcmlhYmxlLnR5cGUgPT09ICdib29sZWFuJyBcbiAgICAgICAgPyAodmFyaWFibGUudmFsdWUgPT09IHRydWUgfHwgdmFyaWFibGUudmFsdWUgPT09ICd0cnVlJyB8fCB2YXJpYWJsZS52YWx1ZSA9PT0gMSlcbiAgICAgICAgOiAodmFyaWFibGUudmFsdWUgfHwgJycpO1xuICAgICAgZm9ybSEuYWRkQ29udHJvbCh2YXJpYWJsZS5uYW1lLCBuZXcgRm9ybUNvbnRyb2woZGVmYXVsdFZhbHVlKSk7XG4gICAgfSk7XG4gIH1cbiAgXG4gIGdldENvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzKGluZGV4OiBudW1iZXIpOiBhbnlbXSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMuZ2V0KGluZGV4KSB8fCBbXTtcbiAgfVxuICBcbiAgZ2V0Q29uZGl0aW9uVmFyaWFibGVzRm9ybShpbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICBsZXQgZm9ybSA9IHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuZ2V0KGluZGV4KTtcbiAgICBpZiAoIWZvcm0pIHtcbiAgICAgIGZvcm0gPSB0aGlzLmZiLmdyb3VwKHt9KTtcbiAgICAgIHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuc2V0KGluZGV4LCBmb3JtKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm07XG4gIH1cbiAgXG4gIGdldFNlbGVjdGVkVGVtcGxhdGUoaW5kZXg6IG51bWJlcik6IEFjdGlvblRlbXBsYXRlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZXMuZ2V0KGluZGV4KSB8fCBudWxsO1xuICB9XG4gIFxuICBnZXRTZWxlY3RDb25maWdGb3JWYXJpYWJsZShpbmRleDogbnVtYmVyLCB2YXJpYWJsZTogYW55KTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHtcbiAgICBjb25zdCBvcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9ICh2YXJpYWJsZS5vcHRpb25zIHx8IFtdKS5tYXAoKG9wdDogc3RyaW5nKSA9PiAoe1xuICAgICAgaWQ6IG9wdCxcbiAgICAgIHZhbHVlOiBvcHQsXG4gICAgICBuYW1lOiBvcHQsXG4gICAgICBsYWJlbDogb3B0XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogdmFyaWFibGUubmFtZSxcbiAgICAgIHBsYWNlaG9sZGVyOiBgU2VsZWN0ICR7dmFyaWFibGUubGFiZWx9YCxcbiAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgIG9uQ2hhbmdlOiAodmFsdWU6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLm9uQ29uZGl0aW9uVmFyaWFibGVWYWx1ZUNoYW5nZShpbmRleCwgdmFyaWFibGUubmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgXG4gIG9uQ29uZGl0aW9uVmFyaWFibGVWYWx1ZUNoYW5nZShjb25kaXRpb25JbmRleDogbnVtYmVyLCB2YXJpYWJsZU5hbWU6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xuICAgIC8vIFVwZGF0ZSB0aGUgdmFyaWFibGUgaW4gdGVtcGxhdGVWYXJpYWJsZXMgYXJyYXlcbiAgICBjb25zdCB2YXJpYWJsZXMgPSB0aGlzLmNvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzLmdldChjb25kaXRpb25JbmRleCkgfHwgW107XG4gICAgY29uc3QgdmFyaWFibGUgPSB2YXJpYWJsZXMuZmluZCh2ID0+IHYubmFtZSA9PT0gdmFyaWFibGVOYW1lKTtcbiAgICBpZiAodmFyaWFibGUpIHtcbiAgICAgIHZhcmlhYmxlLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIC8vIEFsc28gdXBkYXRlIGZvcm0gY29udHJvbFxuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmNvbmRpdGlvblZhcmlhYmxlc0Zvcm1zLmdldChjb25kaXRpb25JbmRleCk7XG4gICAgaWYgKGZvcm0gJiYgZm9ybS5nZXQodmFyaWFibGVOYW1lKSkge1xuICAgICAgZm9ybS5nZXQodmFyaWFibGVOYW1lKT8uc2V0VmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuICBcbiAgb25Db25kaXRpb25WYXJpYWJsZUlucHV0Q2hhbmdlKGNvbmRpdGlvbkluZGV4OiBudW1iZXIsIHZhcmlhYmxlTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgLy8gVXBkYXRlIHRoZSB2YXJpYWJsZSBpbiB0ZW1wbGF0ZVZhcmlhYmxlcyBhcnJheVxuICAgIGNvbnN0IHZhcmlhYmxlcyA9IHRoaXMuY29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMuZ2V0KGNvbmRpdGlvbkluZGV4KSB8fCBbXTtcbiAgICBjb25zdCB2YXJpYWJsZSA9IHZhcmlhYmxlcy5maW5kKHYgPT4gdi5uYW1lID09PSB2YXJpYWJsZU5hbWUpO1xuICAgIGlmICh2YXJpYWJsZSkge1xuICAgICAgdmFyaWFibGUudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgLy8gQWxzbyB1cGRhdGUgZm9ybSBjb250cm9sXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuZ2V0KGNvbmRpdGlvbkluZGV4KTtcbiAgICBpZiAoZm9ybSAmJiBmb3JtLmdldCh2YXJpYWJsZU5hbWUpKSB7XG4gICAgICBmb3JtLmdldCh2YXJpYWJsZU5hbWUpPy5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgb25Db25kaXRpb25WYXJpYWJsZUJvb2xlYW5DaGFuZ2UoY29uZGl0aW9uSW5kZXg6IG51bWJlciwgdmFyaWFibGVOYW1lOiBzdHJpbmcsIHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgLy8gVXBkYXRlIHRoZSB2YXJpYWJsZSBpbiB0ZW1wbGF0ZVZhcmlhYmxlcyBhcnJheVxuICAgIGNvbnN0IHZhcmlhYmxlcyA9IHRoaXMuY29uZGl0aW9uVGVtcGxhdGVWYXJpYWJsZXMuZ2V0KGNvbmRpdGlvbkluZGV4KSB8fCBbXTtcbiAgICBjb25zdCB2YXJpYWJsZSA9IHZhcmlhYmxlcy5maW5kKHYgPT4gdi5uYW1lID09PSB2YXJpYWJsZU5hbWUpO1xuICAgIGlmICh2YXJpYWJsZSkge1xuICAgICAgdmFyaWFibGUudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgLy8gQWxzbyB1cGRhdGUgZm9ybSBjb250cm9sXG4gICAgY29uc3QgZm9ybSA9IHRoaXMuY29uZGl0aW9uVmFyaWFibGVzRm9ybXMuZ2V0KGNvbmRpdGlvbkluZGV4KTtcbiAgICBpZiAoZm9ybSkge1xuICAgICAgaWYgKGZvcm0uZ2V0KHZhcmlhYmxlTmFtZSkpIHtcbiAgICAgICAgZm9ybS5nZXQodmFyaWFibGVOYW1lKT8uc2V0VmFsdWUodmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3JlYXRlIGZvcm0gY29udHJvbCBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICAgIGZvcm0uYWRkQ29udHJvbCh2YXJpYWJsZU5hbWUsIG5ldyBGb3JtQ29udHJvbCh2YWx1ZSkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldENvbmRpdGlvbkZvcm1Hcm91cChpbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5jb25kaXRpb25zRm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gIH1cblxuICBvbkluY2x1ZGVFbHNlQ2hhbmdlKGNoZWNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmluY2x1ZGVFbHNlID0gY2hlY2tlZDtcbiAgICB0aGlzLmNvbmRpdGlvbkZvcm0ucGF0Y2hWYWx1ZSh7IGluY2x1ZGVFbHNlOiBjaGVja2VkIH0pO1xuICB9XG5cbiAgb25DYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWxsZWQuZW1pdCgpO1xuICB9XG5cbiAgb25DcmVhdGVTdGVwKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmRpdGlvbkZvcm0udmFsaWQpIHtcbiAgICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMuY29uZGl0aW9uRm9ybS52YWx1ZTtcbiAgICAgIGNvbnN0IHN0ZXBEYXRhOiBDb25kaXRpb25Gb3JtRGF0YSA9IHtcbiAgICAgICAgY29uZGl0aW9uczogZm9ybVZhbHVlLmNvbmRpdGlvbnMubWFwKChjb25kOiBhbnksIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAvLyBGaW5kIHRoZSBBY3Rpb25UZW1wbGF0ZSBvYmplY3QgZnJvbSB0aGUgc3RvcmVkIElEL3ZhbHVlXG4gICAgICAgICAgY29uc3QgdGVtcGxhdGVJZCA9IGNvbmQudmFsdWU7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRUZW1wbGF0ZSA9IHRoaXMuY29uZGl0aW9uVGVtcGxhdGVzLmZpbmQoXG4gICAgICAgICAgICB0ID0+ICh0LmlkPy50b1N0cmluZygpID09PSB0ZW1wbGF0ZUlkKSB8fCAodC5kaXNwbGF5TmFtZSA9PT0gdGVtcGxhdGVJZClcbiAgICAgICAgICApIHx8IHRoaXMuc2VsZWN0ZWRUZW1wbGF0ZXMuZ2V0KGluZGV4KTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBHZXQgdGVtcGxhdGUgdmFyaWFibGVzIGZvciB0aGlzIGNvbmRpdGlvblxuICAgICAgICAgIGNvbnN0IHRlbXBsYXRlVmFyaWFibGVzID0gdGhpcy5jb25kaXRpb25UZW1wbGF0ZVZhcmlhYmxlcy5nZXQoaW5kZXgpIHx8IFtdO1xuICAgICAgICAgIFxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmaWVsZDogY29uZC5maWVsZCxcbiAgICAgICAgICAgIG9wZXJhdG9yOiBjb25kLm9wZXJhdG9yLFxuICAgICAgICAgICAgdmFsdWU6IHNlbGVjdGVkVGVtcGxhdGUgfHwgbnVsbCxcbiAgICAgICAgICAgIHRlbXBsYXRlVmFyaWFibGVzOiB0ZW1wbGF0ZVZhcmlhYmxlcyxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBjb25kLmRlc2NyaXB0aW9uIHx8ICcnLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGNvbmQubWV0YWRhdGEgfHwgJydcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICAgaW5jbHVkZUVsc2U6IGZvcm1WYWx1ZS5pbmNsdWRlRWxzZSB8fCBmYWxzZVxuICAgICAgfTtcbiAgICAgIGNvbnNvbGUubG9nKCdzdGVwRGF0YScsIHN0ZXBEYXRhKTtcbiAgICAgIHRoaXMuY3JlYXRlU3RlcC5lbWl0KHN0ZXBEYXRhKTtcbiAgICB9XG4gIH1cbn1cblxuIiwiPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtaC1mdWxsIGNxYS1iZy13aGl0ZSBjcWEtcHgtNCBjcWEtcHktMlwiPlxuICA8IS0tIEhlYWRlciAtLT5cbiAgPGgyIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWJsYWNrLTEwMCBjcWEtbWItNFwiPlxuICAgIENyZWF0ZSBDb25kaXRpb24gU3RlcFxuICA8L2gyPlxuXG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWZsZXgtMSBjcWEtb3ZlcmZsb3cteS1hdXRvXCI+XG4gICAgPCEtLSBDb25kaXRpb24gQnVpbGRlciBTZWN0aW9uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtbWItNlwiPlxuICAgICAgPGgzIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLXRleHQtWzEycHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwIGNxYS1tYi0zXCI+XG4gICAgICAgIENvbmRpdGlvbiBCdWlsZGVyXG4gICAgICA8L2gzPlxuXG4gICAgICA8IS0tIENvbmRpdGlvbiBSb3dzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTMgY3FhLW1iLTNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29uZGl0aW9uIG9mIGNvbmRpdGlvbnNGb3JtQXJyYXkuY29udHJvbHM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAqbmdJZj1cImdldENvbmRpdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2ZpZWxkJyk/LnZhbHVlID09PSAnQ09ORElUSU9OX0lGJyB8fCBnZXRDb25kaXRpb25Gb3JtR3JvdXAoaSkuZ2V0KCdmaWVsZCcpPy52YWx1ZSA9PT0gJ0NPTkRJVElPTl9FTFNFX0lGJ1wiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgIDwhLS0gQ29uZGl0aW9uIFJvdyAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgICA8IS0tIENvbmRpdGlvbiBMYWJlbCAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZFwiPlxuICAgICAgICAgICAgICAgIHt7Z2V0Q29uZGl0aW9uRm9ybUdyb3VwKGkpLmdldCgnZmllbGQnKT8udmFsdWUgPT09ICdDT05ESVRJT05fSUYnID8gJ0lGJyA6XG4gICAgICAgICAgICAgICAgZ2V0Q29uZGl0aW9uRm9ybUdyb3VwKGkpLmdldCgnZmllbGQnKT8udmFsdWUgPT09ICdDT05ESVRJT05fRUxTRV9JRicgPyAnRUxTRSBJRicgOiAnRUxTRSd9fVxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICA8IS0tIE9wZXJhdG9yIERyb3Bkb3duIC0tPlxuICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1tYXgtdy1bMTAwcHhdIGNxYS10ZXh0LVsxMHB4XVwiPlxuICAgICAgICAgICAgICAgIDxjcWEtZHluYW1pYy1zZWxlY3QgW2Zvcm1dPVwiZ2V0Q29uZGl0aW9uRm9ybUdyb3VwKGkpXCIgW2NvbmZpZ109XCJnZXRPcGVyYXRvckNvbmZpZyhpKVwiPlxuICAgICAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgICA8L2Rpdj4gLS0+XG5cbiAgICAgICAgICAgICAgPCEtLSBWYWx1ZSBUZW1wbGF0ZSBEcm9wZG93biAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW1pbi13LVsxNTBweF0gY3FhLXRleHQtWzEwcHhdXCI+XG4gICAgICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCBbZm9ybV09XCJnZXRDb25kaXRpb25Gb3JtR3JvdXAoaSlcIiBbY29uZmlnXT1cImdldFZhbHVlQ29uZmlnKGkpXCI+XG4gICAgICAgICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gUmVtb3ZlIEJ1dHRvbiAtLT5cbiAgICAgICAgICAgICAgPGNxYS1idXR0b25cbiAgICAgICAgICAgICAgICAqbmdJZj1cImkgPj0gMVwiXG4gICAgICAgICAgICAgICAgdmFyaWFudD1cInRleHRcIlxuICAgICAgICAgICAgICAgIGljb249XCJjbG9zZVwiXG4gICAgICAgICAgICAgICAgaWNvblBvc2l0aW9uPVwic3RhcnRcIlxuICAgICAgICAgICAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXctZnVsbCBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlcidcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVDb25kaXRpb24oaSlcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1JlbW92ZSBjb25kaXRpb24nXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWJ1dHRvbj5cbiAgICAgICAgICAgICAgPCEtLSA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXctOCBjcWEtaC04IGNxYS1yb3VuZGVkIGNxYS10ZXh0LWdyYXktNTAwIGhvdmVyOmNxYS10ZXh0LWdyYXktNzAwIGhvdmVyOmNxYS1iZy1ncmF5LTEwMCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVDb25kaXRpb24oaSlcIiAqbmdJZj1cImkgPj0gMVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInUmVtb3ZlIGNvbmRpdGlvbidcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1sZyBjcWEtdGV4dC1bMjRweF1cIj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPiAtLT5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIFRlbXBsYXRlIFZhcmlhYmxlcyBTZWN0aW9uIChzaG93biB3aGVuIHRlbXBsYXRlIGlzIHNlbGVjdGVkKSAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJnZXRTZWxlY3RlZFRlbXBsYXRlKGkpXCI+XG4gICAgICAgICAgICAgIDwhLS0gVGVtcGxhdGUgR3JhbW1hciBEaXNwbGF5IC0tPlxuICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWxlYWRpbmctWzIzcHhdIGNxYS10ZXh0LWJsYWNrLTEwMFwiXG4gICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJnZXRTZWxlY3RlZFRlbXBsYXRlKGkpPy5odG1sR3JhbW1hciB8fCBnZXRTZWxlY3RlZFRlbXBsYXRlKGkpPy5uYXR1cmFsVGV4dCB8fCAnJ1wiPlxuICAgICAgICAgICAgICA8L2Rpdj4gLS0+XG5cbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIDwhLS0gRGVzY3JpcHRpb24gYW5kIE1ldGFkYXRhIElucHV0cyAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4IGNxYS1nYXAteC00IGNxYS1tYi00XCIgc3R5bGU9XCJmbGV4LXdyYXA6IHdyYXA7XCI+XG4gICAgICAgICAgICAgICAgPCEtLSBEZXNjcmlwdGlvbiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCIgc3R5bGU9XCJ3aWR0aDogY2FsYyg1MCUgLSAxMnB4KTtcIj5cbiAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtZ3JheS03MDAgY3FhLW1iLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0VudGVyIGRlc2NyaXB0aW9uJ1wiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRDb25kaXRpb25Gb3JtR3JvdXAoaSkuZ2V0KCdkZXNjcmlwdGlvbicpPy52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJnZXRDb25kaXRpb25Gb3JtR3JvdXAoaSkuZ2V0KCdkZXNjcmlwdGlvbicpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIE1ldGFkYXRhIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIiBzdHlsZT1cIndpZHRoOiBjYWxjKDUwJSAtIDEycHgpO1wiPlxuICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtbWItMVwiPlxuICAgICAgICAgICAgICAgICAgICBNZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgbWV0YWRhdGEnXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImdldENvbmRpdGlvbkZvcm1Hcm91cChpKS5nZXQoJ21ldGFkYXRhJyk/LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cImdldENvbmRpdGlvbkZvcm1Hcm91cChpKS5nZXQoJ21ldGFkYXRhJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPCEtLSBUZW1wbGF0ZSBWYXJpYWJsZXMgRm9ybSBGaWVsZHMgLS0+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC00XCIgIHN0eWxlPVwiZmxleC13cmFwOiB3cmFwO1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHZhcmlhYmxlIG9mIGdldENvbmRpdGlvblRlbXBsYXRlVmFyaWFibGVzKGkpXCI+XG4gICAgICAgICAgICAgICAgICA8IS0tIEJvb2xlYW4gdmFyaWFibGVzIHdpdGggbWF0LXNsaWRlLXRvZ2dsZSAtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ2YXJpYWJsZS50eXBlID09PSAnYm9vbGVhbidcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCIgc3R5bGU9XCJ3aWR0aDogY2FsYyg1MCUgLSAxMnB4KTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LWdyYXktNzAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyB2YXJpYWJsZS5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImdldENvbmRpdGlvblZhcmlhYmxlc0Zvcm0oaSkuZ2V0KHZhcmlhYmxlLm5hbWUpPy52YWx1ZSB8fCB2YXJpYWJsZS52YWx1ZSB8fCBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ29uZGl0aW9uVmFyaWFibGVCb29sZWFuQ2hhbmdlKGksIHZhcmlhYmxlLm5hbWUsICRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgIDwhLS0gTm9uLWJvb2xlYW4sIG5vbi1jdXN0b21fY29kZSB2YXJpYWJsZXMgLS0+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidmFyaWFibGUubmFtZSAhPT0gJ2N1c3RvbV9jb2RlJyAmJiB2YXJpYWJsZS50eXBlICE9PSAnYm9vbGVhbidcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEcm9wZG93biBmb3Igc2VsZWN0IHZhcmlhYmxlcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInZhcmlhYmxlLm5hbWUgPT09ICd0eXBlJyB8fCB2YXJpYWJsZS5uYW1lID09PSAnc2Nyb2xsVG8nIHx8IHZhcmlhYmxlLm9wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCIgc3R5bGU9XCJ3aWR0aDogY2FsYyg1MCUgLSAxMnB4KTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtZ3JheS03MDAgY3FhLW1iLTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdmFyaWFibGUubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImdldENvbmRpdGlvblZhcmlhYmxlc0Zvcm0oaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZ0ZvclZhcmlhYmxlKGksIHZhcmlhYmxlKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIFRleHQgSW5wdXQgZm9yIG90aGVyIHZhcmlhYmxlcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInZhcmlhYmxlLm5hbWUgIT09ICd0eXBlJyAmJiB2YXJpYWJsZS5uYW1lICE9PSAnc2Nyb2xsVG8nICYmICF2YXJpYWJsZS5vcHRpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiIHN0eWxlPVwid2lkdGg6IGNhbGMoNTAlIC0gMTJweCk7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LWdyYXktNzAwIGNxYS1tYi0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHZhcmlhYmxlLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidUZXh0IElucHV0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJ2YXJpYWJsZS52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvbkNvbmRpdGlvblZhcmlhYmxlSW5wdXRDaGFuZ2UoaSwgdmFyaWFibGUubmFtZSwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQWRkIENvbmRpdGlvbiBCdXR0b24gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWJvcmRlci0yIGNxYS1ib3JkZXItZGFzaGVkIGNxYS1ib3JkZXItZ3JheS0zMDAgY3FhLXJvdW5kZWQtbGcgY3FhLXAtMSBjcWEtbXQtM1wiPlxuICAgICAgICA8Y3FhLWJ1dHRvblxuICAgICAgICAgIHZhcmlhbnQ9XCJ0ZXh0XCJcbiAgICAgICAgICBpY29uPVwiYWRkXCJcbiAgICAgICAgICBpY29uUG9zaXRpb249XCJzdGFydFwiXG4gICAgICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtdy1mdWxsIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyJ1wiXG4gICAgICAgICAgW3RleHRdPVwiJ0FkZCBDb25kaXRpb24nXCJcbiAgICAgICAgICAoY2xpY2tlZCk9XCJhZGRDb25kaXRpb24oJ0NPTkRJVElPTl9FTFNFX0lGJylcIj5cbiAgICAgICAgPC9jcWEtYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEluY2x1ZGUgRUxTRSBCcmFuY2ggU2VjdGlvbiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1tYi02IGNxYS1wLTMgY3FhLWJnLWdyYXktNTAgY3FhLXJvdW5kZWQtbGdcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIj5cbiAgICAgICAgPGgzIGNsYXNzPVwiY3FhLXRleHQtWzE0cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwIGNxYS1tYi0xXCI+XG4gICAgICAgICAgSW5jbHVkZSBFTFNFIGJyYW5jaFxuICAgICAgICA8L2gzPlxuICAgICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtdGV4dC1ncmF5LTYwMFwiPlxuICAgICAgICAgIEV4ZWN1dGUgYWx0ZXJuYXRpdmUgc3RlcHMgd2hlbiBjb25kaXRpb24gaXMgbm90IG1ldC5cbiAgICAgICAgPC9wPlxuICAgICAgPC9kaXY+XG4gICAgICA8bWF0LXNsaWRlLXRvZ2dsZSBbY2hlY2tlZF09XCJpbmNsdWRlRWxzZVwiIChjaGFuZ2UpPVwib25JbmNsdWRlRWxzZUNoYW5nZSgkZXZlbnQuY2hlY2tlZClcIiBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwhLS0gQWN0aW9uIEJ1dHRvbnMgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtdy1mdWxsIGNxYS1nYXAtMiBjcWEtbXQtYXV0byBjcWEtcHQtNCBjcWEtYm9yZGVyLXQgY3FhLWJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDxjcWEtYnV0dG9uIGNsYXNzPVwiY3FhLXctMS8yXCIgdmFyaWFudD1cIm91dGxpbmVkXCIgdGV4dD1cIkNhbmNlbFwiIFtjdXN0b21DbGFzc109XCInY3FhLWZsZXgtMSBjcWEtdy1mdWxsJ1wiXG4gICAgICAoY2xpY2tlZCk9XCJvbkNhbmNlbCgpXCI+XG4gICAgPC9jcWEtYnV0dG9uPlxuICAgIDxjcWEtYnV0dG9uIGNsYXNzPVwiY3FhLXctMS8yXCIgdmFyaWFudD1cImZpbGxlZFwiIHRleHQ9XCJDcmVhdGUgU3RlcFwiIFtjdXN0b21DbGFzc109XCInY3FhLWZsZXgtMSBjcWEtdy1mdWxsJ1wiXG4gICAgICAoY2xpY2tlZCk9XCJvbkNyZWF0ZVN0ZXAoKVwiPlxuICAgIDwvY3FhLWJ1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=