fx-form-builder-wrapper 2.0.99 → 2.0.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/customize-dropdown/customize-dropdown.component.mjs +398 -0
- package/esm2022/lib/components/dropdown-with-other/dropdown-with-other.component.mjs +6 -3
- package/esm2022/lib/components/fx-form-component/fx-form-component.component.mjs +3 -3
- package/esm2022/lib/components/radio-group/radio-group.component.mjs +6 -3
- package/esm2022/lib/components/summary/summary.component.mjs +12 -93
- package/esm2022/lib/components/uploader/uploader.component.mjs +2 -2
- package/esm2022/lib/fx-builder-wrapper.component.mjs +5 -5
- package/fesm2022/fx-form-builder-wrapper.mjs +412 -102
- package/fesm2022/fx-form-builder-wrapper.mjs.map +1 -1
- package/lib/components/customize-dropdown/customize-dropdown.component.d.ts +65 -0
- package/lib/components/dropdown-with-other/dropdown-with-other.component.d.ts +1 -0
- package/lib/components/radio-group/radio-group.component.d.ts +1 -0
- package/lib/components/summary/summary.component.d.ts +0 -1
- package/package.json +1 -1
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, ViewChild } from '@angular/core';
|
|
3
|
+
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
4
|
+
import { FxBaseComponent, FxComponent, FxSelectSetting, FxStringSetting, FxValidatorService } from '@instantsys-labs/fx';
|
|
5
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/common/http";
|
|
8
|
+
import * as i2 from "../../fx-builder-wrapper.service";
|
|
9
|
+
import * as i3 from "@instantsys-labs/core";
|
|
10
|
+
import * as i4 from "@angular/forms";
|
|
11
|
+
import * as i5 from "@angular/common";
|
|
12
|
+
export class CustomizeDropdownComponent extends FxBaseComponent {
|
|
13
|
+
cdr;
|
|
14
|
+
http;
|
|
15
|
+
fxBuilderWrapperService;
|
|
16
|
+
fxApiService;
|
|
17
|
+
fb;
|
|
18
|
+
eRef;
|
|
19
|
+
destroy$ = new Subject();
|
|
20
|
+
form;
|
|
21
|
+
formObject = {};
|
|
22
|
+
dropdownOpen = false;
|
|
23
|
+
formSubmitted = false;
|
|
24
|
+
fxComponent;
|
|
25
|
+
findingsOptions = [];
|
|
26
|
+
type1Options = [{
|
|
27
|
+
label: 'Proclination',
|
|
28
|
+
value: 'Proclination',
|
|
29
|
+
info: 'Forward inclination of teeth',
|
|
30
|
+
selected: false,
|
|
31
|
+
subOptions: [
|
|
32
|
+
{ label: 'Mild', value: 'mild' },
|
|
33
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
34
|
+
{ label: 'Severe', value: 'severe' }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
label: 'Crowding',
|
|
39
|
+
value: 'Crowding',
|
|
40
|
+
selected: false,
|
|
41
|
+
subOptions: [
|
|
42
|
+
{ label: 'Mild', value: 'mild' },
|
|
43
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
44
|
+
{ label: 'Severe', value: 'severe' }
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: 'Spacing',
|
|
49
|
+
value: 'Spacing',
|
|
50
|
+
selected: false,
|
|
51
|
+
subOptions: [
|
|
52
|
+
{ label: 'Mild', value: 'mild' },
|
|
53
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
54
|
+
{ label: 'Severe', value: 'severe' }
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: 'Retroclination',
|
|
59
|
+
value: 'Retroclination',
|
|
60
|
+
info: 'Backward inclination of teeth',
|
|
61
|
+
selected: false,
|
|
62
|
+
subOptions: [
|
|
63
|
+
{ label: 'Mild', value: 'mild' },
|
|
64
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
65
|
+
{ label: 'Severe', value: 'severe' }
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: 'Rotation',
|
|
70
|
+
value: 'Rotation',
|
|
71
|
+
selected: false,
|
|
72
|
+
subOptions: [
|
|
73
|
+
{ label: 'Mild', value: 'mild' },
|
|
74
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
75
|
+
{ label: 'Severe', value: 'severe' }
|
|
76
|
+
]
|
|
77
|
+
}];
|
|
78
|
+
type2Options = [
|
|
79
|
+
{
|
|
80
|
+
label: 'Normal',
|
|
81
|
+
value: 'Normal',
|
|
82
|
+
info: '',
|
|
83
|
+
selected: false,
|
|
84
|
+
subOptions: [
|
|
85
|
+
{ label: 'Mild', value: 'mild' },
|
|
86
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
87
|
+
{ label: 'Severe', value: 'severe' }
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
label: 'Deep Bite',
|
|
92
|
+
value: 'Deep Bite',
|
|
93
|
+
selected: false,
|
|
94
|
+
subOptions: [
|
|
95
|
+
{ label: 'Mild', value: 'mild' },
|
|
96
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
97
|
+
{ label: 'Severe', value: 'severe' }
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
label: 'Open Bite',
|
|
102
|
+
value: 'Open Bite',
|
|
103
|
+
selected: false,
|
|
104
|
+
subOptions: [
|
|
105
|
+
{ label: 'Mild', value: 'mild' },
|
|
106
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
107
|
+
{ label: 'Severe', value: 'severe' }
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
isRequired = false;
|
|
112
|
+
// @HostListener('document:click', ['$event'])
|
|
113
|
+
// onClickOutside(event: MouseEvent) {
|
|
114
|
+
// if (this.dropdownOpen && !this.eRef.nativeElement.contains(event.target)) {
|
|
115
|
+
// this.dropdownOpen = false;
|
|
116
|
+
// this.cdr.detectChanges();
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
config = {
|
|
120
|
+
displayMode: 'ellipsis',
|
|
121
|
+
placeholderLabel: 'Select Finding'
|
|
122
|
+
};
|
|
123
|
+
customizedDropDownMap = new Map();
|
|
124
|
+
constructor(cdr, http, fxBuilderWrapperService, fxApiService, fb, eRef) {
|
|
125
|
+
super(cdr);
|
|
126
|
+
this.cdr = cdr;
|
|
127
|
+
this.http = http;
|
|
128
|
+
this.fxBuilderWrapperService = fxBuilderWrapperService;
|
|
129
|
+
this.fxApiService = fxApiService;
|
|
130
|
+
this.fb = fb;
|
|
131
|
+
this.eRef = eRef;
|
|
132
|
+
this.form = this.fb.group({
|
|
133
|
+
findings: [[]]
|
|
134
|
+
});
|
|
135
|
+
this.onInit.subscribe(() => this._register(this.form));
|
|
136
|
+
}
|
|
137
|
+
ngAfterViewInit() {
|
|
138
|
+
// setTimeout(()=>{
|
|
139
|
+
// const data = [
|
|
140
|
+
// {
|
|
141
|
+
// label: "Proclination",
|
|
142
|
+
// value: "proclination",
|
|
143
|
+
// subSelection: {
|
|
144
|
+
// label: "Mild",
|
|
145
|
+
// value: "mild"
|
|
146
|
+
// }
|
|
147
|
+
// },
|
|
148
|
+
// {
|
|
149
|
+
// label: "Overbite",
|
|
150
|
+
// value: "overbite",
|
|
151
|
+
// subSelection: {
|
|
152
|
+
// label: "Moderate",
|
|
153
|
+
// value: "moderate"
|
|
154
|
+
// }
|
|
155
|
+
// }
|
|
156
|
+
// ];
|
|
157
|
+
// this.patchExistingValues(data);
|
|
158
|
+
// },2000);
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
const key = this.fxComponent?.fxData?.name;
|
|
161
|
+
if (key && this.customizedDropDownMap.has(key)) {
|
|
162
|
+
const data = this.customizedDropDownMap.get(key)?.findings;
|
|
163
|
+
this.patchExistingValues(data);
|
|
164
|
+
}
|
|
165
|
+
}, 1000);
|
|
166
|
+
setTimeout(() => {
|
|
167
|
+
const mainControl = this.form.get('findings');
|
|
168
|
+
if (this.setting('isFindingsRequired') === 'true') {
|
|
169
|
+
this.isRequired = true;
|
|
170
|
+
mainControl?.setValidators([Validators.required]);
|
|
171
|
+
mainControl?.updateValueAndValidity();
|
|
172
|
+
}
|
|
173
|
+
}, 500);
|
|
174
|
+
}
|
|
175
|
+
ngOnInit() {
|
|
176
|
+
if (this.setting('optionType') === 'type1') {
|
|
177
|
+
this.findingsOptions = this.type1Options;
|
|
178
|
+
}
|
|
179
|
+
else if (this.setting('optionType') === 'type2') {
|
|
180
|
+
this.findingsOptions = this.type2Options;
|
|
181
|
+
}
|
|
182
|
+
this.fxBuilderWrapperService.variables$
|
|
183
|
+
.pipe(takeUntil(this.destroy$))
|
|
184
|
+
.subscribe((variables) => {
|
|
185
|
+
if (!variables)
|
|
186
|
+
return;
|
|
187
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
188
|
+
if (value &&
|
|
189
|
+
typeof value === 'object' &&
|
|
190
|
+
'findings' in value) {
|
|
191
|
+
this.customizedDropDownMap.set(key, value);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
// const serviceUrl = this.fxApiService.getServiceUrl(this.setting('serviceName'));
|
|
196
|
+
// this.getOptions(serviceUrl, this.setting('clinicalNotesURL'));
|
|
197
|
+
}
|
|
198
|
+
getOptions(serviceUrl, url) {
|
|
199
|
+
const finalUrl = serviceUrl + url;
|
|
200
|
+
this.http.get(finalUrl).subscribe({
|
|
201
|
+
next: (response) => {
|
|
202
|
+
// Future API logic here
|
|
203
|
+
},
|
|
204
|
+
error: (err) => console.error('Error fetching options', err)
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
settings() {
|
|
208
|
+
return [
|
|
209
|
+
new FxSelectSetting({ key: 'displayMode', $title: 'Display Mode', value: 'ellipsis' }, [{ option: 'Ellipsis', value: 'ellipsis' }, { option: 'Compact', value: 'compact' }]),
|
|
210
|
+
new FxSelectSetting({ key: 'optionType', $title: 'Option Type', value: 'type1' }, [{ option: 'Finding Type Options', value: 'type1' }, { option: 'Vetical Type Options', value: 'type2' }]),
|
|
211
|
+
new FxStringSetting({ key: 'placeholderLabel', $title: 'Placeholder', value: 'Select Options' }),
|
|
212
|
+
new FxStringSetting({ key: 'findingLabel', $title: 'Label', value: 'Label' }),
|
|
213
|
+
new FxSelectSetting({ key: 'isFindingsRequired', $title: 'Required', value: 'true' }, [{ option: 'Yes', value: 'true' }, { option: 'No', value: 'false' }]),
|
|
214
|
+
new FxStringSetting({ key: 'errorFindingMessage', $title: 'Error Message', value: 'Please fill out the field' }),
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
validations() {
|
|
218
|
+
return [FxValidatorService.required];
|
|
219
|
+
}
|
|
220
|
+
/** Dropdown Behavior **/
|
|
221
|
+
toggleDropdown() {
|
|
222
|
+
this.dropdownOpen = !this.dropdownOpen;
|
|
223
|
+
}
|
|
224
|
+
toggleOption(option, event) {
|
|
225
|
+
event.stopPropagation();
|
|
226
|
+
// Toggle checkbox value
|
|
227
|
+
option.selected = !option.selected;
|
|
228
|
+
// Reset radios when unchecked
|
|
229
|
+
if (!option.selected) {
|
|
230
|
+
option.subSelection = null;
|
|
231
|
+
option.touched = false;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
option.touched = true;
|
|
235
|
+
}
|
|
236
|
+
// ✅ Force UI refresh so radios appear instantly
|
|
237
|
+
this.cdr.detectChanges();
|
|
238
|
+
// Update reactive form
|
|
239
|
+
this.updateFindings();
|
|
240
|
+
}
|
|
241
|
+
/** Form & Label Helpers **/
|
|
242
|
+
get hasSelectedFindings() {
|
|
243
|
+
return this.findingsOptions.some(f => f.selected);
|
|
244
|
+
}
|
|
245
|
+
get selectedFindingsLabel() {
|
|
246
|
+
const selected = this.findingsOptions
|
|
247
|
+
.filter(f => {
|
|
248
|
+
if (f.selected) {
|
|
249
|
+
// If finding has sub-options → only show if a sub-option is selected
|
|
250
|
+
if (f.subOptions?.length) {
|
|
251
|
+
return !!f.subSelection;
|
|
252
|
+
}
|
|
253
|
+
// If no sub-options → always show
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
})
|
|
258
|
+
.map(f => f.label);
|
|
259
|
+
if (selected.length === 0)
|
|
260
|
+
return this.setting('placeholderLabel');
|
|
261
|
+
// Display mode logic (Compact or Ellipsis)
|
|
262
|
+
const maxCount = this.setting('displayMode') === 'compact' ? 2 : 3;
|
|
263
|
+
if (this.setting('displayMode') === 'compact') {
|
|
264
|
+
return selected.length <= maxCount
|
|
265
|
+
? selected.join(', ')
|
|
266
|
+
: `${selected.slice(0, maxCount).join(', ')} +${selected.length - maxCount} more`;
|
|
267
|
+
}
|
|
268
|
+
if (this.setting('displayMode') === 'ellipsis') {
|
|
269
|
+
return selected.length > maxCount
|
|
270
|
+
? `${selected.slice(0, maxCount).join(', ')}, ...`
|
|
271
|
+
: selected.join(', ');
|
|
272
|
+
}
|
|
273
|
+
return selected.join(', ');
|
|
274
|
+
}
|
|
275
|
+
/** Update Findings + Validation **/
|
|
276
|
+
// updateFindings() {
|
|
277
|
+
// const selected = this.findingsOptions
|
|
278
|
+
// .filter(f => {
|
|
279
|
+
// if (f.selected) {
|
|
280
|
+
// // Only include in final form if:
|
|
281
|
+
// // - no subOptions, or
|
|
282
|
+
// // - subOptions with valid subSelection
|
|
283
|
+
// if (f.subOptions?.length) {
|
|
284
|
+
// return !!f.subSelection;
|
|
285
|
+
// }
|
|
286
|
+
// return true;
|
|
287
|
+
// }
|
|
288
|
+
// return false;
|
|
289
|
+
// })
|
|
290
|
+
// .map(f => {
|
|
291
|
+
// const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
292
|
+
// return {
|
|
293
|
+
// label: f.label,
|
|
294
|
+
// value: f.value,
|
|
295
|
+
// subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
296
|
+
// };
|
|
297
|
+
// });
|
|
298
|
+
// // Update reactive form value
|
|
299
|
+
// this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
300
|
+
// // Validation logic remains same
|
|
301
|
+
// const invalidItems = this.findingsOptions.filter(
|
|
302
|
+
// f => f.selected && f.subOptions && !f.subSelection
|
|
303
|
+
// );
|
|
304
|
+
// this.form.get('findings')?.setErrors(
|
|
305
|
+
// invalidItems.length > 0 ? { missingSubSelection: true } : null
|
|
306
|
+
// );
|
|
307
|
+
// }
|
|
308
|
+
updateFindings() {
|
|
309
|
+
// Filter selected options with valid subSelection (if subOptions exist)
|
|
310
|
+
const selected = this.findingsOptions
|
|
311
|
+
.filter(f => {
|
|
312
|
+
if (f.selected) {
|
|
313
|
+
// Only include in final form if:
|
|
314
|
+
// - no subOptions, or
|
|
315
|
+
// - subOptions with valid subSelection
|
|
316
|
+
if (f.subOptions?.length) {
|
|
317
|
+
return !!f.subSelection;
|
|
318
|
+
}
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
return false;
|
|
322
|
+
})
|
|
323
|
+
.map(f => {
|
|
324
|
+
const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
325
|
+
return {
|
|
326
|
+
label: f.label,
|
|
327
|
+
value: f.value,
|
|
328
|
+
subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
// Update reactive form value
|
|
332
|
+
this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
333
|
+
// Validation logic:
|
|
334
|
+
// Check if there are any selected options with subOptions but without subSelection
|
|
335
|
+
const invalidItems = this.findingsOptions.filter(f => f.selected && f.subOptions && !f.subSelection);
|
|
336
|
+
// If there are any invalid items, mark the form as invalid with a custom error
|
|
337
|
+
if (invalidItems.length > 0) {
|
|
338
|
+
this.form.get('findings')?.setErrors({ missingSubSelection: true });
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
// Clear the error if everything is valid
|
|
342
|
+
this.form.get('findings')?.setErrors(null);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
onSubmit() {
|
|
346
|
+
this.formSubmitted = true;
|
|
347
|
+
if (this.form.invalid) {
|
|
348
|
+
console.warn('⚠️ Please select a sub-option for all selected findings with sub-options.');
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
console.log('✅ Form Value:', this.form.value);
|
|
352
|
+
}
|
|
353
|
+
// patchExistingValues(data: any[]) {
|
|
354
|
+
// this.findingsOptions.forEach(opt => {
|
|
355
|
+
// const match = data.find(x => x.value === opt.value);
|
|
356
|
+
// opt.selected = !!match;
|
|
357
|
+
// opt.subSelection = match?.severity?.value || null;
|
|
358
|
+
// });
|
|
359
|
+
// this.updateFindings();
|
|
360
|
+
// }
|
|
361
|
+
patchExistingValues(data) {
|
|
362
|
+
// Iterate through the findingsOptions and find the corresponding option for each entry in data
|
|
363
|
+
this.findingsOptions.forEach(opt => {
|
|
364
|
+
const match = data.find(x => x.value === opt.value);
|
|
365
|
+
if (match) {
|
|
366
|
+
opt.selected = true;
|
|
367
|
+
opt.subSelection = match.subSelection ? match.subSelection.value : null;
|
|
368
|
+
// console.log("Matched Option:", opt);
|
|
369
|
+
// console.log("SubSelection Set To:", this.findingsOptions);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
opt.selected = false;
|
|
373
|
+
opt.subSelection = null;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
// Manually trigger change detection if needed
|
|
377
|
+
this.cdr.detectChanges();
|
|
378
|
+
this.updateFindings();
|
|
379
|
+
}
|
|
380
|
+
selectSubOption(option, subOption) {
|
|
381
|
+
// Set the subSelection to the clicked value
|
|
382
|
+
option.subSelection = subOption.value;
|
|
383
|
+
// Mark the option as touched, which will help in form validation
|
|
384
|
+
option.touched = true;
|
|
385
|
+
// Update the form state
|
|
386
|
+
this.updateFindings();
|
|
387
|
+
}
|
|
388
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomizeDropdownComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.HttpClient }, { token: i2.FxBuilderWrapperService }, { token: i3.ApiServiceRegistry }, { token: i4.FormBuilder }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
389
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CustomizeDropdownComponent, isStandalone: true, selector: "lib-customize-dropdown", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"container\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" class=\"relative\">\r\n <!-- Header -->\r\n <label for=\"findings\" class=\"input-label\">\r\n {{ setting('findingLabel') }}\r\n <span *ngIf=\"isRequired\" class=\"field-required\">*</span>\r\n </label>\r\n <div #dropdownWrapper class=\"relative w-80\">\r\n <button\r\n type=\"button\"\r\n class=\"w-full border border-gray-300 rounded-md px-3 py-2 flex justify-between items-center bg-white text-gray-700 hover:border-blue-400\"\r\n (click)=\"toggleDropdown()\"\r\n >\r\n <span *ngIf=\"hasSelectedFindings; else placeholder\">\r\n {{ selectedFindingsLabel }}\r\n </span>\r\n <ng-template #placeholder>\r\n {{ setting('placeholderLabel') }}\r\n </ng-template>\r\n <svg\r\n class=\"w-5 h-5 ml-2 text-gray-500 transform transition-transform duration-200\"\r\n [class.rotate-180]=\"dropdownOpen\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- Panel -->\r\n <div\r\n *ngIf=\"dropdownOpen\"\r\n class=\"absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-64 overflow-y-auto z-10\"\r\n >\r\n <div\r\n *ngFor=\"let option of findingsOptions\"\r\n class=\"border-b border-gray-100 last:border-none p-2 hover:bg-gray-50 cursor-pointer\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <!-- Checkbox + Label -->\r\n <div class=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"w-4 h-4 text-blue-500 border-gray-300 rounded cursor-pointer\"\r\n [(ngModel)]=\"option.selected\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n (click)=\"toggleOption(option, $event)\"\r\n />\r\n <label\r\n class=\"text-gray-800 font-medium cursor-pointer select-none\"\r\n (click)=\"toggleOption(option, $event)\"\r\n >\r\n {{ option.label }}\r\n </label>\r\n\r\n <span\r\n *ngIf=\"option.info\"\r\n class=\"ml-auto text-blue-500 text-sm cursor-pointer\"\r\n title=\"{{ option.info }}\"\r\n >\r\n \u24D8\r\n </span>\r\n </div>\r\n\r\n <!-- Radios -->\r\n <div\r\n class=\"flex items-center flex-wrap gap-4 ml-6 mt-2 text-sm\"\r\n *ngIf=\"option.selected && option.subOptions\"\r\n >\r\n <ng-container *ngFor=\"let s of option.subOptions\">\r\n <label\r\n class=\"flex items-center space-x-1 cursor-pointer\"\r\n (click)=\"selectSubOption(option, s)\"\r\n >\r\n <input\r\n type=\"radio\"\r\n [name]=\"option.value\"\r\n [value]=\"s.value\"\r\n [(ngModel)]=\"option.subSelection\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n class=\"text-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ s.label }}</span>\r\n </label>\r\n</ng-container>\r\n\r\n <!-- Validation Message -->\r\n <div\r\n *ngIf=\"option.selected && option.subOptions && !option.subSelection\"\r\n class=\"text-red-500 text-xs mt-1 w-full ml-1\"\r\n >\r\n Please select one option\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div>\r\n <small *ngIf=\"form.get('findings')?.touched && form.get('findings')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorFindingMessage') }}\r\n </small>\r\n </div>\r\n \r\n </form>\r\n </div>\r\n</fx-component>\r\n", styles: [".container{width:300px}.dropdown{position:relative;-webkit-user-select:none;user-select:none}.dropdown-header{border:1px solid #ccc;border-radius:4px;padding:6px 8px;background-color:#fff;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.dropdown-panel{position:absolute;width:100%;background:#fff;border:1px solid #ddd;margin-top:4px;border-radius:4px;max-height:250px;overflow-y:auto;z-index:1000;box-shadow:0 2px 8px #0000001a}.dropdown-item{padding:4px 8px;border-bottom:1px solid #f1f1f1}.dropdown-item:last-child{border-bottom:none}.item-header{display:flex;align-items:center;gap:6px}.label{cursor:pointer;flex-grow:1}.info{margin-left:auto;cursor:help;font-size:12px;color:#666}.sub-options{display:flex;align-items:center;flex-wrap:wrap;padding-left:22px;font-size:13px;margin-top:4px}.error{color:#e63946;font-size:11px;margin-left:22px;margin-top:2px}.arrow{font-size:10px;color:#555}.submit-btn{margin-top:1rem;padding:6px 12px;background:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }] });
|
|
390
|
+
}
|
|
391
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomizeDropdownComponent, decorators: [{
|
|
392
|
+
type: Component,
|
|
393
|
+
args: [{ selector: 'lib-customize-dropdown', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"container\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" class=\"relative\">\r\n <!-- Header -->\r\n <label for=\"findings\" class=\"input-label\">\r\n {{ setting('findingLabel') }}\r\n <span *ngIf=\"isRequired\" class=\"field-required\">*</span>\r\n </label>\r\n <div #dropdownWrapper class=\"relative w-80\">\r\n <button\r\n type=\"button\"\r\n class=\"w-full border border-gray-300 rounded-md px-3 py-2 flex justify-between items-center bg-white text-gray-700 hover:border-blue-400\"\r\n (click)=\"toggleDropdown()\"\r\n >\r\n <span *ngIf=\"hasSelectedFindings; else placeholder\">\r\n {{ selectedFindingsLabel }}\r\n </span>\r\n <ng-template #placeholder>\r\n {{ setting('placeholderLabel') }}\r\n </ng-template>\r\n <svg\r\n class=\"w-5 h-5 ml-2 text-gray-500 transform transition-transform duration-200\"\r\n [class.rotate-180]=\"dropdownOpen\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- Panel -->\r\n <div\r\n *ngIf=\"dropdownOpen\"\r\n class=\"absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-64 overflow-y-auto z-10\"\r\n >\r\n <div\r\n *ngFor=\"let option of findingsOptions\"\r\n class=\"border-b border-gray-100 last:border-none p-2 hover:bg-gray-50 cursor-pointer\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <!-- Checkbox + Label -->\r\n <div class=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"w-4 h-4 text-blue-500 border-gray-300 rounded cursor-pointer\"\r\n [(ngModel)]=\"option.selected\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n (click)=\"toggleOption(option, $event)\"\r\n />\r\n <label\r\n class=\"text-gray-800 font-medium cursor-pointer select-none\"\r\n (click)=\"toggleOption(option, $event)\"\r\n >\r\n {{ option.label }}\r\n </label>\r\n\r\n <span\r\n *ngIf=\"option.info\"\r\n class=\"ml-auto text-blue-500 text-sm cursor-pointer\"\r\n title=\"{{ option.info }}\"\r\n >\r\n \u24D8\r\n </span>\r\n </div>\r\n\r\n <!-- Radios -->\r\n <div\r\n class=\"flex items-center flex-wrap gap-4 ml-6 mt-2 text-sm\"\r\n *ngIf=\"option.selected && option.subOptions\"\r\n >\r\n <ng-container *ngFor=\"let s of option.subOptions\">\r\n <label\r\n class=\"flex items-center space-x-1 cursor-pointer\"\r\n (click)=\"selectSubOption(option, s)\"\r\n >\r\n <input\r\n type=\"radio\"\r\n [name]=\"option.value\"\r\n [value]=\"s.value\"\r\n [(ngModel)]=\"option.subSelection\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n class=\"text-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ s.label }}</span>\r\n </label>\r\n</ng-container>\r\n\r\n <!-- Validation Message -->\r\n <div\r\n *ngIf=\"option.selected && option.subOptions && !option.subSelection\"\r\n class=\"text-red-500 text-xs mt-1 w-full ml-1\"\r\n >\r\n Please select one option\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div>\r\n <small *ngIf=\"form.get('findings')?.touched && form.get('findings')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorFindingMessage') }}\r\n </small>\r\n </div>\r\n \r\n </form>\r\n </div>\r\n</fx-component>\r\n", styles: [".container{width:300px}.dropdown{position:relative;-webkit-user-select:none;user-select:none}.dropdown-header{border:1px solid #ccc;border-radius:4px;padding:6px 8px;background-color:#fff;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.dropdown-panel{position:absolute;width:100%;background:#fff;border:1px solid #ddd;margin-top:4px;border-radius:4px;max-height:250px;overflow-y:auto;z-index:1000;box-shadow:0 2px 8px #0000001a}.dropdown-item{padding:4px 8px;border-bottom:1px solid #f1f1f1}.dropdown-item:last-child{border-bottom:none}.item-header{display:flex;align-items:center;gap:6px}.label{cursor:pointer;flex-grow:1}.info{margin-left:auto;cursor:help;font-size:12px;color:#666}.sub-options{display:flex;align-items:center;flex-wrap:wrap;padding-left:22px;font-size:13px;margin-top:4px}.error{color:#e63946;font-size:11px;margin-left:22px;margin-top:2px}.arrow{font-size:10px;color:#555}.submit-btn{margin-top:1rem;padding:6px 12px;background:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
394
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.HttpClient }, { type: i2.FxBuilderWrapperService }, { type: i3.ApiServiceRegistry }, { type: i4.FormBuilder }, { type: i0.ElementRef }], propDecorators: { fxComponent: [{
|
|
395
|
+
type: ViewChild,
|
|
396
|
+
args: ['fxComponent']
|
|
397
|
+
}] } });
|
|
398
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9taXplLWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Z4LWJ1aWxkZXItd3JhcHBlci9zcmMvbGliL2NvbXBvbmVudHMvY3VzdG9taXplLWRyb3Bkb3duL2N1c3RvbWl6ZS1kcm9wZG93bi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9meC1idWlsZGVyLXdyYXBwZXIvc3JjL2xpYi9jb21wb25lbnRzL2N1c3RvbWl6ZS1kcm9wZG93bi9jdXN0b21pemUtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRS9DLE9BQU8sRUFBb0MsU0FBUyxFQUFvQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekgsT0FBTyxFQUEwQixXQUFXLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEcsT0FBTyxFQUNMLGVBQWUsRUFDZixXQUFXLEVBQ1gsZUFBZSxFQUVmLGVBQWUsRUFFZixrQkFBa0IsRUFDbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7OztBQThCMUMsTUFBTSxPQUFPLDBCQUEyQixTQUFRLGVBQWU7SUFvSG5EO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQXhIRixRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztJQUMxQyxJQUFJLENBQWE7SUFDakIsVUFBVSxHQUFXLEVBQUUsQ0FBQztJQUN4QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDSSxXQUFXLENBQWU7SUFFcEQsZUFBZSxHQUEyQixFQUFFLENBQUM7SUFFN0MsWUFBWSxHQUFV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Q0FBdUM7Z0JBQ3ZDLDZEQUE2RDtZQUMvRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sR0FBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQzFCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILDhDQUE4QztRQUM5QyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXpCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQVcsRUFBRSxTQUFjO1FBQ3pDLDRDQUE0QztRQUM1QyxNQUFNLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDdEMsaUVBQWlFO1FBQ2pFLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQzt3R0F0YVksMEJBQTBCOzRGQUExQiwwQkFBMEIscU5DN0N2Qyw4bklBNkdBLHduQ0RwRVksWUFBWSwrUEFBRSxtQkFBbUIsZ3JDQUFFLFdBQVcsdVBBQUUsV0FBVzs7NEZBSTFELDBCQUEwQjtrQkFQdEMsU0FBUzsrQkFDRSx3QkFBd0IsY0FDdEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxXQUFXLENBQUM7eU9BVTVDLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEFwaVNlcnZpY2VSZWdpc3RyeSB9IGZyb20gJ0BpbnN0YW50c3lzLWxhYnMvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgRnhCYXNlQ29tcG9uZW50LFxyXG4gIEZ4Q29tcG9uZW50LFxyXG4gIEZ4U2VsZWN0U2V0dGluZyxcclxuICBGeFNldHRpbmcsXHJcbiAgRnhTdHJpbmdTZXR0aW5nLFxyXG4gIEZ4VmFsaWRhdGlvbixcclxuICBGeFZhbGlkYXRvclNlcnZpY2VcclxufSBmcm9tICdAaW5zdGFudHN5cy1sYWJzL2Z4JztcclxuaW1wb3J0IHsgRnhCdWlsZGVyV3JhcHBlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9meC1idWlsZGVyLXdyYXBwZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW50ZXJmYWNlIFN1Yk9wdGlvbiB7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICB2YWx1ZTogc3RyaW5nO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgQ3VzdG9tRHJvcGRvd25PcHRpb24ge1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgdmFsdWU6IHN0cmluZztcclxuICBpbmZvPzogc3RyaW5nO1xyXG4gIHNlbGVjdGVkOiBib29sZWFuO1xyXG4gIHN1Yk9wdGlvbnM/OiBTdWJPcHRpb25bXTtcclxuICBzdWJTZWxlY3Rpb24/OiBzdHJpbmcgfCBudWxsO1xyXG4gIGRpc2FibGVkPzogYm9vbGVhbjtcclxuICB0b3VjaGVkPzogYm9vbGVhbjtcclxufVxyXG5cclxuaW50ZXJmYWNlIEN1c3RvbURyb3Bkb3duQ29uZmlnIHtcclxuICBkaXNwbGF5TW9kZT86ICdjb21wYWN0JyB8ICdlbGxpcHNpcyc7XHJcbiAgcGxhY2Vob2xkZXJMYWJlbD86IHN0cmluZztcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItY3VzdG9taXplLWRyb3Bkb3duJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIEZvcm1zTW9kdWxlLCBGeENvbXBvbmVudF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2N1c3RvbWl6ZS1kcm9wZG93bi5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vY3VzdG9taXplLWRyb3Bkb3duLmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ3VzdG9taXplRHJvcGRvd25Db21wb25lbnQgZXh0ZW5kcyBGeEJhc2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQgLCBBZnRlclZpZXdJbml0e1xyXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIGZvcm0hOiBGb3JtR3JvdXA7XHJcbiAgZm9ybU9iamVjdDogb2JqZWN0ID0ge307XHJcbiAgZHJvcGRvd25PcGVuID0gZmFsc2U7XHJcbiAgZm9ybVN1Ym1pdHRlZCA9IGZhbHNlO1xyXG4gIEBWaWV3Q2hpbGQoJ2Z4Q29tcG9uZW50JykgZnhDb21wb25lbnQhOiBGeENvbXBvbmVudDtcclxuXHJcbiAgZmluZGluZ3NPcHRpb25zOiBDdXN0b21Ecm9wZG93bk9wdGlvbltdID0gW107XHJcblxyXG4gIHR5cGUxT3B0aW9uczogYW55W10gPSBbICAgIHtcclxuICAgICAgbGFiZWw6ICdQcm9jbGluYXRpb24nLFxyXG4gICAgICB2YWx1ZTogJ1Byb2NsaW5hdGlvbicsXHJcbiAgICAgIGluZm86ICdGb3J3YXJkIGluY2xpbmF0aW9uIG9mIHRlZXRoJyxcclxuICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICBzdWJPcHRpb25zOiBbXHJcbiAgICAgICAgeyBsYWJlbDogJ01pbGQnLCB2YWx1ZTogJ21pbGQnIH0sXHJcbiAgICAgICAgeyBsYWJlbDogJ01vZGVyYXRlJywgdmFsdWU6ICdtb2RlcmF0ZScgfSxcclxuICAgICAgICB7IGxhYmVsOiAnU2V2ZXJlJywgdmFsdWU6ICdzZXZlcmUnIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdDcm93ZGluZycsXHJcbiAgICAgIHZhbHVlOiAnQ3Jvd2RpbmcnLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ1NwYWNpbmcnLFxyXG4gICAgICB2YWx1ZTogJ1NwYWNpbmcnLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ1JldHJvY2xpbmF0aW9uJyxcclxuICAgICAgdmFsdWU6ICdSZXRyb2NsaW5hdGlvbicsXHJcbiAgICAgIGluZm86ICdCYWNrd2FyZCBpbmNsaW5hdGlvbiBvZiB0ZWV0aCcsXHJcbiAgICAgIHNlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcblxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdSb3RhdGlvbicsXHJcbiAgICAgIHZhbHVlOiAnUm90YXRpb24nLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgICBzdWJPcHRpb25zOiBbXHJcbiAgICAgICAgeyBsYWJlbDogJ01pbGQnLCB2YWx1ZTogJ21pbGQnIH0sXHJcbiAgICAgICAgeyBsYWJlbDogJ01vZGVyYXRlJywgdmFsdWU6ICdtb2RlcmF0ZScgfSxcclxuICAgICAgICB7IGxhYmVsOiAnU2V2ZXJlJywgdmFsdWU6ICdzZXZlcmUnIH1cclxuICAgICAgXVxyXG4gICAgfV07XHJcblxyXG4gIHR5cGUyT3B0aW9uczogYW55W10gPSBbXHJcbiAgICAgICAge1xyXG4gICAgICBsYWJlbDogJ05vcm1hbCcsXHJcbiAgICAgIHZhbHVlOiAnTm9ybWFsJyxcclxuICAgICAgaW5mbzogJycsXHJcbiAgICAgIHNlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgc3ViT3B0aW9uczogW1xyXG4gICAgICAgIHsgbGFiZWw6ICdNaWxkJywgdmFsdWU6ICdtaWxkJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdNb2RlcmF0ZScsIHZhbHVlOiAnbW9kZXJhdGUnIH0sXHJcbiAgICAgICAgeyBsYWJlbDogJ1NldmVyZScsIHZhbHVlOiAnc2V2ZXJlJyB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIGxhYmVsOiAnRGVlcCBCaXRlJyxcclxuICAgICAgdmFsdWU6ICdEZWVwIEJpdGUnLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ09wZW4gQml0ZScsXHJcbiAgICAgIHZhbHVlOiAnT3BlbiBCaXRlJyxcclxuICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICBzdWJPcHRpb25zOiBbXHJcbiAgICAgICAgeyBsYWJlbDogJ01pbGQnLCB2YWx1ZTogJ21pbGQnIH0sXHJcbiAgICAgICAgeyBsYWJlbDogJ01vZGVyYXRlJywgdmFsdWU6ICdtb2RlcmF0ZScgfSxcclxuICAgICAgICB7IGxhYmVsOiAnU2V2ZXJlJywgdmFsdWU6ICdzZXZlcmUnIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICBdO1xyXG5cclxuICBpc1JlcXVpcmVkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICAvLyBvbkNsaWNrT3V0c2lkZShldmVudDogTW91c2VFdmVudCkge1xyXG4gIC8vICAgaWYgKHRoaXMuZHJvcGRvd25PcGVuICYmICF0aGlzLmVSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XHJcbiAgLy8gICAgIHRoaXMuZHJvcGRvd25PcGVuID0gZmFsc2U7XHJcbiAgLy8gICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAvLyAgIH1cclxuICAvLyB9XHJcblxyXG4gIGNvbmZpZzogQ3VzdG9tRHJvcGRvd25Db25maWcgPSB7XHJcbiAgICBkaXNwbGF5TW9kZTogJ2VsbGlwc2lzJyxcclxuICAgIHBsYWNlaG9sZGVyTGFiZWw6ICdTZWxlY3QgRmluZGluZydcclxuICB9O1xyXG5cclxuICBjdXN0b21pemVkRHJvcERvd25NYXAgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgZnhCdWlsZGVyV3JhcHBlclNlcnZpY2U6IEZ4QnVpbGRlcldyYXBwZXJTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBmeEFwaVNlcnZpY2U6IEFwaVNlcnZpY2VSZWdpc3RyeSxcclxuICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBlUmVmOiBFbGVtZW50UmVmXHJcbiAgKSB7XHJcbiAgICBzdXBlcihjZHIpO1xyXG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XHJcbiAgICAgIGZpbmRpbmdzOiBbW11dXHJcbiAgICB9KTtcclxuICAgIHRoaXMub25Jbml0LnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZWdpc3Rlcih0aGlzLmZvcm0pKTtcclxuICB9XHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4vLyAgICAgc2V0VGltZW91dCgoKT0+e1xyXG4vLyAgICAgICBjb25zdCBkYXRhID0gW1xyXG4vLyAgIHtcclxuLy8gICAgIGxhYmVsOiBcIlByb2NsaW5hdGlvblwiLFxyXG4vLyAgICAgdmFsdWU6IFwicHJvY2xpbmF0aW9uXCIsXHJcbi8vICAgICBzdWJTZWxlY3Rpb246IHtcclxuLy8gICAgICAgbGFiZWw6IFwiTWlsZFwiLFxyXG4vLyAgICAgICB2YWx1ZTogXCJtaWxkXCJcclxuLy8gICAgIH1cclxuLy8gICB9LFxyXG4vLyAgIHtcclxuLy8gICAgIGxhYmVsOiBcIk92ZXJiaXRlXCIsXHJcbi8vICAgICB2YWx1ZTogXCJvdmVyYml0ZVwiLFxyXG4vLyAgICAgc3ViU2VsZWN0aW9uOiB7XHJcbi8vICAgICAgIGxhYmVsOiBcIk1vZGVyYXRlXCIsXHJcbi8vICAgICAgIHZhbHVlOiBcIm1vZGVyYXRlXCJcclxuLy8gICAgIH1cclxuLy8gICB9XHJcbi8vIF07XHJcblxyXG4vLyB0aGlzLnBhdGNoRXhpc3RpbmdWYWx1ZXMoZGF0YSk7XHJcbi8vICAgICB9LDIwMDApO1xyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgY29uc3Qga2V5ID0gdGhpcy5meENvbXBvbmVudD8uZnhEYXRhPy5uYW1lO1xyXG5cclxuICAgICAgaWYgKGtleSAmJiB0aGlzLmN1c3RvbWl6ZWREcm9wRG93bk1hcC5oYXMoa2V5KSkge1xyXG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmN1c3RvbWl6ZWREcm9wRG93bk1hcC5nZXQoa2V5KT8uZmluZGluZ3M7XHJcbiAgICAgICAgdGhpcy5wYXRjaEV4aXN0aW5nVmFsdWVzKGRhdGEpO1xyXG5cclxuICAgICAgfVxyXG4gICAgfSwgMTAwMCk7XHJcblxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBtYWluQ29udHJvbCA9IHRoaXMuZm9ybS5nZXQoJ2ZpbmRpbmdzJyk7XHJcbiAgICAgICAgICBpZiAodGhpcy5zZXR0aW5nKCdpc0ZpbmRpbmdzUmVxdWlyZWQnKSA9PT0gJ3RydWUnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNSZXF1aXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIG1haW5Db250cm9sPy5zZXRWYWxpZGF0b3JzKFtWYWxpZGF0b3JzLnJlcXVpcmVkXSk7XHJcbiAgICAgICAgICAgIG1haW5Db250cm9sPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSwgNTAwKVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5zZXR0aW5nKCdvcHRpb25UeXBlJykgPT09ICd0eXBlMScpIHtcclxuICAgICAgdGhpcy5maW5kaW5nc09wdGlvbnMgPSB0aGlzLnR5cGUxT3B0aW9ucztcclxuXHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAodGhpcy5zZXR0aW5nKCdvcHRpb25UeXBlJykgPT09ICd0eXBlMicpIHtcclxuICAgICAgdGhpcy5maW5kaW5nc09wdGlvbnMgPSB0aGlzLnR5cGUyT3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmZ4QnVpbGRlcldyYXBwZXJTZXJ2aWNlLnZhcmlhYmxlcyRcclxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxyXG4gICAgICAuc3Vic2NyaWJlKCh2YXJpYWJsZXM6IGFueSkgPT4ge1xyXG5cclxuICAgICAgICBpZiAoIXZhcmlhYmxlcykgcmV0dXJuO1xyXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHZhcmlhYmxlcykgYXMgW3N0cmluZywgYW55XVtdKSB7XHJcbiAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgIHZhbHVlICYmXHJcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcclxuICAgICAgICAgICAgJ2ZpbmRpbmdzJyBpbiB2YWx1ZVxyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VzdG9taXplZERyb3BEb3duTWFwLnNldChrZXksIHZhbHVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgLy8gY29uc3Qgc2VydmljZVVybCA9IHRoaXMuZnhBcGlTZXJ2aWNlLmdldFNlcnZpY2VVcmwodGhpcy5zZXR0aW5nKCdzZXJ2aWNlTmFtZScpKTtcclxuICAgIC8vIHRoaXMuZ2V0T3B0aW9ucyhzZXJ2aWNlVXJsLCB0aGlzLnNldHRpbmcoJ2NsaW5pY2FsTm90ZXNVUkwnKSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgZ2V0T3B0aW9ucyhzZXJ2aWNlVXJsOiBzdHJpbmcsIHVybDogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBmaW5hbFVybCA9IHNlcnZpY2VVcmwgKyB1cmw7XHJcbiAgICB0aGlzLmh0dHAuZ2V0PGFueVtdPihmaW5hbFVybCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICAvLyBGdXR1cmUgQVBJIGxvZ2ljIGhlcmVcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZldGNoaW5nIG9wdGlvbnMnLCBlcnIpXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBzZXR0aW5ncygpOiBGeFNldHRpbmdbXSB7XHJcbiAgICByZXR1cm4gW1xyXG4gICAgICBuZXcgRnhTZWxlY3RTZXR0aW5nKHsga2V5OiAnZGlzcGxheU1vZGUnLCAkdGl0bGU6ICdEaXNwbGF5IE1vZGUnLCB2YWx1ZTogJ2VsbGlwc2lzJyB9LCBbeyBvcHRpb246ICdFbGxpcHNpcycsIHZhbHVlOiAnZWxsaXBzaXMnIH0sIHsgb3B0aW9uOiAnQ29tcGFjdCcsIHZhbHVlOiAnY29tcGFjdCcgfV0pLFxyXG4gICAgICBuZXcgRnhTZWxlY3RTZXR0aW5nKHsga2V5OiAnb3B0aW9uVHlwZScsICR0aXRsZTogJ09wdGlvbiBUeXBlJywgdmFsdWU6ICd0eXBlMScgfSwgW3sgb3B0aW9uOiAnRmluZGluZyBUeXBlIE9wdGlvbnMnLCB2YWx1ZTogJ3R5cGUxJyB9LCB7IG9wdGlvbjogJ1ZldGljYWwgVHlwZSBPcHRpb25zJywgdmFsdWU6ICd0eXBlMicgfV0pLFxyXG4gICAgICBuZXcgRnhTdHJpbmdTZXR0aW5nKHsga2V5OiAncGxhY2Vob2xkZXJMYWJlbCcsICR0aXRsZTogJ1BsYWNlaG9sZGVyJywgdmFsdWU6ICdTZWxlY3QgT3B0aW9ucycgfSksXHJcbiAgICAgICBuZXcgRnhTdHJpbmdTZXR0aW5nKHsga2V5OiAnZmluZGluZ0xhYmVsJywgJHRpdGxlOiAnTGFiZWwnLCB2YWx1ZTogJ0xhYmVsJyB9KSxcclxuICAgICAgIG5ldyBGeFNlbGVjdFNldHRpbmcoeyBrZXk6ICdpc0ZpbmRpbmdzUmVxdWlyZWQnLCAkdGl0bGU6ICdSZXF1aXJlZCcsIHZhbHVlOiAndHJ1ZScgfSwgW3sgb3B0aW9uOiAnWWVzJywgdmFsdWU6ICd0cnVlJyB9LCB7IG9wdGlvbjogJ05vJywgdmFsdWU6ICdmYWxzZScgfV0pLFxyXG4gICAgICAgIG5ldyBGeFN0cmluZ1NldHRpbmcoeyBrZXk6ICdlcnJvckZpbmRpbmdNZXNzYWdlJywgJHRpdGxlOiAnRXJyb3IgTWVzc2FnZScsIHZhbHVlOiAnUGxlYXNlIGZpbGwgb3V0IHRoZSBmaWVsZCcgfSksXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIHZhbGlkYXRpb25zKCk6IEZ4VmFsaWRhdGlvbltdIHtcclxuICAgIHJldHVybiBbRnhWYWxpZGF0b3JTZXJ2aWNlLnJlcXVpcmVkXTtcclxuICB9XHJcblxyXG4gIC8qKiBEcm9wZG93biBCZWhhdmlvciAqKi9cclxuICB0b2dnbGVEcm9wZG93bigpIHtcclxuICAgIHRoaXMuZHJvcGRvd25PcGVuID0gIXRoaXMuZHJvcGRvd25PcGVuO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlT3B0aW9uKG9wdGlvbjogQ3VzdG9tRHJvcGRvd25PcHRpb24sIGV2ZW50OiBFdmVudCkge1xyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgLy8gVG9nZ2xlIGNoZWNrYm94IHZhbHVlXHJcbiAgICBvcHRpb24uc2VsZWN0ZWQgPSAhb3B0aW9uLnNlbGVjdGVkO1xyXG5cclxuICAgIC8vIFJlc2V0IHJhZGlvcyB3aGVuIHVuY2hlY2tlZFxyXG4gICAgaWYgKCFvcHRpb24uc2VsZWN0ZWQpIHtcclxuICAgICAgb3B0aW9uLnN1YlNlbGVjdGlvbiA9IG51bGw7XHJcbiAgICAgIG9wdGlvbi50b3VjaGVkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZXtcclxuICAgICAgb3B0aW9uLnRvdWNoZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOKchSBGb3JjZSBVSSByZWZyZXNoIHNvIHJhZGlvcyBhcHBlYXIgaW5zdGFudGx5XHJcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgLy8gVXBkYXRlIHJlYWN0aXZlIGZvcm1cclxuICAgIHRoaXMudXBkYXRlRmluZGluZ3MoKTtcclxuICB9XHJcblxyXG4gIC8qKiBGb3JtICYgTGFiZWwgSGVscGVycyAqKi9cclxuICBnZXQgaGFzU2VsZWN0ZWRGaW5kaW5ncygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbmRpbmdzT3B0aW9ucy5zb21lKGYgPT4gZi5zZWxlY3RlZCk7XHJcbiAgfVxyXG5cclxuICBnZXQgc2VsZWN0ZWRGaW5kaW5nc0xhYmVsKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuZmluZGluZ3NPcHRpb25zXHJcbiAgICAgIC5maWx0ZXIoZiA9PiB7XHJcbiAgICAgICAgaWYgKGYuc2VsZWN0ZWQpIHtcclxuICAgICAgICAgIC8vIElmIGZpbmRpbmcgaGFzIHN1Yi1vcHRpb25zIOKGkiBvbmx5IHNob3cgaWYgYSBzdWItb3B0aW9uIGlzIHNlbGVjdGVkXHJcbiAgICAgICAgICBpZiAoZi5zdWJPcHRpb25zPy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuICEhZi5zdWJTZWxlY3Rpb247XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvLyBJZiBubyBzdWItb3B0aW9ucyDihpIgYWx3YXlzIHNob3dcclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5tYXAoZiA9PiBmLmxhYmVsKTtcclxuXHJcbiAgICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5zZXR0aW5nKCdwbGFjZWhvbGRlckxhYmVsJyk7XHJcblxyXG4gICAgLy8gRGlzcGxheSBtb2RlIGxvZ2ljIChDb21wYWN0IG9yIEVsbGlwc2lzKVxyXG4gICAgY29uc3QgbWF4Q291bnQgPSB0aGlzLnNldHRpbmcoJ2Rpc3BsYXlNb2RlJykgPT09ICdjb21wYWN0JyA/IDIgOiAzO1xyXG4gICAgaWYgKHRoaXMuc2V0dGluZygnZGlzcGxheU1vZGUnKSA9PT0gJ2NvbXBhY3QnKSB7XHJcbiAgICAgIHJldHVybiBzZWxlY3RlZC5sZW5ndGggPD0gbWF4Q291bnRcclxuICAgICAgICA/IHNlbGVjdGVkLmpvaW4oJywgJylcclxuICAgICAgICA6IGAke3NlbGVjdGVkLnNsaWNlKDAsIG1heENvdW50KS5qb2luKCcsICcpfSArJHtzZWxlY3RlZC5sZW5ndGggLSBtYXhDb3VudH0gbW9yZWA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc2V0dGluZygnZGlzcGxheU1vZGUnKSA9PT0gJ2VsbGlwc2lzJykge1xyXG4gICAgICByZXR1cm4gc2VsZWN0ZWQubGVuZ3RoID4gbWF4Q291bnRcclxuICAgICAgICA/IGAke3NlbGVjdGVkLnNsaWNlKDAsIG1heENvdW50KS5qb2luKCcsICcpfSwgLi4uYFxyXG4gICAgICAgIDogc2VsZWN0ZWQuam9pbignLCAnKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc2VsZWN0ZWQuam9pbignLCAnKTtcclxuICB9XHJcblxyXG4gIC8qKiBVcGRhdGUgRmluZGluZ3MgKyBWYWxpZGF0aW9uICoqL1xyXG4gIC8vIHVwZGF0ZUZpbmRpbmdzKCkge1xyXG4gIC8vICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLmZpbmRpbmdzT3B0aW9uc1xyXG4gIC8vICAgICAuZmlsdGVyKGYgPT4ge1xyXG4gIC8vICAgICAgIGlmIChmLnNlbGVjdGVkKSB7XHJcbiAgLy8gICAgICAgICAvLyBPbmx5IGluY2x1ZGUgaW4gZmluYWwgZm9ybSBpZjpcclxuICAvLyAgICAgICAgIC8vICAtIG5vIHN1Yk9wdGlvbnMsIG9yXHJcbiAgLy8gICAgICAgICAvLyAgLSBzdWJPcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uXHJcbiAgLy8gICAgICAgICBpZiAoZi5zdWJPcHRpb25zPy5sZW5ndGgpIHtcclxuICAvLyAgICAgICAgICAgcmV0dXJuICEhZi5zdWJTZWxlY3Rpb247XHJcbiAgLy8gICAgICAgICB9XHJcbiAgLy8gICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAvLyAgICAgICB9XHJcbiAgLy8gICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gIC8vICAgICB9KVxyXG4gIC8vICAgICAubWFwKGYgPT4ge1xyXG4gIC8vICAgICAgIGNvbnN0IHN1YiA9IGYuc3ViT3B0aW9ucz8uZmluZChzID0+IHMudmFsdWUgPT09IGYuc3ViU2VsZWN0aW9uKSB8fCBudWxsO1xyXG4gIC8vICAgICAgIHJldHVybiB7XHJcbiAgLy8gICAgICAgICBsYWJlbDogZi5sYWJlbCxcclxuICAvLyAgICAgICAgIHZhbHVlOiBmLnZhbHVlLFxyXG4gIC8vICAgICAgICAgc3ViU2VsZWN0aW9uOiBzdWIgPyB7IGxhYmVsOiBzdWIubGFiZWwsIHZhbHVlOiBzdWIudmFsdWUgfSA6IG51bGxcclxuICAvLyAgICAgICB9O1xyXG4gIC8vICAgICB9KTtcclxuXHJcbiAgLy8gICAvLyBVcGRhdGUgcmVhY3RpdmUgZm9ybSB2YWx1ZVxyXG4gIC8vICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBmaW5kaW5nczogc2VsZWN0ZWQgfSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG5cclxuICAvLyAgIC8vIFZhbGlkYXRpb24gbG9naWMgcmVtYWlucyBzYW1lXHJcbiAgLy8gICBjb25zdCBpbnZhbGlkSXRlbXMgPSB0aGlzLmZpbmRpbmdzT3B0aW9ucy5maWx0ZXIoXHJcbiAgLy8gICAgIGYgPT4gZi5zZWxlY3RlZCAmJiBmLnN1Yk9wdGlvbnMgJiYgIWYuc3ViU2VsZWN0aW9uXHJcbiAgLy8gICApO1xyXG4gIC8vICAgdGhpcy5mb3JtLmdldCgnZmluZGluZ3MnKT8uc2V0RXJyb3JzKFxyXG4gIC8vICAgICBpbnZhbGlkSXRlbXMubGVuZ3RoID4gMCA/IHsgbWlzc2luZ1N1YlNlbGVjdGlvbjogdHJ1ZSB9IDogbnVsbFxyXG4gIC8vICAgKTtcclxuICAvLyB9XHJcblxyXG4gIHVwZGF0ZUZpbmRpbmdzKCkge1xyXG4gIC8vIEZpbHRlciBzZWxlY3RlZCBvcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uIChpZiBzdWJPcHRpb25zIGV4aXN0KVxyXG4gIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5maW5kaW5nc09wdGlvbnNcclxuICAgIC5maWx0ZXIoZiA9PiB7XHJcbiAgICAgIGlmIChmLnNlbGVjdGVkKSB7XHJcbiAgICAgICAgLy8gT25seSBpbmNsdWRlIGluIGZpbmFsIGZvcm0gaWY6XHJcbiAgICAgICAgLy8gIC0gbm8gc3ViT3B0aW9ucywgb3JcclxuICAgICAgICAvLyAgLSBzdWJPcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uXHJcbiAgICAgICAgaWYgKGYuc3ViT3B0aW9ucz8ubGVuZ3RoKSB7XHJcbiAgICAgICAgICByZXR1cm4gISFmLnN1YlNlbGVjdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSlcclxuICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgIGNvbnN0IHN1YiA9IGYuc3ViT3B0aW9ucz8uZmluZChzID0+IHMudmFsdWUgPT09IGYuc3ViU2VsZWN0aW9uKSB8fCBudWxsO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxhYmVsOiBmLmxhYmVsLFxyXG4gICAgICAgIHZhbHVlOiBmLnZhbHVlLFxyXG4gICAgICAgIHN1YlNlbGVjdGlvbjogc3ViID8geyBsYWJlbDogc3ViLmxhYmVsLCB2YWx1ZTogc3ViLnZhbHVlIH0gOiBudWxsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuXHJcbiAgLy8gVXBkYXRlIHJlYWN0aXZlIGZvcm0gdmFsdWVcclxuICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7IGZpbmRpbmdzOiBzZWxlY3RlZCB9LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcblxyXG4gIC8vIFZhbGlkYXRpb24gbG9naWM6XHJcbiAgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSBzZWxlY3RlZCBvcHRpb25zIHdpdGggc3ViT3B0aW9ucyBidXQgd2l0aG91dCBzdWJTZWxlY3Rpb25cclxuICBjb25zdCBpbnZhbGlkSXRlbXMgPSB0aGlzLmZpbmRpbmdzT3B0aW9ucy5maWx0ZXIoXHJcbiAgICBmID0+IGYuc2VsZWN0ZWQgJiYgZi5zdWJPcHRpb25zICYmICFmLnN1YlNlbGVjdGlvblxyXG4gICk7XHJcblxyXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgaW52YWxpZCBpdGVtcywgbWFyayB0aGUgZm9ybSBhcyBpbnZhbGlkIHdpdGggYSBjdXN0b20gZXJyb3JcclxuICBpZiAoaW52YWxpZEl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgIHRoaXMuZm9ybS5nZXQoJ2ZpbmRpbmdzJyk/LnNldEVycm9ycyh7IG1pc3NpbmdTdWJTZWxlY3Rpb246IHRydWUgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIENsZWFyIHRoZSBlcnJvciBpZiBldmVyeXRoaW5nIGlzIHZhbGlkXHJcbiAgICB0aGlzLmZvcm0uZ2V0KCdmaW5kaW5ncycpPy5zZXRFcnJvcnMobnVsbCk7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuICBvblN1Ym1pdCgpIHtcclxuICAgIHRoaXMuZm9ybVN1Ym1pdHRlZCA9IHRydWU7XHJcbiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKCfimqDvuI8gUGxlYXNlIHNlbGVjdCBhIHN1Yi1vcHRpb24gZm9yIGFsbCBzZWxlY3RlZCBmaW5kaW5ncyB3aXRoIHN1Yi1vcHRpb25zLicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZygn4pyFIEZvcm0gVmFsdWU6JywgdGhpcy5mb3JtLnZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8vIHBhdGNoRXhpc3RpbmdWYWx1ZXMoZGF0YTogYW55W10pIHtcclxuICAvLyAgIHRoaXMuZmluZGluZ3NPcHRpb25zLmZvckVhY2gob3B0ID0+IHtcclxuICAvLyAgICAgY29uc3QgbWF0Y2ggPSBkYXRhLmZpbmQoeCA9PiB4LnZhbHVlID09PSBvcHQudmFsdWUpO1xyXG4gIC8vICAgICBvcHQuc2VsZWN0ZWQgPSAhIW1hdGNoO1xyXG4gIC8vICAgICBvcHQuc3ViU2VsZWN0aW9uID0gbWF0Y2g/LnNldmVyaXR5Py52YWx1ZSB8fCBudWxsO1xyXG4gIC8vICAgfSk7XHJcbiAgLy8gICB0aGlzLnVwZGF0ZUZpbmRpbmdzKCk7XHJcbiAgLy8gfVxyXG5cclxucGF0Y2hFeGlzdGluZ1ZhbHVlcyhkYXRhOiBhbnlbXSkge1xyXG4gIC8vIEl0ZXJhdGUgdGhyb3VnaCB0aGUgZmluZGluZ3NPcHRpb25zIGFuZCBmaW5kIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbiBmb3IgZWFjaCBlbnRyeSBpbiBkYXRhXHJcbiAgdGhpcy5maW5kaW5nc09wdGlvbnMuZm9yRWFjaChvcHQgPT4ge1xyXG4gICAgY29uc3QgbWF0Y2ggPSBkYXRhLmZpbmQoeCA9PiB4LnZhbHVlID09PSBvcHQudmFsdWUpO1xyXG4gICAgXHJcbiAgICBpZiAobWF0Y2gpIHtcclxuICAgICAgb3B0LnNlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgb3B0LnN1YlNlbGVjdGlvbiA9IG1hdGNoLnN1YlNlbGVjdGlvbiA/IG1hdGNoLnN1YlNlbGVjdGlvbi52YWx1ZSA6IG51bGw7XHJcblxyXG4gICAgICAvLyBjb25zb2xlLmxvZyhcIk1hdGNoZWQgT3B0aW9uOlwiLCBvcHQpO1xyXG4gICAgICAvLyBjb25zb2xlLmxvZyhcIlN1YlNlbGVjdGlvbiBTZXQgVG86XCIsIHRoaXMuZmluZGluZ3NPcHRpb25zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG9wdC5zZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgICBvcHQuc3ViU2VsZWN0aW9uID0gbnVsbDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gTWFudWFsbHkgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIGlmIG5lZWRlZFxyXG4gIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICBcclxuICB0aGlzLnVwZGF0ZUZpbmRpbmdzKCk7XHJcbn1cclxuXHJcbnNlbGVjdFN1Yk9wdGlvbihvcHRpb246IGFueSwgc3ViT3B0aW9uOiBhbnkpIHtcclxuICAvLyBTZXQgdGhlIHN1YlNlbGVjdGlvbiB0byB0aGUgY2xpY2tlZCB2YWx1ZVxyXG4gIG9wdGlvbi5zdWJTZWxlY3Rpb24gPSBzdWJPcHRpb24udmFsdWU7XHJcbiAgLy8gTWFyayB0aGUgb3B0aW9uIGFzIHRvdWNoZWQsIHdoaWNoIHdpbGwgaGVscCBpbiBmb3JtIHZhbGlkYXRpb25cclxuICBvcHRpb24udG91Y2hlZCA9IHRydWU7XHJcbiAgLy8gVXBkYXRlIHRoZSBmb3JtIHN0YXRlXHJcbiAgdGhpcy51cGRhdGVGaW5kaW5ncygpO1xyXG59XHJcblxyXG59XHJcbiIsIjxmeC1jb21wb25lbnQgW2Z4RGF0YV09XCJmeERhdGFcIiAjZnhDb21wb25lbnQ+XHJcbiAgPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxyXG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIiBjbGFzcz1cInJlbGF0aXZlXCI+XHJcbiAgICAgIDwhLS0gSGVhZGVyIC0tPlxyXG4gICAgICA8bGFiZWwgZm9yPVwiZmluZGluZ3NcIiBjbGFzcz1cImlucHV0LWxhYmVsXCI+XHJcbiAgICAgICAge3sgc2V0dGluZygnZmluZGluZ0xhYmVsJykgfX1cclxuICAgICAgICA8c3BhbiAqbmdJZj1cImlzUmVxdWlyZWRcIiBjbGFzcz1cImZpZWxkLXJlcXVpcmVkXCI+Kjwvc3Bhbj5cclxuICAgICAgPC9sYWJlbD5cclxuICAgICAgPGRpdiAjZHJvcGRvd25XcmFwcGVyIGNsYXNzPVwicmVsYXRpdmUgdy04MFwiPlxyXG4gICAgICAgIDxidXR0b25cclxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgY2xhc3M9XCJ3LWZ1bGwgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIHB4LTMgcHktMiBmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXIgYmctd2hpdGUgdGV4dC1ncmF5LTcwMCBob3Zlcjpib3JkZXItYmx1ZS00MDBcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZURyb3Bkb3duKClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiaGFzU2VsZWN0ZWRGaW5kaW5nczsgZWxzZSBwbGFjZWhvbGRlclwiPlxyXG4gICAgICAgICAgICB7eyBzZWxlY3RlZEZpbmRpbmdzTGFiZWwgfX1cclxuICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjcGxhY2Vob2xkZXI+XHJcbiAgICAgICAgICAgIHt7IHNldHRpbmcoJ3BsYWNlaG9sZGVyTGFiZWwnKSB9fVxyXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgIDxzdmdcclxuICAgICAgICAgICAgY2xhc3M9XCJ3LTUgaC01IG1sLTIgdGV4dC1ncmF5LTUwMCB0cmFuc2Zvcm0gdHJhbnNpdGlvbi10cmFuc2Zvcm0gZHVyYXRpb24tMjAwXCJcclxuICAgICAgICAgICAgW2NsYXNzLnJvdGF0ZS0xODBdPVwiZHJvcGRvd25PcGVuXCJcclxuICAgICAgICAgICAgZmlsbD1cIm5vbmVcIlxyXG4gICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIlxyXG4gICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIGQ9XCJNMTkgOWwtNyA3LTctN1wiIC8+XHJcbiAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICA8L2J1dHRvbj5cclxuXHJcbiAgICAgICAgPCEtLSBQYW5lbCAtLT5cclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAqbmdJZj1cImRyb3Bkb3duT3BlblwiXHJcbiAgICAgICAgICBjbGFzcz1cImFic29sdXRlIG10LTEgdy1mdWxsIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZC1tZCBzaGFkb3ctbGcgbWF4LWgtNjQgb3ZlcmZsb3cteS1hdXRvIHotMTBcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBmaW5kaW5nc09wdGlvbnNcIlxyXG4gICAgICAgICAgICBjbGFzcz1cImJvcmRlci1iIGJvcmRlci1ncmF5LTEwMCBsYXN0OmJvcmRlci1ub25lIHAtMiBob3ZlcjpiZy1ncmF5LTUwIGN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDwhLS0gQ2hlY2tib3ggKyBMYWJlbCAtLT5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yXCI+XHJcbiAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTQgaC00IHRleHQtYmx1ZS01MDAgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQgY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJvcHRpb24uc2VsZWN0ZWRcIlxyXG4gICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcHRpb24ob3B0aW9uLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICAgIDxsYWJlbFxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWdyYXktODAwIGZvbnQtbWVkaXVtIGN1cnNvci1wb2ludGVyIHNlbGVjdC1ub25lXCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcHRpb24ob3B0aW9uLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cclxuICAgICAgICAgICAgICA8L2xhYmVsPlxyXG5cclxuICAgICAgICAgICAgICA8c3BhblxyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJvcHRpb24uaW5mb1wiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLWF1dG8gdGV4dC1ibHVlLTUwMCB0ZXh0LXNtIGN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgICAgIHRpdGxlPVwie3sgb3B0aW9uLmluZm8gfX1cIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIOKTmFxyXG4gICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8IS0tIFJhZGlvcyAtLT5cclxuICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZmxleC13cmFwIGdhcC00IG1sLTYgbXQtMiB0ZXh0LXNtXCJcclxuICAgICAgICAgICAgICAqbmdJZj1cIm9wdGlvbi5zZWxlY3RlZCAmJiBvcHRpb24uc3ViT3B0aW9uc1wiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzIG9mIG9wdGlvbi5zdWJPcHRpb25zXCI+XHJcbiAgPGxhYmVsXHJcbiAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHNwYWNlLXgtMSBjdXJzb3ItcG9pbnRlclwiXHJcbiAgICAoY2xpY2spPVwic2VsZWN0U3ViT3B0aW9uKG9wdGlvbiwgcylcIlxyXG4gID5cclxuICAgIDxpbnB1dFxyXG4gICAgICB0eXBlPVwicmFkaW9cIlxyXG4gICAgICBbbmFtZV09XCJvcHRpb24udmFsdWVcIlxyXG4gICAgICBbdmFsdWVdPVwicy52YWx1ZVwiXHJcbiAgICAgIFsobmdNb2RlbCldPVwib3B0aW9uLnN1YlNlbGVjdGlvblwiXHJcbiAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7IHN0YW5kYWxvbmU6IHRydWUgfVwiXHJcbiAgICAgIGNsYXNzPVwidGV4dC1ibHVlLTYwMCBjdXJzb3ItcG9pbnRlclwiXHJcbiAgICAvPlxyXG4gICAgPHNwYW4+e3sgcy5sYWJlbCB9fTwvc3Bhbj5cclxuICA8L2xhYmVsPlxyXG48L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgPCEtLSBWYWxpZGF0aW9uIE1lc3NhZ2UgLS0+XHJcbiAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJvcHRpb24uc2VsZWN0ZWQgJiYgb3B0aW9uLnN1Yk9wdGlvbnMgJiYgIW9wdGlvbi5zdWJTZWxlY3Rpb25cIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXJlZC01MDAgdGV4dC14cyBtdC0xIHctZnVsbCBtbC0xXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICBQbGVhc2Ugc2VsZWN0IG9uZSBvcHRpb25cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgICA8ZGl2PlxyXG4gICAgICA8c21hbGwgKm5nSWY9XCJmb3JtLmdldCgnZmluZGluZ3MnKT8udG91Y2hlZCAmJiBmb3JtLmdldCgnZmluZGluZ3MnKT8uZXJyb3JzPy5bJ3JlcXVpcmVkJ11cIlxyXG4gICAgICAgIGNsYXNzPVwidGV4dC1yZWQtNTAwXCI+XHJcbiAgICAgIHt7IHNldHRpbmcoJ2Vycm9yRmluZGluZ01lc3NhZ2UnKSB9fVxyXG4gICAgICA8L3NtYWxsPlxyXG4gICAgPC9kaXY+XHJcbiAgICAgIFxyXG4gICAgPC9mb3JtPlxyXG4gIDwvZGl2PlxyXG48L2Z4LWNvbXBvbmVudD5cclxuIl19
|