@cqa-lib/cqa-ui 1.1.218 → 1.1.220

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 (45) hide show
  1. package/esm2020/lib/execution-screen/ai-action-step/ai-action-step.component.mjs +44 -8
  2. package/esm2020/lib/execution-screen/ai-agent-step/ai-agent-step.component.mjs +44 -8
  3. package/esm2020/lib/execution-screen/api-step/api-step.component.mjs +44 -8
  4. package/esm2020/lib/execution-screen/basic-step/basic-step.component.mjs +53 -9
  5. package/esm2020/lib/execution-screen/condition-step/condition-step.component.mjs +56 -9
  6. package/esm2020/lib/execution-screen/db-verification-step/db-verification-step.component.mjs +48 -12
  7. package/esm2020/lib/execution-screen/document-verification-step/document-verification-step.component.mjs +41 -5
  8. package/esm2020/lib/execution-screen/execution-step.models.mjs +14 -2
  9. package/esm2020/lib/execution-screen/failed-step/failed-step.component.mjs +41 -5
  10. package/esm2020/lib/execution-screen/file-download-step/file-download-step.component.mjs +42 -6
  11. package/esm2020/lib/execution-screen/live-execution-step/live-execution-step.component.mjs +42 -5
  12. package/esm2020/lib/execution-screen/loop-step/loop-step.component.mjs +65 -11
  13. package/esm2020/lib/execution-screen/main-step-collapse/main-step-collapse.component.mjs +41 -4
  14. package/esm2020/lib/execution-screen/session-changes-modal/session-changes-modal.component.mjs +83 -0
  15. package/esm2020/lib/execution-screen/step-group/step-group.component.mjs +53 -6
  16. package/esm2020/lib/execution-screen/step-renderer/step-renderer.component.mjs +297 -28
  17. package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +4 -4
  18. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer.component.mjs +140 -6
  19. package/esm2020/lib/ui-kit.module.mjs +6 -1
  20. package/esm2020/public-api.mjs +2 -1
  21. package/fesm2015/cqa-lib-cqa-ui.mjs +1103 -94
  22. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  23. package/fesm2020/cqa-lib-cqa-ui.mjs +1086 -94
  24. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  25. package/lib/execution-screen/ai-action-step/ai-action-step.component.d.ts +12 -2
  26. package/lib/execution-screen/ai-agent-step/ai-agent-step.component.d.ts +12 -2
  27. package/lib/execution-screen/api-step/api-step.component.d.ts +12 -2
  28. package/lib/execution-screen/basic-step/basic-step.component.d.ts +18 -2
  29. package/lib/execution-screen/condition-step/condition-step.component.d.ts +21 -2
  30. package/lib/execution-screen/db-verification-step/db-verification-step.component.d.ts +12 -2
  31. package/lib/execution-screen/document-verification-step/document-verification-step.component.d.ts +12 -2
  32. package/lib/execution-screen/execution-step.models.d.ts +14 -0
  33. package/lib/execution-screen/failed-step/failed-step.component.d.ts +11 -2
  34. package/lib/execution-screen/file-download-step/file-download-step.component.d.ts +12 -2
  35. package/lib/execution-screen/live-execution-step/live-execution-step.component.d.ts +12 -2
  36. package/lib/execution-screen/loop-step/loop-step.component.d.ts +23 -2
  37. package/lib/execution-screen/main-step-collapse/main-step-collapse.component.d.ts +18 -2
  38. package/lib/execution-screen/session-changes-modal/session-changes-modal.component.d.ts +34 -0
  39. package/lib/execution-screen/step-group/step-group.component.d.ts +23 -2
  40. package/lib/execution-screen/step-renderer/step-renderer.component.d.ts +33 -3
  41. package/lib/test-case-details/step-details-drawer/step-details-drawer.component.d.ts +24 -0
  42. package/lib/ui-kit.module.d.ts +72 -71
  43. package/package.json +1 -1
  44. package/public-api.d.ts +1 -0
  45. package/styles.css +1 -1
@@ -4,9 +4,9 @@ import { STEP_DETAILS_DRAWER_DATA } from './step-details-drawer-data';
4
4
  import * as i0 from "@angular/core";
5
5
  import * as i1 from "@angular/forms";
6
6
  import * as i2 from "../../custom-input/custom-input.component";
7
- import * as i3 from "../../custom-textarea/custom-textarea.component";
8
- import * as i4 from "../../custom-toggle/custom-toggle.component";
9
- import * as i5 from "../../dynamic-select/dynamic-select-field.component";
7
+ import * as i3 from "../../dynamic-select/dynamic-select-field.component";
8
+ import * as i4 from "../../custom-textarea/custom-textarea.component";
9
+ import * as i5 from "../../custom-toggle/custom-toggle.component";
10
10
  import * as i6 from "@angular/material/icon";
11
11
  import * as i7 from "../../button/button.component";
12
12
  import * as i8 from "@angular/common";
@@ -36,6 +36,19 @@ export class StepDetailsDrawerComponent {
36
36
  this.pwLocator = [];
37
37
  /** Cached select configs per field key (stable refs for change detection). */
38
38
  this.selectConfigCache = {};
39
+ /** Cache for data type select configs */
40
+ this.dataTypeSelectConfigCache = {};
41
+ /** Store data types for test-data fields */
42
+ this.fieldDataTypes = new Map();
43
+ /** Store raw values (without formatting) for test-data fields */
44
+ this.fieldRawValues = new Map();
45
+ /** Pre-computed data type options (static, no need to recreate) */
46
+ this.dataTypeOptions = [
47
+ { id: 'plain-text', value: 'plain-text', name: 'Plain Text', label: 'Plain Text' },
48
+ { id: 'parameter', value: 'parameter', name: '@|Parameter|', label: '@|Parameter|' },
49
+ { id: 'runtime', value: 'runtime', name: '$|Runtime|', label: '$|Runtime|' },
50
+ { id: 'environment', value: 'environment', name: '*|Environment|', label: '*|Environment|' }
51
+ ];
39
52
  this.step = data?.step ?? {};
40
53
  this.stepNumber = data?.stepNumber ?? 1;
41
54
  this.dynamicFields = data?.dynamicFields ?? [];
@@ -126,9 +139,21 @@ export class StepDetailsDrawerComponent {
126
139
  ? field.defaultValue
127
140
  : raw;
128
141
  group[field.key] = [value];
142
+ // Initialize data types and raw values for test-data fields
143
+ if (this.needsDataTypeDropdown(field)) {
144
+ const { dataType, rawValue } = this.parseTestDataValue(String(value || ''));
145
+ this.fieldDataTypes.set(field.key, dataType);
146
+ this.fieldRawValues.set(field.key, rawValue);
147
+ // Ensure form control exists for data type
148
+ const dataTypeControlName = `${field.key}_dataType`;
149
+ if (!this.form.get(dataTypeControlName)) {
150
+ group[dataTypeControlName] = [dataType];
151
+ }
152
+ }
129
153
  }
130
154
  this.form = this.fb.group(group);
131
155
  this.selectConfigCache = {};
156
+ this.dataTypeSelectConfigCache = {};
132
157
  }
133
158
  /** Read value from step by key. No step-type logic; step is a generic key-value bag. */
134
159
  getStepValue(key) {
@@ -204,12 +229,121 @@ export class StepDetailsDrawerComponent {
204
229
  get displayTitle() {
205
230
  return this.drawerTitleValue;
206
231
  }
232
+ /** Check if field needs data type dropdown (test-data, source-value, target-value) */
233
+ needsDataTypeDropdown(field) {
234
+ const label = field.label?.toLowerCase() || '';
235
+ return label === 'test-data' || label === 'source-value' || label === 'target-value' ||
236
+ label === 'source_value' || label === 'target_value';
237
+ }
238
+ /** Parse test data value to extract data type and raw value */
239
+ parseTestDataValue(value) {
240
+ if (!value || typeof value !== 'string') {
241
+ return { dataType: 'plain-text', rawValue: '' };
242
+ }
243
+ // Check for parameter format: @|value|
244
+ if (value.startsWith('@|') && value.endsWith('|')) {
245
+ return { dataType: 'parameter', rawValue: value.slice(2, -1) };
246
+ }
247
+ // Check for runtime format: $|value|
248
+ else if (value.startsWith('$|') && value.endsWith('|')) {
249
+ return { dataType: 'runtime', rawValue: value.slice(2, -1) };
250
+ }
251
+ // Check for environment format: *|value|
252
+ else if (value.startsWith('*|') && value.endsWith('|')) {
253
+ return { dataType: 'environment', rawValue: value.slice(2, -1) };
254
+ }
255
+ // Plain text (no formatting)
256
+ else {
257
+ return { dataType: 'plain-text', rawValue: value };
258
+ }
259
+ }
260
+ /** Format test data value based on data type */
261
+ formatTestDataValue(rawValue, dataType) {
262
+ if (!rawValue) {
263
+ return '';
264
+ }
265
+ switch (dataType) {
266
+ case 'parameter':
267
+ return `@|${rawValue}|`;
268
+ case 'runtime':
269
+ return `$|${rawValue}|`;
270
+ case 'environment':
271
+ return `*|${rawValue}|`;
272
+ case 'plain-text':
273
+ default:
274
+ return rawValue;
275
+ }
276
+ }
277
+ /** Get data type select config for a field */
278
+ getDataTypeSelectConfig(field) {
279
+ if (!this.needsDataTypeDropdown(field))
280
+ return null;
281
+ if (this.dataTypeSelectConfigCache[field.key]) {
282
+ return this.dataTypeSelectConfigCache[field.key];
283
+ }
284
+ const dataTypeControlName = `${field.key}_dataType`;
285
+ // Ensure form control exists
286
+ if (!this.form.get(dataTypeControlName)) {
287
+ const currentDataType = this.fieldDataTypes.get(field.key) || 'plain-text';
288
+ this.form.addControl(dataTypeControlName, this.fb.control(currentDataType));
289
+ }
290
+ const config = {
291
+ key: dataTypeControlName,
292
+ placeholder: 'Select Type',
293
+ multiple: false,
294
+ searchable: false,
295
+ options: this.dataTypeOptions,
296
+ onChange: (value) => {
297
+ this.onDataTypeChange(field.key, value);
298
+ }
299
+ };
300
+ this.dataTypeSelectConfigCache[field.key] = config;
301
+ return config;
302
+ }
303
+ /** Get current data type for a field */
304
+ getCurrentDataType(field) {
305
+ return this.fieldDataTypes.get(field.key) || 'plain-text';
306
+ }
307
+ /** Get raw value (without formatting) for a field */
308
+ getRawValue(field) {
309
+ return this.fieldRawValues.get(field.key) || '';
310
+ }
311
+ /** Handle data type change */
312
+ onDataTypeChange(fieldKey, dataType) {
313
+ // Update stored data type
314
+ this.fieldDataTypes.set(fieldKey, dataType);
315
+ // Get current raw value
316
+ const rawValue = this.fieldRawValues.get(fieldKey) || '';
317
+ // Format the value based on new data type
318
+ const formattedValue = this.formatTestDataValue(rawValue, dataType);
319
+ // Update form control
320
+ if (this.form.get(fieldKey)) {
321
+ this.form.get(fieldKey)?.setValue(formattedValue, { emitEvent: false });
322
+ }
323
+ // Mark for check since we're using OnPush
324
+ this.cdr.markForCheck();
325
+ }
326
+ /** Handle test data value change (raw value input) */
327
+ onTestDataValueChange(fieldKey, rawValue) {
328
+ // Update stored raw value
329
+ this.fieldRawValues.set(fieldKey, rawValue);
330
+ // Get current data type
331
+ const dataType = this.fieldDataTypes.get(fieldKey) || 'plain-text';
332
+ // Format the value based on data type
333
+ const formattedValue = this.formatTestDataValue(rawValue, dataType);
334
+ // Update form control
335
+ if (this.form.get(fieldKey)) {
336
+ this.form.get(fieldKey)?.setValue(formattedValue, { emitEvent: false });
337
+ }
338
+ // Mark for check since we're using OnPush
339
+ this.cdr.markForCheck();
340
+ }
207
341
  }
208
342
  StepDetailsDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerComponent, deps: [{ token: STEP_DETAILS_DRAWER_REF }, { token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: STEP_DETAILS_DRAWER_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
209
- StepDetailsDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepDetailsDrawerComponent, selector: "cqa-step-details-drawer", inputs: { stepData: "stepData", stepNumberInput: "stepNumberInput", dynamicFieldsInput: "dynamicFieldsInput", drawerTitle: "drawerTitle" }, outputs: { saveChanges: "saveChanges", cancel: "cancel", saveAsTemplate: "saveAsTemplate" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<!-- Step Details Drawer \u2013 Edit In Depth. Fully dynamic from DynamicFieldConfig[]. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-bg-white\"\n style=\"border-bottom: 1px solid #E5E5E5;\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 20L14 16L18 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[19px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ displayTitle }}\n </h2>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[5px] cqa-bg-[#D8D9FC] cqa-text-[#090A60] cqa-text-[12px]\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 9L9 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M9 9L19 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- Content: all fields from dynamicFields array (main + constraints in order, then advanced grouped) -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-p-4 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <ng-container *ngIf=\"dynamicFields.length > 0\">\n <!-- All non-advanced fields in array order with section headers -->\n <ng-container *ngFor=\"let field of dynamicFields; let i = index\">\n <ng-container *ngIf=\"isNonAdvancedField(i)\">\n <p *ngIf=\"isFirstInSection(i, 'main')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Attributes</p>\n <p *ngIf=\"isFirstInSection(i, 'constraints')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Constraints</p>\n\n <!-- string / undefined \u2192 text input -->\n <div *ngIf=\"(field.type ?? 'string') === 'string'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- number -->\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea -->\n <div *ngIf=\"field.type === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <span *ngIf=\"field.required\"\n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"field.rows || 4\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"field.tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa--mt-1.5\">{{ field.tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"field.type === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- boolean \u2192 toggle -->\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ field.label }}</p>\n <span *ngIf=\"field.subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{\n field.subLabel }}</span>\n </div>\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n\n <!-- dropdown -->\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Advanced: expandable (all advanced fields from array) -->\n <ng-container *ngIf=\"advancedFields.length > 0\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <ng-container *ngFor=\"let field of advancedFields\">\n <div *ngIf=\"(field.type ?? 'string') === 'string'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\"\n [value]=\"form.get(field.key)?.value\" [fullWidth]=\"true\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ field.label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"field.subLabel\">{{ field.subLabel }}</span>\n </div>\n </div>\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Other Locators section (matching old UI) -->\n <ng-container *ngIf=\"pwLocator && pwLocator.length > 0\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Other Locators</p>\n <div *ngFor=\"let locator of pwLocator; let i = index\" class=\"cqa-mb-3\">\n <div *ngIf=\"locator !== ''\" class=\"cqa-relative cqa-flex cqa-items-center\">\n <input type=\"text\" [value]=\"locator\" #locatorInput readonly\n class=\"cqa-w-full cqa-px-3 cqa-py-2 cqa-pr-20 cqa-border cqa-border-[#E5E7EB] cqa-rounded cqa-text-[14px] cqa-bg-white\"\n style=\"padding-left: 26px;\">\n <button type=\"button\" (click)=\"copyLocator(locatorInput)\"\n class=\"cqa-absolute cqa-left-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#374151]\"\n title=\"Click to Copy\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">content_copy</mat-icon>\n </button>\n <button type=\"button\" (click)=\"deleteLocator(i)\"\n class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#DC2626]\"\n title=\"Delete\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">delete</mat-icon>\n </button>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <p *ngIf=\"dynamicFields.length === 0\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">No fields configured for this step.\n </p>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-white\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>", components: [{ type: i2.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: i3.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "enableMarkdown", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: i4.CustomToggleComponent, selector: "cqa-custom-toggle", inputs: ["checked", "disabled", "ariaLabel"], outputs: ["checkedChange", "change"] }, { type: i5.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i7.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
343
+ StepDetailsDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepDetailsDrawerComponent, selector: "cqa-step-details-drawer", inputs: { stepData: "stepData", stepNumberInput: "stepNumberInput", dynamicFieldsInput: "dynamicFieldsInput", drawerTitle: "drawerTitle" }, outputs: { saveChanges: "saveChanges", cancel: "cancel", saveAsTemplate: "saveAsTemplate" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<!-- Step Details Drawer \u2013 Edit In Depth. Fully dynamic from DynamicFieldConfig[]. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-bg-white\"\n style=\"border-bottom: 1px solid #E5E5E5;\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 20L14 16L18 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[19px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ displayTitle }}\n </h2>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[5px] cqa-bg-[#D8D9FC] cqa-text-[#090A60] cqa-text-[12px]\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 9L9 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M9 9L19 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- Content: all fields from dynamicFields array (main + constraints in order, then advanced grouped) -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-p-4 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <ng-container *ngIf=\"dynamicFields.length > 0\">\n <!-- All non-advanced fields in array order with section headers -->\n <ng-container *ngFor=\"let field of dynamicFields; let i = index\">\n <ng-container *ngIf=\"isNonAdvancedField(i)\">\n <p *ngIf=\"isFirstInSection(i, 'main')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Attributes</p>\n <p *ngIf=\"isFirstInSection(i, 'constraints')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Constraints</p>\n\n <!-- string / undefined \u2192 text input -->\n <div *ngIf=\"(field.type ?? 'string') === 'string' && !needsDataTypeDropdown(field)\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"(field.type ?? 'string') === 'string' && needsDataTypeDropdown(field)\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }} Type</label>\n <cqa-dynamic-select *ngIf=\"getDataTypeSelectConfig(field) && form.contains(field.key + '_dataType')\" \n [form]=\"form\" [config]=\"getDataTypeSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"getRawValue(field)\"\n [fullWidth]=\"true\" (valueChange)=\"onTestDataValueChange(field.key, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- number -->\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea -->\n <div *ngIf=\"field.type === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <span *ngIf=\"field.required\"\n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"field.rows || 4\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"field.tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa--mt-1.5\">{{ field.tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"field.type === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- boolean \u2192 toggle -->\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ field.label }}</p>\n <span *ngIf=\"field.subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{\n field.subLabel }}</span>\n </div>\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n\n <!-- dropdown -->\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Advanced: expandable (all advanced fields from array) -->\n <ng-container *ngIf=\"advancedFields.length > 0\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <ng-container *ngFor=\"let field of advancedFields\">\n <div *ngIf=\"(field.type ?? 'string') === 'string' && !needsDataTypeDropdown(field)\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n \n <!-- Test-data, source-value, or target-value with data type dropdown in advanced section -->\n <ng-container *ngIf=\"(field.type ?? 'string') === 'string' && needsDataTypeDropdown(field)\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }} Type</label>\n <cqa-dynamic-select *ngIf=\"getDataTypeSelectConfig(field) && form.contains(field.key + '_dataType')\" \n [form]=\"form\" [config]=\"getDataTypeSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"getRawValue(field)\"\n [fullWidth]=\"true\" (valueChange)=\"onTestDataValueChange(field.key, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\"\n [value]=\"form.get(field.key)?.value\" [fullWidth]=\"true\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ field.label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"field.subLabel\">{{ field.subLabel }}</span>\n </div>\n </div>\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Other Locators section (matching old UI) -->\n <ng-container *ngIf=\"pwLocator && pwLocator.length > 0\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Other Locators</p>\n <div *ngFor=\"let locator of pwLocator; let i = index\" class=\"cqa-mb-3\">\n <div *ngIf=\"locator !== ''\" class=\"cqa-relative cqa-flex cqa-items-center\">\n <input type=\"text\" [value]=\"locator\" #locatorInput readonly\n class=\"cqa-w-full cqa-px-3 cqa-py-2 cqa-pr-20 cqa-border cqa-border-[#E5E7EB] cqa-rounded cqa-text-[14px] cqa-bg-white\"\n style=\"padding-left: 26px;\">\n <button type=\"button\" (click)=\"copyLocator(locatorInput)\"\n class=\"cqa-absolute cqa-left-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#374151]\"\n title=\"Click to Copy\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">content_copy</mat-icon>\n </button>\n <button type=\"button\" (click)=\"deleteLocator(i)\"\n class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#DC2626]\"\n title=\"Delete\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">delete</mat-icon>\n </button>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <p *ngIf=\"dynamicFields.length === 0\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">No fields configured for this step.\n </p>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-white\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>", components: [{ type: i2.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: i3.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i4.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "enableMarkdown", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: i5.CustomToggleComponent, selector: "cqa-custom-toggle", inputs: ["checked", "disabled", "ariaLabel"], outputs: ["checkedChange", "change"] }, { type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i7.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
210
344
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerComponent, decorators: [{
211
345
  type: Component,
212
- args: [{ selector: 'cqa-step-details-drawer', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Step Details Drawer \u2013 Edit In Depth. Fully dynamic from DynamicFieldConfig[]. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-bg-white\"\n style=\"border-bottom: 1px solid #E5E5E5;\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 20L14 16L18 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[19px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ displayTitle }}\n </h2>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[5px] cqa-bg-[#D8D9FC] cqa-text-[#090A60] cqa-text-[12px]\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 9L9 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M9 9L19 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- Content: all fields from dynamicFields array (main + constraints in order, then advanced grouped) -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-p-4 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <ng-container *ngIf=\"dynamicFields.length > 0\">\n <!-- All non-advanced fields in array order with section headers -->\n <ng-container *ngFor=\"let field of dynamicFields; let i = index\">\n <ng-container *ngIf=\"isNonAdvancedField(i)\">\n <p *ngIf=\"isFirstInSection(i, 'main')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Attributes</p>\n <p *ngIf=\"isFirstInSection(i, 'constraints')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Constraints</p>\n\n <!-- string / undefined \u2192 text input -->\n <div *ngIf=\"(field.type ?? 'string') === 'string'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- number -->\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea -->\n <div *ngIf=\"field.type === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <span *ngIf=\"field.required\"\n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"field.rows || 4\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"field.tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa--mt-1.5\">{{ field.tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"field.type === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- boolean \u2192 toggle -->\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ field.label }}</p>\n <span *ngIf=\"field.subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{\n field.subLabel }}</span>\n </div>\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n\n <!-- dropdown -->\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Advanced: expandable (all advanced fields from array) -->\n <ng-container *ngIf=\"advancedFields.length > 0\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <ng-container *ngFor=\"let field of advancedFields\">\n <div *ngIf=\"(field.type ?? 'string') === 'string'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\"\n [value]=\"form.get(field.key)?.value\" [fullWidth]=\"true\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ field.label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"field.subLabel\">{{ field.subLabel }}</span>\n </div>\n </div>\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Other Locators section (matching old UI) -->\n <ng-container *ngIf=\"pwLocator && pwLocator.length > 0\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Other Locators</p>\n <div *ngFor=\"let locator of pwLocator; let i = index\" class=\"cqa-mb-3\">\n <div *ngIf=\"locator !== ''\" class=\"cqa-relative cqa-flex cqa-items-center\">\n <input type=\"text\" [value]=\"locator\" #locatorInput readonly\n class=\"cqa-w-full cqa-px-3 cqa-py-2 cqa-pr-20 cqa-border cqa-border-[#E5E7EB] cqa-rounded cqa-text-[14px] cqa-bg-white\"\n style=\"padding-left: 26px;\">\n <button type=\"button\" (click)=\"copyLocator(locatorInput)\"\n class=\"cqa-absolute cqa-left-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#374151]\"\n title=\"Click to Copy\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">content_copy</mat-icon>\n </button>\n <button type=\"button\" (click)=\"deleteLocator(i)\"\n class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#DC2626]\"\n title=\"Delete\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">delete</mat-icon>\n </button>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <p *ngIf=\"dynamicFields.length === 0\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">No fields configured for this step.\n </p>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-white\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>" }]
346
+ args: [{ selector: 'cqa-step-details-drawer', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Step Details Drawer \u2013 Edit In Depth. Fully dynamic from DynamicFieldConfig[]. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-bg-white\"\n style=\"border-bottom: 1px solid #E5E5E5;\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 20L14 16L18 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[19px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ displayTitle }}\n </h2>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[5px] cqa-bg-[#D8D9FC] cqa-text-[#090A60] cqa-text-[12px]\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 9L9 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M9 9L19 19\" stroke=\"#4A5565\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <!-- Content: all fields from dynamicFields array (main + constraints in order, then advanced grouped) -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-p-4 cqa-flex cqa-flex-col cqa-gap-1.5\">\n <ng-container *ngIf=\"dynamicFields.length > 0\">\n <!-- All non-advanced fields in array order with section headers -->\n <ng-container *ngFor=\"let field of dynamicFields; let i = index\">\n <ng-container *ngIf=\"isNonAdvancedField(i)\">\n <p *ngIf=\"isFirstInSection(i, 'main')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Attributes</p>\n <p *ngIf=\"isFirstInSection(i, 'constraints')\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text[#0A0A0A] cqa-mb-1\">Constraints</p>\n\n <!-- string / undefined \u2192 text input -->\n <div *ngIf=\"(field.type ?? 'string') === 'string' && !needsDataTypeDropdown(field)\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"(field.type ?? 'string') === 'string' && needsDataTypeDropdown(field)\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }} Type</label>\n <cqa-dynamic-select *ngIf=\"getDataTypeSelectConfig(field) && form.contains(field.key + '_dataType')\" \n [form]=\"form\" [config]=\"getDataTypeSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"getRawValue(field)\"\n [fullWidth]=\"true\" (valueChange)=\"onTestDataValueChange(field.key, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- number -->\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea -->\n <div *ngIf=\"field.type === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[14px] cqa-leading-[17px] cqa-font-medium cqa-text-[#161617]\">{{ field.label }}</label>\n <span *ngIf=\"field.required\"\n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"field.rows || 4\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"field.tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa--mt-1.5\">{{ field.tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"field.type === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-textarea [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- boolean \u2192 toggle -->\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ field.label }}</p>\n <span *ngIf=\"field.subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{\n field.subLabel }}</span>\n </div>\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n\n <!-- dropdown -->\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Advanced: expandable (all advanced fields from array) -->\n <ng-container *ngIf=\"advancedFields.length > 0\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <ng-container *ngFor=\"let field of advancedFields\">\n <div *ngIf=\"(field.type ?? 'string') === 'string' && !needsDataTypeDropdown(field)\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"form.get(field.key)?.value\"\n [fullWidth]=\"true\" (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n \n <!-- Test-data, source-value, or target-value with data type dropdown in advanced section -->\n <ng-container *ngIf=\"(field.type ?? 'string') === 'string' && needsDataTypeDropdown(field)\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }} Type</label>\n <cqa-dynamic-select *ngIf=\"getDataTypeSelectConfig(field) && form.contains(field.key + '_dataType')\" \n [form]=\"form\" [config]=\"getDataTypeSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input [placeholder]=\"field.placeholder || ''\" [value]=\"getRawValue(field)\"\n [fullWidth]=\"true\" (valueChange)=\"onTestDataValueChange(field.key, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <div *ngIf=\"field.type === 'number'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-custom-input type=\"number\" [placeholder]=\"field.placeholder || ''\"\n [value]=\"form.get(field.key)?.value\" [fullWidth]=\"true\"\n (valueChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div *ngIf=\"field.type === 'boolean'\" class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-custom-toggle [checked]=\"form.get(field.key)?.value\"\n (checkedChange)=\"form.get(field.key)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ field.label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"field.subLabel\">{{ field.subLabel }}</span>\n </div>\n </div>\n <div *ngIf=\"field.type === 'dropdown' && getSelectConfig(field) && form.contains(field.key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ field.label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(field)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Other Locators section (matching old UI) -->\n <ng-container *ngIf=\"pwLocator && pwLocator.length > 0\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Other Locators</p>\n <div *ngFor=\"let locator of pwLocator; let i = index\" class=\"cqa-mb-3\">\n <div *ngIf=\"locator !== ''\" class=\"cqa-relative cqa-flex cqa-items-center\">\n <input type=\"text\" [value]=\"locator\" #locatorInput readonly\n class=\"cqa-w-full cqa-px-3 cqa-py-2 cqa-pr-20 cqa-border cqa-border-[#E5E7EB] cqa-rounded cqa-text-[14px] cqa-bg-white\"\n style=\"padding-left: 26px;\">\n <button type=\"button\" (click)=\"copyLocator(locatorInput)\"\n class=\"cqa-absolute cqa-left-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#374151]\"\n title=\"Click to Copy\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">content_copy</mat-icon>\n </button>\n <button type=\"button\" (click)=\"deleteLocator(i)\"\n class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-p-1 cqa-text-[#6B7280] hover:cqa-text-[#DC2626]\"\n title=\"Delete\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">delete</mat-icon>\n </button>\n </div>\n </div>\n </ng-container>\n </ng-container>\n\n <p *ngIf=\"dynamicFields.length === 0\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">No fields configured for this step.\n </p>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-white\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>" }]
213
347
  }], ctorParameters: function () { return [{ type: i9.StepDetailsDrawerRef, decorators: [{
214
348
  type: Inject,
215
349
  args: [STEP_DETAILS_DRAWER_REF]
@@ -233,4 +367,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
233
367
  }], drawerTitle: [{
234
368
  type: Input
235
369
  }] } });
236
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL3N0ZXAtZGV0YWlscy1kcmF3ZXIvc3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL3N0ZXAtZGV0YWlscy1kcmF3ZXIvc3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSx1QkFBdUIsRUFBd0IsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRixPQUFPLEVBQUUsd0JBQXdCLEVBQTZDLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7Ozs7O0FBT2pIOzs7O0dBSUc7QUFPSCxNQUFNLE9BQU8sMEJBQTBCO0lBNERyQyxZQUMyQyxHQUF5QixFQUMxRCxFQUFlLEVBQ2YsR0FBc0IsRUFDZ0IsSUFBNEI7UUFIakMsUUFBRyxHQUFILEdBQUcsQ0FBc0I7UUFDMUQsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBOUR0QixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFzQixDQUFDO1FBQ3JELFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ2xDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQXNCLENBQUM7UUFFekQsYUFBUSxHQUE4QixJQUFJLENBQUM7UUFDM0Msb0JBQWUsR0FBMkIsSUFBSSxDQUFDO1FBQ3hELDZGQUE2RjtRQUNwRix1QkFBa0IsR0FBZ0MsSUFBSSxDQUFDO1FBQ2hFLHdFQUF3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N0MsT0FBTztTQUNSLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELDhGQUE4RjtJQUM5RixJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUMvQixDQUFDOzt1SEFwTlUsMEJBQTBCLGtCQTZEM0IsdUJBQXVCLHlFQUdYLHdCQUF3QjsyR0FoRW5DLDBCQUEwQixzV0NqQ3ZDLHl6WEF5TE07MkZEeEpPLDBCQUEwQjtrQkFOdEMsU0FBUzsrQkFDRSx5QkFBeUIsUUFFN0IsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLG1CQUNiLHVCQUF1QixDQUFDLE1BQU07OzBCQStENUMsTUFBTTsyQkFBQyx1QkFBdUI7OzBCQUc5QixRQUFROzswQkFBSSxNQUFNOzJCQUFDLHdCQUF3Qjs0Q0EvRHBDLFdBQVc7c0JBQXBCLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUUsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNURVBfREVUQUlMU19EUkFXRVJfUkVGLCBTdGVwRGV0YWlsc0RyYXdlclJlZiB9IGZyb20gJy4vc3RlcC1kZXRhaWxzLWRyYXdlci1yZWYnO1xuaW1wb3J0IHsgU1RFUF9ERVRBSUxTX0RSQVdFUl9EQVRBLCBTdGVwRGV0YWlsc0RyYXdlckRhdGEsIER5bmFtaWNGaWVsZENvbmZpZyB9IGZyb20gJy4vc3RlcC1kZXRhaWxzLWRyYXdlci1kYXRhJztcbmltcG9ydCB7IFRlc3RDYXNlU3RlcENvbmZpZyB9IGZyb20gJy4uL3Rlc3QtY2FzZS1zdGVwLm1vZGVscyc7XG5pbXBvcnQgdHlwZSB7XG4gIER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyxcbiAgU2VsZWN0T3B0aW9uLFxufSBmcm9tICcuLi8uLi9keW5hbWljLXNlbGVjdC9keW5hbWljLXNlbGVjdC1maWVsZC5jb21wb25lbnQnO1xuXG4vKipcbiAqIFN0ZXAgRGV0YWlscyBEcmF3ZXIgKEVkaXQgSW4gRGVwdGgpLlxuICogUmVuZGVycyBvbmx5IGZyb20gdGhlIHByb3ZpZGVkIER5bmFtaWNGaWVsZENvbmZpZ1tdOyBubyBmaWx0ZXJpbmcgb3Igc3RlcC10eXBlLWJhc2VkIGZpZWxkIGxvZ2ljLlxuICogRWFjaCBzdGVwIGluc3RhbmNlIHJlY2VpdmVzIGl0cyBvd24gY29tcGxldGUgZmllbGQgY29uZmlndXJhdGlvbi4gR2VuZXJpYyBrZXktYmFzZWQgc3RlcCByZWFkL3dyaXRlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtc3RlcC1kZXRhaWxzLWRyYXdlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdGVwLWRldGFpbHMtZHJhd2VyLmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9LFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3RlcERldGFpbHNEcmF3ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBPdXRwdXQoKSBzYXZlQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXI8VGVzdENhc2VTdGVwQ29uZmlnPigpO1xuICBAT3V0cHV0KCkgY2FuY2VsID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgc2F2ZUFzVGVtcGxhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPFRlc3RDYXNlU3RlcENvbmZpZz4oKTtcblxuICBASW5wdXQoKSBzdGVwRGF0YTogVGVzdENhc2VTdGVwQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIHN0ZXBOdW1iZXJJbnB1dDogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBXaGVuIHByb3ZpZGVkIChlLmcuIFN0b3J5Ym9vayksIHVzZSBpbnN0ZWFkIG9mIFNURVBfREVUQUlMU19EUkFXRVJfREFUQS5keW5hbWljRmllbGRzLiAqL1xuICBASW5wdXQoKSBkeW5hbWljRmllbGRzSW5wdXQ6IER5bmFtaWNGaWVsZENvbmZpZ1tdIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBXaGVuIHByb3ZpZGVkLCB1c2UgYXMgZHJhd2VyIGhlYWRlciB0aXRsZSAob3ZlcnJpZGVzIGRhdGEudGl0bGUpLiAqL1xuICBASW5wdXQoKSBkcmF3ZXJUaXRsZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgc3RlcDogVGVzdENhc2VTdGVwQ29uZmlnO1xuICBzdGVwTnVtYmVyOiBudW1iZXIgfCBzdHJpbmc7XG4gIGR5bmFtaWNGaWVsZHM6IER5bmFtaWNGaWVsZENvbmZpZ1tdID0gW107XG4gIGRyYXdlclRpdGxlVmFsdWUgPSAnU3RlcCBEZXRhaWxzJztcbiAgYWR2YW5jZWRFeHBhbmRlZCA9IGZhbHNlO1xuICBmb3JtOiBGb3JtR3JvdXA7XG4gIHB3TG9jYXRvcjogc3RyaW5nW10gPSBbXTtcblxuICAvKiogQ2FjaGVkIHNlbGVjdCBjb25maWdzIHBlciBmaWVsZCBrZXkgKHN0YWJsZSByZWZzIGZvciBjaGFuZ2UgZGV0ZWN0aW9uKS4gKi9cbiAgcHJpdmF0ZSBzZWxlY3RDb25maWdDYWNoZTogUmVjb3JkPHN0cmluZywgRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnPiA9IHt9O1xuXG4gIC8qKiBBbGwgZmllbGRzIGZyb20gdGhlIHByb3ZpZGVkIGFycmF5IChzYW1lIHJlZmVyZW5jZTsgdXNlZCBmb3Igc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBpbiB0ZW1wbGF0ZSkuICovXG4gIGdldCBhbGxGaWVsZHMoKTogRHluYW1pY0ZpZWxkQ29uZmlnW10ge1xuICAgIHJldHVybiB0aGlzLmR5bmFtaWNGaWVsZHM7XG4gIH1cblxuICAvKiogRmllbGRzIGluIG1haW4gc2VjdGlvbiAoc2VjdGlvbiA9PT0gJ21haW4nIG9yIHVuZGVmaW5lZCkuICovXG4gIGdldCBtYWluRmllbGRzKCk6IER5bmFtaWNGaWVsZENvbmZpZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5keW5hbWljRmllbGRzLmZpbHRlcigoZikgPT4gKGYuc2VjdGlvbiA/PyAnbWFpbicpID09PSAnbWFpbicpO1xuICB9XG5cbiAgLyoqIEZpZWxkcyBpbiBjb25zdHJhaW50cyBzZWN0aW9uLiAqL1xuICBnZXQgY29uc3RyYWludHNGaWVsZHMoKTogRHluYW1pY0ZpZWxkQ29uZmlnW10ge1xuICAgIHJldHVybiB0aGlzLmR5bmFtaWNGaWVsZHMuZmlsdGVyKChmKSA9PiBmLnNlY3Rpb24gPT09ICdjb25zdHJhaW50cycpO1xuICB9XG5cbiAgLyoqIEZpZWxkcyBpbiBhZHZhbmNlZCBzZWN0aW9uIChpbnNpZGUgZXhwYW5kYWJsZSBibG9jaykuICovXG4gIGdldCBhZHZhbmNlZEZpZWxkcygpOiBEeW5hbWljRmllbGRDb25maWdbXSB7XG4gICAgcmV0dXJuIHRoaXMuZHluYW1pY0ZpZWxkcy5maWx0ZXIoKGYpID0+IGYuc2VjdGlvbiA9PT0gJ2FkdmFuY2VkJyk7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGVuIHRoZSBmaWVsZCBhdCBpbmRleCBpcyB0aGUgZmlyc3QgaW4gaXRzIHNlY3Rpb24gKGZvciBzaG93aW5nIHNlY3Rpb24gaGVhZGVycykuICovXG4gIGlzRmlyc3RJblNlY3Rpb24oaW5kZXg6IG51bWJlciwgc2VjdGlvbjogJ21haW4nIHwgJ2NvbnN0cmFpbnRzJyB8ICdhZHZhbmNlZCcpOiBib29sZWFuIHtcbiAgICBjb25zdCBmID0gdGhpcy5keW5hbWljRmllbGRzW2luZGV4XTtcbiAgICBpZiAoIWYpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBmU2VjdGlvbiA9IGYuc2VjdGlvbiA/PyAnbWFpbic7XG4gICAgaWYgKGZTZWN0aW9uICE9PSBzZWN0aW9uKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGluZGV4ID09PSAwKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBwcmV2ID0gdGhpcy5keW5hbWljRmllbGRzW2luZGV4IC0gMV07XG4gICAgcmV0dXJuIChwcmV2Py5zZWN0aW9uID8/ICdtYWluJykgIT09IHNlY3Rpb247XG4gIH1cblxuICAvKiogVHJ1ZSB3aGVuIHRoZSBmaWVsZCBhdCBpbmRleCBpcyBub3QgaW4gdGhlIGFkdmFuY2VkIHNlY3Rpb24gKHJlbmRlciBpbiBtYWluIGZsb3cpLiAqL1xuICBpc05vbkFkdmFuY2VkRmllbGQoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGYgPSB0aGlzLmR5bmFtaWNGaWVsZHNbaW5kZXhdO1xuICAgIHJldHVybiBmICE9IG51bGwgJiYgKGYuc2VjdGlvbiA/PyAnbWFpbicpICE9PSAnYWR2YW5jZWQnO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChTVEVQX0RFVEFJTFNfRFJBV0VSX1JFRikgcHJpdmF0ZSByZWY6IFN0ZXBEZXRhaWxzRHJhd2VyUmVmLFxuICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNURVBfREVUQUlMU19EUkFXRVJfREFUQSkgZGF0YT86IFN0ZXBEZXRhaWxzRHJhd2VyRGF0YVxuICApIHtcbiAgICB0aGlzLnN0ZXAgPSBkYXRhPy5zdGVwID8/ICh7fSBhcyBUZXN0Q2FzZVN0ZXBDb25maWcpO1xuICAgIHRoaXMuc3RlcE51bWJlciA9IGRhdGE/LnN0ZXBOdW1iZXIgPz8gMTtcbiAgICB0aGlzLmR5bmFtaWNGaWVsZHMgPSBkYXRhPy5keW5hbWljRmllbGRzID8/IFtdO1xuICAgIHRoaXMuZHJhd2VyVGl0bGVWYWx1ZSA9IGRhdGE/LnRpdGxlID8/ICdTdGVwIERldGFpbHMnO1xuICAgIHRoaXMucHdMb2NhdG9yID0gZGF0YT8ucHdMb2NhdG9yID8/ICh0aGlzLnN0ZXAgYXMgYW55KS5wd0xvY2F0b3IgPz8gW107XG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7fSk7XG4gICAgdGhpcy5idWlsZEZvcm1Gcm9tRHluYW1pY0ZpZWxkcygpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RlcERhdGEgIT0gbnVsbCB8fCB0aGlzLmR5bmFtaWNGaWVsZHNJbnB1dCAhPSBudWxsIHx8IHRoaXMuZHJhd2VyVGl0bGUgIT0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMuc3RlcERhdGEgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnN0ZXAgPSB0aGlzLnN0ZXBEYXRhO1xuICAgICAgICB0aGlzLnN0ZXBOdW1iZXIgPSB0aGlzLnN0ZXBOdW1iZXJJbnB1dCA/PyAodGhpcy5zdGVwRGF0YSBhcyBhbnkpLnN0ZXBOdW1iZXIgPz8gMTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBwd0xvY2F0b3IgZnJvbSBzdGVwRGF0YSBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKCh0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yKSB7XG4gICAgICAgICAgdGhpcy5wd0xvY2F0b3IgPSBBcnJheS5pc0FycmF5KCh0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yKSA/IFsuLi4odGhpcy5zdGVwRGF0YSBhcyBhbnkpLnB3TG9jYXRvcl0gOiBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZHluYW1pY0ZpZWxkc0lucHV0ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5keW5hbWljRmllbGRzID0gdGhpcy5keW5hbWljRmllbGRzSW5wdXQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5kcmF3ZXJUaXRsZSAhPSBudWxsICYmIHRoaXMuZHJhd2VyVGl0bGUgIT09ICcnKSB7XG4gICAgICAgIHRoaXMuZHJhd2VyVGl0bGVWYWx1ZSA9IHRoaXMuZHJhd2VyVGl0bGU7XG4gICAgICB9XG4gICAgICB0aGlzLmJ1aWxkRm9ybUZyb21EeW5hbWljRmllbGRzKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ3N0ZXBEYXRhJ10gfHwgY2hhbmdlc1snc3RlcE51bWJlcklucHV0J10gfHwgY2hhbmdlc1snZHluYW1pY0ZpZWxkc0lucHV0J10gfHwgY2hhbmdlc1snZHJhd2VyVGl0bGUnXSkge1xuICAgICAgaWYgKHRoaXMuc3RlcERhdGEgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnN0ZXAgPSB0aGlzLnN0ZXBEYXRhO1xuICAgICAgICB0aGlzLnN0ZXBOdW1iZXIgPSB0aGlzLnN0ZXBOdW1iZXJJbnB1dCA/PyAodGhpcy5zdGVwRGF0YSBhcyBhbnkpLnN0ZXBOdW1iZXIgPz8gMTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBwd0xvY2F0b3IgZnJvbSBzdGVwRGF0YSBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKCh0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yKSB7XG4gICAgICAgICAgdGhpcy5wd0xvY2F0b3IgPSBBcnJheS5pc0FycmF5KCh0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yKSA/IFsuLi4odGhpcy5zdGVwRGF0YSBhcyBhbnkpLnB3TG9jYXRvcl0gOiBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZHluYW1pY0ZpZWxkc0lucHV0ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5keW5hbWljRmllbGRzID0gdGhpcy5keW5hbWljRmllbGRzSW5wdXQ7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5kcmF3ZXJUaXRsZSAhPSBudWxsICYmIHRoaXMuZHJhd2VyVGl0bGUgIT09ICcnKSB7XG4gICAgICAgIHRoaXMuZHJhd2VyVGl0bGVWYWx1ZSA9IHRoaXMuZHJhd2VyVGl0bGU7XG4gICAgICB9XG4gICAgICB0aGlzLmJ1aWxkRm9ybUZyb21EeW5hbWljRmllbGRzKCk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEZvcm1Gcm9tRHluYW1pY0ZpZWxkcygpOiB2b2lkIHtcbiAgICBjb25zdCBncm91cDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRoaXMuZHluYW1pY0ZpZWxkcykge1xuICAgICAgY29uc3QgcmF3ID0gdGhpcy5nZXRTdGVwVmFsdWUoZmllbGQua2V5KTtcbiAgICAgIGNvbnN0IHZhbHVlID1cbiAgICAgICAgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpICYmIGZpZWxkLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBmaWVsZC5kZWZhdWx0VmFsdWVcbiAgICAgICAgICA6IHJhdztcbiAgICAgIGdyb3VwW2ZpZWxkLmtleV0gPSBbdmFsdWVdO1xuICAgIH1cbiAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKGdyb3VwKTtcbiAgICB0aGlzLnNlbGVjdENvbmZpZ0NhY2hlID0ge307XG4gIH1cblxuICAvKiogUmVhZCB2YWx1ZSBmcm9tIHN0ZXAgYnkga2V5LiBObyBzdGVwLXR5cGUgbG9naWM7IHN0ZXAgaXMgYSBnZW5lcmljIGtleS12YWx1ZSBiYWcuICovXG4gIGdldFN0ZXBWYWx1ZShrZXk6IHN0cmluZyk6IHVua25vd24ge1xuICAgIGNvbnN0IHN0ZXAgPSB0aGlzLnN0ZXAgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCByYXcgPSBzdGVwW2tleV07XG4gICAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkgcmV0dXJuICcnO1xuICAgIHJldHVybiByYXc7XG4gIH1cblxuICAvKiogV3JpdGUgdmFsdWUgdG8gc3RlcCBieSBrZXkuIE5vIHN0ZXAtdHlwZSBsb2dpYzsgc3RlcCBpcyBhIGdlbmVyaWMga2V5LXZhbHVlIGJhZy4gKi9cbiAgc2V0U3RlcFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGNvbnN0IHN0ZXAgPSB0aGlzLnN0ZXAgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBzdGVwW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIG9uQmFjaygpOiB2b2lkIHtcbiAgICB0aGlzLmNhbmNlbC5lbWl0KCk7XG4gICAgdGhpcy5yZWYuY2xvc2UodW5kZWZpbmVkKTtcbiAgfVxuXG4gIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWwuZW1pdCgpO1xuICAgIHRoaXMucmVmLmNsb3NlKHVuZGVmaW5lZCk7XG4gIH1cblxuICBvbkNhbmNlbCgpOiB2b2lkIHtcbiAgICB0aGlzLmNhbmNlbC5lbWl0KCk7XG4gICAgdGhpcy5yZWYuY2xvc2UodW5kZWZpbmVkKTtcbiAgfVxuXG4gIG9uU2F2ZUFzVGVtcGxhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5hcHBseUZvcm1Ub1N0ZXAoKTtcbiAgICB0aGlzLnNhdmVBc1RlbXBsYXRlLmVtaXQodGhpcy5zdGVwKTtcbiAgICB0aGlzLnJlZi5jbG9zZSh7IGFjdGlvbjogJ3NhdmVBc1RlbXBsYXRlJywgc3RlcDogdGhpcy5zdGVwIH0pO1xuICB9XG5cbiAgb25TYXZlQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmFwcGx5Rm9ybVRvU3RlcCgpO1xuICAgIHRoaXMuc2F2ZUNoYW5nZXMuZW1pdCh0aGlzLnN0ZXApO1xuICAgIHRoaXMucmVmLmNsb3NlKHsgYWN0aW9uOiAnc2F2ZUNoYW5nZXMnLCBzdGVwOiB0aGlzLnN0ZXAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5Rm9ybVRvU3RlcCgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRoaXMuZHluYW1pY0ZpZWxkcykge1xuICAgICAgaWYgKHRoaXMuZm9ybS5jb250YWlucyhmaWVsZC5rZXkpKSB7XG4gICAgICAgIHRoaXMuc2V0U3RlcFZhbHVlKGZpZWxkLmtleSwgdGhpcy5mb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFNhdmUgcHdMb2NhdG9yIChPdGhlciBMb2NhdG9ycylcbiAgICAodGhpcy5zdGVwIGFzIGFueSkucHdMb2NhdG9yID0gWy4uLnRoaXMucHdMb2NhdG9yXTtcbiAgfVxuXG4gIGNvcHlMb2NhdG9yKGlucHV0RWxlbWVudDogSFRNTElucHV0RWxlbWVudCk6IHZvaWQge1xuICAgIGlucHV0RWxlbWVudC5zZWxlY3QoKTtcbiAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO1xuICAgIGlucHV0RWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZSgwLCAwKTtcbiAgICBpbnB1dEVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIGRlbGV0ZUxvY2F0b3IoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5wd0xvY2F0b3IubGVuZ3RoKSB7XG4gICAgICB0aGlzLnB3TG9jYXRvci5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEJ1aWxkIHNlbGVjdCBjb25maWcgZm9yIGRyb3Bkb3duIGZpZWxkIChjYWNoZWQgcGVyIGtleSkuICovXG4gIGdldFNlbGVjdENvbmZpZyhmaWVsZDogRHluYW1pY0ZpZWxkQ29uZmlnKTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCB7XG4gICAgaWYgKGZpZWxkLnR5cGUgIT09ICdkcm9wZG93bicgfHwgIWZpZWxkLm9wdGlvbnM/Lmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHRoaXMuc2VsZWN0Q29uZmlnQ2FjaGVbZmllbGQua2V5XSkgcmV0dXJuIHRoaXMuc2VsZWN0Q29uZmlnQ2FjaGVbZmllbGQua2V5XTtcbiAgICBjb25zdCBvcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IGZpZWxkLm9wdGlvbnMubWFwKChvKSA9PiAoeyB2YWx1ZTogby52YWx1ZSwgbGFiZWw6IG8ubGFiZWwgfSkpO1xuICAgIHRoaXMuc2VsZWN0Q29uZmlnQ2FjaGVbZmllbGQua2V5XSA9IHtcbiAgICAgIGtleTogZmllbGQua2V5LFxuICAgICAgcGxhY2Vob2xkZXI6IGZpZWxkLnBsYWNlaG9sZGVyID8/IGZpZWxkLmxhYmVsLFxuICAgICAgb3B0aW9ucyxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLnNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV07XG4gIH1cblxuICAvKiogUmVzb2x2ZWQgaGVhZGVyIHRpdGxlIGZvciB0ZW1wbGF0ZTogQElucHV0IGRyYXdlclRpdGxlID4gaW5qZWN0ZWQgZGF0YS50aXRsZSA+IGRlZmF1bHQuICovXG4gIGdldCBkaXNwbGF5VGl0bGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5kcmF3ZXJUaXRsZVZhbHVlO1xuICB9XG59XG4iLCI8IS0tIFN0ZXAgRGV0YWlscyBEcmF3ZXIg4oCTIEVkaXQgSW4gRGVwdGguIEZ1bGx5IGR5bmFtaWMgZnJvbSBEeW5hbWljRmllbGRDb25maWdbXS4gLS0+XG48ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1oLWZ1bGwgY3FhLXctZnVsbCBjcWEtbWF4LXctWzQ4MHB4XSBjcWEtYm94LWJvcmRlclwiPlxuICA8IS0tIEhlYWRlcjogYmFjayBjaGV2cm9uLCB0aXRsZSwgU3RlcCBOIHBpbGwsIGNsb3NlIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtMyBjcWEtcHgtMyBjcWEtcHktMiBjcWEtYmctd2hpdGVcIlxuICAgIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNFNUU1RTU7XCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25CYWNrKClcIlxuICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTggY3FhLWgtOCBjcWEtcm91bmRlZCBjcWEtdGV4dC1bIzZCNzI4MF0gaG92ZXI6Y3FhLWJnLVsjRjNGNEY2XSBjcWEtcC0wXCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIkJhY2tcIj5cbiAgICAgICAgPHN2ZyB3aWR0aD1cIjMyXCIgaGVpZ2h0PVwiMzJcIiB2aWV3Qm94PVwiMCAwIDMyIDMyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGggZD1cIk0xOCAyMEwxNCAxNkwxOCAxMlwiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8aDIgY2xhc3M9XCJjcWEtdGV4dC1bMTZweF0gY3FhLWxlYWRpbmctWzE5cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjMTExODI3XSBjcWEtbS0wIGNxYS1mbGV4LTFcIj5cbiAgICAgICAge3sgZGlzcGxheVRpdGxlIH19XG4gICAgICA8L2gyPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtcHgtMiBjcWEtcHktWzJweF0gY3FhLXJvdW5kZWQtWzVweF0gY3FhLWJnLVsjRDhEOUZDXSBjcWEtdGV4dC1bIzA5MEE2MF0gY3FhLXRleHQtWzEycHhdXCI+XG4gICAgICAgIFN0ZXAge3sgc3RlcE51bWJlciB9fVxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkNsb3NlKClcIlxuICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtbWluLWgtWzI4cHhdIGNxYS1taW4tdy1bMjhweF0gY3FhLXJvdW5kZWQgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS1iZy1bI0YzRjRGNl0gY3FhLXAtMFwiXG4gICAgICB0aXRsZT1cIkNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMjhcIiBoZWlnaHQ9XCIyOFwiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xOSA5TDkgMTlcIiBzdHJva2U9XCIjNEE1NTY1XCIgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoIGQ9XCJNOSA5TDE5IDE5XCIgc3Ryb2tlPVwiIzRBNTU2NVwiIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPC9zdmc+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gQ29udGVudDogYWxsIGZpZWxkcyBmcm9tIGR5bmFtaWNGaWVsZHMgYXJyYXkgKG1haW4gKyBjb25zdHJhaW50cyBpbiBvcmRlciwgdGhlbiBhZHZhbmNlZCBncm91cGVkKSAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW92ZXJmbG93LXktYXV0byBjcWEtYmctd2hpdGUgY3FhLXAtNCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjVcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZHluYW1pY0ZpZWxkcy5sZW5ndGggPiAwXCI+XG4gICAgICA8IS0tIEFsbCBub24tYWR2YW5jZWQgZmllbGRzIGluIGFycmF5IG9yZGVyIHdpdGggc2VjdGlvbiBoZWFkZXJzIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZHluYW1pY0ZpZWxkczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNOb25BZHZhbmNlZEZpZWxkKGkpXCI+XG4gICAgICAgICAgPHAgKm5nSWY9XCJpc0ZpcnN0SW5TZWN0aW9uKGksICdtYWluJylcIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWxlYWRpbmctWzE1cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dFsjMEEwQTBBXSBjcWEtbWItMVwiPkF0dHJpYnV0ZXM8L3A+XG4gICAgICAgICAgPHAgKm5nSWY9XCJpc0ZpcnN0SW5TZWN0aW9uKGksICdjb25zdHJhaW50cycpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1sZWFkaW5nLVsxNXB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHRbIzBBMEEwQV0gY3FhLW1iLTFcIj5Db25zdHJhaW50czwvcD5cblxuICAgICAgICAgIDwhLS0gc3RyaW5nIC8gdW5kZWZpbmVkIOKGkiB0ZXh0IGlucHV0IC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCIoZmllbGQudHlwZSA/PyAnc3RyaW5nJykgPT09ICdzdHJpbmcnXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzE2MTYxN11cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXIgfHwgJydcIiBbdmFsdWVdPVwiZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWVcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIiAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBudW1iZXIgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdudW1iZXInXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzE2MTYxN11cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCB0eXBlPVwibnVtYmVyXCIgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyIHx8ICcnXCIgW3ZhbHVlXT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnZhbHVlXCJcbiAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgKHZhbHVlQ2hhbmdlKT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gdGV4dGFyZWEgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICd0ZXh0YXJlYSdcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTFcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzE2MTYxN11cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZmllbGQucmVxdWlyZWRcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTIgY3FhLXB5LTAuNSBjcWEtcm91bmRlZC1mdWxsIGNxYS1iZy1bI0ZFRTJFMl0gY3FhLXRleHQtWyNEQzI2MjZdIGNxYS10ZXh0LVsxMHB4XSBjcWEtZm9udC1tZWRpdW1cIj5SZXF1aXJlZDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGNxYS1jdXN0b20tdGV4dGFyZWEgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyIHx8ICcnXCIgW3ZhbHVlXT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnZhbHVlXCJcbiAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgW3Jvd3NdPVwiZmllbGQucm93cyB8fCA0XCIgY3VzdG9tQ2xhc3M9XCJjcWEtcC0yIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMjBweF1cIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLXRleHRhcmVhPlxuICAgICAgICAgICAgPHAgKm5nSWY9XCJmaWVsZC50aXBcIiBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLS1tdC0xLjVcIj57eyBmaWVsZC50aXAgfX08L3A+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGNvZGUgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdjb2RlJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMVwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzM3NDE1MV1cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS10ZXh0YXJlYSBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXIgfHwgJydcIiBbdmFsdWVdPVwiZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWVcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIiBbcm93c109XCI4XCIgcmVzaXplPVwidmVydGljYWxcIiBjdXN0b21DbGFzcz1cImNxYS1wLTIgY3FhLXRleHQtWzE0cHhdIGNxYS1sZWFkaW5nLVsyMHB4XVwiXG4gICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJmb3JtLmdldChmaWVsZC5rZXkpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2NxYS1jdXN0b20tdGV4dGFyZWE+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGJvb2xlYW4g4oaSIHRvZ2dsZSAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ2Jvb2xlYW4nXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWdhcC0yXCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtdGV4dC1bIzExMTgyN10gY3FhLW0tMFwiPnt7IGZpZWxkLmxhYmVsIH19PC9wPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImZpZWxkLnN1YkxhYmVsXCIgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMzc0MTUxXVwiPnt7XG4gICAgICAgICAgICAgICAgZmllbGQuc3ViTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxjcWEtY3VzdG9tLXRvZ2dsZSBbY2hlY2tlZF09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgIChjaGVja2VkQ2hhbmdlKT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS10b2dnbGU+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGRyb3Bkb3duIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnZHJvcGRvd24nICYmIGdldFNlbGVjdENvbmZpZyhmaWVsZCkgJiYgZm9ybS5jb250YWlucyhmaWVsZC5rZXkpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMS41IGNxYS1zdGVwLWRldGFpbHMtZHJhd2VyLXNlbGVjdFwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzM3NDE1MV1cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhmaWVsZCkhXCI+XG4gICAgICAgICAgICA8L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBBZHZhbmNlZDogZXhwYW5kYWJsZSAoYWxsIGFkdmFuY2VkIGZpZWxkcyBmcm9tIGFycmF5KSAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhZHZhbmNlZEZpZWxkcy5sZW5ndGggPiAwXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLXctZnVsbCBjcWEtdGV4dC1sZWZ0IGNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMxMTE4MjddIGNxYS1weS0yIGNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLVsjRTVFN0VCXVwiXG4gICAgICAgICAgKGNsaWNrKT1cImFkdmFuY2VkRXhwYW5kZWQgPSAhYWR2YW5jZWRFeHBhbmRlZFwiPlxuICAgICAgICAgIDxzcGFuPkFkdmFuY2VkPC9zcGFuPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS10ZXh0LVsyMHB4XSBjcWEtdHJhbnNpdGlvbi10cmFuc2Zvcm1cIiBbY2xhc3MuY3FhLXJvdGF0ZS0xODBdPVwiIWFkdmFuY2VkRXhwYW5kZWRcIj5cbiAgICAgICAgICAgIGV4cGFuZF9sZXNzXG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJhZHZhbmNlZEV4cGFuZGVkXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0zIGNxYS1wdC0yXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2YgYWR2YW5jZWRGaWVsZHNcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIoZmllbGQudHlwZSA/PyAnc3RyaW5nJykgPT09ICdzdHJpbmcnXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjVcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzM3NDE1MV1cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0IFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiIFt2YWx1ZV09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgKHZhbHVlQ2hhbmdlKT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ251bWJlcidcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMzc0MTUxXVwiPnt7IGZpZWxkLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXQgdHlwZT1cIm51bWJlclwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnZhbHVlXCIgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnYm9vbGVhbidcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCI+XG4gICAgICAgICAgICAgIDxjcWEtY3VzdG9tLXRvZ2dsZSBbY2hlY2tlZF09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgICAgKGNoZWNrZWRDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20tdG9nZ2xlPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjNzM3MzczXVwiPnt7IGZpZWxkLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjMEEwQTBBXVwiICpuZ0lmPVwiZmllbGQuc3ViTGFiZWxcIj57eyBmaWVsZC5zdWJMYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnZHJvcGRvd24nICYmIGdldFNlbGVjdENvbmZpZyhmaWVsZCkgJiYgZm9ybS5jb250YWlucyhmaWVsZC5rZXkpXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjUgY3FhLXN0ZXAtZGV0YWlscy1kcmF3ZXItc2VsZWN0XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhmaWVsZCkhXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gT3RoZXIgTG9jYXRvcnMgc2VjdGlvbiAobWF0Y2hpbmcgb2xkIFVJKSAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwd0xvY2F0b3IgJiYgcHdMb2NhdG9yLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtbWItMyBjcWEtbXQtMFwiPk90aGVyIExvY2F0b3JzPC9wPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBsb2NhdG9yIG9mIHB3TG9jYXRvcjsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiY3FhLW1iLTNcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwibG9jYXRvciAhPT0gJydcIiBjbGFzcz1cImNxYS1yZWxhdGl2ZSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibG9jYXRvclwiICNsb2NhdG9ySW5wdXQgcmVhZG9ubHlcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1weC0zIGNxYS1weS0yIGNxYS1wci0yMCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItWyNFNUU3RUJdIGNxYS1yb3VuZGVkIGNxYS10ZXh0LVsxNHB4XSBjcWEtYmctd2hpdGVcIlxuICAgICAgICAgICAgICBzdHlsZT1cInBhZGRpbmctbGVmdDogMjZweDtcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjb3B5TG9jYXRvcihsb2NhdG9ySW5wdXQpXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtYWJzb2x1dGUgY3FhLWxlZnQtMiBjcWEtdG9wLTEvMiBjcWEtdHJhbnNmb3JtIGNxYS0tdHJhbnNsYXRlLXktMS8yIGNxYS1wLTEgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS10ZXh0LVsjMzc0MTUxXVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiQ2xpY2sgdG8gQ29weVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCIhY3FhLXctNCAhY3FhLWgtNCAhY3FhLXRleHQtWzE2cHhdXCI+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImRlbGV0ZUxvY2F0b3IoaSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtcmlnaHQtMiBjcWEtdG9wLTEvMiBjcWEtdHJhbnNmb3JtIGNxYS0tdHJhbnNsYXRlLXktMS8yIGNxYS1wLTEgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS10ZXh0LVsjREMyNjI2XVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIiFjcWEtdy01ICFjcWEtaC01ICFjcWEtdGV4dC1bMjBweF1cIj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8cCAqbmdJZj1cImR5bmFtaWNGaWVsZHMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLXRleHQtWyM2QjcyODBdXCI+Tm8gZmllbGRzIGNvbmZpZ3VyZWQgZm9yIHRoaXMgc3RlcC5cbiAgICA8L3A+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNFNUU1RTVdXCI+IDwvZGl2PlxuICA8IS0tIEZvb3RlciAtLT5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1zdGFydCBjcWEtZ2FwLTIgY3FhLXB4LTQgY3FhLXB5LTQgY3FhLWJvcmRlci10IGNxYS1ib3JkZXItWyNFNUU3RUJdIGNxYS1iZy13aGl0ZVwiPlxuICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJ0ZXh0XCIgYnRuU2l6ZT1cImxnXCIgW3RleHRdPVwiJ0NhbmNlbCdcIiAoY2xpY2tlZCk9XCJvbkNhbmNlbCgpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtdGV4dC1bIzM3NDE1MV0nXCI+PC9jcWEtYnV0dG9uPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1taW4tdy0wXCI+PC9kaXY+XG4gICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgYnRuU2l6ZT1cImxnXCIgW3RleHRdPVwiJ1NhdmUgYXMgVGVtcGxhdGUnXCIgKGNsaWNrZWQpPVwib25TYXZlQXNUZW1wbGF0ZSgpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtYm9yZGVyLVsjNDE0MTQ2XSdcIj48L2NxYS1idXR0b24+XG4gICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIGJ0blNpemU9XCJsZ1wiIFt0ZXh0XT1cIidTYXZlIENoYW5nZXMnXCIgKGNsaWNrZWQpPVwib25TYXZlQ2hhbmdlcygpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtYmctWyMzRjQzRUVdIGNxYS1ib3JkZXItWyMzRjQzRUVdJ1wiPjwvY3FhLWJ1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=
370
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL3N0ZXAtZGV0YWlscy1kcmF3ZXIvc3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rlc3QtY2FzZS1kZXRhaWxzL3N0ZXAtZGV0YWlscy1kcmF3ZXIvc3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSx1QkFBdUIsRUFBd0IsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRixPQUFPLEVBQUUsd0JBQXdCLEVBQTZDLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7Ozs7O0FBT2pIOzs7O0dBSUc7QUFPSCxNQUFNLE9BQU8sMEJBQTBCO0lBNkVyQyxZQUMyQyxHQUF5QixFQUMxRCxFQUFlLEVBQ2YsR0FBc0IsRUFDZ0IsSUFBNEI7UUFIakMsUUFBRyxHQUFILEdBQUcsQ0FBc0I7UUFDMUQsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBL0V0QixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFzQixDQUFDO1FBQ3JELFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ2xDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQXNCLENBQUM7UUFFekQsYUFBUSxHQUE4QixJQUFJLENBQUM7UUFDM0Msb0JBQWUsR0FBMkIsSUFBSSxDQUFDO1FBQ3hELDZGQUE2RjtRQUNwRix1QkFBa0IsR0FBZ0MsSUFBSSxDQUFDO1FBQ2hFLHdFQUF3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LEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxZQUFZLENBQUM7UUFFbkUsc0NBQXNDO1FBQ3RDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFcEUsc0JBQXNCO1FBQ3RCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxDQUFDLGNBQWMsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQ3pFO1FBRUQsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQzs7dUhBdFhVLDBCQUEwQixrQkE4RTNCLHVCQUF1Qix5RUFHWCx3QkFBd0I7MkdBakZuQywwQkFBMEIsc1dDakN2QyxpbGNBeU5NOzJGRHhMTywwQkFBMEI7a0JBTnRDLFNBQVM7K0JBQ0UseUJBQXlCLFFBRTdCLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxtQkFDYix1QkFBdUIsQ0FBQyxNQUFNOzswQkFnRjVDLE1BQU07MkJBQUMsdUJBQXVCOzswQkFHOUIsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyx3QkFBd0I7NENBaEZwQyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUVFLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFFRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTVEVQX0RFVEFJTFNfRFJBV0VSX1JFRiwgU3RlcERldGFpbHNEcmF3ZXJSZWYgfSBmcm9tICcuL3N0ZXAtZGV0YWlscy1kcmF3ZXItcmVmJztcbmltcG9ydCB7IFNURVBfREVUQUlMU19EUkFXRVJfREFUQSwgU3RlcERldGFpbHNEcmF3ZXJEYXRhLCBEeW5hbWljRmllbGRDb25maWcgfSBmcm9tICcuL3N0ZXAtZGV0YWlscy1kcmF3ZXItZGF0YSc7XG5pbXBvcnQgeyBUZXN0Q2FzZVN0ZXBDb25maWcgfSBmcm9tICcuLi90ZXN0LWNhc2Utc3RlcC5tb2RlbHMnO1xuaW1wb3J0IHR5cGUge1xuICBEeW5hbWljU2VsZWN0RmllbGRDb25maWcsXG4gIFNlbGVjdE9wdGlvbixcbn0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcblxuLyoqXG4gKiBTdGVwIERldGFpbHMgRHJhd2VyIChFZGl0IEluIERlcHRoKS5cbiAqIFJlbmRlcnMgb25seSBmcm9tIHRoZSBwcm92aWRlZCBEeW5hbWljRmllbGRDb25maWdbXTsgbm8gZmlsdGVyaW5nIG9yIHN0ZXAtdHlwZS1iYXNlZCBmaWVsZCBsb2dpYy5cbiAqIEVhY2ggc3RlcCBpbnN0YW5jZSByZWNlaXZlcyBpdHMgb3duIGNvbXBsZXRlIGZpZWxkIGNvbmZpZ3VyYXRpb24uIEdlbmVyaWMga2V5LWJhc2VkIHN0ZXAgcmVhZC93cml0ZS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLXN0ZXAtZGV0YWlscy1kcmF3ZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vc3RlcC1kZXRhaWxzLWRyYXdlci5jb21wb25lbnQuaHRtbCcsXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFN0ZXBEZXRhaWxzRHJhd2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBAT3V0cHV0KCkgc2F2ZUNoYW5nZXMgPSBuZXcgRXZlbnRFbWl0dGVyPFRlc3RDYXNlU3RlcENvbmZpZz4oKTtcbiAgQE91dHB1dCgpIGNhbmNlbCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIHNhdmVBc1RlbXBsYXRlID0gbmV3IEV2ZW50RW1pdHRlcjxUZXN0Q2FzZVN0ZXBDb25maWc+KCk7XG5cbiAgQElucHV0KCkgc3RlcERhdGE6IFRlc3RDYXNlU3RlcENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBzdGVwTnVtYmVySW5wdXQ6IG51bWJlciB8IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogV2hlbiBwcm92aWRlZCAoZS5nLiBTdG9yeWJvb2spLCB1c2UgaW5zdGVhZCBvZiBTVEVQX0RFVEFJTFNfRFJBV0VSX0RBVEEuZHluYW1pY0ZpZWxkcy4gKi9cbiAgQElucHV0KCkgZHluYW1pY0ZpZWxkc0lucHV0OiBEeW5hbWljRmllbGRDb25maWdbXSB8IG51bGwgPSBudWxsO1xuICAvKiogV2hlbiBwcm92aWRlZCwgdXNlIGFzIGRyYXdlciBoZWFkZXIgdGl0bGUgKG92ZXJyaWRlcyBkYXRhLnRpdGxlKS4gKi9cbiAgQElucHV0KCkgZHJhd2VyVGl0bGU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIHN0ZXA6IFRlc3RDYXNlU3RlcENvbmZpZztcbiAgc3RlcE51bWJlcjogbnVtYmVyIHwgc3RyaW5nO1xuICBkeW5hbWljRmllbGRzOiBEeW5hbWljRmllbGRDb25maWdbXSA9IFtdO1xuICBkcmF3ZXJUaXRsZVZhbHVlID0gJ1N0ZXAgRGV0YWlscyc7XG4gIGFkdmFuY2VkRXhwYW5kZWQgPSBmYWxzZTtcbiAgZm9ybTogRm9ybUdyb3VwO1xuICBwd0xvY2F0b3I6IHN0cmluZ1tdID0gW107XG5cbiAgLyoqIENhY2hlZCBzZWxlY3QgY29uZmlncyBwZXIgZmllbGQga2V5IChzdGFibGUgcmVmcyBmb3IgY2hhbmdlIGRldGVjdGlvbikuICovXG4gIHByaXZhdGUgc2VsZWN0Q29uZmlnQ2FjaGU6IFJlY29yZDxzdHJpbmcsIER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZz4gPSB7fTtcbiAgXG4gIC8qKiBDYWNoZSBmb3IgZGF0YSB0eXBlIHNlbGVjdCBjb25maWdzICovXG4gIHByaXZhdGUgZGF0YVR5cGVTZWxlY3RDb25maWdDYWNoZTogUmVjb3JkPHN0cmluZywgRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnPiA9IHt9O1xuICBcbiAgLyoqIFN0b3JlIGRhdGEgdHlwZXMgZm9yIHRlc3QtZGF0YSBmaWVsZHMgKi9cbiAgcHJpdmF0ZSBmaWVsZERhdGFUeXBlczogTWFwPHN0cmluZywgJ3BsYWluLXRleHQnIHwgJ3BhcmFtZXRlcicgfCAncnVudGltZScgfCAnZW52aXJvbm1lbnQnPiA9IG5ldyBNYXAoKTtcbiAgXG4gIC8qKiBTdG9yZSByYXcgdmFsdWVzICh3aXRob3V0IGZvcm1hdHRpbmcpIGZvciB0ZXN0LWRhdGEgZmllbGRzICovXG4gIHByaXZhdGUgZmllbGRSYXdWYWx1ZXM6IE1hcDxzdHJpbmcsIHN0cmluZz4gPSBuZXcgTWFwKCk7XG4gIFxuICAvKiogUHJlLWNvbXB1dGVkIGRhdGEgdHlwZSBvcHRpb25zIChzdGF0aWMsIG5vIG5lZWQgdG8gcmVjcmVhdGUpICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGF0YVR5cGVPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtcbiAgICB7IGlkOiAncGxhaW4tdGV4dCcsIHZhbHVlOiAncGxhaW4tdGV4dCcsIG5hbWU6ICdQbGFpbiBUZXh0JywgbGFiZWw6ICdQbGFpbiBUZXh0JyB9LFxuICAgIHsgaWQ6ICdwYXJhbWV0ZXInLCB2YWx1ZTogJ3BhcmFtZXRlcicsIG5hbWU6ICdAfFBhcmFtZXRlcnwnLCBsYWJlbDogJ0B8UGFyYW1ldGVyfCcgfSxcbiAgICB7IGlkOiAncnVudGltZScsIHZhbHVlOiAncnVudGltZScsIG5hbWU6ICckfFJ1bnRpbWV8JywgbGFiZWw6ICckfFJ1bnRpbWV8JyB9LFxuICAgIHsgaWQ6ICdlbnZpcm9ubWVudCcsIHZhbHVlOiAnZW52aXJvbm1lbnQnLCBuYW1lOiAnKnxFbnZpcm9ubWVudHwnLCBsYWJlbDogJyp8RW52aXJvbm1lbnR8JyB9XG4gIF07XG5cbiAgLyoqIEFsbCBmaWVsZHMgZnJvbSB0aGUgcHJvdmlkZWQgYXJyYXkgKHNhbWUgcmVmZXJlbmNlOyB1c2VkIGZvciBzaW5nbGUgc291cmNlIG9mIHRydXRoIGluIHRlbXBsYXRlKS4gKi9cbiAgZ2V0IGFsbEZpZWxkcygpOiBEeW5hbWljRmllbGRDb25maWdbXSB7XG4gICAgcmV0dXJuIHRoaXMuZHluYW1pY0ZpZWxkcztcbiAgfVxuXG4gIC8qKiBGaWVsZHMgaW4gbWFpbiBzZWN0aW9uIChzZWN0aW9uID09PSAnbWFpbicgb3IgdW5kZWZpbmVkKS4gKi9cbiAgZ2V0IG1haW5GaWVsZHMoKTogRHluYW1pY0ZpZWxkQ29uZmlnW10ge1xuICAgIHJldHVybiB0aGlzLmR5bmFtaWNGaWVsZHMuZmlsdGVyKChmKSA9PiAoZi5zZWN0aW9uID8/ICdtYWluJykgPT09ICdtYWluJyk7XG4gIH1cblxuICAvKiogRmllbGRzIGluIGNvbnN0cmFpbnRzIHNlY3Rpb24uICovXG4gIGdldCBjb25zdHJhaW50c0ZpZWxkcygpOiBEeW5hbWljRmllbGRDb25maWdbXSB7XG4gICAgcmV0dXJuIHRoaXMuZHluYW1pY0ZpZWxkcy5maWx0ZXIoKGYpID0+IGYuc2VjdGlvbiA9PT0gJ2NvbnN0cmFpbnRzJyk7XG4gIH1cblxuICAvKiogRmllbGRzIGluIGFkdmFuY2VkIHNlY3Rpb24gKGluc2lkZSBleHBhbmRhYmxlIGJsb2NrKS4gKi9cbiAgZ2V0IGFkdmFuY2VkRmllbGRzKCk6IER5bmFtaWNGaWVsZENvbmZpZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5keW5hbWljRmllbGRzLmZpbHRlcigoZikgPT4gZi5zZWN0aW9uID09PSAnYWR2YW5jZWQnKTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gdGhlIGZpZWxkIGF0IGluZGV4IGlzIHRoZSBmaXJzdCBpbiBpdHMgc2VjdGlvbiAoZm9yIHNob3dpbmcgc2VjdGlvbiBoZWFkZXJzKS4gKi9cbiAgaXNGaXJzdEluU2VjdGlvbihpbmRleDogbnVtYmVyLCBzZWN0aW9uOiAnbWFpbicgfCAnY29uc3RyYWludHMnIHwgJ2FkdmFuY2VkJyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGYgPSB0aGlzLmR5bmFtaWNGaWVsZHNbaW5kZXhdO1xuICAgIGlmICghZikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGZTZWN0aW9uID0gZi5zZWN0aW9uID8/ICdtYWluJztcbiAgICBpZiAoZlNlY3Rpb24gIT09IHNlY3Rpb24pIHJldHVybiBmYWxzZTtcbiAgICBpZiAoaW5kZXggPT09IDApIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IHByZXYgPSB0aGlzLmR5bmFtaWNGaWVsZHNbaW5kZXggLSAxXTtcbiAgICByZXR1cm4gKHByZXY/LnNlY3Rpb24gPz8gJ21haW4nKSAhPT0gc2VjdGlvbjtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gdGhlIGZpZWxkIGF0IGluZGV4IGlzIG5vdCBpbiB0aGUgYWR2YW5jZWQgc2VjdGlvbiAocmVuZGVyIGluIG1haW4gZmxvdykuICovXG4gIGlzTm9uQWR2YW5jZWRGaWVsZChpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZiA9IHRoaXMuZHluYW1pY0ZpZWxkc1tpbmRleF07XG4gICAgcmV0dXJuIGYgIT0gbnVsbCAmJiAoZi5zZWN0aW9uID8/ICdtYWluJykgIT09ICdhZHZhbmNlZCc7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFNURVBfREVUQUlMU19EUkFXRVJfUkVGKSBwcml2YXRlIHJlZjogU3RlcERldGFpbHNEcmF3ZXJSZWYsXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU1RFUF9ERVRBSUxTX0RSQVdFUl9EQVRBKSBkYXRhPzogU3RlcERldGFpbHNEcmF3ZXJEYXRhXG4gICkge1xuICAgIHRoaXMuc3RlcCA9IGRhdGE/LnN0ZXAgPz8gKHt9IGFzIFRlc3RDYXNlU3RlcENvbmZpZyk7XG4gICAgdGhpcy5zdGVwTnVtYmVyID0gZGF0YT8uc3RlcE51bWJlciA/PyAxO1xuICAgIHRoaXMuZHluYW1pY0ZpZWxkcyA9IGRhdGE/LmR5bmFtaWNGaWVsZHMgPz8gW107XG4gICAgdGhpcy5kcmF3ZXJUaXRsZVZhbHVlID0gZGF0YT8udGl0bGUgPz8gJ1N0ZXAgRGV0YWlscyc7XG4gICAgdGhpcy5wd0xvY2F0b3IgPSBkYXRhPy5wd0xvY2F0b3IgPz8gKHRoaXMuc3RlcCBhcyBhbnkpLnB3TG9jYXRvciA/PyBbXTtcbiAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKHt9KTtcbiAgICB0aGlzLmJ1aWxkRm9ybUZyb21EeW5hbWljRmllbGRzKCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdGVwRGF0YSAhPSBudWxsIHx8IHRoaXMuZHluYW1pY0ZpZWxkc0lucHV0ICE9IG51bGwgfHwgdGhpcy5kcmF3ZXJUaXRsZSAhPSBudWxsKSB7XG4gICAgICBpZiAodGhpcy5zdGVwRGF0YSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RlcCA9IHRoaXMuc3RlcERhdGE7XG4gICAgICAgIHRoaXMuc3RlcE51bWJlciA9IHRoaXMuc3RlcE51bWJlcklucHV0ID8/ICh0aGlzLnN0ZXBEYXRhIGFzIGFueSkuc3RlcE51bWJlciA/PyAxO1xuICAgICAgICAvLyBJbml0aWFsaXplIHB3TG9jYXRvciBmcm9tIHN0ZXBEYXRhIGlmIGF2YWlsYWJsZVxuICAgICAgICBpZiAoKHRoaXMuc3RlcERhdGEgYXMgYW55KS5wd0xvY2F0b3IpIHtcbiAgICAgICAgICB0aGlzLnB3TG9jYXRvciA9IEFycmF5LmlzQXJyYXkoKHRoaXMuc3RlcERhdGEgYXMgYW55KS5wd0xvY2F0b3IpID8gWy4uLih0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yXSA6IFtdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5keW5hbWljRmllbGRzSW5wdXQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLmR5bmFtaWNGaWVsZHMgPSB0aGlzLmR5bmFtaWNGaWVsZHNJbnB1dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmRyYXdlclRpdGxlICE9IG51bGwgJiYgdGhpcy5kcmF3ZXJUaXRsZSAhPT0gJycpIHtcbiAgICAgICAgdGhpcy5kcmF3ZXJUaXRsZVZhbHVlID0gdGhpcy5kcmF3ZXJUaXRsZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYnVpbGRGb3JtRnJvbUR5bmFtaWNGaWVsZHMoKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc3RlcERhdGEnXSB8fCBjaGFuZ2VzWydzdGVwTnVtYmVySW5wdXQnXSB8fCBjaGFuZ2VzWydkeW5hbWljRmllbGRzSW5wdXQnXSB8fCBjaGFuZ2VzWydkcmF3ZXJUaXRsZSddKSB7XG4gICAgICBpZiAodGhpcy5zdGVwRGF0YSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc3RlcCA9IHRoaXMuc3RlcERhdGE7XG4gICAgICAgIHRoaXMuc3RlcE51bWJlciA9IHRoaXMuc3RlcE51bWJlcklucHV0ID8/ICh0aGlzLnN0ZXBEYXRhIGFzIGFueSkuc3RlcE51bWJlciA/PyAxO1xuICAgICAgICAvLyBJbml0aWFsaXplIHB3TG9jYXRvciBmcm9tIHN0ZXBEYXRhIGlmIGF2YWlsYWJsZVxuICAgICAgICBpZiAoKHRoaXMuc3RlcERhdGEgYXMgYW55KS5wd0xvY2F0b3IpIHtcbiAgICAgICAgICB0aGlzLnB3TG9jYXRvciA9IEFycmF5LmlzQXJyYXkoKHRoaXMuc3RlcERhdGEgYXMgYW55KS5wd0xvY2F0b3IpID8gWy4uLih0aGlzLnN0ZXBEYXRhIGFzIGFueSkucHdMb2NhdG9yXSA6IFtdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5keW5hbWljRmllbGRzSW5wdXQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLmR5bmFtaWNGaWVsZHMgPSB0aGlzLmR5bmFtaWNGaWVsZHNJbnB1dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmRyYXdlclRpdGxlICE9IG51bGwgJiYgdGhpcy5kcmF3ZXJUaXRsZSAhPT0gJycpIHtcbiAgICAgICAgdGhpcy5kcmF3ZXJUaXRsZVZhbHVlID0gdGhpcy5kcmF3ZXJUaXRsZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYnVpbGRGb3JtRnJvbUR5bmFtaWNGaWVsZHMoKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRm9ybUZyb21EeW5hbWljRmllbGRzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdyb3VwOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIGZvciAoY29uc3QgZmllbGQgb2YgdGhpcy5keW5hbWljRmllbGRzKSB7XG4gICAgICBjb25zdCByYXcgPSB0aGlzLmdldFN0ZXBWYWx1ZShmaWVsZC5rZXkpO1xuICAgICAgY29uc3QgdmFsdWUgPVxuICAgICAgICAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgJiYgZmllbGQuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IGZpZWxkLmRlZmF1bHRWYWx1ZVxuICAgICAgICAgIDogcmF3O1xuICAgICAgZ3JvdXBbZmllbGQua2V5XSA9IFt2YWx1ZV07XG4gICAgICBcbiAgICAgIC8vIEluaXRpYWxpemUgZGF0YSB0eXBlcyBhbmQgcmF3IHZhbHVlcyBmb3IgdGVzdC1kYXRhIGZpZWxkc1xuICAgICAgaWYgKHRoaXMubmVlZHNEYXRhVHlwZURyb3Bkb3duKGZpZWxkKSkge1xuICAgICAgICBjb25zdCB7IGRhdGFUeXBlLCByYXdWYWx1ZSB9ID0gdGhpcy5wYXJzZVRlc3REYXRhVmFsdWUoU3RyaW5nKHZhbHVlIHx8ICcnKSk7XG4gICAgICAgIHRoaXMuZmllbGREYXRhVHlwZXMuc2V0KGZpZWxkLmtleSwgZGF0YVR5cGUpO1xuICAgICAgICB0aGlzLmZpZWxkUmF3VmFsdWVzLnNldChmaWVsZC5rZXksIHJhd1ZhbHVlKTtcbiAgICAgICAgXG4gICAgICAgIC8vIEVuc3VyZSBmb3JtIGNvbnRyb2wgZXhpc3RzIGZvciBkYXRhIHR5cGVcbiAgICAgICAgY29uc3QgZGF0YVR5cGVDb250cm9sTmFtZSA9IGAke2ZpZWxkLmtleX1fZGF0YVR5cGVgO1xuICAgICAgICBpZiAoIXRoaXMuZm9ybS5nZXQoZGF0YVR5cGVDb250cm9sTmFtZSkpIHtcbiAgICAgICAgICBncm91cFtkYXRhVHlwZUNvbnRyb2xOYW1lXSA9IFtkYXRhVHlwZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cChncm91cCk7XG4gICAgdGhpcy5zZWxlY3RDb25maWdDYWNoZSA9IHt9O1xuICAgIHRoaXMuZGF0YVR5cGVTZWxlY3RDb25maWdDYWNoZSA9IHt9O1xuICB9XG5cbiAgLyoqIFJlYWQgdmFsdWUgZnJvbSBzdGVwIGJ5IGtleS4gTm8gc3RlcC10eXBlIGxvZ2ljOyBzdGVwIGlzIGEgZ2VuZXJpYyBrZXktdmFsdWUgYmFnLiAqL1xuICBnZXRTdGVwVmFsdWUoa2V5OiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3QgcmF3ID0gc3RlcFtrZXldO1xuICAgIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09IG51bGwpIHJldHVybiAnJztcbiAgICByZXR1cm4gcmF3O1xuICB9XG5cbiAgLyoqIFdyaXRlIHZhbHVlIHRvIHN0ZXAgYnkga2V5LiBObyBzdGVwLXR5cGUgbG9naWM7IHN0ZXAgaXMgYSBnZW5lcmljIGtleS12YWx1ZSBiYWcuICovXG4gIHNldFN0ZXBWYWx1ZShrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICBjb25zdCBzdGVwID0gdGhpcy5zdGVwIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgc3RlcFtrZXldID0gdmFsdWU7XG4gIH1cblxuICBvbkJhY2soKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWwuZW1pdCgpO1xuICAgIHRoaXMucmVmLmNsb3NlKHVuZGVmaW5lZCk7XG4gIH1cblxuICBvbkNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsLmVtaXQoKTtcbiAgICB0aGlzLnJlZi5jbG9zZSh1bmRlZmluZWQpO1xuICB9XG5cbiAgb25DYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWwuZW1pdCgpO1xuICAgIHRoaXMucmVmLmNsb3NlKHVuZGVmaW5lZCk7XG4gIH1cblxuICBvblNhdmVBc1RlbXBsYXRlKCk6IHZvaWQge1xuICAgIHRoaXMuYXBwbHlGb3JtVG9TdGVwKCk7XG4gICAgdGhpcy5zYXZlQXNUZW1wbGF0ZS5lbWl0KHRoaXMuc3RlcCk7XG4gICAgdGhpcy5yZWYuY2xvc2UoeyBhY3Rpb246ICdzYXZlQXNUZW1wbGF0ZScsIHN0ZXA6IHRoaXMuc3RlcCB9KTtcbiAgfVxuXG4gIG9uU2F2ZUNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5hcHBseUZvcm1Ub1N0ZXAoKTtcbiAgICB0aGlzLnNhdmVDaGFuZ2VzLmVtaXQodGhpcy5zdGVwKTtcbiAgICB0aGlzLnJlZi5jbG9zZSh7IGFjdGlvbjogJ3NhdmVDaGFuZ2VzJywgc3RlcDogdGhpcy5zdGVwIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseUZvcm1Ub1N0ZXAoKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiB0aGlzLmR5bmFtaWNGaWVsZHMpIHtcbiAgICAgIGlmICh0aGlzLmZvcm0uY29udGFpbnMoZmllbGQua2V5KSkge1xuICAgICAgICB0aGlzLnNldFN0ZXBWYWx1ZShmaWVsZC5rZXksIHRoaXMuZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBTYXZlIHB3TG9jYXRvciAoT3RoZXIgTG9jYXRvcnMpXG4gICAgKHRoaXMuc3RlcCBhcyBhbnkpLnB3TG9jYXRvciA9IFsuLi50aGlzLnB3TG9jYXRvcl07XG4gIH1cblxuICBjb3B5TG9jYXRvcihpbnB1dEVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpbnB1dEVsZW1lbnQuc2VsZWN0KCk7XG4gICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTtcbiAgICBpbnB1dEVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgMCk7XG4gICAgaW5wdXRFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICBkZWxldGVMb2NhdG9yKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMucHdMb2NhdG9yLmxlbmd0aCkge1xuICAgICAgdGhpcy5wd0xvY2F0b3Iuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBCdWlsZCBzZWxlY3QgY29uZmlnIGZvciBkcm9wZG93biBmaWVsZCAoY2FjaGVkIHBlciBrZXkpLiAqL1xuICBnZXRTZWxlY3RDb25maWcoZmllbGQ6IER5bmFtaWNGaWVsZENvbmZpZyk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwge1xuICAgIGlmIChmaWVsZC50eXBlICE9PSAnZHJvcGRvd24nIHx8ICFmaWVsZC5vcHRpb25zPy5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV0pIHJldHVybiB0aGlzLnNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV07XG4gICAgY29uc3Qgb3B0aW9uczogU2VsZWN0T3B0aW9uW10gPSBmaWVsZC5vcHRpb25zLm1hcCgobykgPT4gKHsgdmFsdWU6IG8udmFsdWUsIGxhYmVsOiBvLmxhYmVsIH0pKTtcbiAgICB0aGlzLnNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV0gPSB7XG4gICAgICBrZXk6IGZpZWxkLmtleSxcbiAgICAgIHBsYWNlaG9sZGVyOiBmaWVsZC5wbGFjZWhvbGRlciA/PyBmaWVsZC5sYWJlbCxcbiAgICAgIG9wdGlvbnMsXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RDb25maWdDYWNoZVtmaWVsZC5rZXldO1xuICB9XG5cbiAgLyoqIFJlc29sdmVkIGhlYWRlciB0aXRsZSBmb3IgdGVtcGxhdGU6IEBJbnB1dCBkcmF3ZXJUaXRsZSA+IGluamVjdGVkIGRhdGEudGl0bGUgPiBkZWZhdWx0LiAqL1xuICBnZXQgZGlzcGxheVRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZHJhd2VyVGl0bGVWYWx1ZTtcbiAgfVxuICBcbiAgLyoqIENoZWNrIGlmIGZpZWxkIG5lZWRzIGRhdGEgdHlwZSBkcm9wZG93biAodGVzdC1kYXRhLCBzb3VyY2UtdmFsdWUsIHRhcmdldC12YWx1ZSkgKi9cbiAgbmVlZHNEYXRhVHlwZURyb3Bkb3duKGZpZWxkOiBEeW5hbWljRmllbGRDb25maWcpOiBib29sZWFuIHtcbiAgICBjb25zdCBsYWJlbCA9IGZpZWxkLmxhYmVsPy50b0xvd2VyQ2FzZSgpIHx8ICcnO1xuICAgIHJldHVybiBsYWJlbCA9PT0gJ3Rlc3QtZGF0YScgfHwgbGFiZWwgPT09ICdzb3VyY2UtdmFsdWUnIHx8IGxhYmVsID09PSAndGFyZ2V0LXZhbHVlJyB8fCBcbiAgICAgICAgICAgbGFiZWwgPT09ICdzb3VyY2VfdmFsdWUnIHx8IGxhYmVsID09PSAndGFyZ2V0X3ZhbHVlJztcbiAgfVxuICBcbiAgLyoqIFBhcnNlIHRlc3QgZGF0YSB2YWx1ZSB0byBleHRyYWN0IGRhdGEgdHlwZSBhbmQgcmF3IHZhbHVlICovXG4gIHByaXZhdGUgcGFyc2VUZXN0RGF0YVZhbHVlKHZhbHVlOiBzdHJpbmcpOiB7IGRhdGFUeXBlOiAncGxhaW4tdGV4dCcgfCAncGFyYW1ldGVyJyB8ICdydW50aW1lJyB8ICdlbnZpcm9ubWVudCcsIHJhd1ZhbHVlOiBzdHJpbmcgfSB7XG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4geyBkYXRhVHlwZTogJ3BsYWluLXRleHQnLCByYXdWYWx1ZTogJycgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIHBhcmFtZXRlciBmb3JtYXQ6IEB8dmFsdWV8XG4gICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoJ0B8JykgJiYgdmFsdWUuZW5kc1dpdGgoJ3wnKSkge1xuICAgICAgcmV0dXJuIHsgZGF0YVR5cGU6ICdwYXJhbWV0ZXInLCByYXdWYWx1ZTogdmFsdWUuc2xpY2UoMiwgLTEpIH07XG4gICAgfVxuICAgIC8vIENoZWNrIGZvciBydW50aW1lIGZvcm1hdDogJHx2YWx1ZXxcbiAgICBlbHNlIGlmICh2YWx1ZS5zdGFydHNXaXRoKCckfCcpICYmIHZhbHVlLmVuZHNXaXRoKCd8JykpIHtcbiAgICAgIHJldHVybiB7IGRhdGFUeXBlOiAncnVudGltZScsIHJhd1ZhbHVlOiB2YWx1ZS5zbGljZSgyLCAtMSkgfTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgZm9yIGVudmlyb25tZW50IGZvcm1hdDogKnx2YWx1ZXxcbiAgICBlbHNlIGlmICh2YWx1ZS5zdGFydHNXaXRoKCcqfCcpICYmIHZhbHVlLmVuZHNXaXRoKCd8JykpIHtcbiAgICAgIHJldHVybiB7IGRhdGFUeXBlOiAnZW52aXJvbm1lbnQnLCByYXdWYWx1ZTogdmFsdWUuc2xpY2UoMiwgLTEpIH07XG4gICAgfVxuICAgIC8vIFBsYWluIHRleHQgKG5vIGZvcm1hdHRpbmcpXG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4geyBkYXRhVHlwZTogJ3BsYWluLXRleHQnLCByYXdWYWx1ZTogdmFsdWUgfTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKiBGb3JtYXQgdGVzdCBkYXRhIHZhbHVlIGJhc2VkIG9uIGRhdGEgdHlwZSAqL1xuICBwcml2YXRlIGZvcm1hdFRlc3REYXRhVmFsdWUocmF3VmFsdWU6IHN0cmluZywgZGF0YVR5cGU6ICdwbGFpbi10ZXh0JyB8ICdwYXJhbWV0ZXInIHwgJ3J1bnRpbWUnIHwgJ2Vudmlyb25tZW50Jyk6IHN0cmluZyB7XG4gICAgaWYgKCFyYXdWYWx1ZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdwYXJhbWV0ZXInOlxuICAgICAgICByZXR1cm4gYEB8JHtyYXdWYWx1ZX18YDtcbiAgICAgIGNhc2UgJ3J1bnRpbWUnOlxuICAgICAgICByZXR1cm4gYCR8JHtyYXdWYWx1ZX18YDtcbiAgICAgIGNhc2UgJ2Vudmlyb25tZW50JzpcbiAgICAgICAgcmV0dXJuIGAqfCR7cmF3VmFsdWV9fGA7XG4gICAgICBjYXNlICdwbGFpbi10ZXh0JzpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiByYXdWYWx1ZTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKiBHZXQgZGF0YSB0eXBlIHNlbGVjdCBjb25maWcgZm9yIGEgZmllbGQgKi9cbiAgZ2V0RGF0YVR5cGVTZWxlY3RDb25maWcoZmllbGQ6IER5bmFtaWNGaWVsZENvbmZpZyk6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwge1xuICAgIGlmICghdGhpcy5uZWVkc0RhdGFUeXBlRHJvcGRvd24oZmllbGQpKSByZXR1cm4gbnVsbDtcbiAgICBcbiAgICBpZiAodGhpcy5kYXRhVHlwZVNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV0pIHtcbiAgICAgIHJldHVybiB0aGlzLmRhdGFUeXBlU2VsZWN0Q29uZmlnQ2FjaGVbZmllbGQua2V5XTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgZGF0YVR5cGVDb250cm9sTmFtZSA9IGAke2ZpZWxkLmtleX1fZGF0YVR5cGVgO1xuICAgIFxuICAgIC8vIEVuc3VyZSBmb3JtIGNvbnRyb2wgZXhpc3RzXG4gICAgaWYgKCF0aGlzLmZvcm0uZ2V0KGRhdGFUeXBlQ29udHJvbE5hbWUpKSB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YVR5cGUgPSB0aGlzLmZpZWxkRGF0YVR5cGVzLmdldChmaWVsZC5rZXkpIHx8ICdwbGFpbi10ZXh0JztcbiAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKGRhdGFUeXBlQ29udHJvbE5hbWUsIHRoaXMuZmIuY29udHJvbChjdXJyZW50RGF0YVR5cGUpKTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgY29uZmlnOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcgPSB7XG4gICAgICBrZXk6IGRhdGFUeXBlQ29udHJvbE5hbWUsXG4gICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBUeXBlJyxcbiAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgb3B0aW9uczogdGhpcy5kYXRhVHlwZU9wdGlvbnMsXG4gICAgICBvbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5vbkRhdGFUeXBlQ2hhbmdlKGZpZWxkLmtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH07XG4gICAgXG4gICAgdGhpcy5kYXRhVHlwZVNlbGVjdENvbmZpZ0NhY2hlW2ZpZWxkLmtleV0gPSBjb25maWc7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuICBcbiAgLyoqIEdldCBjdXJyZW50IGRhdGEgdHlwZSBmb3IgYSBmaWVsZCAqL1xuICBnZXRDdXJyZW50RGF0YVR5cGUoZmllbGQ6IER5bmFtaWNGaWVsZENvbmZpZyk6ICdwbGFpbi10ZXh0JyB8ICdwYXJhbWV0ZXInIHwgJ3J1bnRpbWUnIHwgJ2Vudmlyb25tZW50JyB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGREYXRhVHlwZXMuZ2V0KGZpZWxkLmtleSkgfHwgJ3BsYWluLXRleHQnO1xuICB9XG4gIFxuICAvKiogR2V0IHJhdyB2YWx1ZSAod2l0aG91dCBmb3JtYXR0aW5nKSBmb3IgYSBmaWVsZCAqL1xuICBnZXRSYXdWYWx1ZShmaWVsZDogRHluYW1pY0ZpZWxkQ29uZmlnKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5maWVsZFJhd1ZhbHVlcy5nZXQoZmllbGQua2V5KSB8fCAnJztcbiAgfVxuICBcbiAgLyoqIEhhbmRsZSBkYXRhIHR5cGUgY2hhbmdlICovXG4gIG9uRGF0YVR5cGVDaGFuZ2UoZmllbGRLZXk6IHN0cmluZywgZGF0YVR5cGU6ICdwbGFpbi10ZXh0JyB8ICdwYXJhbWV0ZXInIHwgJ3J1bnRpbWUnIHwgJ2Vudmlyb25tZW50Jyk6IHZvaWQge1xuICAgIC8vIFVwZGF0ZSBzdG9yZWQgZGF0YSB0eXBlXG4gICAgdGhpcy5maWVsZERhdGFUeXBlcy5zZXQoZmllbGRLZXksIGRhdGFUeXBlKTtcbiAgICBcbiAgICAvLyBHZXQgY3VycmVudCByYXcgdmFsdWVcbiAgICBjb25zdCByYXdWYWx1ZSA9IHRoaXMuZmllbGRSYXdWYWx1ZXMuZ2V0KGZpZWxkS2V5KSB8fCAnJztcbiAgICBcbiAgICAvLyBGb3JtYXQgdGhlIHZhbHVlIGJhc2VkIG9uIG5ldyBkYXRhIHR5cGVcbiAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuZm9ybWF0VGVzdERhdGFWYWx1ZShyYXdWYWx1ZSwgZGF0YVR5cGUpO1xuICAgIFxuICAgIC8vIFVwZGF0ZSBmb3JtIGNvbnRyb2xcbiAgICBpZiAodGhpcy5mb3JtLmdldChmaWVsZEtleSkpIHtcbiAgICAgIHRoaXMuZm9ybS5nZXQoZmllbGRLZXkpPy5zZXRWYWx1ZShmb3JtYXR0ZWRWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cbiAgICBcbiAgICAvLyBNYXJrIGZvciBjaGVjayBzaW5jZSB3ZSdyZSB1c2luZyBPblB1c2hcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuICBcbiAgLyoqIEhhbmRsZSB0ZXN0IGRhdGEgdmFsdWUgY2hhbmdlIChyYXcgdmFsdWUgaW5wdXQpICovXG4gIG9uVGVzdERhdGFWYWx1ZUNoYW5nZShmaWVsZEtleTogc3RyaW5nLCByYXdWYWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgLy8gVXBkYXRlIHN0b3JlZCByYXcgdmFsdWVcbiAgICB0aGlzLmZpZWxkUmF3VmFsdWVzLnNldChmaWVsZEtleSwgcmF3VmFsdWUpO1xuICAgIFxuICAgIC8vIEdldCBjdXJyZW50IGRhdGEgdHlwZVxuICAgIGNvbnN0IGRhdGFUeXBlID0gdGhpcy5maWVsZERhdGFUeXBlcy5nZXQoZmllbGRLZXkpIHx8ICdwbGFpbi10ZXh0JztcbiAgICBcbiAgICAvLyBGb3JtYXQgdGhlIHZhbHVlIGJhc2VkIG9uIGRhdGEgdHlwZVxuICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5mb3JtYXRUZXN0RGF0YVZhbHVlKHJhd1ZhbHVlLCBkYXRhVHlwZSk7XG4gICAgXG4gICAgLy8gVXBkYXRlIGZvcm0gY29udHJvbFxuICAgIGlmICh0aGlzLmZvcm0uZ2V0KGZpZWxkS2V5KSkge1xuICAgICAgdGhpcy5mb3JtLmdldChmaWVsZEtleSk/LnNldFZhbHVlKGZvcm1hdHRlZFZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfVxuICAgIFxuICAgIC8vIE1hcmsgZm9yIGNoZWNrIHNpbmNlIHdlJ3JlIHVzaW5nIE9uUHVzaFxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8IS0tIFN0ZXAgRGV0YWlscyBEcmF3ZXIg4oCTIEVkaXQgSW4gRGVwdGguIEZ1bGx5IGR5bmFtaWMgZnJvbSBEeW5hbWljRmllbGRDb25maWdbXS4gLS0+XG48ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1oLWZ1bGwgY3FhLXctZnVsbCBjcWEtbWF4LXctWzQ4MHB4XSBjcWEtYm94LWJvcmRlclwiPlxuICA8IS0tIEhlYWRlcjogYmFjayBjaGV2cm9uLCB0aXRsZSwgU3RlcCBOIHBpbGwsIGNsb3NlIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtMyBjcWEtcHgtMyBjcWEtcHktMiBjcWEtYmctd2hpdGVcIlxuICAgIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNFNUU1RTU7XCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25CYWNrKClcIlxuICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTggY3FhLWgtOCBjcWEtcm91bmRlZCBjcWEtdGV4dC1bIzZCNzI4MF0gaG92ZXI6Y3FhLWJnLVsjRjNGNEY2XSBjcWEtcC0wXCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIkJhY2tcIj5cbiAgICAgICAgPHN2ZyB3aWR0aD1cIjMyXCIgaGVpZ2h0PVwiMzJcIiB2aWV3Qm94PVwiMCAwIDMyIDMyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGggZD1cIk0xOCAyMEwxNCAxNkwxOCAxMlwiIHN0cm9rZT1cIiMwQTBBMEFcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8aDIgY2xhc3M9XCJjcWEtdGV4dC1bMTZweF0gY3FhLWxlYWRpbmctWzE5cHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjMTExODI3XSBjcWEtbS0wIGNxYS1mbGV4LTFcIj5cbiAgICAgICAge3sgZGlzcGxheVRpdGxlIH19XG4gICAgICA8L2gyPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtcHgtMiBjcWEtcHktWzJweF0gY3FhLXJvdW5kZWQtWzVweF0gY3FhLWJnLVsjRDhEOUZDXSBjcWEtdGV4dC1bIzA5MEE2MF0gY3FhLXRleHQtWzEycHhdXCI+XG4gICAgICAgIFN0ZXAge3sgc3RlcE51bWJlciB9fVxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkNsb3NlKClcIlxuICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtbWluLWgtWzI4cHhdIGNxYS1taW4tdy1bMjhweF0gY3FhLXJvdW5kZWQgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS1iZy1bI0YzRjRGNl0gY3FhLXAtMFwiXG4gICAgICB0aXRsZT1cIkNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMjhcIiBoZWlnaHQ9XCIyOFwiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xOSA5TDkgMTlcIiBzdHJva2U9XCIjNEE1NTY1XCIgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDxwYXRoIGQ9XCJNOSA5TDE5IDE5XCIgc3Ryb2tlPVwiIzRBNTU2NVwiIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPC9zdmc+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gQ29udGVudDogYWxsIGZpZWxkcyBmcm9tIGR5bmFtaWNGaWVsZHMgYXJyYXkgKG1haW4gKyBjb25zdHJhaW50cyBpbiBvcmRlciwgdGhlbiBhZHZhbmNlZCBncm91cGVkKSAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW92ZXJmbG93LXktYXV0byBjcWEtYmctd2hpdGUgY3FhLXAtNCBjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjVcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZHluYW1pY0ZpZWxkcy5sZW5ndGggPiAwXCI+XG4gICAgICA8IS0tIEFsbCBub24tYWR2YW5jZWQgZmllbGRzIGluIGFycmF5IG9yZGVyIHdpdGggc2VjdGlvbiBoZWFkZXJzIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZHluYW1pY0ZpZWxkczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNOb25BZHZhbmNlZEZpZWxkKGkpXCI+XG4gICAgICAgICAgPHAgKm5nSWY9XCJpc0ZpcnN0SW5TZWN0aW9uKGksICdtYWluJylcIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWxlYWRpbmctWzE1cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dFsjMEEwQTBBXSBjcWEtbWItMVwiPkF0dHJpYnV0ZXM8L3A+XG4gICAgICAgICAgPHAgKm5nSWY9XCJpc0ZpcnN0SW5TZWN0aW9uKGksICdjb25zdHJhaW50cycpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1sZWFkaW5nLVsxNXB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHRbIzBBMEEwQV0gY3FhLW1iLTFcIj5Db25zdHJhaW50czwvcD5cblxuICAgICAgICAgIDwhLS0gc3RyaW5nIC8gdW5kZWZpbmVkIOKGkiB0ZXh0IGlucHV0IC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCIoZmllbGQudHlwZSA/PyAnc3RyaW5nJykgPT09ICdzdHJpbmcnICYmICFuZWVkc0RhdGFUeXBlRHJvcGRvd24oZmllbGQpXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzE3cHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzE2MTYxN11cIj57eyBmaWVsZC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXIgfHwgJydcIiBbdmFsdWVdPVwiZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWVcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIiAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBUZXN0LWRhdGEsIHNvdXJjZS12YWx1ZSwgb3IgdGFyZ2V0LXZhbHVlIHdpdGggZGF0YSB0eXBlIGRyb3Bkb3duIC0tPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIoZmllbGQudHlwZSA/PyAnc3RyaW5nJykgPT09ICdzdHJpbmcnICYmIG5lZWRzRGF0YVR5cGVEcm9wZG93bihmaWVsZClcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xXCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMTdweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMTYxNjE3XVwiPnt7IGZpZWxkLmxhYmVsIH19IFR5cGU8L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0ICpuZ0lmPVwiZ2V0RGF0YVR5cGVTZWxlY3RDb25maWcoZmllbGQpICYmIGZvcm0uY29udGFpbnMoZmllbGQua2V5ICsgJ19kYXRhVHlwZScpXCIgXG4gICAgICAgICAgICAgICAgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwiZ2V0RGF0YVR5cGVTZWxlY3RDb25maWcoZmllbGQpIVwiPlxuICAgICAgICAgICAgICA8L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTFcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzE0cHhdIGNxYS1sZWFkaW5nLVsxN3B4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMxNjE2MTddXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXIgfHwgJydcIiBbdmFsdWVdPVwiZ2V0UmF3VmFsdWUoZmllbGQpXCJcbiAgICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIiAodmFsdWVDaGFuZ2UpPVwib25UZXN0RGF0YVZhbHVlQ2hhbmdlKGZpZWxkLmtleSwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDwhLS0gbnVtYmVyIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnbnVtYmVyJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMVwiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzE0cHhdIGNxYS1sZWFkaW5nLVsxN3B4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMxNjE2MTddXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXQgdHlwZT1cIm51bWJlclwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiIFt2YWx1ZV09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiICh2YWx1ZUNoYW5nZSk9XCJmb3JtLmdldChmaWVsZC5rZXkpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIHRleHRhcmVhIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAndGV4dGFyZWEnXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzE0cHhdIGNxYS1sZWFkaW5nLVsxN3B4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMxNjE2MTddXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImZpZWxkLnJlcXVpcmVkXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImNxYS1weC0yIGNxYS1weS0wLjUgY3FhLXJvdW5kZWQtZnVsbCBjcWEtYmctWyNGRUUyRTJdIGNxYS10ZXh0LVsjREMyNjI2XSBjcWEtdGV4dC1bMTBweF0gY3FhLWZvbnQtbWVkaXVtXCI+UmVxdWlyZWQ8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxjcWEtY3VzdG9tLXRleHRhcmVhIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiIFt2YWx1ZV09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiIFtyb3dzXT1cImZpZWxkLnJvd3MgfHwgNFwiIGN1c3RvbUNsYXNzPVwiY3FhLXAtMiBjcWEtdGV4dC1bMTRweF0gY3FhLWxlYWRpbmctWzIwcHhdXCJcbiAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS10ZXh0YXJlYT5cbiAgICAgICAgICAgIDxwICpuZ0lmPVwiZmllbGQudGlwXCIgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLXRleHQtWyM2QjcyODBdIGNxYS0tbXQtMS41XCI+e3sgZmllbGQudGlwIH19PC9wPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBjb2RlIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnY29kZSdcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTFcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGNxYS1jdXN0b20tdGV4dGFyZWEgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyIHx8ICcnXCIgW3ZhbHVlXT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnZhbHVlXCJcbiAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgW3Jvd3NdPVwiOFwiIHJlc2l6ZT1cInZlcnRpY2FsXCIgY3VzdG9tQ2xhc3M9XCJjcWEtcC0yIGNxYS10ZXh0LVsxNHB4XSBjcWEtbGVhZGluZy1bMjBweF1cIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLXRleHRhcmVhPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBib29sZWFuIOKGkiB0b2dnbGUgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdib29sZWFuJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLXRleHQtWyMxMTE4MjddIGNxYS1tLTBcIj57eyBmaWVsZC5sYWJlbCB9fTwvcD5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJmaWVsZC5zdWJMYWJlbFwiIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1bIzM3NDE1MV1cIj57e1xuICAgICAgICAgICAgICAgIGZpZWxkLnN1YkxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS10b2dnbGUgW2NoZWNrZWRdPVwiZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWVcIlxuICAgICAgICAgICAgICAoY2hlY2tlZENoYW5nZSk9XCJmb3JtLmdldChmaWVsZC5rZXkpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2NxYS1jdXN0b20tdG9nZ2xlPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBkcm9wZG93biAtLT5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ2Ryb3Bkb3duJyAmJiBnZXRTZWxlY3RDb25maWcoZmllbGQpICYmIGZvcm0uY29udGFpbnMoZmllbGQua2V5KVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNSBjcWEtc3RlcC1kZXRhaWxzLWRyYXdlci1zZWxlY3RcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCBbZm9ybV09XCJmb3JtXCIgW2NvbmZpZ109XCJnZXRTZWxlY3RDb25maWcoZmllbGQpIVwiPlxuICAgICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQWR2YW5jZWQ6IGV4cGFuZGFibGUgKGFsbCBhZHZhbmNlZCBmaWVsZHMgZnJvbSBhcnJheSkgLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWR2YW5jZWRGaWVsZHMubGVuZ3RoID4gMFwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS13LWZ1bGwgY3FhLXRleHQtbGVmdCBjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMTExODI3XSBjcWEtcHktMiBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1bI0U1RTdFQl1cIlxuICAgICAgICAgIChjbGljayk9XCJhZHZhbmNlZEV4cGFuZGVkID0gIWFkdmFuY2VkRXhwYW5kZWRcIj5cbiAgICAgICAgICA8c3Bhbj5BZHZhbmNlZDwvc3Bhbj5cbiAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1bMjBweF0gY3FhLXRyYW5zaXRpb24tdHJhbnNmb3JtXCIgW2NsYXNzLmNxYS1yb3RhdGUtMTgwXT1cIiFhZHZhbmNlZEV4cGFuZGVkXCI+XG4gICAgICAgICAgICBleHBhbmRfbGVzc1xuICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiYWR2YW5jZWRFeHBhbmRlZFwiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMyBjcWEtcHQtMlwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGFkdmFuY2VkRmllbGRzXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiKGZpZWxkLnR5cGUgPz8gJ3N0cmluZycpID09PSAnc3RyaW5nJyAmJiAhbmVlZHNEYXRhVHlwZURyb3Bkb3duKGZpZWxkKVwiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtMS41XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dCBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXIgfHwgJydcIiBbdmFsdWVdPVwiZm9ybS5nZXQoZmllbGQua2V5KT8udmFsdWVcIlxuICAgICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiICh2YWx1ZUNoYW5nZSk9XCJmb3JtLmdldChmaWVsZC5rZXkpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIFRlc3QtZGF0YSwgc291cmNlLXZhbHVlLCBvciB0YXJnZXQtdmFsdWUgd2l0aCBkYXRhIHR5cGUgZHJvcGRvd24gaW4gYWR2YW5jZWQgc2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIoZmllbGQudHlwZSA/PyAnc3RyaW5nJykgPT09ICdzdHJpbmcnICYmIG5lZWRzRGF0YVR5cGVEcm9wZG93bihmaWVsZClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX0gVHlwZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdCAqbmdJZj1cImdldERhdGFUeXBlU2VsZWN0Q29uZmlnKGZpZWxkKSAmJiBmb3JtLmNvbnRhaW5zKGZpZWxkLmtleSArICdfZGF0YVR5cGUnKVwiIFxuICAgICAgICAgICAgICAgICAgW2Zvcm1dPVwiZm9ybVwiIFtjb25maWddPVwiZ2V0RGF0YVR5cGVTZWxlY3RDb25maWcoZmllbGQpIVwiPlxuICAgICAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0IFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiIFt2YWx1ZV09XCJnZXRSYXdWYWx1ZShmaWVsZClcIlxuICAgICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCIgKHZhbHVlQ2hhbmdlKT1cIm9uVGVzdERhdGFWYWx1ZUNoYW5nZShmaWVsZC5rZXksICRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ251bWJlcidcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtZ2FwLTEuNVwiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMzc0MTUxXVwiPnt7IGZpZWxkLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXQgdHlwZT1cIm51bWJlclwiIFtwbGFjZWhvbGRlcl09XCJmaWVsZC5wbGFjZWhvbGRlciB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW3ZhbHVlXT1cImZvcm0uZ2V0KGZpZWxkLmtleSk/LnZhbHVlXCIgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnYm9vbGVhbidcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCI+XG4gICAgICAgICAgICAgIDxjcWEtY3VzdG9tLXRvZ2dsZSBbY2hlY2tlZF09XCJmb3JtLmdldChmaWVsZC5rZXkpPy52YWx1ZVwiXG4gICAgICAgICAgICAgICAgKGNoZWNrZWRDaGFuZ2UpPVwiZm9ybS5nZXQoZmllbGQua2V5KT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20tdG9nZ2xlPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjNzM3MzczXVwiPnt7IGZpZWxkLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS10ZXh0LVsjMEEwQTBBXVwiICpuZ0lmPVwiZmllbGQuc3ViTGFiZWxcIj57eyBmaWVsZC5zdWJMYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnZHJvcGRvd24nICYmIGdldFNlbGVjdENvbmZpZyhmaWVsZCkgJiYgZm9ybS5jb250YWlucyhmaWVsZC5rZXkpXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0xLjUgY3FhLXN0ZXAtZGV0YWlscy1kcmF3ZXItc2VsZWN0XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1tZWRpdW0gY3FhLXRleHQtWyMzNzQxNTFdXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0IFtmb3JtXT1cImZvcm1cIiBbY29uZmlnXT1cImdldFNlbGVjdENvbmZpZyhmaWVsZCkhXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gT3RoZXIgTG9jYXRvcnMgc2VjdGlvbiAobWF0Y2hpbmcgb2xkIFVJKSAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwd0xvY2F0b3IgJiYgcHdMb2NhdG9yLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC1bMTJweF0gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtbWItMyBjcWEtbXQtMFwiPk90aGVyIExvY2F0b3JzPC9wPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBsb2NhdG9yIG9mIHB3TG9jYXRvcjsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiY3FhLW1iLTNcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwibG9jYXRvciAhPT0gJydcIiBjbGFzcz1cImNxYS1yZWxhdGl2ZSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibG9jYXRvclwiICNsb2NhdG9ySW5wdXQgcmVhZG9ubHlcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1weC0zIGNxYS1weS0yIGNxYS1wci0yMCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItWyNFNUU3RUJdIGNxYS1yb3VuZGVkIGNxYS10ZXh0LVsxNHB4XSBjcWEtYmctd2hpdGVcIlxuICAgICAgICAgICAgICBzdHlsZT1cInBhZGRpbmctbGVmdDogMjZweDtcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjb3B5TG9jYXRvcihsb2NhdG9ySW5wdXQpXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtYWJzb2x1dGUgY3FhLWxlZnQtMiBjcWEtdG9wLTEvMiBjcWEtdHJhbnNmb3JtIGNxYS0tdHJhbnNsYXRlLXktMS8yIGNxYS1wLTEgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS10ZXh0LVsjMzc0MTUxXVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiQ2xpY2sgdG8gQ29weVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCIhY3FhLXctNCAhY3FhLWgtNCAhY3FhLXRleHQtWzE2cHhdXCI+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImRlbGV0ZUxvY2F0b3IoaSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtcmlnaHQtMiBjcWEtdG9wLTEvMiBjcWEtdHJhbnNmb3JtIGNxYS0tdHJhbnNsYXRlLXktMS8yIGNxYS1wLTEgY3FhLXRleHQtWyM2QjcyODBdIGhvdmVyOmNxYS10ZXh0LVsjREMyNjI2XVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIiFjcWEtdy01ICFjcWEtaC01ICFjcWEtdGV4dC1bMjBweF1cIj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8cCAqbmdJZj1cImR5bmFtaWNGaWVsZHMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJjcWEtdGV4dC1bMTRweF0gY3FhLXRleHQtWyM2QjcyODBdXCI+Tm8gZmllbGRzIGNvbmZpZ3VyZWQgZm9yIHRoaXMgc3RlcC5cbiAgICA8L3A+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNFNUU1RTVdXCI+IDwvZGl2PlxuICA8IS0tIEZvb3RlciAtLT5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1zdGFydCBjcWEtZ2FwLTIgY3FhLXB4LTQgY3FhLXB5LTQgY3FhLWJvcmRlci10IGNxYS1ib3JkZXItWyNFNUU3RUJdIGNxYS1iZy13aGl0ZVwiPlxuICAgIDxjcWEtYnV0dG9uIHZhcmlhbnQ9XCJ0ZXh0XCIgYnRuU2l6ZT1cImxnXCIgW3RleHRdPVwiJ0NhbmNlbCdcIiAoY2xpY2tlZCk9XCJvbkNhbmNlbCgpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtdGV4dC1bIzM3NDE1MV0nXCI+PC9jcWEtYnV0dG9uPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1taW4tdy0wXCI+PC9kaXY+XG4gICAgPGNxYS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVkXCIgYnRuU2l6ZT1cImxnXCIgW3RleHRdPVwiJ1NhdmUgYXMgVGVtcGxhdGUnXCIgKGNsaWNrZWQpPVwib25TYXZlQXNUZW1wbGF0ZSgpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtYm9yZGVyLVsjNDE0MTQ2XSdcIj48L2NxYS1idXR0b24+XG4gICAgPGNxYS1idXR0b24gdmFyaWFudD1cImZpbGxlZFwiIGJ0blNpemU9XCJsZ1wiIFt0ZXh0XT1cIidTYXZlIENoYW5nZXMnXCIgKGNsaWNrZWQpPVwib25TYXZlQ2hhbmdlcygpXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLXRleHQtWzE0cHhdIGNxYS1weS1bOXB4XSBjcWEtYmctWyMzRjQzRUVdIGNxYS1ib3JkZXItWyMzRjQzRUVdJ1wiPjwvY3FhLWJ1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=