@cqa-lib/cqa-ui 1.1.201 → 1.1.203

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 (24) hide show
  1. package/esm2020/lib/item-list/item-list.component.mjs +3 -3
  2. package/esm2020/lib/step-builder/step-builder-action/step-builder-action.component.mjs +75 -13
  3. package/esm2020/lib/step-builder/step-builder-ai-agent/step-builder-ai-agent.component.mjs +3 -3
  4. package/esm2020/lib/step-builder/step-builder-document/step-builder-document.component.mjs +5 -6
  5. package/esm2020/lib/step-builder/step-builder-group/step-builder-group.component.mjs +148 -0
  6. package/esm2020/lib/test-case-details/condition-step/condition-step.component.mjs +7 -5
  7. package/esm2020/lib/test-case-details/loop-step/loop-step.component.mjs +7 -5
  8. package/esm2020/lib/test-case-details/normal-step/normal-step.component.mjs +3 -3
  9. package/esm2020/lib/test-case-details/step-group/step-group.component.mjs +6 -5
  10. package/esm2020/lib/test-case-details/test-data-modal/test-data-modal.component.mjs +9 -8
  11. package/esm2020/lib/ui-kit.module.mjs +6 -6
  12. package/esm2020/public-api.mjs +2 -2
  13. package/fesm2015/cqa-lib-cqa-ui.mjs +198 -623
  14. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  15. package/fesm2020/cqa-lib-cqa-ui.mjs +201 -618
  16. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  17. package/lib/step-builder/step-builder-action/step-builder-action.component.d.ts +10 -2
  18. package/lib/step-builder/step-builder-group/step-builder-group.component.d.ts +48 -0
  19. package/lib/ui-kit.module.d.ts +2 -2
  20. package/package.json +1 -1
  21. package/public-api.d.ts +1 -1
  22. package/styles.css +1 -1
  23. package/esm2020/lib/step-builder/step-builder-api/step-builder-api.component.mjs +0 -636
  24. package/lib/step-builder/step-builder-api/step-builder-api.component.d.ts +0 -121
@@ -1,636 +0,0 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
2
- import { FormArray, FormGroup, Validators } from '@angular/forms';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "@angular/forms";
5
- import * as i2 from "../../dynamic-select/dynamic-select-field.component";
6
- import * as i3 from "../../custom-input/custom-input.component";
7
- import * as i4 from "../../button/button.component";
8
- import * as i5 from "@angular/material/icon";
9
- import * as i6 from "../../custom-textarea/custom-textarea.component";
10
- import * as i7 from "@angular/material/checkbox";
11
- import * as i8 from "@angular/common";
12
- export class StepBuilderApiComponent {
13
- constructor(fb) {
14
- this.fb = fb;
15
- /** Options for HTTP method dropdown */
16
- this.httpMethodOptions = [
17
- { id: 'GET', value: 'GET', name: 'GET', label: 'GET' },
18
- { id: 'POST', value: 'POST', name: 'POST', label: 'POST' },
19
- { id: 'PUT', value: 'PUT', name: 'PUT', label: 'PUT' },
20
- { id: 'PATCH', value: 'PATCH', name: 'PATCH', label: 'PATCH' },
21
- { id: 'DELETE', value: 'DELETE', name: 'DELETE', label: 'DELETE' },
22
- { id: 'HEAD', value: 'HEAD', name: 'HEAD', label: 'HEAD' },
23
- { id: 'OPTIONS', value: 'OPTIONS', name: 'OPTIONS', label: 'OPTIONS' }
24
- ];
25
- /** Options for header name dropdown */
26
- this.headerNameOptions = [];
27
- /** Current progress step */
28
- this.currentStep = 'request-details';
29
- /** Response preview data */
30
- this.responsePreview = null;
31
- /** Loading state */
32
- this.isLoading = false;
33
- /** Emit when step is created */
34
- this.createStep = new EventEmitter();
35
- /** Emit when cancelled */
36
- this.cancelled = new EventEmitter();
37
- /** Emit when request is sent */
38
- this.sendRequest = new EventEmitter();
39
- /** Emit when cURL is imported */
40
- this.importCurl = new EventEmitter();
41
- this.selectedTab = 'headers';
42
- this.selectedProgressStep = 'request-details';
43
- this.formSubmitted = false;
44
- // progressSteps: ProgressStep[] = ['request-details', 'store-response', 'validation'];
45
- // Cache config objects to prevent infinite change detection loops
46
- this.verificationTypeConfigCache = null;
47
- this.expectedTypeConfigCache = null;
48
- this.httpMethodConfigCache = null;
49
- this.headerNameConfigCache = null;
50
- this.paramNameConfigCache = null;
51
- this.hasLoadedInitialData = false;
52
- // Get first HTTP method option (default to 'GET' if options not available yet)
53
- const firstMethod = this.httpMethodOptions.length > 0
54
- ? this.httpMethodOptions[0].value
55
- : 'GET';
56
- this.apiForm = this.fb.group({
57
- method: [firstMethod, Validators.required],
58
- url: ['', [Validators.required, this.urlValidator()]],
59
- headers: this.fb.array([]),
60
- body: [''],
61
- params: this.fb.array([]),
62
- scripts: [''],
63
- variableName: [''],
64
- validation: this.fb.array([])
65
- });
66
- }
67
- urlValidator() {
68
- return (control) => {
69
- const url = control.value;
70
- if (!url) {
71
- return null; // Let required validator handle empty case
72
- }
73
- // Pattern for plain URLs only (no parameters)
74
- const urlPattern = /^(https?:\/\/)?([\w-]+(\.[\w-]+)+)([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?$/;
75
- // Pattern to detect any parameter patterns: *|param|, $|param|, @|param|, or ${param}
76
- const parameterPattern = /(\*\|[\w-]+\|(\*)?|\$\|[\w-]+\|(\*)?|@\|[\w-]+\|(\*)?|\$\{[^}]+\})/;
77
- // Pattern for parameter-only values: *|param|, $|param|, @|param|, or ${param}
78
- const envPattern = /^\*\|[\w-]+\|(\*)?$|^\$\|[\w-]+\|(\*)?$|^@\|[\w-]+\|(\*)?$|^\$\{[^}]+\}$/;
79
- // Pattern to allow URLs with embedded parameters: *|param|, $|param|, @|param|, or ${param}
80
- const flexibleUrlPattern = /^[@]?(https?:\/\/)?([\w-]+(\.[\w-]+)+)([\w.,@?^=%&:/~+#-]*(\*\|[\w-]+\|(\*)?|\$\|[\w-]+\|(\*)?|@\|[\w-]+\|(\*)?|\$\{[^}]+\})[\w.,@?^=%&:/~+#-]*)*$/;
81
- // Pattern that allows parameters anywhere after http:// or https://
82
- const protocolWithParamsPattern = /^https?:\/\/(\*\|[\w-]+\|(\*)?|\$\|[\w-]+\|(\*)?|@\|[\w-]+\|(\*)?|\$\{[^}]+\})[^\s]*$|^https?:\/\/[^\s]*(\*\|[\w-]+\|(\*)?|\$\|[\w-]+\|(\*)?|@\|[\w-]+\|(\*)?|\$\{[^}]+\})[^\s]*$/;
83
- // Check if URL contains parameters
84
- if (parameterPattern.test(url)) {
85
- // If it contains parameters, check if it matches allowed patterns
86
- const envCombined = new RegExp(`${urlPattern.source}|${flexibleUrlPattern.source}|${envPattern.source}|${protocolWithParamsPattern.source}`);
87
- if (!envCombined.test(url)) {
88
- return { hasParameter: true };
89
- }
90
- }
91
- else {
92
- // If no parameters, check if it's a valid plain URL
93
- if (!urlPattern.test(url)) {
94
- return { pattern: true };
95
- }
96
- }
97
- return null;
98
- };
99
- }
100
- ngOnInit() {
101
- // Sync currentStep input with selectedProgressStep
102
- if (this.currentStep) {
103
- this.selectedProgressStep = this.currentStep;
104
- }
105
- // Set method to first option if not already set
106
- if (!this.apiForm.get('method')?.value && this.httpMethodOptions.length > 0) {
107
- this.apiForm.get('method')?.setValue(this.httpMethodOptions[0].value);
108
- }
109
- // Load initial data if provided (edit mode)
110
- if (this.initialData) {
111
- this.loadInitialData(this.initialData);
112
- this.hasLoadedInitialData = true;
113
- }
114
- else {
115
- // Add initial header row for new step
116
- this.addHeader();
117
- }
118
- // Initialize validation form array if starting on validation step
119
- if (this.selectedProgressStep === 'validation' && this.validationFormArray.length === 0) {
120
- this.addValidationRule();
121
- }
122
- }
123
- loadInitialData(data) {
124
- console.log('loadInitialData: Loading data', data);
125
- console.log('loadInitialData: Headers count', data.headers?.length || 0);
126
- console.log('loadInitialData: Headers data', data.headers);
127
- // Set basic fields
128
- this.apiForm.patchValue({
129
- method: data.method || 'GET',
130
- url: data.url || '',
131
- body: data.body || '',
132
- scripts: data.scripts || '',
133
- variableName: data.variableName || ''
134
- });
135
- // Load headers
136
- // Clear existing headers first
137
- while (this.headersFormArray.length !== 0) {
138
- this.headersFormArray.removeAt(0);
139
- }
140
- if (data.headers && data.headers.length > 0) {
141
- // Add headers from initial data (include all headers, even if empty)
142
- data.headers.forEach(header => {
143
- const headerGroup = this.fb.group({
144
- name: [header.name || '', Validators.required],
145
- value: [header.value || '', Validators.required]
146
- });
147
- this.headersFormArray.push(headerGroup);
148
- });
149
- console.log('loadInitialData: Loaded headers into form array, count:', this.headersFormArray.length);
150
- }
151
- // Ensure at least one header row exists
152
- if (this.headersFormArray.length === 0) {
153
- console.log('loadInitialData: No headers found, adding empty header row');
154
- this.addHeader();
155
- }
156
- // Load params
157
- // Clear existing params first
158
- while (this.paramsFormArray.length !== 0) {
159
- this.paramsFormArray.removeAt(0);
160
- }
161
- if (data.params && data.params.length > 0) {
162
- // Add params from initial data (include all params, even if empty)
163
- data.params.forEach(param => {
164
- const paramGroup = this.fb.group({
165
- name: [param.name || '', Validators.required],
166
- value: [param.value || '', Validators.required]
167
- });
168
- this.paramsFormArray.push(paramGroup);
169
- });
170
- }
171
- // Load validation rules
172
- if (data.validation && data.validation.length > 0) {
173
- // Clear existing validation rules
174
- while (this.validationFormArray.length !== 0) {
175
- this.validationFormArray.removeAt(0);
176
- }
177
- // Add validation rules from initial data
178
- data.validation.forEach(rule => {
179
- const validationGroup = this.fb.group({
180
- jsonPath: [rule.jsonPath || '', Validators.required],
181
- verificationType: [rule.verificationType || 'equals', Validators.required],
182
- expectedType: [rule.expectedType || 'string', Validators.required],
183
- expectedValue: [rule.expectedValue !== undefined ? rule.expectedValue : '', Validators.required],
184
- result: [rule.result || 'Not run'],
185
- checked: [rule.checked || false]
186
- });
187
- // Ensure all controls are enabled
188
- validationGroup.enable({ emitEvent: false });
189
- this.validationFormArray.push(validationGroup);
190
- });
191
- }
192
- }
193
- get headersFormArray() {
194
- return this.apiForm.get('headers');
195
- }
196
- get paramsFormArray() {
197
- return this.apiForm.get('params');
198
- }
199
- get validationFormArray() {
200
- return this.apiForm.get('validation');
201
- }
202
- addHeader() {
203
- // Get first header name option
204
- const headerOptions = this.headerNameOptions.length > 0
205
- ? this.headerNameOptions
206
- : [
207
- { id: 'string', value: 'string', name: 'string', label: 'string' },
208
- { id: 'Content-Type', value: 'Content-Type', name: 'Content-Type', label: 'Content-Type' },
209
- { id: 'Authorization', value: 'Authorization', name: 'Authorization', label: 'Authorization' },
210
- { id: 'Accept', value: 'Accept', name: 'Accept', label: 'Accept' }
211
- ];
212
- const firstHeaderName = headerOptions.length > 0 ? headerOptions[0].value : '';
213
- const headerGroup = this.fb.group({
214
- name: [firstHeaderName, Validators.required],
215
- value: ['', Validators.required]
216
- });
217
- this.headersFormArray.push(headerGroup);
218
- }
219
- removeHeader(index) {
220
- this.headersFormArray.removeAt(index);
221
- }
222
- addParam() {
223
- const paramGroup = this.fb.group({
224
- name: ['', Validators.required],
225
- value: ['', Validators.required]
226
- });
227
- this.paramsFormArray.push(paramGroup);
228
- }
229
- removeParam(index) {
230
- this.paramsFormArray.removeAt(index);
231
- }
232
- ngOnChanges(changes) {
233
- // Reset config caches when inputs change
234
- if (changes['httpMethodOptions']) {
235
- this.httpMethodConfigCache = null;
236
- // Set method to first option if not already set or if we're not in edit mode
237
- if (!this.hasLoadedInitialData && this.httpMethodOptions.length > 0) {
238
- const methodControl = this.apiForm.get('method');
239
- if (methodControl && !methodControl.value) {
240
- methodControl.setValue(this.httpMethodOptions[0].value);
241
- }
242
- }
243
- }
244
- if (changes['headerNameOptions']) {
245
- this.headerNameConfigCache = null;
246
- // Update header names to first option for empty headers (only if not in edit mode)
247
- if (!this.hasLoadedInitialData && this.headerNameOptions.length > 0) {
248
- this.headersFormArray.controls.forEach((headerGroup) => {
249
- const nameControl = headerGroup.get('name');
250
- if (nameControl && !nameControl.value) {
251
- nameControl.setValue(this.headerNameOptions[0].value);
252
- }
253
- });
254
- }
255
- }
256
- // Load initial data if it's set after component initialization
257
- if (changes['initialData'] && !changes['initialData'].firstChange && this.initialData && !this.hasLoadedInitialData) {
258
- this.loadInitialData(this.initialData);
259
- this.hasLoadedInitialData = true;
260
- }
261
- }
262
- getHttpMethodConfig() {
263
- if (!this.httpMethodConfigCache) {
264
- this.httpMethodConfigCache = {
265
- key: 'method',
266
- placeholder: 'Select method',
267
- multiple: false,
268
- searchable: false,
269
- options: this.httpMethodOptions
270
- };
271
- }
272
- return this.httpMethodConfigCache;
273
- }
274
- getHeaderNameConfig(index) {
275
- if (!this.headerNameConfigCache) {
276
- const defaultOptions = [
277
- { id: 'string', value: 'string', name: 'string', label: 'string' },
278
- { id: 'Content-Type', value: 'Content-Type', name: 'Content-Type', label: 'Content-Type' },
279
- { id: 'Authorization', value: 'Authorization', name: 'Authorization', label: 'Authorization' },
280
- { id: 'Accept', value: 'Accept', name: 'Accept', label: 'Accept' }
281
- ];
282
- this.headerNameConfigCache = {
283
- key: 'name',
284
- placeholder: 'Select header',
285
- multiple: false,
286
- searchable: true,
287
- options: this.headerNameOptions.length > 0 ? this.headerNameOptions : defaultOptions
288
- };
289
- }
290
- return this.headerNameConfigCache;
291
- }
292
- getParamNameConfig(index) {
293
- if (!this.paramNameConfigCache) {
294
- this.paramNameConfigCache = {
295
- key: 'name',
296
- placeholder: 'Parameter name',
297
- multiple: false,
298
- searchable: false,
299
- options: []
300
- };
301
- }
302
- return this.paramNameConfigCache;
303
- }
304
- getHeaderFormGroup(index) {
305
- return this.headersFormArray.at(index);
306
- }
307
- getParamFormGroup(index) {
308
- return this.paramsFormArray.at(index);
309
- }
310
- onTabChange(tab) {
311
- this.selectedTab = tab;
312
- }
313
- onSendRequest() {
314
- this.formSubmitted = true;
315
- this.markFormGroupTouched(this.apiForm);
316
- console.log('onSendRequest: apiForm', this.apiForm.value);
317
- console.log('onSendRequest: apiForm valid', this.apiForm);
318
- if (this.apiForm.valid) {
319
- const formValue = this.apiForm.value;
320
- const headers = formValue.headers.map((h) => ({
321
- name: h.name,
322
- value: h.value
323
- }));
324
- const params = formValue.params ? formValue.params.map((p) => ({
325
- name: p.name,
326
- value: p.value
327
- })) : [];
328
- this.sendRequest.emit({
329
- method: formValue.method,
330
- url: formValue.url,
331
- headers,
332
- body: formValue.body,
333
- params
334
- });
335
- }
336
- }
337
- onImportCurl() {
338
- this.importCurl.emit();
339
- }
340
- onCancel() {
341
- this.cancelled.emit();
342
- }
343
- onCreateStep() {
344
- this.formSubmitted = true;
345
- this.markFormGroupTouched(this.apiForm);
346
- if (this.apiForm.valid) {
347
- const formValue = this.apiForm.value;
348
- const stepData = {
349
- method: formValue.method,
350
- url: formValue.url,
351
- headers: formValue.headers.map((h) => ({
352
- name: h.name,
353
- value: h.value
354
- })),
355
- body: formValue.body,
356
- params: formValue.params ? formValue.params.map((p) => ({
357
- name: p.name,
358
- value: p.value
359
- })) : [],
360
- scripts: formValue.scripts,
361
- variableName: formValue.variableName || '',
362
- validation: formValue.validation ? formValue.validation.map((v) => ({
363
- jsonPath: v.jsonPath,
364
- verificationType: v.verificationType,
365
- expectedType: v.expectedType,
366
- expectedValue: v.expectedValue,
367
- result: v.result || 'Not run'
368
- })) : []
369
- };
370
- console.log('9999999', stepData);
371
- this.createStep.emit(stepData);
372
- }
373
- }
374
- onNext() {
375
- // Move to next step or create step if on last step
376
- const stepOrder = ['request-details', 'store-response', 'validation'];
377
- const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
378
- if (currentIndex < stepOrder.length - 1) {
379
- this.onProgressStepChange(stepOrder[currentIndex + 1]);
380
- }
381
- else {
382
- this.onCreateStep();
383
- }
384
- }
385
- onBack() {
386
- // Move to previous step
387
- const stepOrder = ['request-details', 'store-response', 'validation'];
388
- const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
389
- if (currentIndex > 0) {
390
- this.onProgressStepChange(stepOrder[currentIndex - 1]);
391
- }
392
- }
393
- canGoBack() {
394
- const stepOrder = ['request-details', 'store-response', 'validation'];
395
- const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
396
- return currentIndex > 0;
397
- }
398
- isLastStep() {
399
- const stepOrder = ['request-details', 'store-response', 'validation'];
400
- const currentIndex = stepOrder.indexOf(this.selectedProgressStep);
401
- return currentIndex === stepOrder.length - 1;
402
- }
403
- getProgressStepClass(step) {
404
- const stepOrder = ['request-details', 'store-response', 'validation'];
405
- const currentIndex = stepOrder.indexOf(this.currentStep);
406
- const stepIndex = stepOrder.indexOf(step);
407
- if (stepIndex < currentIndex) {
408
- return 'cqa-text-gray-400'; // Completed
409
- }
410
- else if (stepIndex === currentIndex) {
411
- return 'cqa-text-purple-600 cqa-font-semibold'; // Active
412
- }
413
- else {
414
- return 'cqa-text-gray-400'; // Pending
415
- }
416
- }
417
- getProgressStepNumber(step) {
418
- const stepOrder = ['request-details', 'store-response', 'validation'];
419
- return stepOrder.indexOf(step) + 1;
420
- }
421
- getProgressStepLabel(step) {
422
- const labels = {
423
- 'request-details': 'Request Details',
424
- 'store-response': 'Store Response',
425
- 'validation': 'Validation'
426
- };
427
- return labels[step];
428
- }
429
- formatJsonResponse(data) {
430
- if (!data)
431
- return '';
432
- try {
433
- return JSON.stringify(data, null, 2);
434
- }
435
- catch {
436
- return String(data);
437
- }
438
- }
439
- onProgressStepChange(step) {
440
- this.selectedProgressStep = step;
441
- // Initialize validation form array if switching to validation step
442
- if (step === 'validation' && this.validationFormArray.length === 0) {
443
- this.addValidationRule();
444
- }
445
- }
446
- addValidationRule() {
447
- const validationGroup = this.fb.group({
448
- checked: [false],
449
- jsonPath: ['', Validators.required],
450
- verificationType: ['equals'],
451
- expectedType: ['string'],
452
- expectedValue: ['', Validators.required],
453
- result: ['Not run']
454
- });
455
- // Ensure all controls are enabled to avoid disabled attribute warnings
456
- validationGroup.enable({ emitEvent: false });
457
- this.validationFormArray.push(validationGroup);
458
- }
459
- removeValidationRule(index) {
460
- this.validationFormArray.removeAt(index);
461
- }
462
- getValidationFormGroup(index) {
463
- return this.validationFormArray.at(index);
464
- }
465
- trackByValidationRuleIndex(index) {
466
- return index;
467
- }
468
- trackByHeaderIndex(index) {
469
- return index;
470
- }
471
- trackByParamIndex(index) {
472
- return index;
473
- }
474
- getVerificationTypeOptions() {
475
- return [
476
- { id: 'equals', value: 'equals', name: 'Equals', label: 'Equals' },
477
- { id: 'not_equals', value: 'not_equals', name: 'Not Equals', label: 'Not Equals' },
478
- { id: 'contains', value: 'contains', name: 'Contains', label: 'Contains' },
479
- { id: 'not_contains', value: 'not_contains', name: 'Not Contains', label: 'Not Contains' },
480
- { id: 'greater_than', value: 'greater_than', name: 'Greater Than', label: 'Greater Than' },
481
- { id: 'less_than', value: 'less_than', name: 'Less Than', label: 'Less Than' },
482
- { id: 'greater_than_or_equals', value: 'greater_than_or_equals', name: 'Greater Than Or Equals', label: 'Greater Than Or Equals' },
483
- { id: 'less_than_or_equals', value: 'less_than_or_equals', name: 'Less Than Or Equals', label: 'Less Than Or Equals' },
484
- { id: 'exists', value: 'exists', name: 'Exists', label: 'Exists' },
485
- { id: 'not_exists', value: 'not_exists', name: 'Not Exists', label: 'Not Exists' }
486
- ];
487
- }
488
- getExpectedTypeOptions() {
489
- return [
490
- { id: 'string', value: 'string', name: 'String', label: 'String' },
491
- { id: 'number', value: 'number', name: 'Number', label: 'Number' },
492
- { id: 'boolean', value: 'boolean', name: 'Boolean', label: 'Boolean' },
493
- { id: 'object', value: 'object', name: 'Object', label: 'Object' },
494
- { id: 'array', value: 'array', name: 'Array', label: 'Array' },
495
- { id: 'null', value: 'null', name: 'Null', label: 'Null' }
496
- ];
497
- }
498
- getVerificationTypeConfig(index) {
499
- // Cache the config to prevent infinite change detection loops
500
- if (!this.verificationTypeConfigCache) {
501
- this.verificationTypeConfigCache = {
502
- key: 'verificationType',
503
- placeholder: 'Select verification type',
504
- multiple: false,
505
- searchable: false,
506
- options: this.getVerificationTypeOptions()
507
- };
508
- }
509
- return this.verificationTypeConfigCache;
510
- }
511
- getExpectedTypeConfig(index) {
512
- // Cache the config to prevent infinite change detection loops
513
- if (!this.expectedTypeConfigCache) {
514
- this.expectedTypeConfigCache = {
515
- key: 'expectedType',
516
- placeholder: 'Select expected type',
517
- multiple: false,
518
- searchable: false,
519
- options: this.getExpectedTypeOptions()
520
- };
521
- }
522
- return this.expectedTypeConfigCache;
523
- }
524
- getResultClass(result) {
525
- if (result === 'Pass') {
526
- return 'cqa-bg-green-500 cqa-text-white';
527
- }
528
- else if (result === 'Fail') {
529
- return 'cqa-bg-red-500 cqa-text-white';
530
- }
531
- return 'cqa-bg-gray-300 cqa-text-gray-700';
532
- }
533
- get allValidationRulesSelected() {
534
- return this.validationFormArray.length > 0 &&
535
- this.validationFormArray.controls.every(control => control.get('checked')?.value);
536
- }
537
- get someValidationRulesSelected() {
538
- return this.validationFormArray.controls.some(control => control.get('checked')?.value) &&
539
- !this.allValidationRulesSelected;
540
- }
541
- onSelectAllValidationRules(checked) {
542
- this.validationFormArray.controls.forEach(control => {
543
- control.get('checked')?.setValue(checked);
544
- });
545
- }
546
- onDeleteSelectedValidationRules() {
547
- const indicesToRemove = [];
548
- this.validationFormArray.controls.forEach((control, index) => {
549
- if (control.get('checked')?.value) {
550
- indicesToRemove.push(index);
551
- }
552
- });
553
- // Remove in reverse order to maintain correct indices
554
- indicesToRemove.reverse().forEach(index => {
555
- this.removeValidationRule(index);
556
- });
557
- }
558
- markFormGroupTouched(formGroup) {
559
- Object.keys(formGroup.controls).forEach(key => {
560
- const control = formGroup.get(key);
561
- if (control) {
562
- control.markAsTouched();
563
- if (control instanceof FormGroup) {
564
- this.markFormGroupTouched(control);
565
- }
566
- else if (control instanceof FormArray) {
567
- control.controls.forEach((ctrl) => {
568
- if (ctrl instanceof FormGroup) {
569
- this.markFormGroupTouched(ctrl);
570
- }
571
- else {
572
- ctrl.markAsTouched();
573
- }
574
- });
575
- }
576
- }
577
- });
578
- }
579
- onUrlChange(value) {
580
- const urlControl = this.apiForm.get('url');
581
- if (urlControl) {
582
- urlControl.setValue(value);
583
- urlControl.updateValueAndValidity();
584
- }
585
- }
586
- onUrlBlur() {
587
- const urlControl = this.apiForm.get('url');
588
- if (urlControl) {
589
- urlControl.markAsTouched();
590
- }
591
- }
592
- getUrlErrors() {
593
- const urlControl = this.apiForm.get('url');
594
- if (!urlControl || (!this.formSubmitted && !urlControl.touched)) {
595
- return [];
596
- }
597
- const errors = [];
598
- if (urlControl.errors?.['required']) {
599
- errors.push('URL is required');
600
- }
601
- else if (urlControl.errors?.['pattern']) {
602
- errors.push('URL is not valid');
603
- }
604
- else if (urlControl.errors?.['hasParameter']) {
605
- errors.push('URL format is invalid. Please check the parameter format.');
606
- }
607
- return errors;
608
- }
609
- }
610
- StepBuilderApiComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderApiComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
611
- StepBuilderApiComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderApiComponent, selector: "cqa-step-builder-api", inputs: { httpMethodOptions: "httpMethodOptions", headerNameOptions: "headerNameOptions", currentStep: "currentStep", responsePreview: "responsePreview", isLoading: "isLoading", initialData: "initialData" }, outputs: { createStep: "createStep", cancelled: "cancelled", sendRequest: "sendRequest", importCurl: "importCurl" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create API Test Step\n </h2>\n\n <!-- Progress Tracker -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-mb-6 cqa-pb-4 cqa-border-b cqa-border-gray-200\">\n <!-- <div *ngFor=\"let step of progressSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-2\"\n [ngClass]=\"getProgressStepClass(step)\">\n <span class=\"cqa-text-sm cqa-font-medium\">{{ getProgressStepNumber(step) }} {{ getProgressStepLabel(step) }}</span>\n <span *ngIf=\"step !== 'validation'\" class=\"cqa-text-gray-300\">\u2022</span>\n </div> -->\n <div class=\"cqa-flex cqa-items-center cqa-w-full cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'request-details'}\" (click)=\"onProgressStepChange('request-details')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">1</div>\n <div>Request Details</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'store-response'}\" (click)=\"onProgressStepChange('store-response')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">2</div>\n <div>Store Response</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'validation'}\" (click)=\"onProgressStepChange('validation')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">3</div>\n <div>Validation</div>\n <div></div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"selectedProgressStep === 'request-details'\">\n <!-- API Request Configuration -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-2 cqa-mb-3\">\n <div class=\"cqa-w-32 cqa-flex-shrink-0\">\n <cqa-dynamic-select\n [form]=\"apiForm\"\n [config]=\"getHttpMethodConfig()\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Enter API endpoint URL'\"\n [value]=\"apiForm.get('url')?.value || ''\"\n [fullWidth]=\"true\"\n [errors]=\"getUrlErrors()\"\n (valueChange)=\"onUrlChange($event)\"\n (blurred)=\"onUrlBlur()\">\n </cqa-custom-input>\n </div>\n <cqa-button\n variant=\"outlined\"\n text=\"Import API cURL\"\n (clicked)=\"onImportCurl()\">\n </cqa-button>\n <cqa-button\n variant=\"filled\"\n text=\"Send Request\"\n (clicked)=\"onSendRequest()\"\n [disabled]=\"!apiForm.get('url')?.value || isLoading\">\n </cqa-button>\n </div>\n\n <!-- Request Details Tabs -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Tab Navigation -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'headers'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'headers'\"\n (click)=\"onTabChange('headers')\">\n Headers\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'body'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'body'\"\n (click)=\"onTabChange('body')\">\n Body\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'params'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'params'\"\n (click)=\"onTabChange('params')\">\n Params\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'scripts'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'scripts'\"\n (click)=\"onTabChange('scripts')\">\n Scripts\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-4 cqa-border cqa-border-gray-200 cqa-border-t-0 cqa-rounded-b-lg\">\n <!-- Headers Tab -->\n <div *ngIf=\"selectedTab === 'headers'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Name*</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Value*</div>\n </div>\n <div *ngFor=\"let header of headersFormArray.controls; let i = index; trackBy: trackByHeaderIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-dynamic-select\n [form]=\"getHeaderFormGroup(i)\"\n [config]=\"getHeaderNameConfig(i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Header value'\"\n [value]=\"getHeaderFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getHeaderFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeHeader(i)\"\n [attr.aria-label]=\"'Remove header'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addHeader()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Header</span>\n </button>\n </div>\n\n <!-- Body Tab -->\n <div *ngIf=\"selectedTab === 'body'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter request body (JSON, XML, etc.)'\"\n [value]=\"apiForm.get('body')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('body')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- Params Tab -->\n <div *ngIf=\"selectedTab === 'params'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Value</div>\n </div>\n <div *ngFor=\"let param of paramsFormArray.controls; let i = index; trackBy: trackByParamIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-custom-input\n [placeholder]=\"'Parameter name'\"\n [value]=\"getParamFormGroup(i).get('name')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('name')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Parameter value'\"\n [value]=\"getParamFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeParam(i)\"\n [attr.aria-label]=\"'Remove parameter'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addParam()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Parameter</span>\n </button>\n </div>\n\n <!-- Scripts Tab -->\n <div *ngIf=\"selectedTab === 'scripts'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter scripts (JavaScript, etc.)'\"\n [value]=\"apiForm.get('scripts')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('scripts')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'store-response'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Store Response Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Store Response\n </h3>\n\n <!-- Variable Name Input -->\n <div class=\"cqa-mb-6\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1 cqa-block\">\n Variable Name\n </label>\n <cqa-custom-input\n [placeholder]=\"'Variable Name'\"\n [value]=\"apiForm.get('variableName')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('variableName')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'validation'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Validation Rules Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Validation Rules\n </h3>\n\n <!-- Validation Rules Table -->\n <div class=\"cqa-bg-white cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-4\">\n <!-- Table Header -->\n <div class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200 cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox\n [checked]=\"allValidationRulesSelected\"\n [indeterminate]=\"someValidationRulesSelected\"\n (change)=\"onSelectAllValidationRules($event.checked)\">\n </mat-checkbox>\n </div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">jsonPath</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">verificationType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedValue</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Result</div>\n </div>\n\n <!-- Table Body -->\n <div class=\"cqa-flex cqa-flex-col\">\n <div *ngFor=\"let validationRule of validationFormArray.controls; let i = index; trackBy: trackByValidationRuleIndex\" \n [formGroup]=\"getValidationFormGroup(i)\"\n class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-border-b cqa-border-gray-200 cqa-items-center cqa-last:border-b-0\">\n <!-- Checkbox -->\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox formControlName=\"checked\">\n </mat-checkbox>\n </div>\n\n <!-- jsonPath -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'jsonPath'\"\n [value]=\"getValidationFormGroup(i).get('jsonPath')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('jsonPath')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- verificationType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getVerificationTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getExpectedTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedValue -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'expectedValue'\"\n [value]=\"getValidationFormGroup(i).get('expectedValue')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('expectedValue')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Result and Delete -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button\n type=\"button\"\n class=\"cqa-px-3 cqa-py-1 cqa-rounded cqa-text-[10px] cqa-font-medium\"\n [ngClass]=\"getResultClass(getValidationFormGroup(i).get('result')?.value || 'Not run')\">\n {{ getValidationFormGroup(i).get('result')?.value || 'Not run' }}\n </button>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeValidationRule(i)\"\n [attr.aria-label]=\"'Delete validation rule'\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Add Another Rule and Delete Selected -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-mb-4\">\n <button\n *ngIf=\"someValidationRulesSelected || allValidationRulesSelected\"\n type=\"button\"\n class=\"cqa-text-red-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-red-700 cqa-transition-colors\"\n (click)=\"onDeleteSelectedValidationRules()\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n <span>Delete Selected</span>\n </button>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addValidationRule()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Another</span>\n </button>\n </div>\n </div>\n</ng-container>\n\n\n <!-- Response Preview Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-6\">\n <div class=\"cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Response Preview</h3>\n </div>\n <div class=\"cqa-p-4 cqa-bg-gray-50 cqa-overflow-auto\" style=\"max-height: 300px;\">\n <pre *ngIf=\"responsePreview\" class=\"cqa-text-xs cqa-font-mono cqa-text-gray-800 cqa-whitespace-pre-wrap\">{{ formatJsonResponse(responsePreview) }}</pre>\n <p *ngIf=\"!responsePreview\" class=\"cqa-text-sm cqa-text-gray-400 cqa-text-center cqa-py-8\">\n No response yet. Send a request to see the response preview.\n </p>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <!-- Cancel button (only on first step) -->\n <cqa-button\n *ngIf=\"selectedProgressStep === 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <!-- Back button (on all steps except first) -->\n <cqa-button\n *ngIf=\"selectedProgressStep !== 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Back\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onBack()\">\n </cqa-button>\n <!-- Next/Create Step button -->\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n [text]=\"isLastStep() ? 'Create Step' : 'Next'\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"isLastStep() ? onCreateStep() : onNext()\">\n </cqa-button>\n </div>\n</div>\n\n", components: [{ type: i2.DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i3.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: i4.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i6.CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], directives: [{ type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
612
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderApiComponent, decorators: [{
613
- type: Component,
614
- args: [{ selector: 'cqa-step-builder-api', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create API Test Step\n </h2>\n\n <!-- Progress Tracker -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-mb-6 cqa-pb-4 cqa-border-b cqa-border-gray-200\">\n <!-- <div *ngFor=\"let step of progressSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-2\"\n [ngClass]=\"getProgressStepClass(step)\">\n <span class=\"cqa-text-sm cqa-font-medium\">{{ getProgressStepNumber(step) }} {{ getProgressStepLabel(step) }}</span>\n <span *ngIf=\"step !== 'validation'\" class=\"cqa-text-gray-300\">\u2022</span>\n </div> -->\n <div class=\"cqa-flex cqa-items-center cqa-w-full cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'request-details'}\" (click)=\"onProgressStepChange('request-details')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">1</div>\n <div>Request Details</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'store-response'}\" (click)=\"onProgressStepChange('store-response')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">2</div>\n <div>Store Response</div>\n <div></div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [ngClass]=\"{'cqa-text-purple-600 cqa-font-semibold': selectedProgressStep === 'validation'}\" (click)=\"onProgressStepChange('validation')\">\n <div class=\"cqa-w-8 cqa-h-8 cqa-flex cqa-items-center cqa-justify-center cqa-rounded-full cqa-bg-purple-600 cqa-text-white cqa-text-xs cqa-font-semibold\">3</div>\n <div>Validation</div>\n <div></div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"selectedProgressStep === 'request-details'\">\n <!-- API Request Configuration -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-2 cqa-mb-3\">\n <div class=\"cqa-w-32 cqa-flex-shrink-0\">\n <cqa-dynamic-select\n [form]=\"apiForm\"\n [config]=\"getHttpMethodConfig()\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Enter API endpoint URL'\"\n [value]=\"apiForm.get('url')?.value || ''\"\n [fullWidth]=\"true\"\n [errors]=\"getUrlErrors()\"\n (valueChange)=\"onUrlChange($event)\"\n (blurred)=\"onUrlBlur()\">\n </cqa-custom-input>\n </div>\n <cqa-button\n variant=\"outlined\"\n text=\"Import API cURL\"\n (clicked)=\"onImportCurl()\">\n </cqa-button>\n <cqa-button\n variant=\"filled\"\n text=\"Send Request\"\n (clicked)=\"onSendRequest()\"\n [disabled]=\"!apiForm.get('url')?.value || isLoading\">\n </cqa-button>\n </div>\n\n <!-- Request Details Tabs -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-hidden cqa-mb-6\">\n <!-- Tab Navigation -->\n <div class=\"cqa-flex cqa-items-center cqa-border-b cqa-border-gray-200 cqa-bg-gray-50\">\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'headers'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'headers'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'headers'\"\n (click)=\"onTabChange('headers')\">\n Headers\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'body'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'body'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'body'\"\n (click)=\"onTabChange('body')\">\n Body\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'params'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'params'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'params'\"\n (click)=\"onTabChange('params')\">\n Params\n </button>\n <button\n type=\"button\"\n class=\"cqa-px-4 cqa-py-2 cqa-text-sm cqa-font-medium cqa-transition-colors cqa-border-b-2\"\n [class.cqa-text-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-border-blue-600]=\"selectedTab === 'scripts'\"\n [class.cqa-text-gray-600]=\"selectedTab !== 'scripts'\"\n [class.cqa-border-transparent]=\"selectedTab !== 'scripts'\"\n (click)=\"onTabChange('scripts')\">\n Scripts\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-p-4 cqa-border cqa-border-gray-200 cqa-border-t-0 cqa-rounded-b-lg\">\n <!-- Headers Tab -->\n <div *ngIf=\"selectedTab === 'headers'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Name*</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Header Value*</div>\n </div>\n <div *ngFor=\"let header of headersFormArray.controls; let i = index; trackBy: trackByHeaderIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-dynamic-select\n [form]=\"getHeaderFormGroup(i)\"\n [config]=\"getHeaderNameConfig(i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Header value'\"\n [value]=\"getHeaderFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getHeaderFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeHeader(i)\"\n [attr.aria-label]=\"'Remove header'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addHeader()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Header</span>\n </button>\n </div>\n\n <!-- Body Tab -->\n <div *ngIf=\"selectedTab === 'body'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter request body (JSON, XML, etc.)'\"\n [value]=\"apiForm.get('body')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('body')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- Params Tab -->\n <div *ngIf=\"selectedTab === 'params'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-start\">\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Name</div>\n <div class=\"cqa-text-xs cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Parameter Value</div>\n </div>\n <div *ngFor=\"let param of paramsFormArray.controls; let i = index; trackBy: trackByParamIndex\" \n class=\"cqa-grid cqa-grid-cols-2 cqa-gap-4 cqa-items-center\">\n <div>\n <cqa-custom-input\n [placeholder]=\"'Parameter name'\"\n [value]=\"getParamFormGroup(i).get('name')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('name')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-flex-1\">\n <cqa-custom-input\n [placeholder]=\"'Parameter value'\"\n [value]=\"getParamFormGroup(i).get('value')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getParamFormGroup(i).get('value')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeParam(i)\"\n [attr.aria-label]=\"'Remove parameter'\">\n <mat-icon class=\"cqa-text-lg\">delete</mat-icon>\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-self-start cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addParam()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Parameter</span>\n </button>\n </div>\n\n <!-- Scripts Tab -->\n <div *ngIf=\"selectedTab === 'scripts'\" class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <cqa-custom-textarea\n [placeholder]=\"'Enter scripts (JavaScript, etc.)'\"\n [value]=\"apiForm.get('scripts')?.value || ''\"\n [fullWidth]=\"true\"\n [rows]=\"10\"\n (valueChange)=\"apiForm.get('scripts')?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n </div>\n </div>\n\n\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'store-response'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Store Response Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Store Response\n </h3>\n\n <!-- Variable Name Input -->\n <div class=\"cqa-mb-6\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-gray-700 cqa-mb-1 cqa-block\">\n Variable Name\n </label>\n <cqa-custom-input\n [placeholder]=\"'Variable Name'\"\n [value]=\"apiForm.get('variableName')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"apiForm.get('variableName')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"selectedProgressStep === 'validation'\">\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-max-h-[500px] cqa-overflow-y-auto\">\n <!-- Validation Rules Title -->\n <h3 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Validation Rules\n </h3>\n\n <!-- Validation Rules Table -->\n <div class=\"cqa-bg-white cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-4\">\n <!-- Table Header -->\n <div class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200 cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox\n [checked]=\"allValidationRulesSelected\"\n [indeterminate]=\"someValidationRulesSelected\"\n (change)=\"onSelectAllValidationRules($event.checked)\">\n </mat-checkbox>\n </div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">jsonPath</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">verificationType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedType</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">expectedValue</div>\n <div class=\"cqa-text-[10px] cqa-font-semibold cqa-text-gray-700 cqa-uppercase\">Result</div>\n </div>\n\n <!-- Table Body -->\n <div class=\"cqa-flex cqa-flex-col\">\n <div *ngFor=\"let validationRule of validationFormArray.controls; let i = index; trackBy: trackByValidationRuleIndex\" \n [formGroup]=\"getValidationFormGroup(i)\"\n class=\"cqa-grid cqa-grid-cols-6 cqa-gap-2 cqa-p-3 cqa-border-b cqa-border-gray-200 cqa-items-center cqa-last:border-b-0\">\n <!-- Checkbox -->\n <div class=\"cqa-flex cqa-items-center\">\n <mat-checkbox formControlName=\"checked\">\n </mat-checkbox>\n </div>\n\n <!-- jsonPath -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'jsonPath'\"\n [value]=\"getValidationFormGroup(i).get('jsonPath')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('jsonPath')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- verificationType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getVerificationTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedType -->\n <div>\n <cqa-dynamic-select\n [form]=\"getValidationFormGroup(i)\"\n [config]=\"getExpectedTypeConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- expectedValue -->\n <div>\n <cqa-custom-input\n [placeholder]=\"'expectedValue'\"\n [value]=\"getValidationFormGroup(i).get('expectedValue')?.value || ''\"\n [fullWidth]=\"true\"\n (valueChange)=\"getValidationFormGroup(i).get('expectedValue')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Result and Delete -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button\n type=\"button\"\n class=\"cqa-px-3 cqa-py-1 cqa-rounded cqa-text-[10px] cqa-font-medium\"\n [ngClass]=\"getResultClass(getValidationFormGroup(i).get('result')?.value || 'Not run')\">\n {{ getValidationFormGroup(i).get('result')?.value || 'Not run' }}\n </button>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-rounded cqa-text-red-500 hover:cqa-text-red-700 hover:cqa-bg-red-50 cqa-transition-colors\"\n (click)=\"removeValidationRule(i)\"\n [attr.aria-label]=\"'Delete validation rule'\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Add Another Rule and Delete Selected -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-mb-4\">\n <button\n *ngIf=\"someValidationRulesSelected || allValidationRulesSelected\"\n type=\"button\"\n class=\"cqa-text-red-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-red-700 cqa-transition-colors\"\n (click)=\"onDeleteSelectedValidationRules()\">\n <mat-icon class=\"cqa-text-base\">delete</mat-icon>\n <span>Delete Selected</span>\n </button>\n <button\n type=\"button\"\n class=\"cqa-text-blue-600 cqa-text-sm cqa-font-medium cqa-flex cqa-items-center cqa-gap-1 hover:cqa-text-blue-700 cqa-transition-colors\"\n (click)=\"addValidationRule()\">\n <mat-icon class=\"cqa-text-base\">add</mat-icon>\n <span>Add Another</span>\n </button>\n </div>\n </div>\n</ng-container>\n\n\n <!-- Response Preview Section -->\n <div class=\"cqa-flex cqa-flex-col cqa-border cqa-border-gray-200 cqa-rounded-lg cqa-overflow-hidden cqa-mb-6\">\n <div class=\"cqa-p-3 cqa-bg-gray-50 cqa-border-b cqa-border-gray-200\">\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-gray-900\">Response Preview</h3>\n </div>\n <div class=\"cqa-p-4 cqa-bg-gray-50 cqa-overflow-auto\" style=\"max-height: 300px;\">\n <pre *ngIf=\"responsePreview\" class=\"cqa-text-xs cqa-font-mono cqa-text-gray-800 cqa-whitespace-pre-wrap\">{{ formatJsonResponse(responsePreview) }}</pre>\n <p *ngIf=\"!responsePreview\" class=\"cqa-text-sm cqa-text-gray-400 cqa-text-center cqa-py-8\">\n No response yet. Send a request to see the response preview.\n </p>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <!-- Cancel button (only on first step) -->\n <cqa-button\n *ngIf=\"selectedProgressStep === 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <!-- Back button (on all steps except first) -->\n <cqa-button\n *ngIf=\"selectedProgressStep !== 'request-details'\"\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Back\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onBack()\">\n </cqa-button>\n <!-- Next/Create Step button -->\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n [text]=\"isLastStep() ? 'Create Step' : 'Next'\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"isLastStep() ? onCreateStep() : onNext()\">\n </cqa-button>\n </div>\n</div>\n\n", styles: [] }]
615
- }], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { httpMethodOptions: [{
616
- type: Input
617
- }], headerNameOptions: [{
618
- type: Input
619
- }], currentStep: [{
620
- type: Input
621
- }], responsePreview: [{
622
- type: Input
623
- }], isLoading: [{
624
- type: Input
625
- }], initialData: [{
626
- type: Input
627
- }], createStep: [{
628
- type: Output
629
- }], cancelled: [{
630
- type: Output
631
- }], sendRequest: [{
632
- type: Output
633
- }], importCurl: [{
634
- type: Output
635
- }] } });
636
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1idWlsZGVyLWFwaS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3N0ZXAtYnVpbGRlci9zdGVwLWJ1aWxkZXItYXBpL3N0ZXAtYnVpbGRlci1hcGkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zdGVwLWJ1aWxkZXIvc3RlcC1idWlsZGVyLWFwaS9zdGVwLWJ1aWxkZXItYXBpLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQW1ELE1BQU0sZUFBZSxDQUFDO0FBQ3hILE9BQU8sRUFBRSxTQUFTLEVBQWUsU0FBUyxFQUFlLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7O0FBdUM1RixNQUFNLE9BQU8sdUJBQXVCO0lBcURsQyxZQUFvQixFQUFlO1FBQWYsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQXBEbkMsdUNBQXVDO1FBQzlCLHNCQUFpQixHQUFtQjtZQUMzQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7WUFDdEQsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFO1lBQzFELEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtZQUN0RCxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7WUFDOUQsRUFBRSxF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QixDQUFDOztvSEFucUJVLHVCQUF1Qjt3R0FBdkIsdUJBQXVCLCtiQ3hDcEMscXprQkFnWkE7MkZEeFdhLHVCQUF1QjtrQkFObkMsU0FBUzsrQkFDRSxzQkFBc0IsUUFHMUIsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFO2tHQUlyQixpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBV0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0csZUFBZTtzQkFBdkIsS0FBSztnQkFHRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0ksVUFBVTtzQkFBbkIsTUFBTTtnQkFHRyxTQUFTO3NCQUFsQixNQUFNO2dCQUdHLFdBQVc7c0JBQXBCLE1BQU07Z0JBR0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUFycmF5LCBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBGb3JtQ29udHJvbCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZywgU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1zZWxlY3QvZHluYW1pYy1zZWxlY3QtZmllbGQuY29tcG9uZW50JztcblxuZXhwb3J0IHR5cGUgSHR0cE1ldGhvZCA9ICdHRVQnIHwgJ1BPU1QnIHwgJ1BVVCcgfCAnUEFUQ0gnIHwgJ0RFTEVURScgfCAnSEVBRCcgfCAnT1BUSU9OUyc7XG5leHBvcnQgdHlwZSBSZXF1ZXN0VGFiID0gJ2hlYWRlcnMnIHwgJ2JvZHknIHwgJ3BhcmFtcycgfCAnc2NyaXB0cyc7XG5leHBvcnQgdHlwZSBQcm9ncmVzc1N0ZXAgPSAncmVxdWVzdC1kZXRhaWxzJyB8ICdzdG9yZS1yZXNwb25zZScgfCAndmFsaWRhdGlvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGVhZGVyUm93IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25SdWxlIHtcbiAganNvblBhdGg6IHN0cmluZztcbiAgdmVyaWZpY2F0aW9uVHlwZTogc3RyaW5nO1xuICBleHBlY3RlZFR5cGU6IHN0cmluZztcbiAgZXhwZWN0ZWRWYWx1ZTogYW55O1xuICByZXN1bHQ/OiAnUGFzcycgfCAnRmFpbCcgfCAnTm90IHJ1bic7XG4gIGNoZWNrZWQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFwaUZvcm1EYXRhIHtcbiAgbWV0aG9kOiBIdHRwTWV0aG9kO1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVyczogSGVhZGVyUm93W107XG4gIGJvZHk/OiBzdHJpbmc7XG4gIHBhcmFtcz86IEhlYWRlclJvd1tdO1xuICBzY3JpcHRzPzogc3RyaW5nO1xuICB2YXJpYWJsZU5hbWU/OiBzdHJpbmc7XG4gIHN0b3JlUmVzcG9uc2U/OiBhbnk7XG4gIHZhbGlkYXRpb24/OiBWYWxpZGF0aW9uUnVsZVtdO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtc3RlcC1idWlsZGVyLWFwaScsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdGVwLWJ1aWxkZXItYXBpLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbXSxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9XG59KVxuZXhwb3J0IGNsYXNzIFN0ZXBCdWlsZGVyQXBpQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICAvKiogT3B0aW9ucyBmb3IgSFRUUCBtZXRob2QgZHJvcGRvd24gKi9cbiAgQElucHV0KCkgaHR0cE1ldGhvZE9wdGlvbnM6IFNlbGVjdE9wdGlvbltdID0gW1xuICAgIHsgaWQ6ICdHRVQnLCB2YWx1ZTogJ0dFVCcsIG5hbWU6ICdHRVQnLCBsYWJlbDogJ0dFVCcgfSxcbiAgICB7IGlkOiAnUE9TVCcsIHZhbHVlOiAnUE9TVCcsIG5hbWU6ICdQT1NUJywgbGFiZWw6ICdQT1NUJyB9LFxuICAgIHsgaWQ6ICdQVVQnLCB2YWx1ZTogJ1BVVCcsIG5hbWU6ICdQVVQnLCBsYWJlbDogJ1BVVCcgfSxcbiAgICB7IGlkOiAnUEFUQ0gnLCB2YWx1ZTogJ1BBVENIJywgbmFtZTogJ1BBVENIJywgbGFiZWw6ICdQQVRDSCcgfSxcbiAgICB7IGlkOiAnREVMRVRFJywgdmFsdWU6ICdERUxFVEUnLCBuYW1lOiAnREVMRVRFJywgbGFiZWw6ICdERUxFVEUnIH0sXG4gICAgeyBpZDogJ0hFQUQnLCB2YWx1ZTogJ0hFQUQnLCBuYW1lOiAnSEVBRCcsIGxhYmVsOiAnSEVBRCcgfSxcbiAgICB7IGlkOiAnT1BUSU9OUycsIHZhbHVlOiAnT1BUSU9OUycsIG5hbWU6ICdPUFRJT05TJywgbGFiZWw6ICdPUFRJT05TJyB9XG4gIF07XG5cbiAgLyoqIE9wdGlvbnMgZm9yIGhlYWRlciBuYW1lIGRyb3Bkb3duICovXG4gIEBJbnB1dCgpIGhlYWRlck5hbWVPcHRpb25zOiBTZWxlY3RPcHRpb25bXSA9IFtdO1xuXG4gIC8qKiBDdXJyZW50IHByb2dyZXNzIHN0ZXAgKi9cbiAgQElucHV0KCkgY3VycmVudFN0ZXA6IFByb2dyZXNzU3RlcCA9ICdyZXF1ZXN0LWRldGFpbHMnO1xuXG4gIC8qKiBSZXNwb25zZSBwcmV2aWV3IGRhdGEgKi9cbiAgQElucHV0KCkgcmVzcG9uc2VQcmV2aWV3OiBhbnkgPSBudWxsO1xuXG4gIC8qKiBMb2FkaW5nIHN0YXRlICovXG4gIEBJbnB1dCgpIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBJbml0aWFsIGZvcm0gZGF0YSBmb3IgZWRpdCBtb2RlICovXG4gIEBJbnB1dCgpIGluaXRpYWxEYXRhPzogQXBpRm9ybURhdGE7XG5cbiAgLyoqIEVtaXQgd2hlbiBzdGVwIGlzIGNyZWF0ZWQgKi9cbiAgQE91dHB1dCgpIGNyZWF0ZVN0ZXAgPSBuZXcgRXZlbnRFbWl0dGVyPEFwaUZvcm1EYXRhPigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gY2FuY2VsbGVkICovXG4gIEBPdXRwdXQoKSBjYW5jZWxsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqIEVtaXQgd2hlbiByZXF1ZXN0IGlzIHNlbnQgKi9cbiAgQE91dHB1dCgpIHNlbmRSZXF1ZXN0ID0gbmV3IEV2ZW50RW1pdHRlcjx7IG1ldGhvZDogSHR0cE1ldGhvZDsgdXJsOiBzdHJpbmc7IGhlYWRlcnM6IEhlYWRlclJvd1tdOyBib2R5Pzogc3RyaW5nOyBwYXJhbXM/OiBIZWFkZXJSb3dbXSB9PigpO1xuXG4gIC8qKiBFbWl0IHdoZW4gY1VSTCBpcyBpbXBvcnRlZCAqL1xuICBAT3V0cHV0KCkgaW1wb3J0Q3VybCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBhcGlGb3JtOiBGb3JtR3JvdXA7XG4gIHNlbGVjdGVkVGFiOiBSZXF1ZXN0VGFiID0gJ2hlYWRlcnMnO1xuICBzZWxlY3RlZFByb2dyZXNzU3RlcDogUHJvZ3Jlc3NTdGVwID0gJ3JlcXVlc3QtZGV0YWlscyc7XG4gIGZvcm1TdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLy8gcHJvZ3Jlc3NTdGVwczogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gIFxuICAvLyBDYWNoZSBjb25maWcgb2JqZWN0cyB0byBwcmV2ZW50IGluZmluaXRlIGNoYW5nZSBkZXRlY3Rpb24gbG9vcHNcbiAgcHJpdmF0ZSB2ZXJpZmljYXRpb25UeXBlQ29uZmlnQ2FjaGU6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGV4cGVjdGVkVHlwZUNvbmZpZ0NhY2hlOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBodHRwTWV0aG9kQ29uZmlnQ2FjaGU6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGhlYWRlck5hbWVDb25maWdDYWNoZTogRHluYW1pY1NlbGVjdEZpZWxkQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGFyYW1OYW1lQ29uZmlnQ2FjaGU6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGhhc0xvYWRlZEluaXRpYWxEYXRhOiBib29sZWFuID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIpIHtcbiAgICAvLyBHZXQgZmlyc3QgSFRUUCBtZXRob2Qgb3B0aW9uIChkZWZhdWx0IHRvICdHRVQnIGlmIG9wdGlvbnMgbm90IGF2YWlsYWJsZSB5ZXQpXG4gICAgY29uc3QgZmlyc3RNZXRob2QgPSB0aGlzLmh0dHBNZXRob2RPcHRpb25zLmxlbmd0aCA+IDAgXG4gICAgICA/IHRoaXMuaHR0cE1ldGhvZE9wdGlvbnNbMF0udmFsdWUgXG4gICAgICA6ICdHRVQnO1xuICAgIFxuICAgIHRoaXMuYXBpRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgbWV0aG9kOiBbZmlyc3RNZXRob2QsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdXJsOiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCB0aGlzLnVybFZhbGlkYXRvcigpXV0sXG4gICAgICBoZWFkZXJzOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIGJvZHk6IFsnJ10sXG4gICAgICBwYXJhbXM6IHRoaXMuZmIuYXJyYXkoW10pLFxuICAgICAgc2NyaXB0czogWycnXSxcbiAgICAgIHZhcmlhYmxlTmFtZTogWycnXSxcbiAgICAgIHZhbGlkYXRpb246IHRoaXMuZmIuYXJyYXkoW10pXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVybFZhbGlkYXRvcigpIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEZvcm1Db250cm9sKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgdXJsID0gY29udHJvbC52YWx1ZTtcbiAgICAgIGlmICghdXJsKSB7XG4gICAgICAgIHJldHVybiBudWxsOyAvLyBMZXQgcmVxdWlyZWQgdmFsaWRhdG9yIGhhbmRsZSBlbXB0eSBjYXNlXG4gICAgICB9XG5cbiAgICAgIC8vIFBhdHRlcm4gZm9yIHBsYWluIFVSTHMgb25seSAobm8gcGFyYW1ldGVycylcbiAgICAgIGNvbnN0IHVybFBhdHRlcm4gPSAvXihodHRwcz86XFwvXFwvKT8oW1xcdy1dKyhcXC5bXFx3LV0rKSspKFtcXHcuLEA/Xj0lJjovfisjLV0qW1xcd0A/Xj0lJi9+KyMtXSk/JC87XG4gICAgICBcbiAgICAgIC8vIFBhdHRlcm4gdG8gZGV0ZWN0IGFueSBwYXJhbWV0ZXIgcGF0dGVybnM6ICp8cGFyYW18LCAkfHBhcmFtfCwgQHxwYXJhbXwsIG9yICR7cGFyYW19XG4gICAgICBjb25zdCBwYXJhbWV0ZXJQYXR0ZXJuID0gLyhcXCpcXHxbXFx3LV0rXFx8KFxcKik/fFxcJFxcfFtcXHctXStcXHwoXFwqKT98QFxcfFtcXHctXStcXHwoXFwqKT98XFwkXFx7W159XStcXH0pLztcbiAgICAgIFxuICAgICAgLy8gUGF0dGVybiBmb3IgcGFyYW1ldGVyLW9ubHkgdmFsdWVzOiAqfHBhcmFtfCwgJHxwYXJhbXwsIEB8cGFyYW18LCBvciAke3BhcmFtfVxuICAgICAgY29uc3QgZW52UGF0dGVybiA9IC9eXFwqXFx8W1xcdy1dK1xcfChcXCopPyR8XlxcJFxcfFtcXHctXStcXHwoXFwqKT8kfF5AXFx8W1xcdy1dK1xcfChcXCopPyR8XlxcJFxce1tefV0rXFx9JC87XG4gICAgICBcbiAgICAgIC8vIFBhdHRlcm4gdG8gYWxsb3cgVVJMcyB3aXRoIGVtYmVkZGVkIHBhcmFtZXRlcnM6ICp8cGFyYW18LCAkfHBhcmFtfCwgQHxwYXJhbXwsIG9yICR7cGFyYW19XG4gICAgICBjb25zdCBmbGV4aWJsZVVybFBhdHRlcm4gPSAvXltAXT8oaHR0cHM/OlxcL1xcLyk/KFtcXHctXSsoXFwuW1xcdy1dKykrKShbXFx3LixAP149JSY6L34rIy1dKihcXCpcXHxbXFx3LV0rXFx8KFxcKik/fFxcJFxcfFtcXHctXStcXHwoXFwqKT98QFxcfFtcXHctXStcXHwoXFwqKT98XFwkXFx7W159XStcXH0pW1xcdy4sQD9ePSUmOi9+KyMtXSopKiQvO1xuICAgICAgXG4gICAgICAvLyBQYXR0ZXJuIHRoYXQgYWxsb3dzIHBhcmFtZXRlcnMgYW55d2hlcmUgYWZ0ZXIgaHR0cDovLyBvciBodHRwczovL1xuICAgICAgY29uc3QgcHJvdG9jb2xXaXRoUGFyYW1zUGF0dGVybiA9IC9eaHR0cHM/OlxcL1xcLyhcXCpcXHxbXFx3LV0rXFx8KFxcKik/fFxcJFxcfFtcXHctXStcXHwoXFwqKT98QFxcfFtcXHctXStcXHwoXFwqKT98XFwkXFx7W159XStcXH0pW15cXHNdKiR8Xmh0dHBzPzpcXC9cXC9bXlxcc10qKFxcKlxcfFtcXHctXStcXHwoXFwqKT98XFwkXFx8W1xcdy1dK1xcfChcXCopP3xAXFx8W1xcdy1dK1xcfChcXCopP3xcXCRcXHtbXn1dK1xcfSlbXlxcc10qJC87XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIFVSTCBjb250YWlucyBwYXJhbWV0ZXJzXG4gICAgICBpZiAocGFyYW1ldGVyUGF0dGVybi50ZXN0KHVybCkpIHtcbiAgICAgICAgLy8gSWYgaXQgY29udGFpbnMgcGFyYW1ldGVycywgY2hlY2sgaWYgaXQgbWF0Y2hlcyBhbGxvd2VkIHBhdHRlcm5zXG4gICAgICAgIGNvbnN0IGVudkNvbWJpbmVkID0gbmV3IFJlZ0V4cChgJHt1cmxQYXR0ZXJuLnNvdXJjZX18JHtmbGV4aWJsZVVybFBhdHRlcm4uc291cmNlfXwke2VudlBhdHRlcm4uc291cmNlfXwke3Byb3RvY29sV2l0aFBhcmFtc1BhdHRlcm4uc291cmNlfWApO1xuICAgICAgICBpZiAoIWVudkNvbWJpbmVkLnRlc3QodXJsKSkge1xuICAgICAgICAgIHJldHVybiB7IGhhc1BhcmFtZXRlcjogdHJ1ZSB9O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBubyBwYXJhbWV0ZXJzLCBjaGVjayBpZiBpdCdzIGEgdmFsaWQgcGxhaW4gVVJMXG4gICAgICAgIGlmICghdXJsUGF0dGVybi50ZXN0KHVybCkpIHtcbiAgICAgICAgICByZXR1cm4geyBwYXR0ZXJuOiB0cnVlIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIFxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIFN5bmMgY3VycmVudFN0ZXAgaW5wdXQgd2l0aCBzZWxlY3RlZFByb2dyZXNzU3RlcFxuICAgIGlmICh0aGlzLmN1cnJlbnRTdGVwKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkUHJvZ3Jlc3NTdGVwID0gdGhpcy5jdXJyZW50U3RlcDtcbiAgICB9XG4gICAgXG4gICAgLy8gU2V0IG1ldGhvZCB0byBmaXJzdCBvcHRpb24gaWYgbm90IGFscmVhZHkgc2V0XG4gICAgaWYgKCF0aGlzLmFwaUZvcm0uZ2V0KCdtZXRob2QnKT8udmFsdWUgJiYgdGhpcy5odHRwTWV0aG9kT3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmFwaUZvcm0uZ2V0KCdtZXRob2QnKT8uc2V0VmFsdWUodGhpcy5odHRwTWV0aG9kT3B0aW9uc1swXS52YWx1ZSk7XG4gICAgfVxuICAgIFxuICAgIC8vIExvYWQgaW5pdGlhbCBkYXRhIGlmIHByb3ZpZGVkIChlZGl0IG1vZGUpXG4gICAgaWYgKHRoaXMuaW5pdGlhbERhdGEpIHtcbiAgICAgIHRoaXMubG9hZEluaXRpYWxEYXRhKHRoaXMuaW5pdGlhbERhdGEpO1xuICAgICAgdGhpcy5oYXNMb2FkZWRJbml0aWFsRGF0YSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFkZCBpbml0aWFsIGhlYWRlciByb3cgZm9yIG5ldyBzdGVwXG4gICAgICB0aGlzLmFkZEhlYWRlcigpO1xuICAgIH1cbiAgICBcbiAgICAvLyBJbml0aWFsaXplIHZhbGlkYXRpb24gZm9ybSBhcnJheSBpZiBzdGFydGluZyBvbiB2YWxpZGF0aW9uIHN0ZXBcbiAgICBpZiAodGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3ZhbGlkYXRpb24nICYmIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuYWRkVmFsaWRhdGlvblJ1bGUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvYWRJbml0aWFsRGF0YShkYXRhOiBBcGlGb3JtRGF0YSk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdsb2FkSW5pdGlhbERhdGE6IExvYWRpbmcgZGF0YScsIGRhdGEpO1xuICAgIGNvbnNvbGUubG9nKCdsb2FkSW5pdGlhbERhdGE6IEhlYWRlcnMgY291bnQnLCBkYXRhLmhlYWRlcnM/Lmxlbmd0aCB8fCAwKTtcbiAgICBjb25zb2xlLmxvZygnbG9hZEluaXRpYWxEYXRhOiBIZWFkZXJzIGRhdGEnLCBkYXRhLmhlYWRlcnMpO1xuICAgIFxuICAgIC8vIFNldCBiYXNpYyBmaWVsZHNcbiAgICB0aGlzLmFwaUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICBtZXRob2Q6IGRhdGEubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgdXJsOiBkYXRhLnVybCB8fCAnJyxcbiAgICAgIGJvZHk6IGRhdGEuYm9keSB8fCAnJyxcbiAgICAgIHNjcmlwdHM6IGRhdGEuc2NyaXB0cyB8fCAnJyxcbiAgICAgIHZhcmlhYmxlTmFtZTogZGF0YS52YXJpYWJsZU5hbWUgfHwgJydcbiAgICB9KTtcblxuICAgIC8vIExvYWQgaGVhZGVyc1xuICAgIC8vIENsZWFyIGV4aXN0aW5nIGhlYWRlcnMgZmlyc3RcbiAgICB3aGlsZSAodGhpcy5oZWFkZXJzRm9ybUFycmF5Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhpcy5oZWFkZXJzRm9ybUFycmF5LnJlbW92ZUF0KDApO1xuICAgIH1cbiAgICBcbiAgICBpZiAoZGF0YS5oZWFkZXJzICYmIGRhdGEuaGVhZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBBZGQgaGVhZGVycyBmcm9tIGluaXRpYWwgZGF0YSAoaW5jbHVkZSBhbGwgaGVhZGVycywgZXZlbiBpZiBlbXB0eSlcbiAgICAgIGRhdGEuaGVhZGVycy5mb3JFYWNoKGhlYWRlciA9PiB7XG4gICAgICAgIGNvbnN0IGhlYWRlckdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgbmFtZTogW2hlYWRlci5uYW1lIHx8ICcnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgICB2YWx1ZTogW2hlYWRlci52YWx1ZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGVhZGVyc0Zvcm1BcnJheS5wdXNoKGhlYWRlckdyb3VwKTtcbiAgICAgIH0pO1xuICAgICAgY29uc29sZS5sb2coJ2xvYWRJbml0aWFsRGF0YTogTG9hZGVkIGhlYWRlcnMgaW50byBmb3JtIGFycmF5LCBjb3VudDonLCB0aGlzLmhlYWRlcnNGb3JtQXJyYXkubGVuZ3RoKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRW5zdXJlIGF0IGxlYXN0IG9uZSBoZWFkZXIgcm93IGV4aXN0c1xuICAgIGlmICh0aGlzLmhlYWRlcnNGb3JtQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLmxvZygnbG9hZEluaXRpYWxEYXRhOiBObyBoZWFkZXJzIGZvdW5kLCBhZGRpbmcgZW1wdHkgaGVhZGVyIHJvdycpO1xuICAgICAgdGhpcy5hZGRIZWFkZXIoKTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIHBhcmFtc1xuICAgIC8vIENsZWFyIGV4aXN0aW5nIHBhcmFtcyBmaXJzdFxuICAgIHdoaWxlICh0aGlzLnBhcmFtc0Zvcm1BcnJheS5sZW5ndGggIT09IDApIHtcbiAgICAgIHRoaXMucGFyYW1zRm9ybUFycmF5LnJlbW92ZUF0KDApO1xuICAgIH1cbiAgICBcbiAgICBpZiAoZGF0YS5wYXJhbXMgJiYgZGF0YS5wYXJhbXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gQWRkIHBhcmFtcyBmcm9tIGluaXRpYWwgZGF0YSAoaW5jbHVkZSBhbGwgcGFyYW1zLCBldmVuIGlmIGVtcHR5KVxuICAgICAgZGF0YS5wYXJhbXMuZm9yRWFjaChwYXJhbSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICBuYW1lOiBbcGFyYW0ubmFtZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgdmFsdWU6IFtwYXJhbS52YWx1ZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFyYW1zRm9ybUFycmF5LnB1c2gocGFyYW1Hcm91cCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIHZhbGlkYXRpb24gcnVsZXNcbiAgICBpZiAoZGF0YS52YWxpZGF0aW9uICYmIGRhdGEudmFsaWRhdGlvbi5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBDbGVhciBleGlzdGluZyB2YWxpZGF0aW9uIHJ1bGVzXG4gICAgICB3aGlsZSAodGhpcy52YWxpZGF0aW9uRm9ybUFycmF5Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkucmVtb3ZlQXQoMCk7XG4gICAgICB9XG4gICAgICAvLyBBZGQgdmFsaWRhdGlvbiBydWxlcyBmcm9tIGluaXRpYWwgZGF0YVxuICAgICAgZGF0YS52YWxpZGF0aW9uLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRpb25Hcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgIGpzb25QYXRoOiBbcnVsZS5qc29uUGF0aCB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgdmVyaWZpY2F0aW9uVHlwZTogW3J1bGUudmVyaWZpY2F0aW9uVHlwZSB8fCAnZXF1YWxzJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgZXhwZWN0ZWRUeXBlOiBbcnVsZS5leHBlY3RlZFR5cGUgfHwgJ3N0cmluZycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICAgIGV4cGVjdGVkVmFsdWU6IFtydWxlLmV4cGVjdGVkVmFsdWUgIT09IHVuZGVmaW5lZCA/IHJ1bGUuZXhwZWN0ZWRWYWx1ZSA6ICcnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgICAgICByZXN1bHQ6IFtydWxlLnJlc3VsdCB8fCAnTm90IHJ1biddLFxuICAgICAgICAgIGNoZWNrZWQ6IFtydWxlLmNoZWNrZWQgfHwgZmFsc2VdXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBFbnN1cmUgYWxsIGNvbnRyb2xzIGFyZSBlbmFibGVkXG4gICAgICAgIHZhbGlkYXRpb25Hcm91cC5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkucHVzaCh2YWxpZGF0aW9uR3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGhlYWRlcnNGb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5hcGlGb3JtLmdldCgnaGVhZGVycycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGdldCBwYXJhbXNGb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5hcGlGb3JtLmdldCgncGFyYW1zJykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgZ2V0IHZhbGlkYXRpb25Gb3JtQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5hcGlGb3JtLmdldCgndmFsaWRhdGlvbicpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGFkZEhlYWRlcigpOiB2b2lkIHtcbiAgICAvLyBHZXQgZmlyc3QgaGVhZGVyIG5hbWUgb3B0aW9uXG4gICAgY29uc3QgaGVhZGVyT3B0aW9ucyA9IHRoaXMuaGVhZGVyTmFtZU9wdGlvbnMubGVuZ3RoID4gMCBcbiAgICAgID8gdGhpcy5oZWFkZXJOYW1lT3B0aW9ucyBcbiAgICAgIDogW1xuICAgICAgICAgIHsgaWQ6ICdzdHJpbmcnLCB2YWx1ZTogJ3N0cmluZycsIG5hbWU6ICdzdHJpbmcnLCBsYWJlbDogJ3N0cmluZycgfSxcbiAgICAgICAgICB7IGlkOiAnQ29udGVudC1UeXBlJywgdmFsdWU6ICdDb250ZW50LVR5cGUnLCBuYW1lOiAnQ29udGVudC1UeXBlJywgbGFiZWw6ICdDb250ZW50LVR5cGUnIH0sXG4gICAgICAgICAgeyBpZDogJ0F1dGhvcml6YXRpb24nLCB2YWx1ZTogJ0F1dGhvcml6YXRpb24nLCBuYW1lOiAnQXV0aG9yaXphdGlvbicsIGxhYmVsOiAnQXV0aG9yaXphdGlvbicgfSxcbiAgICAgICAgICB7IGlkOiAnQWNjZXB0JywgdmFsdWU6ICdBY2NlcHQnLCBuYW1lOiAnQWNjZXB0JywgbGFiZWw6ICdBY2NlcHQnIH1cbiAgICAgICAgXTtcbiAgICBcbiAgICBjb25zdCBmaXJzdEhlYWRlck5hbWUgPSBoZWFkZXJPcHRpb25zLmxlbmd0aCA+IDAgPyBoZWFkZXJPcHRpb25zWzBdLnZhbHVlIDogJyc7XG4gICAgXG4gICAgY29uc3QgaGVhZGVyR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIG5hbWU6IFtmaXJzdEhlYWRlck5hbWUsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmFsdWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF1cbiAgICB9KTtcbiAgICB0aGlzLmhlYWRlcnNGb3JtQXJyYXkucHVzaChoZWFkZXJHcm91cCk7XG4gIH1cblxuICByZW1vdmVIZWFkZXIoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuaGVhZGVyc0Zvcm1BcnJheS5yZW1vdmVBdChpbmRleCk7XG4gIH1cblxuICBhZGRQYXJhbSgpOiB2b2lkIHtcbiAgICBjb25zdCBwYXJhbUdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBuYW1lOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmFsdWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF1cbiAgICB9KTtcbiAgICB0aGlzLnBhcmFtc0Zvcm1BcnJheS5wdXNoKHBhcmFtR3JvdXApO1xuICB9XG5cbiAgcmVtb3ZlUGFyYW0oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucGFyYW1zRm9ybUFycmF5LnJlbW92ZUF0KGluZGV4KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBSZXNldCBjb25maWcgY2FjaGVzIHdoZW4gaW5wdXRzIGNoYW5nZVxuICAgIGlmIChjaGFuZ2VzWydodHRwTWV0aG9kT3B0aW9ucyddKSB7XG4gICAgICB0aGlzLmh0dHBNZXRob2RDb25maWdDYWNoZSA9IG51bGw7XG4gICAgICAvLyBTZXQgbWV0aG9kIHRvIGZpcnN0IG9wdGlvbiBpZiBub3QgYWxyZWFkeSBzZXQgb3IgaWYgd2UncmUgbm90IGluIGVkaXQgbW9kZVxuICAgICAgaWYgKCF0aGlzLmhhc0xvYWRlZEluaXRpYWxEYXRhICYmIHRoaXMuaHR0cE1ldGhvZE9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBtZXRob2RDb250cm9sID0gdGhpcy5hcGlGb3JtLmdldCgnbWV0aG9kJyk7XG4gICAgICAgIGlmIChtZXRob2RDb250cm9sICYmICFtZXRob2RDb250cm9sLnZhbHVlKSB7XG4gICAgICAgICAgbWV0aG9kQ29udHJvbC5zZXRWYWx1ZSh0aGlzLmh0dHBNZXRob2RPcHRpb25zWzBdLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snaGVhZGVyTmFtZU9wdGlvbnMnXSkge1xuICAgICAgdGhpcy5oZWFkZXJOYW1lQ29uZmlnQ2FjaGUgPSBudWxsO1xuICAgICAgLy8gVXBkYXRlIGhlYWRlciBuYW1lcyB0byBmaXJzdCBvcHRpb24gZm9yIGVtcHR5IGhlYWRlcnMgKG9ubHkgaWYgbm90IGluIGVkaXQgbW9kZSlcbiAgICAgIGlmICghdGhpcy5oYXNMb2FkZWRJbml0aWFsRGF0YSAmJiB0aGlzLmhlYWRlck5hbWVPcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5oZWFkZXJzRm9ybUFycmF5LmNvbnRyb2xzLmZvckVhY2goKGhlYWRlckdyb3VwOiBhbnkpID0+IHtcbiAgICAgICAgICBjb25zdCBuYW1lQ29udHJvbCA9IGhlYWRlckdyb3VwLmdldCgnbmFtZScpO1xuICAgICAgICAgIGlmIChuYW1lQ29udHJvbCAmJiAhbmFtZUNvbnRyb2wudmFsdWUpIHtcbiAgICAgICAgICAgIG5hbWVDb250cm9sLnNldFZhbHVlKHRoaXMuaGVhZGVyTmFtZU9wdGlvbnNbMF0udmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIExvYWQgaW5pdGlhbCBkYXRhIGlmIGl0J3Mgc2V0IGFmdGVyIGNvbXBvbmVudCBpbml0aWFsaXphdGlvblxuICAgIGlmIChjaGFuZ2VzWydpbml0aWFsRGF0YSddICYmICFjaGFuZ2VzWydpbml0aWFsRGF0YSddLmZpcnN0Q2hhbmdlICYmIHRoaXMuaW5pdGlhbERhdGEgJiYgIXRoaXMuaGFzTG9hZGVkSW5pdGlhbERhdGEpIHtcbiAgICAgIHRoaXMubG9hZEluaXRpYWxEYXRhKHRoaXMuaW5pdGlhbERhdGEpO1xuICAgICAgdGhpcy5oYXNMb2FkZWRJbml0aWFsRGF0YSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgZ2V0SHR0cE1ldGhvZENvbmZpZygpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIGlmICghdGhpcy5odHRwTWV0aG9kQ29uZmlnQ2FjaGUpIHtcbiAgICAgIHRoaXMuaHR0cE1ldGhvZENvbmZpZ0NhY2hlID0ge1xuICAgICAgICBrZXk6ICdtZXRob2QnLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBtZXRob2QnLFxuICAgICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLmh0dHBNZXRob2RPcHRpb25zXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwTWV0aG9kQ29uZmlnQ2FjaGU7XG4gIH1cblxuICBnZXRIZWFkZXJOYW1lQ29uZmlnKGluZGV4OiBudW1iZXIpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIGlmICghdGhpcy5oZWFkZXJOYW1lQ29uZmlnQ2FjaGUpIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zID0gW1xuICAgICAgICB7IGlkOiAnc3RyaW5nJywgdmFsdWU6ICdzdHJpbmcnLCBuYW1lOiAnc3RyaW5nJywgbGFiZWw6ICdzdHJpbmcnIH0sXG4gICAgICAgIHsgaWQ6ICdDb250ZW50LVR5cGUnLCB2YWx1ZTogJ0NvbnRlbnQtVHlwZScsIG5hbWU6ICdDb250ZW50LVR5cGUnLCBsYWJlbDogJ0NvbnRlbnQtVHlwZScgfSxcbiAgICAgICAgeyBpZDogJ0F1dGhvcml6YXRpb24nLCB2YWx1ZTogJ0F1dGhvcml6YXRpb24nLCBuYW1lOiAnQXV0aG9yaXphdGlvbicsIGxhYmVsOiAnQXV0aG9yaXphdGlvbicgfSxcbiAgICAgICAgeyBpZDogJ0FjY2VwdCcsIHZhbHVlOiAnQWNjZXB0JywgbmFtZTogJ0FjY2VwdCcsIGxhYmVsOiAnQWNjZXB0JyB9XG4gICAgICBdO1xuICAgICAgXG4gICAgICB0aGlzLmhlYWRlck5hbWVDb25maWdDYWNoZSA9IHtcbiAgICAgICAga2V5OiAnbmFtZScsXG4gICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IGhlYWRlcicsXG4gICAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgICAgc2VhcmNoYWJsZTogdHJ1ZSxcbiAgICAgICAgb3B0aW9uczogdGhpcy5oZWFkZXJOYW1lT3B0aW9ucy5sZW5ndGggPiAwID8gdGhpcy5oZWFkZXJOYW1lT3B0aW9ucyA6IGRlZmF1bHRPcHRpb25zXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5oZWFkZXJOYW1lQ29uZmlnQ2FjaGU7XG4gIH1cblxuICBnZXRQYXJhbU5hbWVDb25maWcoaW5kZXg6IG51bWJlcik6IER5bmFtaWNTZWxlY3RGaWVsZENvbmZpZyB7XG4gICAgaWYgKCF0aGlzLnBhcmFtTmFtZUNvbmZpZ0NhY2hlKSB7XG4gICAgICB0aGlzLnBhcmFtTmFtZUNvbmZpZ0NhY2hlID0ge1xuICAgICAgICBrZXk6ICduYW1lJyxcbiAgICAgICAgcGxhY2Vob2xkZXI6ICdQYXJhbWV0ZXIgbmFtZScsXG4gICAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IFtdXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wYXJhbU5hbWVDb25maWdDYWNoZTtcbiAgfVxuXG4gIGdldEhlYWRlckZvcm1Hcm91cChpbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5oZWFkZXJzRm9ybUFycmF5LmF0KGluZGV4KSBhcyBGb3JtR3JvdXA7XG4gIH1cblxuICBnZXRQYXJhbUZvcm1Hcm91cChpbmRleDogbnVtYmVyKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5wYXJhbXNGb3JtQXJyYXkuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgfVxuXG4gIG9uVGFiQ2hhbmdlKHRhYjogUmVxdWVzdFRhYik6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSB0YWI7XG4gIH1cblxuICBvblNlbmRSZXF1ZXN0KCk6IHZvaWQge1xuICAgIHRoaXMuZm9ybVN1Ym1pdHRlZCA9IHRydWU7XG4gICAgdGhpcy5tYXJrRm9ybUdyb3VwVG91Y2hlZCh0aGlzLmFwaUZvcm0pO1xuICAgIGNvbnNvbGUubG9nKCdvblNlbmRSZXF1ZXN0OiBhcGlGb3JtJywgdGhpcy5hcGlGb3JtLnZhbHVlKTtcbiAgICBjb25zb2xlLmxvZygnb25TZW5kUmVxdWVzdDogYXBpRm9ybSB2YWxpZCcsIHRoaXMuYXBpRm9ybSk7XG4gICAgaWYgKHRoaXMuYXBpRm9ybS52YWxpZCkge1xuICAgICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy5hcGlGb3JtLnZhbHVlO1xuICAgICAgY29uc3QgaGVhZGVycyA9IGZvcm1WYWx1ZS5oZWFkZXJzLm1hcCgoaDogYW55KSA9PiAoe1xuICAgICAgICBuYW1lOiBoLm5hbWUsXG4gICAgICAgIHZhbHVlOiBoLnZhbHVlXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBmb3JtVmFsdWUucGFyYW1zID8gZm9ybVZhbHVlLnBhcmFtcy5tYXAoKHA6IGFueSkgPT4gKHtcbiAgICAgICAgbmFtZTogcC5uYW1lLFxuICAgICAgICB2YWx1ZTogcC52YWx1ZVxuICAgICAgfSkpIDogW107XG5cbiAgICAgIHRoaXMuc2VuZFJlcXVlc3QuZW1pdCh7XG4gICAgICAgIG1ldGhvZDogZm9ybVZhbHVlLm1ldGhvZCxcbiAgICAgICAgdXJsOiBmb3JtVmFsdWUudXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5OiBmb3JtVmFsdWUuYm9keSxcbiAgICAgICAgcGFyYW1zXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvbkltcG9ydEN1cmwoKTogdm9pZCB7XG4gICAgdGhpcy5pbXBvcnRDdXJsLmVtaXQoKTtcbiAgfVxuXG4gIG9uQ2FuY2VsKCk6IHZvaWQge1xuICAgIHRoaXMuY2FuY2VsbGVkLmVtaXQoKTtcbiAgfVxuXG4gIG9uQ3JlYXRlU3RlcCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1TdWJtaXR0ZWQgPSB0cnVlO1xuICAgIHRoaXMubWFya0Zvcm1Hcm91cFRvdWNoZWQodGhpcy5hcGlGb3JtKTtcbiAgICBcbiAgICBpZiAodGhpcy5hcGlGb3JtLnZhbGlkKSB7XG4gICAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmFwaUZvcm0udmFsdWU7XG4gICAgICBjb25zdCBzdGVwRGF0YTogQXBpRm9ybURhdGEgPSB7XG4gICAgICAgIG1ldGhvZDogZm9ybVZhbHVlLm1ldGhvZCxcbiAgICAgICAgdXJsOiBmb3JtVmFsdWUudXJsLFxuICAgICAgICBoZWFkZXJzOiBmb3JtVmFsdWUuaGVhZGVycy5tYXAoKGg6IGFueSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBoLm5hbWUsXG4gICAgICAgICAgdmFsdWU6IGgudmFsdWVcbiAgICAgICAgfSkpLFxuICAgICAgICBib2R5OiBmb3JtVmFsdWUuYm9keSxcbiAgICAgICAgcGFyYW1zOiBmb3JtVmFsdWUucGFyYW1zID8gZm9ybVZhbHVlLnBhcmFtcy5tYXAoKHA6IGFueSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBwLm5hbWUsXG4gICAgICAgICAgdmFsdWU6IHAudmFsdWVcbiAgICAgICAgfSkpIDogW10sXG4gICAgICAgIHNjcmlwdHM6IGZvcm1WYWx1ZS5zY3JpcHRzLFxuICAgICAgICB2YXJpYWJsZU5hbWU6IGZvcm1WYWx1ZS52YXJpYWJsZU5hbWUgfHwgJycsXG4gICAgICAgIHZhbGlkYXRpb246IGZvcm1WYWx1ZS52YWxpZGF0aW9uID8gZm9ybVZhbHVlLnZhbGlkYXRpb24ubWFwKCh2OiBhbnkpID0+ICh7XG4gICAgICAgICAganNvblBhdGg6IHYuanNvblBhdGgsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uVHlwZTogdi52ZXJpZmljYXRpb25UeXBlLFxuICAgICAgICAgIGV4cGVjdGVkVHlwZTogdi5leHBlY3RlZFR5cGUsXG4gICAgICAgICAgZXhwZWN0ZWRWYWx1ZTogdi5leHBlY3RlZFZhbHVlLFxuICAgICAgICAgIHJlc3VsdDogdi5yZXN1bHQgfHwgJ05vdCBydW4nXG4gICAgICAgIH0pKSA6IFtdXG4gICAgICB9O1xuICAgICAgY29uc29sZS5sb2coJzk5OTk5OTknLCBzdGVwRGF0YSk7XG4gICAgICB0aGlzLmNyZWF0ZVN0ZXAuZW1pdChzdGVwRGF0YSk7XG4gICAgfVxuICB9XG5cbiAgb25OZXh0KCk6IHZvaWQge1xuICAgIC8vIE1vdmUgdG8gbmV4dCBzdGVwIG9yIGNyZWF0ZSBzdGVwIGlmIG9uIGxhc3Qgc3RlcFxuICAgIGNvbnN0IHN0ZXBPcmRlcjogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2YodGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCk7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA8IHN0ZXBPcmRlci5sZW5ndGggLSAxKSB7XG4gICAgICB0aGlzLm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKHN0ZXBPcmRlcltjdXJyZW50SW5kZXggKyAxXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub25DcmVhdGVTdGVwKCk7XG4gICAgfVxuICB9XG5cbiAgb25CYWNrKCk6IHZvaWQge1xuICAgIC8vIE1vdmUgdG8gcHJldmlvdXMgc3RlcFxuICAgIGNvbnN0IHN0ZXBPcmRlcjogUHJvZ3Jlc3NTdGVwW10gPSBbJ3JlcXVlc3QtZGV0YWlscycsICdzdG9yZS1yZXNwb25zZScsICd2YWxpZGF0aW9uJ107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcE9yZGVyLmluZGV4T2YodGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCk7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA+IDApIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzc1N0ZXBDaGFuZ2Uoc3RlcE9yZGVyW2N1cnJlbnRJbmRleCAtIDFdKTtcbiAgICB9XG4gIH1cblxuICBjYW5Hb0JhY2soKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3RlcE9yZGVyOiBQcm9ncmVzc1N0ZXBbXSA9IFsncmVxdWVzdC1kZXRhaWxzJywgJ3N0b3JlLXJlc3BvbnNlJywgJ3ZhbGlkYXRpb24nXTtcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBzdGVwT3JkZXIuaW5kZXhPZih0aGlzLnNlbGVjdGVkUHJvZ3Jlc3NTdGVwKTtcbiAgICByZXR1cm4gY3VycmVudEluZGV4ID4gMDtcbiAgfVxuXG4gIGlzTGFzdFN0ZXAoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3RlcE9yZGVyOiBQcm9ncmVzc1N0ZXBbXSA9IFsncmVxdWVzdC1kZXRhaWxzJywgJ3N0b3JlLXJlc3BvbnNlJywgJ3ZhbGlkYXRpb24nXTtcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBzdGVwT3JkZXIuaW5kZXhPZih0aGlzLnNlbGVjdGVkUHJvZ3Jlc3NTdGVwKTtcbiAgICByZXR1cm4gY3VycmVudEluZGV4ID09PSBzdGVwT3JkZXIubGVuZ3RoIC0gMTtcbiAgfVxuXG4gIGdldFByb2dyZXNzU3RlcENsYXNzKHN0ZXA6IFByb2dyZXNzU3RlcCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RlcE9yZGVyOiBQcm9ncmVzc1N0ZXBbXSA9IFsncmVxdWVzdC1kZXRhaWxzJywgJ3N0b3JlLXJlc3BvbnNlJywgJ3ZhbGlkYXRpb24nXTtcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBzdGVwT3JkZXIuaW5kZXhPZih0aGlzLmN1cnJlbnRTdGVwKTtcbiAgICBjb25zdCBzdGVwSW5kZXggPSBzdGVwT3JkZXIuaW5kZXhPZihzdGVwKTtcblxuICAgIGlmIChzdGVwSW5kZXggPCBjdXJyZW50SW5kZXgpIHtcbiAgICAgIHJldHVybiAnY3FhLXRleHQtZ3JheS00MDAnOyAvLyBDb21wbGV0ZWRcbiAgICB9IGVsc2UgaWYgKHN0ZXBJbmRleCA9PT0gY3VycmVudEluZGV4KSB7XG4gICAgICByZXR1cm4gJ2NxYS10ZXh0LXB1cnBsZS02MDAgY3FhLWZvbnQtc2VtaWJvbGQnOyAvLyBBY3RpdmVcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICdjcWEtdGV4dC1ncmF5LTQwMCc7IC8vIFBlbmRpbmdcbiAgICB9XG4gIH1cblxuICBnZXRQcm9ncmVzc1N0ZXBOdW1iZXIoc3RlcDogUHJvZ3Jlc3NTdGVwKTogbnVtYmVyIHtcbiAgICBjb25zdCBzdGVwT3JkZXI6IFByb2dyZXNzU3RlcFtdID0gWydyZXF1ZXN0LWRldGFpbHMnLCAnc3RvcmUtcmVzcG9uc2UnLCAndmFsaWRhdGlvbiddO1xuICAgIHJldHVybiBzdGVwT3JkZXIuaW5kZXhPZihzdGVwKSArIDE7XG4gIH1cblxuICBnZXRQcm9ncmVzc1N0ZXBMYWJlbChzdGVwOiBQcm9ncmVzc1N0ZXApOiBzdHJpbmcge1xuICAgIGNvbnN0IGxhYmVsczogUmVjb3JkPFByb2dyZXNzU3RlcCwgc3RyaW5nPiA9IHtcbiAgICAgICdyZXF1ZXN0LWRldGFpbHMnOiAnUmVxdWVzdCBEZXRhaWxzJyxcbiAgICAgICdzdG9yZS1yZXNwb25zZSc6ICdTdG9yZSBSZXNwb25zZScsXG4gICAgICAndmFsaWRhdGlvbic6ICdWYWxpZGF0aW9uJ1xuICAgIH07XG4gICAgcmV0dXJuIGxhYmVsc1tzdGVwXTtcbiAgfVxuXG4gIGZvcm1hdEpzb25SZXNwb25zZShkYXRhOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0YSkgcmV0dXJuICcnO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMik7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gU3RyaW5nKGRhdGEpO1xuICAgIH1cbiAgfVxuICBcbiAgb25Qcm9ncmVzc1N0ZXBDaGFuZ2Uoc3RlcDogUHJvZ3Jlc3NTdGVwKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFByb2dyZXNzU3RlcCA9IHN0ZXA7XG4gICAgLy8gSW5pdGlhbGl6ZSB2YWxpZGF0aW9uIGZvcm0gYXJyYXkgaWYgc3dpdGNoaW5nIHRvIHZhbGlkYXRpb24gc3RlcFxuICAgIGlmIChzdGVwID09PSAndmFsaWRhdGlvbicgJiYgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5hZGRWYWxpZGF0aW9uUnVsZSgpO1xuICAgIH1cbiAgfVxuXG4gIGFkZFZhbGlkYXRpb25SdWxlKCk6IHZvaWQge1xuICAgIGNvbnN0IHZhbGlkYXRpb25Hcm91cCA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgY2hlY2tlZDogW2ZhbHNlXSxcbiAgICAgIGpzb25QYXRoOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmVyaWZpY2F0aW9uVHlwZTogWydlcXVhbHMnXSxcbiAgICAgIGV4cGVjdGVkVHlwZTogWydzdHJpbmcnXSxcbiAgICAgIGV4cGVjdGVkVmFsdWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICByZXN1bHQ6IFsnTm90IHJ1biddXG4gICAgfSk7XG4gICAgLy8gRW5zdXJlIGFsbCBjb250cm9scyBhcmUgZW5hYmxlZCB0byBhdm9pZCBkaXNhYmxlZCBhdHRyaWJ1dGUgd2FybmluZ3NcbiAgICB2YWxpZGF0aW9uR3JvdXAuZW5hYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkucHVzaCh2YWxpZGF0aW9uR3JvdXApO1xuICB9XG5cbiAgcmVtb3ZlVmFsaWRhdGlvblJ1bGUoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5yZW1vdmVBdChpbmRleCk7XG4gIH1cblxuICBnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGluZGV4OiBudW1iZXIpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkuYXQoaW5kZXgpIGFzIEZvcm1Hcm91cDtcbiAgfVxuXG4gIHRyYWNrQnlWYWxpZGF0aW9uUnVsZUluZGV4KGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIHRyYWNrQnlIZWFkZXJJbmRleChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICB0cmFja0J5UGFyYW1JbmRleChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBnZXRWZXJpZmljYXRpb25UeXBlT3B0aW9ucygpOiBTZWxlY3RPcHRpb25bXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsgaWQ6ICdlcXVhbHMnLCB2YWx1ZTogJ2VxdWFscycsIG5hbWU6ICdFcXVhbHMnLCBsYWJlbDogJ0VxdWFscycgfSxcbiAgICAgIHsgaWQ6ICdub3RfZXF1YWxzJywgdmFsdWU6ICdub3RfZXF1YWxzJywgbmFtZTogJ05vdCBFcXVhbHMnLCBsYWJlbDogJ05vdCBFcXVhbHMnIH0sXG4gICAgICB7IGlkOiAnY29udGFpbnMnLCB2YWx1ZTogJ2NvbnRhaW5zJywgbmFtZTogJ0NvbnRhaW5zJywgbGFiZWw6ICdDb250YWlucycgfSxcbiAgICAgIHsgaWQ6ICdub3RfY29udGFpbnMnLCB2YWx1ZTogJ25vdF9jb250YWlucycsIG5hbWU6ICdOb3QgQ29udGFpbnMnLCBsYWJlbDogJ05vdCBDb250YWlucycgfSxcbiAgICAgIHsgaWQ6ICdncmVhdGVyX3RoYW4nLCB2YWx1ZTogJ2dyZWF0ZXJfdGhhbicsIG5hbWU6ICdHcmVhdGVyIFRoYW4nLCBsYWJlbDogJ0dyZWF0ZXIgVGhhbicgfSxcbiAgICAgIHsgaWQ6ICdsZXNzX3RoYW4nLCB2YWx1ZTogJ2xlc3NfdGhhbicsIG5hbWU6ICdMZXNzIFRoYW4nLCBsYWJlbDogJ0xlc3MgVGhhbicgfSxcbiAgICAgIHsgaWQ6ICdncmVhdGVyX3RoYW5fb3JfZXF1YWxzJywgdmFsdWU6ICdncmVhdGVyX3RoYW5fb3JfZXF1YWxzJywgbmFtZTogJ0dyZWF0ZXIgVGhhbiBPciBFcXVhbHMnLCBsYWJlbDogJ0dyZWF0ZXIgVGhhbiBPciBFcXVhbHMnIH0sXG4gICAgICB7IGlkOiAnbGVzc190aGFuX29yX2VxdWFscycsIHZhbHVlOiAnbGVzc190aGFuX29yX2VxdWFscycsIG5hbWU6ICdMZXNzIFRoYW4gT3IgRXF1YWxzJywgbGFiZWw6ICdMZXNzIFRoYW4gT3IgRXF1YWxzJyB9LFxuICAgICAgeyBpZDogJ2V4aXN0cycsIHZhbHVlOiAnZXhpc3RzJywgbmFtZTogJ0V4aXN0cycsIGxhYmVsOiAnRXhpc3RzJyB9LFxuICAgICAgeyBpZDogJ25vdF9leGlzdHMnLCB2YWx1ZTogJ25vdF9leGlzdHMnLCBuYW1lOiAnTm90IEV4aXN0cycsIGxhYmVsOiAnTm90IEV4aXN0cycgfVxuICAgIF07XG4gIH1cblxuICBnZXRFeHBlY3RlZFR5cGVPcHRpb25zKCk6IFNlbGVjdE9wdGlvbltdIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyBpZDogJ3N0cmluZycsIHZhbHVlOiAnc3RyaW5nJywgbmFtZTogJ1N0cmluZycsIGxhYmVsOiAnU3RyaW5nJyB9LFxuICAgICAgeyBpZDogJ251bWJlcicsIHZhbHVlOiAnbnVtYmVyJywgbmFtZTogJ051bWJlcicsIGxhYmVsOiAnTnVtYmVyJyB9LFxuICAgICAgeyBpZDogJ2Jvb2xlYW4nLCB2YWx1ZTogJ2Jvb2xlYW4nLCBuYW1lOiAnQm9vbGVhbicsIGxhYmVsOiAnQm9vbGVhbicgfSxcbiAgICAgIHsgaWQ6ICdvYmplY3QnLCB2YWx1ZTogJ29iamVjdCcsIG5hbWU6ICdPYmplY3QnLCBsYWJlbDogJ09iamVjdCcgfSxcbiAgICAgIHsgaWQ6ICdhcnJheScsIHZhbHVlOiAnYXJyYXknLCBuYW1lOiAnQXJyYXknLCBsYWJlbDogJ0FycmF5JyB9LFxuICAgICAgeyBpZDogJ251bGwnLCB2YWx1ZTogJ251bGwnLCBuYW1lOiAnTnVsbCcsIGxhYmVsOiAnTnVsbCcgfVxuICAgIF07XG4gIH1cblxuICBnZXRWZXJpZmljYXRpb25UeXBlQ29uZmlnKGluZGV4OiBudW1iZXIpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIC8vIENhY2hlIHRoZSBjb25maWcgdG8gcHJldmVudCBpbmZpbml0ZSBjaGFuZ2UgZGV0ZWN0aW9uIGxvb3BzXG4gICAgaWYgKCF0aGlzLnZlcmlmaWNhdGlvblR5cGVDb25maWdDYWNoZSkge1xuICAgICAgdGhpcy52ZXJpZmljYXRpb25UeXBlQ29uZmlnQ2FjaGUgPSB7XG4gICAgICAgIGtleTogJ3ZlcmlmaWNhdGlvblR5cGUnLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCB2ZXJpZmljYXRpb24gdHlwZScsXG4gICAgICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMuZ2V0VmVyaWZpY2F0aW9uVHlwZU9wdGlvbnMoKVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmVyaWZpY2F0aW9uVHlwZUNvbmZpZ0NhY2hlO1xuICB9XG5cbiAgZ2V0RXhwZWN0ZWRUeXBlQ29uZmlnKGluZGV4OiBudW1iZXIpOiBEeW5hbWljU2VsZWN0RmllbGRDb25maWcge1xuICAgIC8vIENhY2hlIHRoZSBjb25maWcgdG8gcHJldmVudCBpbmZpbml0ZSBjaGFuZ2UgZGV0ZWN0aW9uIGxvb3BzXG4gICAgaWYgKCF0aGlzLmV4cGVjdGVkVHlwZUNvbmZpZ0NhY2hlKSB7XG4gICAgICB0aGlzLmV4cGVjdGVkVHlwZUNvbmZpZ0NhY2hlID0ge1xuICAgICAgICBrZXk6ICdleHBlY3RlZFR5cGUnLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBleHBlY3RlZCB0eXBlJyxcbiAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgICAgb3B0aW9uczogdGhpcy5nZXRFeHBlY3RlZFR5cGVPcHRpb25zKClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmV4cGVjdGVkVHlwZUNvbmZpZ0NhY2hlO1xuICB9XG5cbiAgZ2V0UmVzdWx0Q2xhc3MocmVzdWx0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChyZXN1bHQgPT09ICdQYXNzJykge1xuICAgICAgcmV0dXJuICdjcWEtYmctZ3JlZW4tNTAwIGNxYS10ZXh0LXdoaXRlJztcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gJ0ZhaWwnKSB7XG4gICAgICByZXR1cm4gJ2NxYS1iZy1yZWQtNTAwIGNxYS10ZXh0LXdoaXRlJztcbiAgICB9XG4gICAgcmV0dXJuICdjcWEtYmctZ3JheS0zMDAgY3FhLXRleHQtZ3JheS03MDAnO1xuICB9XG5cbiAgZ2V0IGFsbFZhbGlkYXRpb25SdWxlc1NlbGVjdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkubGVuZ3RoID4gMCAmJiBcbiAgICAgICAgICAgdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LmNvbnRyb2xzLmV2ZXJ5KGNvbnRyb2wgPT4gY29udHJvbC5nZXQoJ2NoZWNrZWQnKT8udmFsdWUpO1xuICB9XG5cbiAgZ2V0IHNvbWVWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0aW9uRm9ybUFycmF5LmNvbnRyb2xzLnNvbWUoY29udHJvbCA9PiBjb250cm9sLmdldCgnY2hlY2tlZCcpPy52YWx1ZSkgJiYgXG4gICAgICAgICAgICF0aGlzLmFsbFZhbGlkYXRpb25SdWxlc1NlbGVjdGVkO1xuICB9XG5cbiAgb25TZWxlY3RBbGxWYWxpZGF0aW9uUnVsZXMoY2hlY2tlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGlvbkZvcm1BcnJheS5jb250cm9scy5mb3JFYWNoKGNvbnRyb2wgPT4ge1xuICAgICAgY29udHJvbC5nZXQoJ2NoZWNrZWQnKT8uc2V0VmFsdWUoY2hlY2tlZCk7XG4gICAgfSk7XG4gIH1cblxuICBvbkRlbGV0ZVNlbGVjdGVkVmFsaWRhdGlvblJ1bGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IGluZGljZXNUb1JlbW92ZTogbnVtYmVyW10gPSBbXTtcbiAgICB0aGlzLnZhbGlkYXRpb25Gb3JtQXJyYXkuY29udHJvbHMuZm9yRWFjaCgoY29udHJvbCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChjb250cm9sLmdldCgnY2hlY2tlZCcpPy52YWx1ZSkge1xuICAgICAgICBpbmRpY2VzVG9SZW1vdmUucHVzaChpbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gUmVtb3ZlIGluIHJldmVyc2Ugb3JkZXIgdG8gbWFpbnRhaW4gY29ycmVjdCBpbmRpY2VzXG4gICAgaW5kaWNlc1RvUmVtb3ZlLnJldmVyc2UoKS5mb3JFYWNoKGluZGV4ID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlVmFsaWRhdGlvblJ1bGUoaW5kZXgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXJrRm9ybUdyb3VwVG91Y2hlZChmb3JtR3JvdXA6IEZvcm1Hcm91cCk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKGZvcm1Hcm91cC5jb250cm9scykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5nZXQoa2V5KTtcbiAgICAgIGlmIChjb250cm9sKSB7XG4gICAgICAgIGNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgIHRoaXMubWFya0Zvcm1Hcm91cFRvdWNoZWQoY29udHJvbCk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1BcnJheSkge1xuICAgICAgICAgIGNvbnRyb2wuY29udHJvbHMuZm9yRWFjaCgoY3RybDogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoY3RybCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgICAgICB0aGlzLm1hcmtGb3JtR3JvdXBUb3VjaGVkKGN0cmwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3RybC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG9uVXJsQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB1cmxDb250cm9sID0gdGhpcy5hcGlGb3JtLmdldCgndXJsJyk7XG4gICAgaWYgKHVybENvbnRyb2wpIHtcbiAgICAgIHVybENvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xuICAgICAgdXJsQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgfVxuICB9XG5cbiAgb25VcmxCbHVyKCk6IHZvaWQge1xuICAgIGNvbnN0IHVybENvbnRyb2wgPSB0aGlzLmFwaUZvcm0uZ2V0KCd1cmwnKTtcbiAgICBpZiAodXJsQ29udHJvbCkge1xuICAgICAgdXJsQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0VXJsRXJyb3JzKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB1cmxDb250cm9sID0gdGhpcy5hcGlGb3JtLmdldCgndXJsJyk7XG4gICAgaWYgKCF1cmxDb250cm9sIHx8ICghdGhpcy5mb3JtU3VibWl0dGVkICYmICF1cmxDb250cm9sLnRvdWNoZWQpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgIFxuICAgIGlmICh1cmxDb250cm9sLmVycm9ycz8uWydyZXF1aXJlZCddKSB7XG4gICAgICBlcnJvcnMucHVzaCgnVVJMIGlzIHJlcXVpcmVkJyk7XG4gICAgfSBlbHNlIGlmICh1cmxDb250cm9sLmVycm9ycz8uWydwYXR0ZXJuJ10pIHtcbiAgICAgIGVycm9ycy5wdXNoKCdVUkwgaXMgbm90IHZhbGlkJyk7XG4gICAgfSBlbHNlIGlmICh1cmxDb250cm9sLmVycm9ycz8uWydoYXNQYXJhbWV0ZXInXSkge1xuICAgICAgZXJyb3JzLnB1c2goJ1VSTCBmb3JtYXQgaXMgaW52YWxpZC4gUGxlYXNlIGNoZWNrIHRoZSBwYXJhbWV0ZXIgZm9ybWF0LicpO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG59XG5cbiIsIjxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWgtZnVsbCBjcWEtYmctd2hpdGUgY3FhLXB4LTQgY3FhLXB5LTJcIj5cbiAgPCEtLSBIZWFkZXIgLS0+XG4gIDxoMiBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ibGFjay0xMDAgY3FhLW1iLTRcIj5cbiAgICBDcmVhdGUgQVBJIFRlc3QgU3RlcFxuICA8L2gyPlxuXG4gIDwhLS0gUHJvZ3Jlc3MgVHJhY2tlciAtLT5cbiAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC00IGNxYS1tYi02IGNxYS1wYi00IGNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwXCI+XG4gICAgPCEtLSA8ZGl2ICpuZ0Zvcj1cImxldCBzdGVwIG9mIHByb2dyZXNzU3RlcHNcIlxuICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiXG4gICAgICAgICBbbmdDbGFzc109XCJnZXRQcm9ncmVzc1N0ZXBDbGFzcyhzdGVwKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW1cIj57eyBnZXRQcm9ncmVzc1N0ZXBOdW1iZXIoc3RlcCkgfX0ge3sgZ2V0UHJvZ3Jlc3NTdGVwTGFiZWwoc3RlcCkgfX08L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cInN0ZXAgIT09ICd2YWxpZGF0aW9uJ1wiIGNsYXNzPVwiY3FhLXRleHQtZ3JheS0zMDBcIj7igKI8L3NwYW4+XG4gICAgPC9kaXY+IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS13LWZ1bGwgY3FhLWp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yXCIgW25nQ2xhc3NdPVwieydjcWEtdGV4dC1wdXJwbGUtNjAwIGNxYS1mb250LXNlbWlib2xkJzogc2VsZWN0ZWRQcm9ncmVzc1N0ZXAgPT09ICdyZXF1ZXN0LWRldGFpbHMnfVwiIChjbGljayk9XCJvblByb2dyZXNzU3RlcENoYW5nZSgncmVxdWVzdC1kZXRhaWxzJylcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXctOCBjcWEtaC04IGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1yb3VuZGVkLWZ1bGwgY3FhLWJnLXB1cnBsZS02MDAgY3FhLXRleHQtd2hpdGUgY3FhLXRleHQteHMgY3FhLWZvbnQtc2VtaWJvbGRcIj4xPC9kaXY+XG4gICAgICAgICAgPGRpdj5SZXF1ZXN0IERldGFpbHM8L2Rpdj5cbiAgICAgICAgICA8ZGl2PjwvZGl2PlxuICAgICAgICAgPC9kaXY+XG4gICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIiBbbmdDbGFzc109XCJ7J2NxYS10ZXh0LXB1cnBsZS02MDAgY3FhLWZvbnQtc2VtaWJvbGQnOiBzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3N0b3JlLXJlc3BvbnNlJ31cIiAoY2xpY2spPVwib25Qcm9ncmVzc1N0ZXBDaGFuZ2UoJ3N0b3JlLXJlc3BvbnNlJylcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXctOCBjcWEtaC04IGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1yb3VuZGVkLWZ1bGwgY3FhLWJnLXB1cnBsZS02MDAgY3FhLXRleHQtd2hpdGUgY3FhLXRleHQteHMgY3FhLWZvbnQtc2VtaWJvbGRcIj4yPC9kaXY+XG4gICAgICAgICAgPGRpdj5TdG9yZSBSZXNwb25zZTwvZGl2PlxuICAgICAgICAgIDxkaXY+PC9kaXY+XG4gICAgICAgICA8L2Rpdj5cbiAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiIFtuZ0NsYXNzXT1cInsnY3FhLXRleHQtcHVycGxlLTYwMCBjcWEtZm9udC1zZW1pYm9sZCc6IHNlbGVjdGVkUHJvZ3Jlc3NTdGVwID09PSAndmFsaWRhdGlvbid9XCIgKGNsaWNrKT1cIm9uUHJvZ3Jlc3NTdGVwQ2hhbmdlKCd2YWxpZGF0aW9uJylcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXctOCBjcWEtaC04IGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1yb3VuZGVkLWZ1bGwgY3FhLWJnLXB1cnBsZS02MDAgY3FhLXRleHQtd2hpdGUgY3FhLXRleHQteHMgY3FhLWZvbnQtc2VtaWJvbGRcIj4zPC9kaXY+XG4gICAgICAgICAgPGRpdj5WYWxpZGF0aW9uPC9kaXY+XG4gICAgICAgICAgPGRpdj48L2Rpdj5cbiAgICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkUHJvZ3Jlc3NTdGVwID09PSAncmVxdWVzdC1kZXRhaWxzJ1wiPlxuICA8IS0tIEFQSSBSZXF1ZXN0IENvbmZpZ3VyYXRpb24gLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtc3RhcnQgY3FhLWdhcC0yIGNxYS1tYi0zXCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS13LTMyIGNxYS1mbGV4LXNocmluay0wXCI+XG4gICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0XG4gICAgICAgIFtmb3JtXT1cImFwaUZvcm1cIlxuICAgICAgICBbY29uZmlnXT1cImdldEh0dHBNZXRob2RDb25maWcoKVwiPlxuICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTFcIj5cbiAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgQVBJIGVuZHBvaW50IFVSTCdcIlxuICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3VybCcpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgIFtlcnJvcnNdPVwiZ2V0VXJsRXJyb3JzKClcIlxuICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25VcmxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgIChibHVycmVkKT1cIm9uVXJsQmx1cigpXCI+XG4gICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGNxYS1idXR0b25cbiAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lZFwiXG4gICAgICB0ZXh0PVwiSW1wb3J0IEFQSSBjVVJMXCJcbiAgICAgIChjbGlja2VkKT1cIm9uSW1wb3J0Q3VybCgpXCI+XG4gICAgPC9jcWEtYnV0dG9uPlxuICAgIDxjcWEtYnV0dG9uXG4gICAgICB2YXJpYW50PVwiZmlsbGVkXCJcbiAgICAgIHRleHQ9XCJTZW5kIFJlcXVlc3RcIlxuICAgICAgKGNsaWNrZWQpPVwib25TZW5kUmVxdWVzdCgpXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhYXBpRm9ybS5nZXQoJ3VybCcpPy52YWx1ZSB8fCBpc0xvYWRpbmdcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gUmVxdWVzdCBEZXRhaWxzIFRhYnMgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWZsZXgtMSBjcWEtb3ZlcmZsb3ctaGlkZGVuIGNxYS1tYi02XCI+XG4gICAgPCEtLSBUYWIgTmF2aWdhdGlvbiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtYmctZ3JheS01MFwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAnaGVhZGVycydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ2hlYWRlcnMnXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnaGVhZGVycydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci10cmFuc3BhcmVudF09XCJzZWxlY3RlZFRhYiAhPT0gJ2hlYWRlcnMnXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCdoZWFkZXJzJylcIj5cbiAgICAgICAgSGVhZGVyc1xuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1weC00IGNxYS1weS0yIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtdHJhbnNpdGlvbi1jb2xvcnMgY3FhLWJvcmRlci1iLTJcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtYmx1ZS02MDBdPVwic2VsZWN0ZWRUYWIgPT09ICdib2R5J1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAnYm9keSdcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtZ3JheS02MDBdPVwic2VsZWN0ZWRUYWIgIT09ICdib2R5J1wiXG4gICAgICAgIFtjbGFzcy5jcWEtYm9yZGVyLXRyYW5zcGFyZW50XT1cInNlbGVjdGVkVGFiICE9PSAnYm9keSdcIlxuICAgICAgICAoY2xpY2spPVwib25UYWJDaGFuZ2UoJ2JvZHknKVwiPlxuICAgICAgICBCb2R5XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiY3FhLXB4LTQgY3FhLXB5LTIgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10cmFuc2l0aW9uLWNvbG9ycyBjcWEtYm9yZGVyLWItMlwiXG4gICAgICAgIFtjbGFzcy5jcWEtdGV4dC1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ3BhcmFtcydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ3BhcmFtcydcIlxuICAgICAgICBbY2xhc3MuY3FhLXRleHQtZ3JheS02MDBdPVwic2VsZWN0ZWRUYWIgIT09ICdwYXJhbXMnXCJcbiAgICAgICAgW2NsYXNzLmNxYS1ib3JkZXItdHJhbnNwYXJlbnRdPVwic2VsZWN0ZWRUYWIgIT09ICdwYXJhbXMnXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCdwYXJhbXMnKVwiPlxuICAgICAgICBQYXJhbXNcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtcHgtNCBjcWEtcHktMiBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1ib3JkZXItYi0yXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWJsdWUtNjAwXT1cInNlbGVjdGVkVGFiID09PSAnc2NyaXB0cydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci1ibHVlLTYwMF09XCJzZWxlY3RlZFRhYiA9PT0gJ3NjcmlwdHMnXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWdyYXktNjAwXT1cInNlbGVjdGVkVGFiICE9PSAnc2NyaXB0cydcIlxuICAgICAgICBbY2xhc3MuY3FhLWJvcmRlci10cmFuc3BhcmVudF09XCJzZWxlY3RlZFRhYiAhPT0gJ3NjcmlwdHMnXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uVGFiQ2hhbmdlKCdzY3JpcHRzJylcIj5cbiAgICAgICAgU2NyaXB0c1xuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFRhYiBDb250ZW50IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLXAtNCBjcWEtYm9yZGVyIGNxYS1ib3JkZXItZ3JheS0yMDAgY3FhLWJvcmRlci10LTAgY3FhLXJvdW5kZWQtYi1sZ1wiPlxuICAgICAgPCEtLSBIZWFkZXJzIFRhYiAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2hlYWRlcnMnXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC0zXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZ3JpZCBjcWEtZ3JpZC1jb2xzLTIgY3FhLWdhcC00IGNxYS1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtdXBwZXJjYXNlXCI+SGVhZGVyIE5hbWUqPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5IZWFkZXIgVmFsdWUqPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgaGVhZGVyc0Zvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUhlYWRlckluZGV4XCIgXG4gICAgICAgICAgICAgY2xhc3M9XCJjcWEtZ3JpZCBjcWEtZ3JpZC1jb2xzLTIgY3FhLWdhcC00IGNxYS1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdFxuICAgICAgICAgICAgICBbZm9ybV09XCJnZXRIZWFkZXJGb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cImdldEhlYWRlck5hbWVDb25maWcoaSlcIj5cbiAgICAgICAgICAgIDwvY3FhLWR5bmFtaWMtc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTFcIj5cbiAgICAgICAgICAgICAgPGNxYS1jdXN0b20taW5wdXRcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0hlYWRlciB2YWx1ZSdcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRIZWFkZXJGb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0SGVhZGVyRm9ybUdyb3VwKGkpLmdldCgndmFsdWUnKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2NxYS1jdXN0b20taW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXctOCBjcWEtaC04IGNxYS1yb3VuZGVkIGNxYS10ZXh0LXJlZC01MDAgaG92ZXI6Y3FhLXRleHQtcmVkLTcwMCBob3ZlcjpjcWEtYmctcmVkLTUwIGNxYS10cmFuc2l0aW9uLWNvbG9yc1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVIZWFkZXIoaSlcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidSZW1vdmUgaGVhZGVyJ1wiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1sZ1wiPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cImNxYS10ZXh0LWJsdWUtNjAwIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtc2VsZi1zdGFydCBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMSBob3ZlcjpjcWEtdGV4dC1ibHVlLTcwMCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgIChjbGljayk9XCJhZGRIZWFkZXIoKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS10ZXh0LWJhc2VcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgIDxzcGFuPkFkZCBIZWFkZXI8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQm9keSBUYWIgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdib2R5J1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8Y3FhLWN1c3RvbS10ZXh0YXJlYVxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgcmVxdWVzdCBib2R5IChKU09OLCBYTUwsIGV0Yy4pJ1wiXG4gICAgICAgICAgW3ZhbHVlXT1cImFwaUZvcm0uZ2V0KCdib2R5Jyk/LnZhbHVlIHx8ICcnXCJcbiAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgIFtyb3dzXT1cIjEwXCJcbiAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiYXBpRm9ybS5nZXQoJ2JvZHknKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICA8L2NxYS1jdXN0b20tdGV4dGFyZWE+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBQYXJhbXMgVGFiIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAncGFyYW1zJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWdyaWQgY3FhLWdyaWQtY29scy0yIGNxYS1nYXAtNCBjcWEtaXRlbXMtc3RhcnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQteHMgY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPlBhcmFtZXRlciBOYW1lPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5QYXJhbWV0ZXIgVmFsdWU8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHBhcmFtIG9mIHBhcmFtc0Zvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVBhcmFtSW5kZXhcIiBcbiAgICAgICAgICAgICBjbGFzcz1cImNxYS1ncmlkIGNxYS1ncmlkLWNvbHMtMiBjcWEtZ2FwLTQgY3FhLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1BhcmFtZXRlciBuYW1lJ1wiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRQYXJhbUZvcm1Hcm91cChpKS5nZXQoJ25hbWUnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCduYW1lJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xXCI+XG4gICAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidQYXJhbWV0ZXIgdmFsdWUnXCJcbiAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgICAgICAgICAgW2Z1bGxXaWR0aF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0UGFyYW1Gb3JtR3JvdXAoaSkuZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtdy04IGNxYS1oLTggY3FhLXJvdW5kZWQgY3FhLXRleHQtcmVkLTUwMCBob3ZlcjpjcWEtdGV4dC1yZWQtNzAwIGhvdmVyOmNxYS1iZy1yZWQtNTAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZVBhcmFtKGkpXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInUmVtb3ZlIHBhcmFtZXRlcidcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY3FhLXRleHQtbGdcIj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC1ibHVlLTYwMCBjcWEtdGV4dC1zbSBjcWEtZm9udC1tZWRpdW0gY3FhLXNlbGYtc3RhcnQgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgaG92ZXI6Y3FhLXRleHQtYmx1ZS03MDAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgICAoY2xpY2spPVwiYWRkUGFyYW0oKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNxYS10ZXh0LWJhc2VcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgIDxzcGFuPkFkZCBQYXJhbWV0ZXI8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU2NyaXB0cyBUYWIgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdzY3JpcHRzJ1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1nYXAtM1wiPlxuICAgICAgICA8Y3FhLWN1c3RvbS10ZXh0YXJlYVxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInRW50ZXIgc2NyaXB0cyAoSmF2YVNjcmlwdCwgZXRjLiknXCJcbiAgICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3NjcmlwdHMnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgW3Jvd3NdPVwiMTBcIlxuICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhcGlGb3JtLmdldCgnc2NyaXB0cycpPy5zZXRWYWx1ZSgkZXZlbnQpXCI+XG4gICAgICAgIDwvY3FhLWN1c3RvbS10ZXh0YXJlYT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuXG48L25nLWNvbnRhaW5lcj5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3N0b3JlLXJlc3BvbnNlJ1wiPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1mbGV4LTEgY3FhLW1heC1oLVs1MDBweF0gY3FhLW92ZXJmbG93LXktYXV0b1wiPlxuICAgIDwhLS0gU3RvcmUgUmVzcG9uc2UgVGl0bGUgLS0+XG4gICAgPGgzIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWJsYWNrLTEwMCBjcWEtbWItNFwiPlxuICAgICAgU3RvcmUgUmVzcG9uc2VcbiAgICA8L2gzPlxuXG4gICAgPCEtLSBWYXJpYWJsZSBOYW1lIElucHV0IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtbWItNlwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwiY3FhLXRleHQtWzEycHhdIGNxYS1mb250LW1lZGl1bSBjcWEtdGV4dC1ncmF5LTcwMCBjcWEtbWItMSBjcWEtYmxvY2tcIj5cbiAgICAgICAgVmFyaWFibGUgTmFtZVxuICAgICAgPC9sYWJlbD5cbiAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInVmFyaWFibGUgTmFtZSdcIlxuICAgICAgICBbdmFsdWVdPVwiYXBpRm9ybS5nZXQoJ3ZhcmlhYmxlTmFtZScpPy52YWx1ZSB8fCAnJ1wiXG4gICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICh2YWx1ZUNoYW5nZSk9XCJhcGlGb3JtLmdldCgndmFyaWFibGVOYW1lJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3ZhbGlkYXRpb24nXCI+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWZsZXgtMSBjcWEtbWF4LWgtWzUwMHB4XSBjcWEtb3ZlcmZsb3cteS1hdXRvXCI+XG4gICAgPCEtLSBWYWxpZGF0aW9uIFJ1bGVzIFRpdGxlIC0tPlxuICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LVsxMnB4XSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1ibGFjay0xMDAgY3FhLW1iLTRcIj5cbiAgICAgIFZhbGlkYXRpb24gUnVsZXNcbiAgICA8L2gzPlxuXG4gICAgPCEtLSBWYWxpZGF0aW9uIFJ1bGVzIFRhYmxlIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtYmctd2hpdGUgY3FhLWJvcmRlciBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1yb3VuZGVkLWxnIGNxYS1vdmVyZmxvdy1oaWRkZW4gY3FhLW1iLTRcIj5cbiAgICAgIDwhLS0gVGFibGUgSGVhZGVyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNxYS1ncmlkIGNxYS1ncmlkLWNvbHMtNiBjcWEtZ2FwLTIgY3FhLXAtMyBjcWEtYmctZ3JheS01MCBjcWEtYm9yZGVyLWIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgW2NoZWNrZWRdPVwiYWxsVmFsaWRhdGlvblJ1bGVzU2VsZWN0ZWRcIlxuICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic29tZVZhbGlkYXRpb25SdWxlc1NlbGVjdGVkXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwib25TZWxlY3RBbGxWYWxpZGF0aW9uUnVsZXMoJGV2ZW50LmNoZWNrZWQpXCI+XG4gICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5qc29uUGF0aDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj52ZXJpZmljYXRpb25UeXBlPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPmV4cGVjdGVkVHlwZTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktNzAwIGNxYS11cHBlcmNhc2VcIj5leHBlY3RlZFZhbHVlPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdGV4dC1bMTBweF0gY3FhLWZvbnQtc2VtaWJvbGQgY3FhLXRleHQtZ3JheS03MDAgY3FhLXVwcGVyY2FzZVwiPlJlc3VsdDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gVGFibGUgQm9keSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2xcIj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdmFsaWRhdGlvblJ1bGUgb2YgdmFsaWRhdGlvbkZvcm1BcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVZhbGlkYXRpb25SdWxlSW5kZXhcIiBcbiAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWdyaWQgY3FhLWdyaWQtY29scy02IGNxYS1nYXAtMiBjcWEtcC0zIGNxYS1ib3JkZXItYiBjcWEtYm9yZGVyLWdyYXktMjAwIGNxYS1pdGVtcy1jZW50ZXIgY3FhLWxhc3Q6Ym9yZGVyLWItMFwiPlxuICAgICAgICAgIDwhLS0gQ2hlY2tib3ggLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggZm9ybUNvbnRyb2xOYW1lPVwiY2hlY2tlZFwiPlxuICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGpzb25QYXRoIC0tPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ2pzb25QYXRoJ1wiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpLmdldCgnanNvblBhdGgnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2pzb25QYXRoJyk/LnNldFZhbHVlKCRldmVudClcIj5cbiAgICAgICAgICAgIDwvY3FhLWN1c3RvbS1pbnB1dD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gdmVyaWZpY2F0aW9uVHlwZSAtLT5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGNxYS1keW5hbWljLXNlbGVjdFxuICAgICAgICAgICAgICBbZm9ybV09XCJnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJnZXRWZXJpZmljYXRpb25UeXBlQ29uZmlnKGkpXCI+XG4gICAgICAgICAgICA8L2NxYS1keW5hbWljLXNlbGVjdD5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gZXhwZWN0ZWRUeXBlIC0tPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8Y3FhLWR5bmFtaWMtc2VsZWN0XG4gICAgICAgICAgICAgIFtmb3JtXT1cImdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSlcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cImdldEV4cGVjdGVkVHlwZUNvbmZpZyhpKVwiPlxuICAgICAgICAgICAgPC9jcWEtZHluYW1pYy1zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIGV4cGVjdGVkVmFsdWUgLS0+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxjcWEtY3VzdG9tLWlucHV0XG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInZXhwZWN0ZWRWYWx1ZSdcIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2V4cGVjdGVkVmFsdWUnKT8udmFsdWUgfHwgJydcIlxuICAgICAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiZ2V0VmFsaWRhdGlvbkZvcm1Hcm91cChpKS5nZXQoJ2V4cGVjdGVkVmFsdWUnKT8uc2V0VmFsdWUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9jcWEtY3VzdG9tLWlucHV0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBSZXN1bHQgYW5kIERlbGV0ZSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTJcIj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLXB4LTMgY3FhLXB5LTEgY3FhLXJvdW5kZWQgY3FhLXRleHQtWzEwcHhdIGNxYS1mb250LW1lZGl1bVwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFJlc3VsdENsYXNzKGdldFZhbGlkYXRpb25Gb3JtR3JvdXAoaSkuZ2V0KCdyZXN1bHQnKT8udmFsdWUgfHwgJ05vdCBydW4nKVwiPlxuICAgICAgICAgICAgICB7eyBnZXRWYWxpZGF0aW9uRm9ybUdyb3VwKGkpLmdldCgncmVzdWx0Jyk/LnZhbHVlIHx8ICdOb3QgcnVuJyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTYgY3FhLWgtNiBjcWEtcm91bmRlZCBjcWEtdGV4dC1yZWQtNTAwIGhvdmVyOmNxYS10ZXh0LXJlZC03MDAgaG92ZXI6Y3FhLWJnLXJlZC01MCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlVmFsaWRhdGlvblJ1bGUoaSlcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidEZWxldGUgdmFsaWRhdGlvbiBydWxlJ1wiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBBZGQgQW5vdGhlciBSdWxlIGFuZCBEZWxldGUgU2VsZWN0ZWQgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWl0ZW1zLWNlbnRlciBjcWEtbWItNFwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAqbmdJZj1cInNvbWVWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZCB8fCBhbGxWYWxpZGF0aW9uUnVsZXNTZWxlY3RlZFwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS10ZXh0LXJlZC02MDAgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xIGhvdmVyOmNxYS10ZXh0LXJlZC03MDAgY3FhLXRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlU2VsZWN0ZWRWYWxpZGF0aW9uUnVsZXMoKVwiPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+RGVsZXRlIFNlbGVjdGVkPC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS10ZXh0LWJsdWUtNjAwIGNxYS10ZXh0LXNtIGNxYS1mb250LW1lZGl1bSBjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMSBob3ZlcjpjcWEtdGV4dC1ibHVlLTcwMCBjcWEtdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAoY2xpY2spPVwiYWRkVmFsaWRhdGlvblJ1bGUoKVwiPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjcWEtdGV4dC1iYXNlXCI+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+QWRkIEFub3RoZXI8L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuXG4gIDwhLS0gUmVzcG9uc2UgUHJldmlldyBTZWN0aW9uIC0tPlxuICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1ncmF5LTIwMCBjcWEtcm91bmRlZC1sZyBjcWEtb3ZlcmZsb3ctaGlkZGVuIGNxYS1tYi02XCI+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1wLTMgY3FhLWJnLWdyYXktNTAgY3FhLWJvcmRlci1iIGNxYS1ib3JkZXItZ3JheS0yMDBcIj5cbiAgICAgIDxoMyBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LWdyYXktOTAwXCI+UmVzcG9uc2UgUHJldmlldzwvaDM+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1wLTQgY3FhLWJnLWdyYXktNTAgY3FhLW92ZXJmbG93LWF1dG9cIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDMwMHB4O1wiPlxuICAgICAgPHByZSAqbmdJZj1cInJlc3BvbnNlUHJldmlld1wiIGNsYXNzPVwiY3FhLXRleHQteHMgY3FhLWZvbnQtbW9ubyBjcWEtdGV4dC1ncmF5LTgwMCBjcWEtd2hpdGVzcGFjZS1wcmUtd3JhcFwiPnt7IGZvcm1hdEpzb25SZXNwb25zZShyZXNwb25zZVByZXZpZXcpIH19PC9wcmU+XG4gICAgICA8cCAqbmdJZj1cIiFyZXNwb25zZVByZXZpZXdcIiBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS10ZXh0LWdyYXktNDAwIGNxYS10ZXh0LWNlbnRlciBjcWEtcHktOFwiPlxuICAgICAgICBObyByZXNwb25zZSB5ZXQuIFNlbmQgYSByZXF1ZXN0IHRvIHNlZSB0aGUgcmVzcG9uc2UgcHJldmlldy5cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwhLS0gQWN0aW9uIEJ1dHRvbnMgLS0+XG4gIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtdy1mdWxsIGNxYS1nYXAtMiBjcWEtbXQtYXV0byBjcWEtcHQtNCBjcWEtYm9yZGVyLXQgY3FhLWJvcmRlci1ncmF5LTIwMFwiPlxuICAgIDwhLS0gQ2FuY2VsIGJ1dHRvbiAob25seSBvbiBmaXJzdCBzdGVwKSAtLT5cbiAgICA8Y3FhLWJ1dHRvblxuICAgICAgKm5nSWY9XCJzZWxlY3RlZFByb2dyZXNzU3RlcCA9PT0gJ3JlcXVlc3QtZGV0YWlscydcIlxuICAgICAgY2xhc3M9XCJjcWEtdy0xLzJcIlxuICAgICAgdmFyaWFudD1cIm91dGxpbmVkXCJcbiAgICAgIHRleHQ9XCJDYW5jZWxcIlxuICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtZmxleC0xIGNxYS13LWZ1bGwnXCJcbiAgICAgIChjbGlja2VkKT1cIm9uQ2FuY2VsKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPCEtLSBCYWNrIGJ1dHRvbiAob24gYWxsIHN0ZXBzIGV4Y2VwdCBmaXJzdCkgLS0+XG4gICAgPGNxYS1idXR0b25cbiAgICAgICpuZ0lmPVwic2VsZWN0ZWRQcm9ncmVzc1N0ZXAgIT09ICdyZXF1ZXN0LWRldGFpbHMnXCJcbiAgICAgIGNsYXNzPVwiY3FhLXctMS8yXCJcbiAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lZFwiXG4gICAgICB0ZXh0PVwiQmFja1wiXG4gICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2NxYS1mbGV4LTEgY3FhLXctZnVsbCdcIlxuICAgICAgKGNsaWNrZWQpPVwib25CYWNrKClcIj5cbiAgICA8L2NxYS1idXR0b24+XG4gICAgPCEtLSBOZXh0L0NyZWF0ZSBTdGVwIGJ1dHRvbiAtLT5cbiAgICA8Y3FhLWJ1dHRvblxuICAgICAgY2xhc3M9XCJjcWEtdy0xLzJcIlxuICAgICAgdmFyaWFudD1cImZpbGxlZFwiXG4gICAgICBbdGV4dF09XCJpc0xhc3RTdGVwKCkgPyAnQ3JlYXRlIFN0ZXAnIDogJ05leHQnXCJcbiAgICAgIFtjdXN0b21DbGFzc109XCInY3FhLWZsZXgtMSBjcWEtdy1mdWxsJ1wiXG4gICAgICAoY2xpY2tlZCk9XCJpc0xhc3RTdGVwKCkgPyBvbkNyZWF0ZVN0ZXAoKSA6IG9uTmV4dCgpXCI+XG4gICAgPC9jcWEtYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG4iXX0=