fx-form-builder-wrapper 2.0.90 → 2.0.92
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/uploader/uploader.component.mjs +36 -13
- package/fesm2022/fx-form-builder-wrapper.mjs +34 -11
- package/fesm2022/fx-form-builder-wrapper.mjs.map +1 -1
- package/package.json +1 -1
- package/esm2022/lib/components/customize-dropdown/customize-dropdown.component.mjs +0 -317
- package/esm2022/lib/components/multiselect-with-form-fields/customize-dropdown.component.mjs +0 -243
- package/esm2022/lib/components/multiselect-with-form-fields/multiselect-dropdown.component.mjs +0 -166
- package/lib/components/customize-dropdown/customize-dropdown.component.d.ts +0 -60
- package/lib/components/multiselect-with-form-fields/customize-dropdown.component.d.ts +0 -59
- package/lib/components/multiselect-with-form-fields/multiselect-dropdown.component.d.ts +0 -51
package/package.json
CHANGED
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { FormsModule, ReactiveFormsModule } 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
|
-
findingsOptions = [
|
|
25
|
-
{
|
|
26
|
-
label: 'Proclination',
|
|
27
|
-
value: 'proclination',
|
|
28
|
-
info: 'Forward inclination of teeth',
|
|
29
|
-
selected: false,
|
|
30
|
-
subOptions: [
|
|
31
|
-
{ label: 'Mild', value: 'mild' },
|
|
32
|
-
{ label: 'Moderate', value: 'moderate' },
|
|
33
|
-
{ label: 'Severe', value: 'severe' }
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
label: 'Crowding',
|
|
38
|
-
value: 'crowding',
|
|
39
|
-
selected: false,
|
|
40
|
-
subOptions: [
|
|
41
|
-
{ label: 'Mild', value: 'mild' },
|
|
42
|
-
{ label: 'Moderate', value: 'moderate' },
|
|
43
|
-
{ label: 'Severe', value: 'severe' }
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
label: 'Spacing',
|
|
48
|
-
value: 'spacing',
|
|
49
|
-
selected: false,
|
|
50
|
-
subOptions: [
|
|
51
|
-
{ label: 'Mild', value: 'mild' },
|
|
52
|
-
{ label: 'Moderate', value: 'moderate' },
|
|
53
|
-
{ label: 'Severe', value: 'severe' }
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
label: 'Retroclination',
|
|
58
|
-
value: 'retroclination',
|
|
59
|
-
info: 'Backward inclination of teeth',
|
|
60
|
-
selected: false
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
label: 'Rotation',
|
|
64
|
-
value: 'rotation',
|
|
65
|
-
selected: false
|
|
66
|
-
}
|
|
67
|
-
];
|
|
68
|
-
// @HostListener('document:click', ['$event'])
|
|
69
|
-
// onClickOutside(event: MouseEvent) {
|
|
70
|
-
// if (this.dropdownOpen && !this.eRef.nativeElement.contains(event.target)) {
|
|
71
|
-
// this.dropdownOpen = false;
|
|
72
|
-
// this.cdr.detectChanges();
|
|
73
|
-
// }
|
|
74
|
-
// }
|
|
75
|
-
config = {
|
|
76
|
-
displayMode: 'ellipsis',
|
|
77
|
-
placeholderLabel: 'Select Finding'
|
|
78
|
-
};
|
|
79
|
-
constructor(cdr, http, fxBuilderWrapperService, fxApiService, fb, eRef) {
|
|
80
|
-
super(cdr);
|
|
81
|
-
this.cdr = cdr;
|
|
82
|
-
this.http = http;
|
|
83
|
-
this.fxBuilderWrapperService = fxBuilderWrapperService;
|
|
84
|
-
this.fxApiService = fxApiService;
|
|
85
|
-
this.fb = fb;
|
|
86
|
-
this.eRef = eRef;
|
|
87
|
-
this.form = this.fb.group({
|
|
88
|
-
findings: [[]]
|
|
89
|
-
});
|
|
90
|
-
this.onInit.subscribe(() => this._register(this.form));
|
|
91
|
-
}
|
|
92
|
-
ngAfterViewInit() {
|
|
93
|
-
setTimeout(() => {
|
|
94
|
-
const data = [
|
|
95
|
-
{
|
|
96
|
-
label: "Proclination",
|
|
97
|
-
value: "proclination",
|
|
98
|
-
subSelection: {
|
|
99
|
-
label: "Mild",
|
|
100
|
-
value: "mild"
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
label: "Overbite",
|
|
105
|
-
value: "overbite",
|
|
106
|
-
subSelection: {
|
|
107
|
-
label: "Moderate",
|
|
108
|
-
value: "moderate"
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
];
|
|
112
|
-
this.patchExistingValues(data);
|
|
113
|
-
}, 2000);
|
|
114
|
-
}
|
|
115
|
-
ngOnInit() {
|
|
116
|
-
this.fxBuilderWrapperService.variables$
|
|
117
|
-
.pipe(takeUntil(this.destroy$))
|
|
118
|
-
.subscribe((variables) => {
|
|
119
|
-
console.log("Variables");
|
|
120
|
-
});
|
|
121
|
-
const serviceUrl = this.fxApiService.getServiceUrl(this.setting('serviceName'));
|
|
122
|
-
this.getOptions(serviceUrl, this.setting('clinicalNotesURL'));
|
|
123
|
-
}
|
|
124
|
-
getOptions(serviceUrl, url) {
|
|
125
|
-
const finalUrl = serviceUrl + url;
|
|
126
|
-
this.http.get(finalUrl).subscribe({
|
|
127
|
-
next: (response) => {
|
|
128
|
-
// Future API logic here
|
|
129
|
-
},
|
|
130
|
-
error: (err) => console.error('Error fetching options', err)
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
settings() {
|
|
134
|
-
return [
|
|
135
|
-
new FxSelectSetting({ key: 'displayMode', $title: 'Display Mode', value: 'ellipsis' }, [{ option: 'Ellipsis', value: 'ellipsis' }, { option: 'Compact', value: 'compact' }]),
|
|
136
|
-
new FxStringSetting({ key: 'placeholderLabel', $title: 'Placeholder', value: 'Select Options' }),
|
|
137
|
-
];
|
|
138
|
-
}
|
|
139
|
-
validations() {
|
|
140
|
-
return [FxValidatorService.required];
|
|
141
|
-
}
|
|
142
|
-
/** Dropdown Behavior **/
|
|
143
|
-
toggleDropdown() {
|
|
144
|
-
this.dropdownOpen = !this.dropdownOpen;
|
|
145
|
-
}
|
|
146
|
-
toggleOption(option, event) {
|
|
147
|
-
event.stopPropagation();
|
|
148
|
-
// Toggle checkbox value
|
|
149
|
-
option.selected = !option.selected;
|
|
150
|
-
// Reset radios when unchecked
|
|
151
|
-
if (!option.selected) {
|
|
152
|
-
option.subSelection = null;
|
|
153
|
-
option.touched = false;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
option.touched = true;
|
|
157
|
-
}
|
|
158
|
-
// ✅ Force UI refresh so radios appear instantly
|
|
159
|
-
this.cdr.detectChanges();
|
|
160
|
-
// Update reactive form
|
|
161
|
-
this.updateFindings();
|
|
162
|
-
}
|
|
163
|
-
/** Form & Label Helpers **/
|
|
164
|
-
get hasSelectedFindings() {
|
|
165
|
-
return this.findingsOptions.some(f => f.selected);
|
|
166
|
-
}
|
|
167
|
-
get selectedFindingsLabel() {
|
|
168
|
-
const selected = this.findingsOptions
|
|
169
|
-
.filter(f => {
|
|
170
|
-
if (f.selected) {
|
|
171
|
-
// If finding has sub-options → only show if a sub-option is selected
|
|
172
|
-
if (f.subOptions?.length) {
|
|
173
|
-
return !!f.subSelection;
|
|
174
|
-
}
|
|
175
|
-
// If no sub-options → always show
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
return false;
|
|
179
|
-
})
|
|
180
|
-
.map(f => f.label);
|
|
181
|
-
if (selected.length === 0)
|
|
182
|
-
return this.setting('placeholderLabel');
|
|
183
|
-
// Display mode logic (Compact or Ellipsis)
|
|
184
|
-
const maxCount = this.setting('displayMode') === 'compact' ? 2 : 3;
|
|
185
|
-
if (this.setting('displayMode') === 'compact') {
|
|
186
|
-
return selected.length <= maxCount
|
|
187
|
-
? selected.join(', ')
|
|
188
|
-
: `${selected.slice(0, maxCount).join(', ')} +${selected.length - maxCount} more`;
|
|
189
|
-
}
|
|
190
|
-
if (this.setting('displayMode') === 'ellipsis') {
|
|
191
|
-
return selected.length > maxCount
|
|
192
|
-
? `${selected.slice(0, maxCount).join(', ')}, ...`
|
|
193
|
-
: selected.join(', ');
|
|
194
|
-
}
|
|
195
|
-
return selected.join(', ');
|
|
196
|
-
}
|
|
197
|
-
/** Update Findings + Validation **/
|
|
198
|
-
// updateFindings() {
|
|
199
|
-
// const selected = this.findingsOptions
|
|
200
|
-
// .filter(f => {
|
|
201
|
-
// if (f.selected) {
|
|
202
|
-
// // Only include in final form if:
|
|
203
|
-
// // - no subOptions, or
|
|
204
|
-
// // - subOptions with valid subSelection
|
|
205
|
-
// if (f.subOptions?.length) {
|
|
206
|
-
// return !!f.subSelection;
|
|
207
|
-
// }
|
|
208
|
-
// return true;
|
|
209
|
-
// }
|
|
210
|
-
// return false;
|
|
211
|
-
// })
|
|
212
|
-
// .map(f => {
|
|
213
|
-
// const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
214
|
-
// return {
|
|
215
|
-
// label: f.label,
|
|
216
|
-
// value: f.value,
|
|
217
|
-
// subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
218
|
-
// };
|
|
219
|
-
// });
|
|
220
|
-
// // Update reactive form value
|
|
221
|
-
// this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
222
|
-
// // Validation logic remains same
|
|
223
|
-
// const invalidItems = this.findingsOptions.filter(
|
|
224
|
-
// f => f.selected && f.subOptions && !f.subSelection
|
|
225
|
-
// );
|
|
226
|
-
// this.form.get('findings')?.setErrors(
|
|
227
|
-
// invalidItems.length > 0 ? { missingSubSelection: true } : null
|
|
228
|
-
// );
|
|
229
|
-
// }
|
|
230
|
-
updateFindings() {
|
|
231
|
-
// Filter selected options with valid subSelection (if subOptions exist)
|
|
232
|
-
const selected = this.findingsOptions
|
|
233
|
-
.filter(f => {
|
|
234
|
-
if (f.selected) {
|
|
235
|
-
// Only include in final form if:
|
|
236
|
-
// - no subOptions, or
|
|
237
|
-
// - subOptions with valid subSelection
|
|
238
|
-
if (f.subOptions?.length) {
|
|
239
|
-
return !!f.subSelection;
|
|
240
|
-
}
|
|
241
|
-
return true;
|
|
242
|
-
}
|
|
243
|
-
return false;
|
|
244
|
-
})
|
|
245
|
-
.map(f => {
|
|
246
|
-
const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
247
|
-
return {
|
|
248
|
-
label: f.label,
|
|
249
|
-
value: f.value,
|
|
250
|
-
subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
251
|
-
};
|
|
252
|
-
});
|
|
253
|
-
// Update reactive form value
|
|
254
|
-
this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
255
|
-
// Validation logic:
|
|
256
|
-
// Check if there are any selected options with subOptions but without subSelection
|
|
257
|
-
const invalidItems = this.findingsOptions.filter(f => f.selected && f.subOptions && !f.subSelection);
|
|
258
|
-
// If there are any invalid items, mark the form as invalid with a custom error
|
|
259
|
-
if (invalidItems.length > 0) {
|
|
260
|
-
this.form.get('findings')?.setErrors({ missingSubSelection: true });
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
// Clear the error if everything is valid
|
|
264
|
-
this.form.get('findings')?.setErrors(null);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
onSubmit() {
|
|
268
|
-
this.formSubmitted = true;
|
|
269
|
-
if (this.form.invalid) {
|
|
270
|
-
console.warn('⚠️ Please select a sub-option for all selected findings with sub-options.');
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
console.log('✅ Form Value:', this.form.value);
|
|
274
|
-
}
|
|
275
|
-
// patchExistingValues(data: any[]) {
|
|
276
|
-
// this.findingsOptions.forEach(opt => {
|
|
277
|
-
// const match = data.find(x => x.value === opt.value);
|
|
278
|
-
// opt.selected = !!match;
|
|
279
|
-
// opt.subSelection = match?.severity?.value || null;
|
|
280
|
-
// });
|
|
281
|
-
// this.updateFindings();
|
|
282
|
-
// }
|
|
283
|
-
patchExistingValues(data) {
|
|
284
|
-
// Iterate through the findingsOptions and find the corresponding option for each entry in data
|
|
285
|
-
this.findingsOptions.forEach(opt => {
|
|
286
|
-
const match = data.find(x => x.value === opt.value);
|
|
287
|
-
if (match) {
|
|
288
|
-
opt.selected = true;
|
|
289
|
-
opt.subSelection = match.subSelection ? match.subSelection.value : null;
|
|
290
|
-
console.log("Matched Option:", opt);
|
|
291
|
-
console.log("SubSelection Set To:", this.findingsOptions);
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
opt.selected = false;
|
|
295
|
-
opt.subSelection = null;
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
// Manually trigger change detection if needed
|
|
299
|
-
this.cdr.detectChanges();
|
|
300
|
-
this.updateFindings();
|
|
301
|
-
}
|
|
302
|
-
selectSubOption(option, subOption) {
|
|
303
|
-
// Set the subSelection to the clicked value
|
|
304
|
-
option.subSelection = subOption.value;
|
|
305
|
-
// Mark the option as touched, which will help in form validation
|
|
306
|
-
option.touched = true;
|
|
307
|
-
// Update the form state
|
|
308
|
-
this.updateFindings();
|
|
309
|
-
}
|
|
310
|
-
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 });
|
|
311
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CustomizeDropdownComponent, isStandalone: true, selector: "lib-customize-dropdown", 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 <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 </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}\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"] }] });
|
|
312
|
-
}
|
|
313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomizeDropdownComponent, decorators: [{
|
|
314
|
-
type: Component,
|
|
315
|
-
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 <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 </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}\n"] }]
|
|
316
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.HttpClient }, { type: i2.FxBuilderWrapperService }, { type: i3.ApiServiceRegistry }, { type: i4.FormBuilder }, { type: i0.ElementRef }] });
|
|
317
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9taXplLWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Z4LWJ1aWxkZXItd3JhcHBlci9zcmMvbGliL2NvbXBvbmVudHMvY3VzdG9taXplLWRyb3Bkb3duL2N1c3RvbWl6ZS1kcm9wZG93bi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9meC1idWlsZGVyLXdyYXBwZXIvc3JjL2xpYi9jb21wb25lbnRzL2N1c3RvbWl6ZS1kcm9wZG93bi9jdXN0b21pemUtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRS9DLE9BQU8sRUFBb0MsU0FBUyxFQUFvQyxNQUFNLGVBQWUsQ0FBQztBQUM5RyxPQUFPLEVBQTBCLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTFGLE9BQU8sRUFDTCxlQUFlLEVBQ2YsV0FBVyxFQUNYLGVBQWUsRUFFZixlQUFlLEVBRWYsa0JBQWtCLEVBQ25CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7QUE4QjFDLE1BQU0sT0FBTywwQkFBMkIsU0FBUSxlQUFlO0lBa0VuRDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUF0RUYsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7SUFDMUMsSUFBSSxDQUFhO0lBQ2pCLFVBQVUsR0FBVyxFQUFFLENBQUM7SUFDeEIsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUNyQixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBRXRCLGVBQWUsR0FBMkI7UUFDeEM7WUFDRSxLQUFLLEVBQUUsY0FBYztZQUNyQixLQUFLLEVBQUUsY0FBYztZQUNyQixJQUFJLEVB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QUFDLGlCQUFpQixFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM1RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sR0FBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQzFCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILDhDQUE4QztRQUM5QyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXpCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQVcsRUFBRSxTQUFjO1FBQ3pDLDRDQUE0QztRQUM1QyxNQUFNLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDdEMsaUVBQWlFO1FBQ2pFLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQzt3R0F4VVksMEJBQTBCOzRGQUExQiwwQkFBMEIseUdDN0N2QyxrdEhBa0dBLDhrQ0R6RFksWUFBWSwrUEFBRSxtQkFBbUIsZ3JDQUFFLFdBQVcsdVBBQUUsV0FBVzs7NEZBSTFELDBCQUEwQjtrQkFQdEMsU0FBUzsrQkFDRSx3QkFBd0IsY0FDdEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxXQUFXLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQXBpU2VydmljZVJlZ2lzdHJ5IH0gZnJvbSAnQGluc3RhbnRzeXMtbGFicy9jb3JlJztcclxuaW1wb3J0IHtcclxuICBGeEJhc2VDb21wb25lbnQsXHJcbiAgRnhDb21wb25lbnQsXHJcbiAgRnhTZWxlY3RTZXR0aW5nLFxyXG4gIEZ4U2V0dGluZyxcclxuICBGeFN0cmluZ1NldHRpbmcsXHJcbiAgRnhWYWxpZGF0aW9uLFxyXG4gIEZ4VmFsaWRhdG9yU2VydmljZVxyXG59IGZyb20gJ0BpbnN0YW50c3lzLWxhYnMvZngnO1xyXG5pbXBvcnQgeyBGeEJ1aWxkZXJXcmFwcGVyU2VydmljZSB9IGZyb20gJy4uLy4uL2Z4LWJ1aWxkZXItd3JhcHBlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XHJcblxyXG5pbnRlcmZhY2UgU3ViT3B0aW9uIHtcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHZhbHVlOiBzdHJpbmc7XHJcbn1cclxuXHJcbmludGVyZmFjZSBDdXN0b21Ecm9wZG93bk9wdGlvbiB7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICB2YWx1ZTogc3RyaW5nO1xyXG4gIGluZm8/OiBzdHJpbmc7XHJcbiAgc2VsZWN0ZWQ6IGJvb2xlYW47XHJcbiAgc3ViT3B0aW9ucz86IFN1Yk9wdGlvbltdO1xyXG4gIHN1YlNlbGVjdGlvbj86IHN0cmluZyB8IG51bGw7XHJcbiAgZGlzYWJsZWQ/OiBib29sZWFuO1xyXG4gIHRvdWNoZWQ/OiBib29sZWFuO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgQ3VzdG9tRHJvcGRvd25Db25maWcge1xyXG4gIGRpc3BsYXlNb2RlPzogJ2NvbXBhY3QnIHwgJ2VsbGlwc2lzJztcclxuICBwbGFjZWhvbGRlckxhYmVsPzogc3RyaW5nO1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2xpYi1jdXN0b21pemUtZHJvcGRvd24nLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgRm9ybXNNb2R1bGUsIEZ4Q29tcG9uZW50XSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY3VzdG9taXplLWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9jdXN0b21pemUtZHJvcGRvd24uY29tcG9uZW50LmNzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDdXN0b21pemVEcm9wZG93bkNvbXBvbmVudCBleHRlbmRzIEZ4QmFzZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCAsIEFmdGVyVmlld0luaXR7XHJcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XHJcbiAgZm9ybSE6IEZvcm1Hcm91cDtcclxuICBmb3JtT2JqZWN0OiBvYmplY3QgPSB7fTtcclxuICBkcm9wZG93bk9wZW4gPSBmYWxzZTtcclxuICBmb3JtU3VibWl0dGVkID0gZmFsc2U7XHJcblxyXG4gIGZpbmRpbmdzT3B0aW9uczogQ3VzdG9tRHJvcGRvd25PcHRpb25bXSA9IFtcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdQcm9jbGluYXRpb24nLFxyXG4gICAgICB2YWx1ZTogJ3Byb2NsaW5hdGlvbicsXHJcbiAgICAgIGluZm86ICdGb3J3YXJkIGluY2xpbmF0aW9uIG9mIHRlZXRoJyxcclxuICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICBzdWJPcHRpb25zOiBbXHJcbiAgICAgICAgeyBsYWJlbDogJ01pbGQnLCB2YWx1ZTogJ21pbGQnIH0sXHJcbiAgICAgICAgeyBsYWJlbDogJ01vZGVyYXRlJywgdmFsdWU6ICdtb2RlcmF0ZScgfSxcclxuICAgICAgICB7IGxhYmVsOiAnU2V2ZXJlJywgdmFsdWU6ICdzZXZlcmUnIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdDcm93ZGluZycsXHJcbiAgICAgIHZhbHVlOiAnY3Jvd2RpbmcnLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ1NwYWNpbmcnLFxyXG4gICAgICB2YWx1ZTogJ3NwYWNpbmcnLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIHN1Yk9wdGlvbnM6IFtcclxuICAgICAgICB7IGxhYmVsOiAnTWlsZCcsIHZhbHVlOiAnbWlsZCcgfSxcclxuICAgICAgICB7IGxhYmVsOiAnTW9kZXJhdGUnLCB2YWx1ZTogJ21vZGVyYXRlJyB9LFxyXG4gICAgICAgIHsgbGFiZWw6ICdTZXZlcmUnLCB2YWx1ZTogJ3NldmVyZScgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBsYWJlbDogJ1JldHJvY2xpbmF0aW9uJyxcclxuICAgICAgdmFsdWU6ICdyZXRyb2NsaW5hdGlvbicsXHJcbiAgICAgIGluZm86ICdCYWNrd2FyZCBpbmNsaW5hdGlvbiBvZiB0ZWV0aCcsXHJcbiAgICAgIHNlbGVjdGVkOiBmYWxzZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbGFiZWw6ICdSb3RhdGlvbicsXHJcbiAgICAgIHZhbHVlOiAncm90YXRpb24nLFxyXG4gICAgICBzZWxlY3RlZDogZmFsc2VcclxuICAgIH1cclxuICBdO1xyXG5cclxuICAvLyBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgLy8gb25DbGlja091dHNpZGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAvLyAgIGlmICh0aGlzLmRyb3Bkb3duT3BlbiAmJiAhdGhpcy5lUmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KSkge1xyXG4gIC8vICAgICB0aGlzLmRyb3Bkb3duT3BlbiA9IGZhbHNlO1xyXG4gIC8vICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gfVxyXG5cclxuICBjb25maWc6IEN1c3RvbURyb3Bkb3duQ29uZmlnID0ge1xyXG4gICAgZGlzcGxheU1vZGU6ICdlbGxpcHNpcycsXHJcbiAgICBwbGFjZWhvbGRlckxhYmVsOiAnU2VsZWN0IEZpbmRpbmcnXHJcbiAgfTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXHJcbiAgICBwcml2YXRlIGZ4QnVpbGRlcldyYXBwZXJTZXJ2aWNlOiBGeEJ1aWxkZXJXcmFwcGVyU2VydmljZSxcclxuICAgIHByaXZhdGUgZnhBcGlTZXJ2aWNlOiBBcGlTZXJ2aWNlUmVnaXN0cnksXHJcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcclxuICAgIHByaXZhdGUgZVJlZjogRWxlbWVudFJlZlxyXG4gICkge1xyXG4gICAgc3VwZXIoY2RyKTtcclxuICAgIHRoaXMuZm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xyXG4gICAgICBmaW5kaW5nczogW1tdXVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLm9uSW5pdC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcmVnaXN0ZXIodGhpcy5mb3JtKSk7XHJcbiAgfVxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHNldFRpbWVvdXQoKCk9PntcclxuICAgICAgY29uc3QgZGF0YSA9IFtcclxuICB7XHJcbiAgICBsYWJlbDogXCJQcm9jbGluYXRpb25cIixcclxuICAgIHZhbHVlOiBcInByb2NsaW5hdGlvblwiLFxyXG4gICAgc3ViU2VsZWN0aW9uOiB7XHJcbiAgICAgIGxhYmVsOiBcIk1pbGRcIixcclxuICAgICAgdmFsdWU6IFwibWlsZFwiXHJcbiAgICB9XHJcbiAgfSxcclxuICB7XHJcbiAgICBsYWJlbDogXCJPdmVyYml0ZVwiLFxyXG4gICAgdmFsdWU6IFwib3ZlcmJpdGVcIixcclxuICAgIHN1YlNlbGVjdGlvbjoge1xyXG4gICAgICBsYWJlbDogXCJNb2RlcmF0ZVwiLFxyXG4gICAgICB2YWx1ZTogXCJtb2RlcmF0ZVwiXHJcbiAgICB9XHJcbiAgfVxyXG5dO1xyXG50aGlzLnBhdGNoRXhpc3RpbmdWYWx1ZXMoZGF0YSk7XHJcbiAgICB9LDIwMDApO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZ4QnVpbGRlcldyYXBwZXJTZXJ2aWNlLnZhcmlhYmxlcyRcclxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxyXG4gICAgICAuc3Vic2NyaWJlKCh2YXJpYWJsZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKFwiVmFyaWFibGVzXCIsKVxyXG4gICAgICB9KTtcclxuICAgIGNvbnN0IHNlcnZpY2VVcmwgPSB0aGlzLmZ4QXBpU2VydmljZS5nZXRTZXJ2aWNlVXJsKHRoaXMuc2V0dGluZygnc2VydmljZU5hbWUnKSk7XHJcbiAgICB0aGlzLmdldE9wdGlvbnMoc2VydmljZVVybCwgdGhpcy5zZXR0aW5nKCdjbGluaWNhbE5vdGVzVVJMJykpO1xyXG4gIH1cclxuXHJcbiAgZ2V0T3B0aW9ucyhzZXJ2aWNlVXJsOiBzdHJpbmcsIHVybDogc3RyaW5nKSB7XHJcbiAgICBjb25zdCBmaW5hbFVybCA9IHNlcnZpY2VVcmwgKyB1cmw7XHJcbiAgICB0aGlzLmh0dHAuZ2V0PGFueVtdPihmaW5hbFVybCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICAvLyBGdXR1cmUgQVBJIGxvZ2ljIGhlcmVcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGZldGNoaW5nIG9wdGlvbnMnLCBlcnIpXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBzZXR0aW5ncygpOiBGeFNldHRpbmdbXSB7XHJcbiAgICByZXR1cm4gW1xyXG4gICAgICBuZXcgRnhTZWxlY3RTZXR0aW5nKHsga2V5OiAnZGlzcGxheU1vZGUnLCAkdGl0bGU6ICdEaXNwbGF5IE1vZGUnLCB2YWx1ZTogJ2VsbGlwc2lzJyB9LCBbeyBvcHRpb246ICdFbGxpcHNpcycsIHZhbHVlOiAnZWxsaXBzaXMnIH0sIHsgb3B0aW9uOiAnQ29tcGFjdCcsIHZhbHVlOiAnY29tcGFjdCcgfV0pLFxyXG4gICAgICBuZXcgRnhTdHJpbmdTZXR0aW5nKHsga2V5OiAncGxhY2Vob2xkZXJMYWJlbCcsICR0aXRsZTogJ1BsYWNlaG9sZGVyJywgdmFsdWU6ICdTZWxlY3QgT3B0aW9ucycgfSksXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIHZhbGlkYXRpb25zKCk6IEZ4VmFsaWRhdGlvbltdIHtcclxuICAgIHJldHVybiBbRnhWYWxpZGF0b3JTZXJ2aWNlLnJlcXVpcmVkXTtcclxuICB9XHJcblxyXG4gIC8qKiBEcm9wZG93biBCZWhhdmlvciAqKi9cclxuICB0b2dnbGVEcm9wZG93bigpIHtcclxuICAgIHRoaXMuZHJvcGRvd25PcGVuID0gIXRoaXMuZHJvcGRvd25PcGVuO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlT3B0aW9uKG9wdGlvbjogQ3VzdG9tRHJvcGRvd25PcHRpb24sIGV2ZW50OiBFdmVudCkge1xyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgLy8gVG9nZ2xlIGNoZWNrYm94IHZhbHVlXHJcbiAgICBvcHRpb24uc2VsZWN0ZWQgPSAhb3B0aW9uLnNlbGVjdGVkO1xyXG5cclxuICAgIC8vIFJlc2V0IHJhZGlvcyB3aGVuIHVuY2hlY2tlZFxyXG4gICAgaWYgKCFvcHRpb24uc2VsZWN0ZWQpIHtcclxuICAgICAgb3B0aW9uLnN1YlNlbGVjdGlvbiA9IG51bGw7XHJcbiAgICAgIG9wdGlvbi50b3VjaGVkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZXtcclxuICAgICAgb3B0aW9uLnRvdWNoZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOKchSBGb3JjZSBVSSByZWZyZXNoIHNvIHJhZGlvcyBhcHBlYXIgaW5zdGFudGx5XHJcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgLy8gVXBkYXRlIHJlYWN0aXZlIGZvcm1cclxuICAgIHRoaXMudXBkYXRlRmluZGluZ3MoKTtcclxuICB9XHJcblxyXG4gIC8qKiBGb3JtICYgTGFiZWwgSGVscGVycyAqKi9cclxuICBnZXQgaGFzU2VsZWN0ZWRGaW5kaW5ncygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbmRpbmdzT3B0aW9ucy5zb21lKGYgPT4gZi5zZWxlY3RlZCk7XHJcbiAgfVxyXG5cclxuICBnZXQgc2VsZWN0ZWRGaW5kaW5nc0xhYmVsKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuZmluZGluZ3NPcHRpb25zXHJcbiAgICAgIC5maWx0ZXIoZiA9PiB7XHJcbiAgICAgICAgaWYgKGYuc2VsZWN0ZWQpIHtcclxuICAgICAgICAgIC8vIElmIGZpbmRpbmcgaGFzIHN1Yi1vcHRpb25zIOKGkiBvbmx5IHNob3cgaWYgYSBzdWItb3B0aW9uIGlzIHNlbGVjdGVkXHJcbiAgICAgICAgICBpZiAoZi5zdWJPcHRpb25zPy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuICEhZi5zdWJTZWxlY3Rpb247XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvLyBJZiBubyBzdWItb3B0aW9ucyDihpIgYWx3YXlzIHNob3dcclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5tYXAoZiA9PiBmLmxhYmVsKTtcclxuXHJcbiAgICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5zZXR0aW5nKCdwbGFjZWhvbGRlckxhYmVsJyk7XHJcblxyXG4gICAgLy8gRGlzcGxheSBtb2RlIGxvZ2ljIChDb21wYWN0IG9yIEVsbGlwc2lzKVxyXG4gICAgY29uc3QgbWF4Q291bnQgPSB0aGlzLnNldHRpbmcoJ2Rpc3BsYXlNb2RlJykgPT09ICdjb21wYWN0JyA/IDIgOiAzO1xyXG4gICAgaWYgKHRoaXMuc2V0dGluZygnZGlzcGxheU1vZGUnKSA9PT0gJ2NvbXBhY3QnKSB7XHJcbiAgICAgIHJldHVybiBzZWxlY3RlZC5sZW5ndGggPD0gbWF4Q291bnRcclxuICAgICAgICA/IHNlbGVjdGVkLmpvaW4oJywgJylcclxuICAgICAgICA6IGAke3NlbGVjdGVkLnNsaWNlKDAsIG1heENvdW50KS5qb2luKCcsICcpfSArJHtzZWxlY3RlZC5sZW5ndGggLSBtYXhDb3VudH0gbW9yZWA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc2V0dGluZygnZGlzcGxheU1vZGUnKSA9PT0gJ2VsbGlwc2lzJykge1xyXG4gICAgICByZXR1cm4gc2VsZWN0ZWQubGVuZ3RoID4gbWF4Q291bnRcclxuICAgICAgICA/IGAke3NlbGVjdGVkLnNsaWNlKDAsIG1heENvdW50KS5qb2luKCcsICcpfSwgLi4uYFxyXG4gICAgICAgIDogc2VsZWN0ZWQuam9pbignLCAnKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc2VsZWN0ZWQuam9pbignLCAnKTtcclxuICB9XHJcblxyXG4gIC8qKiBVcGRhdGUgRmluZGluZ3MgKyBWYWxpZGF0aW9uICoqL1xyXG4gIC8vIHVwZGF0ZUZpbmRpbmdzKCkge1xyXG4gIC8vICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLmZpbmRpbmdzT3B0aW9uc1xyXG4gIC8vICAgICAuZmlsdGVyKGYgPT4ge1xyXG4gIC8vICAgICAgIGlmIChmLnNlbGVjdGVkKSB7XHJcbiAgLy8gICAgICAgICAvLyBPbmx5IGluY2x1ZGUgaW4gZmluYWwgZm9ybSBpZjpcclxuICAvLyAgICAgICAgIC8vICAtIG5vIHN1Yk9wdGlvbnMsIG9yXHJcbiAgLy8gICAgICAgICAvLyAgLSBzdWJPcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uXHJcbiAgLy8gICAgICAgICBpZiAoZi5zdWJPcHRpb25zPy5sZW5ndGgpIHtcclxuICAvLyAgICAgICAgICAgcmV0dXJuICEhZi5zdWJTZWxlY3Rpb247XHJcbiAgLy8gICAgICAgICB9XHJcbiAgLy8gICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAvLyAgICAgICB9XHJcbiAgLy8gICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gIC8vICAgICB9KVxyXG4gIC8vICAgICAubWFwKGYgPT4ge1xyXG4gIC8vICAgICAgIGNvbnN0IHN1YiA9IGYuc3ViT3B0aW9ucz8uZmluZChzID0+IHMudmFsdWUgPT09IGYuc3ViU2VsZWN0aW9uKSB8fCBudWxsO1xyXG4gIC8vICAgICAgIHJldHVybiB7XHJcbiAgLy8gICAgICAgICBsYWJlbDogZi5sYWJlbCxcclxuICAvLyAgICAgICAgIHZhbHVlOiBmLnZhbHVlLFxyXG4gIC8vICAgICAgICAgc3ViU2VsZWN0aW9uOiBzdWIgPyB7IGxhYmVsOiBzdWIubGFiZWwsIHZhbHVlOiBzdWIudmFsdWUgfSA6IG51bGxcclxuICAvLyAgICAgICB9O1xyXG4gIC8vICAgICB9KTtcclxuXHJcbiAgLy8gICAvLyBVcGRhdGUgcmVhY3RpdmUgZm9ybSB2YWx1ZVxyXG4gIC8vICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBmaW5kaW5nczogc2VsZWN0ZWQgfSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG5cclxuICAvLyAgIC8vIFZhbGlkYXRpb24gbG9naWMgcmVtYWlucyBzYW1lXHJcbiAgLy8gICBjb25zdCBpbnZhbGlkSXRlbXMgPSB0aGlzLmZpbmRpbmdzT3B0aW9ucy5maWx0ZXIoXHJcbiAgLy8gICAgIGYgPT4gZi5zZWxlY3RlZCAmJiBmLnN1Yk9wdGlvbnMgJiYgIWYuc3ViU2VsZWN0aW9uXHJcbiAgLy8gICApO1xyXG4gIC8vICAgdGhpcy5mb3JtLmdldCgnZmluZGluZ3MnKT8uc2V0RXJyb3JzKFxyXG4gIC8vICAgICBpbnZhbGlkSXRlbXMubGVuZ3RoID4gMCA/IHsgbWlzc2luZ1N1YlNlbGVjdGlvbjogdHJ1ZSB9IDogbnVsbFxyXG4gIC8vICAgKTtcclxuICAvLyB9XHJcblxyXG4gIHVwZGF0ZUZpbmRpbmdzKCkge1xyXG4gIC8vIEZpbHRlciBzZWxlY3RlZCBvcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uIChpZiBzdWJPcHRpb25zIGV4aXN0KVxyXG4gIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5maW5kaW5nc09wdGlvbnNcclxuICAgIC5maWx0ZXIoZiA9PiB7XHJcbiAgICAgIGlmIChmLnNlbGVjdGVkKSB7XHJcbiAgICAgICAgLy8gT25seSBpbmNsdWRlIGluIGZpbmFsIGZvcm0gaWY6XHJcbiAgICAgICAgLy8gIC0gbm8gc3ViT3B0aW9ucywgb3JcclxuICAgICAgICAvLyAgLSBzdWJPcHRpb25zIHdpdGggdmFsaWQgc3ViU2VsZWN0aW9uXHJcbiAgICAgICAgaWYgKGYuc3ViT3B0aW9ucz8ubGVuZ3RoKSB7XHJcbiAgICAgICAgICByZXR1cm4gISFmLnN1YlNlbGVjdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSlcclxuICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgIGNvbnN0IHN1YiA9IGYuc3ViT3B0aW9ucz8uZmluZChzID0+IHMudmFsdWUgPT09IGYuc3ViU2VsZWN0aW9uKSB8fCBudWxsO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxhYmVsOiBmLmxhYmVsLFxyXG4gICAgICAgIHZhbHVlOiBmLnZhbHVlLFxyXG4gICAgICAgIHN1YlNlbGVjdGlvbjogc3ViID8geyBsYWJlbDogc3ViLmxhYmVsLCB2YWx1ZTogc3ViLnZhbHVlIH0gOiBudWxsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuXHJcbiAgLy8gVXBkYXRlIHJlYWN0aXZlIGZvcm0gdmFsdWVcclxuICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7IGZpbmRpbmdzOiBzZWxlY3RlZCB9LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcblxyXG4gIC8vIFZhbGlkYXRpb24gbG9naWM6XHJcbiAgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSBzZWxlY3RlZCBvcHRpb25zIHdpdGggc3ViT3B0aW9ucyBidXQgd2l0aG91dCBzdWJTZWxlY3Rpb25cclxuICBjb25zdCBpbnZhbGlkSXRlbXMgPSB0aGlzLmZpbmRpbmdzT3B0aW9ucy5maWx0ZXIoXHJcbiAgICBmID0+IGYuc2VsZWN0ZWQgJiYgZi5zdWJPcHRpb25zICYmICFmLnN1YlNlbGVjdGlvblxyXG4gICk7XHJcblxyXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgaW52YWxpZCBpdGVtcywgbWFyayB0aGUgZm9ybSBhcyBpbnZhbGlkIHdpdGggYSBjdXN0b20gZXJyb3JcclxuICBpZiAoaW52YWxpZEl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgIHRoaXMuZm9ybS5nZXQoJ2ZpbmRpbmdzJyk/LnNldEVycm9ycyh7IG1pc3NpbmdTdWJTZWxlY3Rpb246IHRydWUgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIENsZWFyIHRoZSBlcnJvciBpZiBldmVyeXRoaW5nIGlzIHZhbGlkXHJcbiAgICB0aGlzLmZvcm0uZ2V0KCdmaW5kaW5ncycpPy5zZXRFcnJvcnMobnVsbCk7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuICBvblN1Ym1pdCgpIHtcclxuICAgIHRoaXMuZm9ybVN1Ym1pdHRlZCA9IHRydWU7XHJcbiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKCfimqDvuI8gUGxlYXNlIHNlbGVjdCBhIHN1Yi1vcHRpb24gZm9yIGFsbCBzZWxlY3RlZCBmaW5kaW5ncyB3aXRoIHN1Yi1vcHRpb25zLicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZygn4pyFIEZvcm0gVmFsdWU6JywgdGhpcy5mb3JtLnZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8vIHBhdGNoRXhpc3RpbmdWYWx1ZXMoZGF0YTogYW55W10pIHtcclxuICAvLyAgIHRoaXMuZmluZGluZ3NPcHRpb25zLmZvckVhY2gob3B0ID0+IHtcclxuICAvLyAgICAgY29uc3QgbWF0Y2ggPSBkYXRhLmZpbmQoeCA9PiB4LnZhbHVlID09PSBvcHQudmFsdWUpO1xyXG4gIC8vICAgICBvcHQuc2VsZWN0ZWQgPSAhIW1hdGNoO1xyXG4gIC8vICAgICBvcHQuc3ViU2VsZWN0aW9uID0gbWF0Y2g/LnNldmVyaXR5Py52YWx1ZSB8fCBudWxsO1xyXG4gIC8vICAgfSk7XHJcbiAgLy8gICB0aGlzLnVwZGF0ZUZpbmRpbmdzKCk7XHJcbiAgLy8gfVxyXG5cclxucGF0Y2hFeGlzdGluZ1ZhbHVlcyhkYXRhOiBhbnlbXSkge1xyXG4gIC8vIEl0ZXJhdGUgdGhyb3VnaCB0aGUgZmluZGluZ3NPcHRpb25zIGFuZCBmaW5kIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbiBmb3IgZWFjaCBlbnRyeSBpbiBkYXRhXHJcbiAgdGhpcy5maW5kaW5nc09wdGlvbnMuZm9yRWFjaChvcHQgPT4ge1xyXG4gICAgY29uc3QgbWF0Y2ggPSBkYXRhLmZpbmQoeCA9PiB4LnZhbHVlID09PSBvcHQudmFsdWUpO1xyXG4gICAgXHJcbiAgICBpZiAobWF0Y2gpIHtcclxuICAgICAgb3B0LnNlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgb3B0LnN1YlNlbGVjdGlvbiA9IG1hdGNoLnN1YlNlbGVjdGlvbiA/IG1hdGNoLnN1YlNlbGVjdGlvbi52YWx1ZSA6IG51bGw7XHJcblxyXG4gICAgICBjb25zb2xlLmxvZyhcIk1hdGNoZWQgT3B0aW9uOlwiLCBvcHQpO1xyXG4gICAgICBjb25zb2xlLmxvZyhcIlN1YlNlbGVjdGlvbiBTZXQgVG86XCIsIHRoaXMuZmluZGluZ3NPcHRpb25zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG9wdC5zZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgICBvcHQuc3ViU2VsZWN0aW9uID0gbnVsbDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gTWFudWFsbHkgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIGlmIG5lZWRlZFxyXG4gIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICBcclxuICB0aGlzLnVwZGF0ZUZpbmRpbmdzKCk7XHJcbn1cclxuXHJcbnNlbGVjdFN1Yk9wdGlvbihvcHRpb246IGFueSwgc3ViT3B0aW9uOiBhbnkpIHtcclxuICAvLyBTZXQgdGhlIHN1YlNlbGVjdGlvbiB0byB0aGUgY2xpY2tlZCB2YWx1ZVxyXG4gIG9wdGlvbi5zdWJTZWxlY3Rpb24gPSBzdWJPcHRpb24udmFsdWU7XHJcbiAgLy8gTWFyayB0aGUgb3B0aW9uIGFzIHRvdWNoZWQsIHdoaWNoIHdpbGwgaGVscCBpbiBmb3JtIHZhbGlkYXRpb25cclxuICBvcHRpb24udG91Y2hlZCA9IHRydWU7XHJcbiAgLy8gVXBkYXRlIHRoZSBmb3JtIHN0YXRlXHJcbiAgdGhpcy51cGRhdGVGaW5kaW5ncygpO1xyXG59XHJcblxyXG59XHJcbiIsIjxmeC1jb21wb25lbnQgW2Z4RGF0YV09XCJmeERhdGFcIiAjZnhDb21wb25lbnQ+XHJcbiAgPGRpdiBjbGFzcz1cImNvbnRhaW5lclwiPlxyXG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIiBjbGFzcz1cInJlbGF0aXZlXCI+XHJcbiAgICAgIDwhLS0gSGVhZGVyIC0tPlxyXG4gICAgICA8ZGl2ICNkcm9wZG93bldyYXBwZXIgY2xhc3M9XCJyZWxhdGl2ZSB3LTgwXCI+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBjbGFzcz1cInctZnVsbCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWQgcHgtMyBweS0yIGZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlciBiZy13aGl0ZSB0ZXh0LWdyYXktNzAwIGhvdmVyOmJvcmRlci1ibHVlLTQwMFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRHJvcGRvd24oKVwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJoYXNTZWxlY3RlZEZpbmRpbmdzOyBlbHNlIHBsYWNlaG9sZGVyXCI+XHJcbiAgICAgICAgICAgIHt7IHNlbGVjdGVkRmluZGluZ3NMYWJlbCB9fVxyXG4gICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNwbGFjZWhvbGRlcj5cclxuICAgICAgICAgICAge3sgc2V0dGluZygncGxhY2Vob2xkZXJMYWJlbCcpIH19XHJcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgPHN2Z1xyXG4gICAgICAgICAgICBjbGFzcz1cInctNSBoLTUgbWwtMiB0ZXh0LWdyYXktNTAwIHRyYW5zZm9ybSB0cmFuc2l0aW9uLXRyYW5zZm9ybSBkdXJhdGlvbi0yMDBcIlxyXG4gICAgICAgICAgICBbY2xhc3Mucm90YXRlLTE4MF09XCJkcm9wZG93bk9wZW5cIlxyXG4gICAgICAgICAgICBmaWxsPVwibm9uZVwiXHJcbiAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiXHJcbiAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8cGF0aCBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBzdHJva2Utd2lkdGg9XCIyXCIgZD1cIk0xOSA5bC03IDctNy03XCIgLz5cclxuICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG5cclxuICAgICAgICA8IS0tIFBhbmVsIC0tPlxyXG4gICAgICAgIDxkaXZcclxuICAgICAgICAgICpuZ0lmPVwiZHJvcGRvd25PcGVuXCJcclxuICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgbXQtMSB3LWZ1bGwgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIHNoYWRvdy1sZyBtYXgtaC02NCBvdmVyZmxvdy15LWF1dG8gei0xMFwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIGZpbmRpbmdzT3B0aW9uc1wiXHJcbiAgICAgICAgICAgIGNsYXNzPVwiYm9yZGVyLWIgYm9yZGVyLWdyYXktMTAwIGxhc3Q6Ym9yZGVyLW5vbmUgcC0yIGhvdmVyOmJnLWdyYXktNTAgY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPCEtLSBDaGVja2JveCArIExhYmVsIC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTJcIj5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInctNCBoLTQgdGV4dC1ibHVlLTUwMCBib3JkZXItZ3JheS0zMDAgcm91bmRlZCBjdXJzb3ItcG9pbnRlclwiXHJcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm9wdGlvbi5zZWxlY3RlZFwiXHJcbiAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU9wdGlvbihvcHRpb24sICRldmVudClcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgPGxhYmVsXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtZ3JheS04MDAgZm9udC1tZWRpdW0gY3Vyc29yLXBvaW50ZXIgc2VsZWN0LW5vbmVcIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU9wdGlvbihvcHRpb24sICRldmVudClcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5sYWJlbCB9fVxyXG4gICAgICAgICAgICAgIDwvbGFiZWw+XHJcblxyXG4gICAgICAgICAgICAgIDxzcGFuXHJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm9wdGlvbi5pbmZvXCJcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtYXV0byB0ZXh0LWJsdWUtNTAwIHRleHQtc20gY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBvcHRpb24uaW5mbyB9fVwiXHJcbiAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAg4pOYXHJcbiAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gUmFkaW9zIC0tPlxyXG4gICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBmbGV4LXdyYXAgZ2FwLTQgbWwtNiBtdC0yIHRleHQtc21cIlxyXG4gICAgICAgICAgICAgICpuZ0lmPVwib3B0aW9uLnNlbGVjdGVkICYmIG9wdGlvbi5zdWJPcHRpb25zXCJcclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHMgb2Ygb3B0aW9uLnN1Yk9wdGlvbnNcIj5cclxuICA8bGFiZWxcclxuICAgIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgc3BhY2UteC0xIGN1cnNvci1wb2ludGVyXCJcclxuICAgIChjbGljayk9XCJzZWxlY3RTdWJPcHRpb24ob3B0aW9uLCBzKVwiXHJcbiAgPlxyXG4gICAgPGlucHV0XHJcbiAgICAgIHR5cGU9XCJyYWRpb1wiXHJcbiAgICAgIFtuYW1lXT1cIm9wdGlvbi52YWx1ZVwiXHJcbiAgICAgIFt2YWx1ZV09XCJzLnZhbHVlXCJcclxuICAgICAgWyhuZ01vZGVsKV09XCJvcHRpb24uc3ViU2VsZWN0aW9uXCJcclxuICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcclxuICAgICAgY2xhc3M9XCJ0ZXh0LWJsdWUtNjAwIGN1cnNvci1wb2ludGVyXCJcclxuICAgIC8+XHJcbiAgICA8c3Bhbj57eyBzLmxhYmVsIH19PC9zcGFuPlxyXG4gIDwvbGFiZWw+XHJcbjwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICA8IS0tIFZhbGlkYXRpb24gTWVzc2FnZSAtLT5cclxuICAgICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm9wdGlvbi5zZWxlY3RlZCAmJiBvcHRpb24uc3ViT3B0aW9ucyAmJiAhb3B0aW9uLnN1YlNlbGVjdGlvblwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtcmVkLTUwMCB0ZXh0LXhzIG10LTEgdy1mdWxsIG1sLTFcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIFBsZWFzZSBzZWxlY3Qgb25lIG9wdGlvblxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZm9ybT5cclxuICA8L2Rpdj5cclxuPC9meC1jb21wb25lbnQ+XHJcbiJdfQ==
|