bways-report 0.1.6 → 0.1.8
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/README.md +293 -464
- package/esm2022/lib/core/config/bways-report-config.mjs +83 -0
- package/esm2022/lib/core/index.mjs +2 -1
- package/esm2022/lib/core/models/report-definition.model.mjs +1 -1
- package/esm2022/lib/core/services/report-data-discovery.service.mjs +6 -3
- package/esm2022/lib/core/services/report-session-context.service.mjs +11 -7
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
- package/esm2022/lib/core/utils/data-normalization.util.mjs +87 -1
- package/esm2022/lib/core/utils/report-parameter.util.mjs +119 -3
- package/esm2022/lib/data-access/adapters/endpoint-datasource.adapter.mjs +69 -0
- package/esm2022/lib/data-access/adapters/endpoint-lookup.adapter.mjs +98 -0
- package/esm2022/lib/data-access/adapters/endpoint-masterdata.adapter.mjs +57 -0
- package/esm2022/lib/data-access/adapters/endpoint-persistence.adapter.mjs +85 -0
- package/esm2022/lib/data-access/adapters/endpoint-schema-discovery.adapter.mjs +163 -0
- package/esm2022/lib/data-access/adapters/endpoint-tokens.mjs +12 -0
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +4 -23
- package/esm2022/lib/data-access/adapters/index.mjs +8 -1
- package/esm2022/lib/data-access/contracts/lookup.contract.mjs +1 -1
- package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +12 -2
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +5 -5
- package/esm2022/lib/features/designer/components/dialogs/report-saved-dialog.component.mjs +407 -0
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +109 -60
- package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +3 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +110 -20
- package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +3 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +60 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +11 -5
- package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +3 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +15 -3
- package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +204 -10
- package/esm2022/lib/features/designer/designer.component.mjs +276 -21
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +9 -2
- package/esm2022/lib/features/embed/bways-report-builder.component.mjs +207 -0
- package/esm2022/lib/features/embed/bways-report-menu.component.mjs +433 -0
- package/esm2022/lib/features/embed/bways-report-page.component.mjs +204 -0
- package/esm2022/lib/features/embed/index.mjs +5 -0
- package/esm2022/lib/features/embed/inject-report-menu.mjs +99 -0
- package/esm2022/lib/features/index.mjs +2 -1
- package/esm2022/lib/features/persistence/services/report-store.service.mjs +43 -5
- package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +4 -4
- package/esm2022/lib/features/routing/index.mjs +2 -2
- package/esm2022/lib/features/routing/models/report-route.models.mjs +1 -1
- package/esm2022/lib/features/routing/report-routes.mjs +42 -1
- package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +6 -8
- package/esm2022/lib/features/routing/services/report-menu.service.mjs +14 -4
- package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +22 -3
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +16 -2
- package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +28 -5
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +86 -19
- package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +8 -1
- package/esm2022/lib/primitives/components/index.mjs +2 -1
- package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +9 -3
- package/esm2022/lib/primitives/components/searchable-select/rpt-searchable-select.component.mjs +386 -0
- package/esm2022/lib/provide-reporting.mjs +137 -7
- package/fesm2022/bways-report.mjs +4286 -859
- package/fesm2022/bways-report.mjs.map +1 -1
- package/lib/core/config/bways-report-config.d.ts +161 -0
- package/lib/core/index.d.ts +1 -0
- package/lib/core/models/report-definition.model.d.ts +16 -0
- package/lib/core/services/report-session-context.service.d.ts +1 -0
- package/lib/core/tokens/reporting-config.token.d.ts +16 -0
- package/lib/core/utils/data-normalization.util.d.ts +10 -0
- package/lib/core/utils/report-parameter.util.d.ts +18 -1
- package/lib/data-access/adapters/endpoint-datasource.adapter.d.ts +13 -0
- package/lib/data-access/adapters/endpoint-lookup.adapter.d.ts +14 -0
- package/lib/data-access/adapters/endpoint-masterdata.adapter.d.ts +11 -0
- package/lib/data-access/adapters/endpoint-persistence.adapter.d.ts +15 -0
- package/lib/data-access/adapters/endpoint-schema-discovery.adapter.d.ts +21 -0
- package/lib/data-access/adapters/endpoint-tokens.d.ts +21 -0
- package/lib/data-access/adapters/index.d.ts +7 -0
- package/lib/data-access/contracts/lookup.contract.d.ts +2 -2
- package/lib/features/designer/components/component-palette/component-palette.component.d.ts +1 -0
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +1 -1
- package/lib/features/designer/components/dialogs/report-saved-dialog.component.d.ts +34 -0
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +1 -0
- package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +12 -2
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +10 -0
- package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +13 -1
- package/lib/features/designer/designer.component.d.ts +15 -0
- package/lib/features/embed/bways-report-builder.component.d.ts +48 -0
- package/lib/features/embed/bways-report-menu.component.d.ts +40 -0
- package/lib/features/embed/bways-report-page.component.d.ts +61 -0
- package/lib/features/embed/index.d.ts +4 -0
- package/lib/features/embed/inject-report-menu.d.ts +44 -0
- package/lib/features/index.d.ts +1 -0
- package/lib/features/persistence/services/report-store.service.d.ts +5 -0
- package/lib/features/routing/index.d.ts +1 -1
- package/lib/features/routing/models/report-route.models.d.ts +3 -0
- package/lib/features/routing/report-routes.d.ts +40 -0
- package/lib/features/routing/resolvers/report.resolver.d.ts +1 -1
- package/lib/features/runtime/dynamic-renderer.component.d.ts +1 -0
- package/lib/features/runtime/report-grid-bridge.component.d.ts +1 -1
- package/lib/primitives/components/button/rpt-button.component.d.ts +3 -0
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +16 -3
- package/lib/primitives/components/index.d.ts +2 -0
- package/lib/primitives/components/searchable-select/rpt-searchable-select.component.d.ts +89 -0
- package/lib/provide-reporting.d.ts +22 -6
- package/package.json +1 -1
package/esm2022/lib/primitives/components/searchable-select/rpt-searchable-select.component.mjs
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, forwardRef, HostListener, computed, effect, inject, input, output, signal, untracked, viewChild, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
4
|
+
import { Overlay, OverlayModule, } from '@angular/cdk/overlay';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/cdk/overlay";
|
|
7
|
+
export class RptSearchableSelectComponent {
|
|
8
|
+
elementRef;
|
|
9
|
+
overlay = inject(Overlay);
|
|
10
|
+
panelId = 'rpt-select-panel-' + Math.random().toString(36).substring(2, 9);
|
|
11
|
+
scrollStrategy = this.overlay.scrollStrategies.reposition();
|
|
12
|
+
triggerWidth = signal('auto');
|
|
13
|
+
overlayPositions = [
|
|
14
|
+
{
|
|
15
|
+
originX: 'start',
|
|
16
|
+
originY: 'bottom',
|
|
17
|
+
overlayX: 'start',
|
|
18
|
+
overlayY: 'top',
|
|
19
|
+
offsetY: 4,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
originX: 'start',
|
|
23
|
+
originY: 'top',
|
|
24
|
+
overlayX: 'start',
|
|
25
|
+
overlayY: 'bottom',
|
|
26
|
+
offsetY: -4,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
originX: 'end',
|
|
30
|
+
originY: 'bottom',
|
|
31
|
+
overlayX: 'end',
|
|
32
|
+
overlayY: 'top',
|
|
33
|
+
offsetY: 4,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
originX: 'end',
|
|
37
|
+
originY: 'top',
|
|
38
|
+
overlayX: 'end',
|
|
39
|
+
overlayY: 'bottom',
|
|
40
|
+
offsetY: -4,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
constructor(elementRef) {
|
|
44
|
+
this.elementRef = elementRef;
|
|
45
|
+
// Sync input value() if explicitly provided
|
|
46
|
+
effect(() => {
|
|
47
|
+
const v = this.value();
|
|
48
|
+
if (v !== undefined) {
|
|
49
|
+
untracked(() => this.internalValue.set(v));
|
|
50
|
+
}
|
|
51
|
+
}, { allowSignalWrites: true });
|
|
52
|
+
}
|
|
53
|
+
// --- Inputs ---
|
|
54
|
+
options = input([]);
|
|
55
|
+
value = input(undefined);
|
|
56
|
+
placeholder = input('-- Select --');
|
|
57
|
+
searchPlaceholder = input('Search...');
|
|
58
|
+
disabled = input(false);
|
|
59
|
+
loading = input(false);
|
|
60
|
+
loadingText = input('Loading...');
|
|
61
|
+
emptyText = input('No matching options found');
|
|
62
|
+
clearable = input(true);
|
|
63
|
+
searchable = input(true);
|
|
64
|
+
size = input('sm');
|
|
65
|
+
id = input('');
|
|
66
|
+
ariaLabel = input('');
|
|
67
|
+
valueKey = input('value');
|
|
68
|
+
labelKey = input('label');
|
|
69
|
+
sublabelKey = input('sublabel');
|
|
70
|
+
badgeKey = input('badge');
|
|
71
|
+
panelMaxHeight = input('240px');
|
|
72
|
+
openAbove = input(undefined);
|
|
73
|
+
// --- Outputs ---
|
|
74
|
+
valueChange = output();
|
|
75
|
+
selectionChange = output();
|
|
76
|
+
opened = output();
|
|
77
|
+
closed = output();
|
|
78
|
+
// --- View Children ---
|
|
79
|
+
triggerBtnEl = viewChild('triggerBtn');
|
|
80
|
+
searchInputEl = viewChild('searchInput');
|
|
81
|
+
optionsListEl = viewChild('optionsList');
|
|
82
|
+
// --- Internal State Signals ---
|
|
83
|
+
internalValue = signal('');
|
|
84
|
+
isOpen = signal(false);
|
|
85
|
+
opensAbove = signal(false);
|
|
86
|
+
searchTerm = signal('');
|
|
87
|
+
focusedIndex = signal(-1);
|
|
88
|
+
cvaDisabled = signal(false);
|
|
89
|
+
// --- ControlValueAccessor Callbacks ---
|
|
90
|
+
onChange = () => { };
|
|
91
|
+
onTouched = () => { };
|
|
92
|
+
isDisabled = computed(() => this.disabled() || this.cvaDisabled());
|
|
93
|
+
// Normalized options
|
|
94
|
+
normalizedOptions = computed(() => {
|
|
95
|
+
const raw = this.options();
|
|
96
|
+
if (!Array.isArray(raw))
|
|
97
|
+
return [];
|
|
98
|
+
const vKey = this.valueKey();
|
|
99
|
+
const lKey = this.labelKey();
|
|
100
|
+
const subKey = this.sublabelKey();
|
|
101
|
+
const bKey = this.badgeKey();
|
|
102
|
+
return raw
|
|
103
|
+
.filter((item) => item !== null && item !== undefined)
|
|
104
|
+
.map((item) => {
|
|
105
|
+
if (typeof item === 'string' || typeof item === 'number') {
|
|
106
|
+
return {
|
|
107
|
+
value: item,
|
|
108
|
+
label: String(item),
|
|
109
|
+
data: item,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const value = item[vKey] ?? item['value'] ?? item['key'] ?? item['id'] ?? item['name'] ?? '';
|
|
113
|
+
const label = item[lKey] ?? item['label'] ?? item['displayName'] ?? item['name'] ?? String(value);
|
|
114
|
+
const sublabel = item[subKey] ?? item['sublabel'] ?? item['schema'] ?? item['category'] ?? item['dataType'];
|
|
115
|
+
const badge = item[bKey] ?? item['badge'] ?? item['type'];
|
|
116
|
+
const disabled = !!item['disabled'];
|
|
117
|
+
return {
|
|
118
|
+
value,
|
|
119
|
+
label: String(label),
|
|
120
|
+
sublabel: sublabel ? String(sublabel) : undefined,
|
|
121
|
+
badge: badge ? String(badge) : undefined,
|
|
122
|
+
disabled,
|
|
123
|
+
group: item['group'] ? String(item['group']) : undefined,
|
|
124
|
+
data: item['data'] ?? item,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
// Filtered options with responsive search
|
|
129
|
+
filteredOptions = computed(() => {
|
|
130
|
+
const all = this.normalizedOptions();
|
|
131
|
+
const term = this.searchTerm().trim().toLowerCase();
|
|
132
|
+
if (!term)
|
|
133
|
+
return all;
|
|
134
|
+
return all.filter((opt) => {
|
|
135
|
+
const matchLabel = opt.label.toLowerCase().includes(term);
|
|
136
|
+
const matchVal = String(opt.value).toLowerCase().includes(term);
|
|
137
|
+
const matchSub = opt.sublabel?.toLowerCase().includes(term);
|
|
138
|
+
const matchBadge = opt.badge?.toLowerCase().includes(term);
|
|
139
|
+
return matchLabel || matchVal || matchSub || matchBadge;
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
// Incremental rendering for smooth performance with thousands of SPs/tables (3000+)
|
|
143
|
+
MAX_VISIBLE_OPTIONS = 150;
|
|
144
|
+
INITIAL_VISIBLE_OPTIONS = 150;
|
|
145
|
+
renderedLimit = signal(150);
|
|
146
|
+
visibleFilteredOptions = computed(() => {
|
|
147
|
+
const filtered = this.filteredOptions();
|
|
148
|
+
const limit = this.renderedLimit();
|
|
149
|
+
if (filtered.length <= limit)
|
|
150
|
+
return filtered;
|
|
151
|
+
return filtered.slice(0, limit);
|
|
152
|
+
});
|
|
153
|
+
excessCount = computed(() => {
|
|
154
|
+
return Math.max(0, this.filteredOptions().length - this.renderedLimit());
|
|
155
|
+
});
|
|
156
|
+
onOptionsScroll(event) {
|
|
157
|
+
const el = event.target;
|
|
158
|
+
if (!el)
|
|
159
|
+
return;
|
|
160
|
+
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 120) {
|
|
161
|
+
this.loadMore();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
loadMore() {
|
|
165
|
+
const total = this.filteredOptions().length;
|
|
166
|
+
const current = this.renderedLimit();
|
|
167
|
+
if (current < total) {
|
|
168
|
+
this.renderedLimit.update((c) => Math.min(total, c + 150));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
loadAll() {
|
|
172
|
+
this.renderedLimit.set(this.filteredOptions().length);
|
|
173
|
+
}
|
|
174
|
+
selectedOption = computed(() => {
|
|
175
|
+
const cur = this.internalValue();
|
|
176
|
+
if (cur === null || cur === undefined || cur === '')
|
|
177
|
+
return undefined;
|
|
178
|
+
const strCur = String(cur);
|
|
179
|
+
return this.normalizedOptions().find((opt) => String(opt.value) === strCur);
|
|
180
|
+
});
|
|
181
|
+
// --- ControlValueAccessor Implementation ---
|
|
182
|
+
writeValue(obj) {
|
|
183
|
+
this.internalValue.set(obj ?? '');
|
|
184
|
+
}
|
|
185
|
+
registerOnChange(fn) {
|
|
186
|
+
this.onChange = fn;
|
|
187
|
+
}
|
|
188
|
+
registerOnTouched(fn) {
|
|
189
|
+
this.onTouched = fn;
|
|
190
|
+
}
|
|
191
|
+
setDisabledState(isDisabled) {
|
|
192
|
+
this.cvaDisabled.set(isDisabled);
|
|
193
|
+
}
|
|
194
|
+
// --- Interaction Methods ---
|
|
195
|
+
toggle(event) {
|
|
196
|
+
if (event) {
|
|
197
|
+
event.stopPropagation();
|
|
198
|
+
}
|
|
199
|
+
if (this.isDisabled())
|
|
200
|
+
return;
|
|
201
|
+
if (this.isOpen()) {
|
|
202
|
+
this.close();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this.open();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
open() {
|
|
209
|
+
if (this.isDisabled() || this.isOpen())
|
|
210
|
+
return;
|
|
211
|
+
const rect = this.elementRef.nativeElement.getBoundingClientRect();
|
|
212
|
+
if (rect.width > 0) {
|
|
213
|
+
this.triggerWidth.set(rect.width);
|
|
214
|
+
}
|
|
215
|
+
const manualPreference = this.openAbove();
|
|
216
|
+
if (manualPreference !== undefined) {
|
|
217
|
+
this.opensAbove.set(manualPreference);
|
|
218
|
+
}
|
|
219
|
+
this.isOpen.set(true);
|
|
220
|
+
this.searchTerm.set('');
|
|
221
|
+
this.renderedLimit.set(this.INITIAL_VISIBLE_OPTIONS);
|
|
222
|
+
this.focusedIndex.set(-1);
|
|
223
|
+
this.opened.emit();
|
|
224
|
+
}
|
|
225
|
+
onPositionChange(change) {
|
|
226
|
+
this.opensAbove.set(change.connectionPair.originY === 'top');
|
|
227
|
+
}
|
|
228
|
+
onOverlayAttached() {
|
|
229
|
+
setTimeout(() => {
|
|
230
|
+
this.searchInputEl()?.nativeElement.focus();
|
|
231
|
+
}, 25);
|
|
232
|
+
}
|
|
233
|
+
close() {
|
|
234
|
+
if (!this.isOpen())
|
|
235
|
+
return;
|
|
236
|
+
this.isOpen.set(false);
|
|
237
|
+
this.focusedIndex.set(-1);
|
|
238
|
+
this.onTouched();
|
|
239
|
+
this.closed.emit();
|
|
240
|
+
}
|
|
241
|
+
selectOption(opt) {
|
|
242
|
+
if (opt.disabled)
|
|
243
|
+
return;
|
|
244
|
+
this.internalValue.set(opt.value);
|
|
245
|
+
this.onChange(opt.value);
|
|
246
|
+
this.valueChange.emit(opt.value);
|
|
247
|
+
this.selectionChange.emit(opt);
|
|
248
|
+
this.close();
|
|
249
|
+
this.triggerBtnEl()?.nativeElement.focus();
|
|
250
|
+
}
|
|
251
|
+
clearSelection(event) {
|
|
252
|
+
event.stopPropagation();
|
|
253
|
+
event.preventDefault();
|
|
254
|
+
this.internalValue.set('');
|
|
255
|
+
this.onChange('');
|
|
256
|
+
this.valueChange.emit('');
|
|
257
|
+
this.searchTerm.set('');
|
|
258
|
+
this.renderedLimit.set(this.INITIAL_VISIBLE_OPTIONS);
|
|
259
|
+
this.focusedIndex.set(-1);
|
|
260
|
+
}
|
|
261
|
+
clearSearch(event) {
|
|
262
|
+
event.stopPropagation();
|
|
263
|
+
this.searchTerm.set('');
|
|
264
|
+
this.renderedLimit.set(this.INITIAL_VISIBLE_OPTIONS);
|
|
265
|
+
this.focusedIndex.set(-1);
|
|
266
|
+
this.searchInputEl()?.nativeElement.focus();
|
|
267
|
+
}
|
|
268
|
+
onSearchInput(event) {
|
|
269
|
+
const val = event.target.value;
|
|
270
|
+
this.searchTerm.set(val);
|
|
271
|
+
this.renderedLimit.set(this.INITIAL_VISIBLE_OPTIONS);
|
|
272
|
+
this.focusedIndex.set(0);
|
|
273
|
+
}
|
|
274
|
+
onTriggerKeydown(event) {
|
|
275
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
|
|
276
|
+
event.preventDefault();
|
|
277
|
+
this.open();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
onSearchKeydown(event) {
|
|
281
|
+
const visible = this.visibleFilteredOptions();
|
|
282
|
+
const count = visible.length;
|
|
283
|
+
switch (event.key) {
|
|
284
|
+
case 'ArrowDown': {
|
|
285
|
+
event.preventDefault();
|
|
286
|
+
if (count > 0) {
|
|
287
|
+
const next = (this.focusedIndex() + 1) % count;
|
|
288
|
+
this.focusedIndex.set(next);
|
|
289
|
+
this.scrollFocusedIntoView();
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
case 'ArrowUp': {
|
|
294
|
+
event.preventDefault();
|
|
295
|
+
if (count > 0) {
|
|
296
|
+
const prev = this.focusedIndex() <= 0 ? count - 1 : this.focusedIndex() - 1;
|
|
297
|
+
this.focusedIndex.set(prev);
|
|
298
|
+
this.scrollFocusedIntoView();
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'Enter': {
|
|
303
|
+
event.preventDefault();
|
|
304
|
+
const idx = this.focusedIndex();
|
|
305
|
+
if (idx >= 0 && idx < count) {
|
|
306
|
+
this.selectOption(visible[idx]);
|
|
307
|
+
}
|
|
308
|
+
else if (count === 1) {
|
|
309
|
+
this.selectOption(visible[0]);
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
case 'Escape': {
|
|
314
|
+
event.preventDefault();
|
|
315
|
+
this.close();
|
|
316
|
+
this.triggerBtnEl()?.nativeElement.focus();
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
case 'Tab': {
|
|
320
|
+
this.close();
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
scrollFocusedIntoView() {
|
|
326
|
+
const listEl = this.optionsListEl()?.nativeElement;
|
|
327
|
+
if (!listEl)
|
|
328
|
+
return;
|
|
329
|
+
const items = listEl.querySelectorAll('.select-option-item');
|
|
330
|
+
const idx = this.focusedIndex();
|
|
331
|
+
if (items && items[idx]) {
|
|
332
|
+
items[idx].scrollIntoView({ block: 'nearest' });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
isSelected(opt) {
|
|
336
|
+
const cur = this.internalValue();
|
|
337
|
+
if (cur === null || cur === undefined || cur === '')
|
|
338
|
+
return false;
|
|
339
|
+
return String(cur) === String(opt.value);
|
|
340
|
+
}
|
|
341
|
+
onDocumentClick(event) {
|
|
342
|
+
if (!this.isOpen())
|
|
343
|
+
return;
|
|
344
|
+
const target = event.target;
|
|
345
|
+
if (!this.elementRef.nativeElement.contains(target)) {
|
|
346
|
+
this.close();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
onEscape() {
|
|
350
|
+
if (this.isOpen()) {
|
|
351
|
+
this.close();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptSearchableSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
355
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RptSearchableSelectComponent, isStandalone: true, selector: "rpt-searchable-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, sublabelKey: { classPropertyName: "sublabelKey", publicName: "sublabelKey", isSignal: true, isRequired: false, transformFunction: null }, badgeKey: { classPropertyName: "badgeKey", publicName: "badgeKey", isSignal: true, isRequired: false, transformFunction: null }, panelMaxHeight: { classPropertyName: "panelMaxHeight", publicName: "panelMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, openAbove: { classPropertyName: "openAbove", publicName: "openAbove", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange", opened: "opened", closed: "closed" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" }, properties: { "class.is-open": "isOpen()", "class.opens-above": "opensAbove()", "class.is-disabled": "isDisabled()", "class.size-sm": "size() === \"sm\"", "class.size-md": "size() === \"md\"", "class.size-lg": "size() === \"lg\"" } }, providers: [
|
|
356
|
+
{
|
|
357
|
+
provide: NG_VALUE_ACCESSOR,
|
|
358
|
+
useExisting: forwardRef(() => RptSearchableSelectComponent),
|
|
359
|
+
multi: true,
|
|
360
|
+
},
|
|
361
|
+
], viewQueries: [{ propertyName: "triggerBtnEl", first: true, predicate: ["triggerBtn"], descendants: true, isSignal: true }, { propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "optionsListEl", first: true, predicate: ["optionsList"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"rpt-search-select-wrapper\" #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <!-- Trigger Button -->\n <button\n #triggerBtn\n type=\"button\"\n class=\"select-trigger\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [class.is-open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-label]=\"ariaLabel() || placeholder()\"\n (click)=\"toggle($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <div class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n @if (selectedOption()) {\n <span class=\"selected-text\">{{ selectedOption()!.label }}</span>\n @if (selectedOption()!.sublabel) {\n <span class=\"selected-sublabel\">{{ selectedOption()!.sublabel }}</span>\n }\n @if (selectedOption()!.badge) {\n <span class=\"selected-badge\">{{ selectedOption()!.badge }}</span>\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n </div>\n\n <div class=\"trigger-actions\">\n @if (loading()) {\n <span class=\"spinner-dot\" title=\"Loading options...\"></span>\n }\n\n @if (selectedOption() && clearable() && !isDisabled()) {\n <button\n type=\"button\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n >\n \u2715\n </button>\n }\n\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\">\n <path d=\"M1 1L5 5L9 1\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n</div>\n\n<!-- Dropdown Popover Panel in CDK Overlay (attached to body, outside any clipped card) -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayWidth]=\"triggerWidth()\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"8\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttached()\"\n (detach)=\"close()\"\n>\n <div\n class=\"select-panel\"\n [id]=\"panelId\"\n [class.opens-above]=\"opensAbove()\"\n [style.max-height]=\"panelMaxHeight()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Search Input Box -->\n @if (searchable()) {\n <div class=\"select-search-box\">\n <span class=\"search-icon\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchTerm()\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"search-clear-btn\"\n title=\"Clear search\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n }\n\n <!-- Options List -->\n <div class=\"select-options-list\" #optionsList (scroll)=\"onOptionsScroll($event)\">\n @if (loading()) {\n <div class=\"select-status-row loading\">\n <span class=\"spinner-dot\"></span>\n <span>{{ loadingText() }}</span>\n </div>\n } @else if (normalizedOptions().length === 0) {\n <div class=\"select-status-row empty\">\n <span>{{ emptyText() }}</span>\n </div>\n } @else if (visibleFilteredOptions().length === 0) {\n <div class=\"select-status-row empty\">\n <span>No options match \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.value; let i = $index) {\n <div\n role=\"option\"\n class=\"select-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [class.is-disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <div class=\"option-content\">\n <span class=\"option-label\" [title]=\"opt.label\">{{ opt.label }}</span>\n @if (opt.sublabel) {\n <span class=\"option-sublabel\" [title]=\"opt.sublabel\">{{ opt.sublabel }}</span>\n }\n </div>\n\n <div class=\"option-meta\">\n @if (opt.badge) {\n <span class=\"option-badge\">{{ opt.badge }}</span>\n }\n @if (isSelected(opt)) {\n <span class=\"option-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n </div>\n }\n\n @if (excessCount() > 0) {\n <div class=\"select-excess-hint\">\n <span class=\"excess-text\">Showing {{ visibleFilteredOptions().length }} of {{ filteredOptions().length }} matches. Scroll down to browse or</span>\n <button\n type=\"button\"\n class=\"select-load-all-btn\"\n (click)=\"loadAll(); $event.stopPropagation();\"\n >\n Load all {{ filteredOptions().length }}\n </button>\n </div>\n }\n }\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;width:100%;position:relative;box-sizing:border-box}.rpt-search-select-wrapper{position:relative;width:100%;box-sizing:border-box}:host(.size-sm) .select-trigger{min-height:28px;padding:4px 8px;font-size:var(--rpt-font-size-sm, .75rem)}:host(.size-md) .select-trigger{min-height:36px;padding:6px 10px;font-size:var(--rpt-font-size-base, .8125rem)}:host(.size-lg) .select-trigger{min-height:42px;padding:8px 12px;font-size:var(--rpt-font-size-base, .875rem)}.select-trigger{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);color:var(--rpt-color-text, #0f172a);font-family:inherit;outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.select-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.select-trigger:focus-visible,.select-trigger.is-open{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb33}.select-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #94a3b8);border-color:var(--rpt-color-border, #e2e8f0);cursor:not-allowed}.trigger-label{flex:1;min-width:0;display:flex;align-items:center;gap:6px;overflow:hidden}.selected-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;color:var(--rpt-color-text, #0f172a)}.selected-sublabel{font-size:.675rem;color:var(--rpt-color-text-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.selected-badge{font-size:.6rem;font-weight:600;padding:1px 4px;border-radius:3px;background-color:#e2e8f0;color:#475569;text-transform:uppercase;letter-spacing:.03em;flex-shrink:0}.placeholder-text{color:var(--rpt-color-text-muted, #94a3b8);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trigger-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}.trigger-clear-btn{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;border:none;font-size:.55rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;padding:0;line-height:1;transition:background-color .12s ease,color .12s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.select-panel{width:100%;min-width:180px;max-width:100vw;box-sizing:border-box;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #00000024,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:select-pop .12s cubic-bezier(0,0,.2,1)}.select-panel.opens-above{box-shadow:0 -10px 25px -5px #00000024,0 -8px 10px -6px #00000014;animation:select-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes select-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes select-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.select-search-box{display:flex;align-items:center;gap:6px;padding:6px 8px;background-color:#f8fafc;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .75rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.search-input::placeholder{color:#94a3b8}.search-clear-btn{border:none;background:#e2e8f0;color:#64748b;width:14px;height:14px;border-radius:50%;font-size:.5rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:background-color .12s}.search-clear-btn:hover{background:#cbd5e1;color:#0f172a}.select-options-list{overflow-y:auto;overscroll-behavior:contain;padding:3px}.select-option-item{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;border-radius:4px;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.select-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.select-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.select-option-item.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.option-content{display:flex;flex-direction:column;min-width:0;flex:1}.option-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.35}.option-sublabel{font-size:.65rem;color:var(--rpt-color-text-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.option-meta{display:flex;align-items:center;gap:6px;flex-shrink:0}.option-badge{font-size:.6rem;font-weight:600;padding:1px 4px;border-radius:3px;background-color:#e2e8f0;color:#475569;text-transform:uppercase;letter-spacing:.03em}.select-option-item.is-selected .option-badge{background-color:#dbeafe;color:#1e40af}.option-check{font-size:.75rem;font-weight:700;color:var(--rpt-color-primary, #2563eb)}.select-status-row{padding:10px 12px;font-size:.72rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.select-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:var(--rpt-color-primary, #2563eb)}.select-status-row.empty{color:var(--rpt-color-text-muted, #94a3b8)}.select-excess-hint{font-size:.6875rem;color:var(--rpt-color-text-secondary, #475569);display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;background-color:#f8fafc;border-top:1px dashed var(--rpt-color-border, #cbd5e1);margin-top:2px;position:sticky;bottom:0;z-index:2;box-shadow:0 -2px 6px #0000000a}.excess-text{flex:1;line-height:1.25}.select-load-all-btn{background:#eff6ff;border:1px solid #bfdbfe;color:#2563eb;font-size:.6875rem;font-weight:600;padding:3px 8px;border-radius:4px;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:all .12s ease}.select-load-all-btn:hover{background:#2563eb;color:#fff;border-color:#2563eb}.spinner-dot{display:inline-block;width:11px;height:11px;border:2px solid #bfdbfe;border-top-color:var(--rpt-color-primary, #2563eb);border-radius:50%;animation:select-spin .6s linear infinite}@keyframes select-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
362
|
+
}
|
|
363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptSearchableSelectComponent, decorators: [{
|
|
364
|
+
type: Component,
|
|
365
|
+
args: [{ selector: 'rpt-searchable-select', standalone: true, imports: [CommonModule, FormsModule, OverlayModule], providers: [
|
|
366
|
+
{
|
|
367
|
+
provide: NG_VALUE_ACCESSOR,
|
|
368
|
+
useExisting: forwardRef(() => RptSearchableSelectComponent),
|
|
369
|
+
multi: true,
|
|
370
|
+
},
|
|
371
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
372
|
+
'[class.is-open]': 'isOpen()',
|
|
373
|
+
'[class.opens-above]': 'opensAbove()',
|
|
374
|
+
'[class.is-disabled]': 'isDisabled()',
|
|
375
|
+
'[class.size-sm]': 'size() === "sm"',
|
|
376
|
+
'[class.size-md]': 'size() === "md"',
|
|
377
|
+
'[class.size-lg]': 'size() === "lg"',
|
|
378
|
+
}, template: "<div class=\"rpt-search-select-wrapper\" #origin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <!-- Trigger Button -->\n <button\n #triggerBtn\n type=\"button\"\n class=\"select-trigger\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [class.is-open]=\"isOpen()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-label]=\"ariaLabel() || placeholder()\"\n (click)=\"toggle($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <div class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n @if (selectedOption()) {\n <span class=\"selected-text\">{{ selectedOption()!.label }}</span>\n @if (selectedOption()!.sublabel) {\n <span class=\"selected-sublabel\">{{ selectedOption()!.sublabel }}</span>\n }\n @if (selectedOption()!.badge) {\n <span class=\"selected-badge\">{{ selectedOption()!.badge }}</span>\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n </div>\n\n <div class=\"trigger-actions\">\n @if (loading()) {\n <span class=\"spinner-dot\" title=\"Loading options...\"></span>\n }\n\n @if (selectedOption() && clearable() && !isDisabled()) {\n <button\n type=\"button\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n >\n \u2715\n </button>\n }\n\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\">\n <path d=\"M1 1L5 5L9 1\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n</div>\n\n<!-- Dropdown Popover Panel in CDK Overlay (attached to body, outside any clipped card) -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayWidth]=\"triggerWidth()\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"8\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttached()\"\n (detach)=\"close()\"\n>\n <div\n class=\"select-panel\"\n [id]=\"panelId\"\n [class.opens-above]=\"opensAbove()\"\n [style.max-height]=\"panelMaxHeight()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Search Input Box -->\n @if (searchable()) {\n <div class=\"select-search-box\">\n <span class=\"search-icon\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n [placeholder]=\"searchPlaceholder()\"\n [value]=\"searchTerm()\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"search-clear-btn\"\n title=\"Clear search\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n }\n\n <!-- Options List -->\n <div class=\"select-options-list\" #optionsList (scroll)=\"onOptionsScroll($event)\">\n @if (loading()) {\n <div class=\"select-status-row loading\">\n <span class=\"spinner-dot\"></span>\n <span>{{ loadingText() }}</span>\n </div>\n } @else if (normalizedOptions().length === 0) {\n <div class=\"select-status-row empty\">\n <span>{{ emptyText() }}</span>\n </div>\n } @else if (visibleFilteredOptions().length === 0) {\n <div class=\"select-status-row empty\">\n <span>No options match \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.value; let i = $index) {\n <div\n role=\"option\"\n class=\"select-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [class.is-disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <div class=\"option-content\">\n <span class=\"option-label\" [title]=\"opt.label\">{{ opt.label }}</span>\n @if (opt.sublabel) {\n <span class=\"option-sublabel\" [title]=\"opt.sublabel\">{{ opt.sublabel }}</span>\n }\n </div>\n\n <div class=\"option-meta\">\n @if (opt.badge) {\n <span class=\"option-badge\">{{ opt.badge }}</span>\n }\n @if (isSelected(opt)) {\n <span class=\"option-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n </div>\n }\n\n @if (excessCount() > 0) {\n <div class=\"select-excess-hint\">\n <span class=\"excess-text\">Showing {{ visibleFilteredOptions().length }} of {{ filteredOptions().length }} matches. Scroll down to browse or</span>\n <button\n type=\"button\"\n class=\"select-load-all-btn\"\n (click)=\"loadAll(); $event.stopPropagation();\"\n >\n Load all {{ filteredOptions().length }}\n </button>\n </div>\n }\n }\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;width:100%;position:relative;box-sizing:border-box}.rpt-search-select-wrapper{position:relative;width:100%;box-sizing:border-box}:host(.size-sm) .select-trigger{min-height:28px;padding:4px 8px;font-size:var(--rpt-font-size-sm, .75rem)}:host(.size-md) .select-trigger{min-height:36px;padding:6px 10px;font-size:var(--rpt-font-size-base, .8125rem)}:host(.size-lg) .select-trigger{min-height:42px;padding:8px 12px;font-size:var(--rpt-font-size-base, .875rem)}.select-trigger{width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:6px;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);color:var(--rpt-color-text, #0f172a);font-family:inherit;outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.select-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.select-trigger:focus-visible,.select-trigger.is-open{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb33}.select-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #94a3b8);border-color:var(--rpt-color-border, #e2e8f0);cursor:not-allowed}.trigger-label{flex:1;min-width:0;display:flex;align-items:center;gap:6px;overflow:hidden}.selected-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;color:var(--rpt-color-text, #0f172a)}.selected-sublabel{font-size:.675rem;color:var(--rpt-color-text-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.selected-badge{font-size:.6rem;font-weight:600;padding:1px 4px;border-radius:3px;background-color:#e2e8f0;color:#475569;text-transform:uppercase;letter-spacing:.03em;flex-shrink:0}.placeholder-text{color:var(--rpt-color-text-muted, #94a3b8);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trigger-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}.trigger-clear-btn{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;border:none;font-size:.55rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;padding:0;line-height:1;transition:background-color .12s ease,color .12s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.select-panel{width:100%;min-width:180px;max-width:100vw;box-sizing:border-box;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #00000024,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:select-pop .12s cubic-bezier(0,0,.2,1)}.select-panel.opens-above{box-shadow:0 -10px 25px -5px #00000024,0 -8px 10px -6px #00000014;animation:select-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes select-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes select-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.select-search-box{display:flex;align-items:center;gap:6px;padding:6px 8px;background-color:#f8fafc;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .75rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.search-input::placeholder{color:#94a3b8}.search-clear-btn{border:none;background:#e2e8f0;color:#64748b;width:14px;height:14px;border-radius:50%;font-size:.5rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:background-color .12s}.search-clear-btn:hover{background:#cbd5e1;color:#0f172a}.select-options-list{overflow-y:auto;overscroll-behavior:contain;padding:3px}.select-option-item{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;border-radius:4px;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.select-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.select-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.select-option-item.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.option-content{display:flex;flex-direction:column;min-width:0;flex:1}.option-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.35}.option-sublabel{font-size:.65rem;color:var(--rpt-color-text-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.option-meta{display:flex;align-items:center;gap:6px;flex-shrink:0}.option-badge{font-size:.6rem;font-weight:600;padding:1px 4px;border-radius:3px;background-color:#e2e8f0;color:#475569;text-transform:uppercase;letter-spacing:.03em}.select-option-item.is-selected .option-badge{background-color:#dbeafe;color:#1e40af}.option-check{font-size:.75rem;font-weight:700;color:var(--rpt-color-primary, #2563eb)}.select-status-row{padding:10px 12px;font-size:.72rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.select-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:var(--rpt-color-primary, #2563eb)}.select-status-row.empty{color:var(--rpt-color-text-muted, #94a3b8)}.select-excess-hint{font-size:.6875rem;color:var(--rpt-color-text-secondary, #475569);display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;background-color:#f8fafc;border-top:1px dashed var(--rpt-color-border, #cbd5e1);margin-top:2px;position:sticky;bottom:0;z-index:2;box-shadow:0 -2px 6px #0000000a}.excess-text{flex:1;line-height:1.25}.select-load-all-btn{background:#eff6ff;border:1px solid #bfdbfe;color:#2563eb;font-size:.6875rem;font-weight:600;padding:3px 8px;border-radius:4px;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:all .12s ease}.select-load-all-btn:hover{background:#2563eb;color:#fff;border-color:#2563eb}.spinner-dot{display:inline-block;width:11px;height:11px;border:2px solid #bfdbfe;border-top-color:var(--rpt-color-primary, #2563eb);border-radius:50%;animation:select-spin .6s linear infinite}@keyframes select-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
379
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onDocumentClick: [{
|
|
380
|
+
type: HostListener,
|
|
381
|
+
args: ['document:click', ['$event']]
|
|
382
|
+
}], onEscape: [{
|
|
383
|
+
type: HostListener,
|
|
384
|
+
args: ['document:keydown.escape']
|
|
385
|
+
}] } });
|
|
386
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnB0LXNlYXJjaGFibGUtc2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9zZWFyY2hhYmxlLXNlbGVjdC9ycHQtc2VhcmNoYWJsZS1zZWxlY3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvcHJpbWl0aXZlcy9jb21wb25lbnRzL3NlYXJjaGFibGUtc2VsZWN0L3JwdC1zZWFyY2hhYmxlLXNlbGVjdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUdMLE9BQU8sRUFDUCxhQUFhLEdBRWQsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBbUM5QixNQUFNLE9BQU8sNEJBQTRCO0lBQ3RCLFVBQVUsQ0FBMEI7SUFDcEMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUVsQyxPQUFPLEdBQUcsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzNFLGNBQWMsR0FBbUIsSUFBSSxDQUFDLE9BQU8s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QixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVUxQyxRQUFRO3NCQURQLFlBQVk7dUJBQUMseUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgZm9yd2FyZFJlZixcbiAgSG9zdExpc3RlbmVyLFxuICBjb21wdXRlZCxcbiAgZWZmZWN0LFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxuICB2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiwgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBDb25uZWN0ZWRQb3NpdGlvbixcbiAgQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uQ2hhbmdlLFxuICBPdmVybGF5LFxuICBPdmVybGF5TW9kdWxlLFxuICBTY3JvbGxTdHJhdGVneSxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNlYXJjaGFibGVTZWxlY3RPcHRpb248VCA9IGFueT4ge1xuICB2YWx1ZTogVDtcbiAgbGFiZWw6IHN0cmluZztcbiAgc3VibGFiZWw/OiBzdHJpbmc7XG4gIGJhZGdlPzogc3RyaW5nO1xuICBkaXNhYmxlZD86IGJvb2xlYW47XG4gIGdyb3VwPzogc3RyaW5nO1xuICBkYXRhPzogYW55O1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtc2VhcmNoYWJsZS1zZWxlY3QnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgT3ZlcmxheU1vZHVsZV0sXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gUnB0U2VhcmNoYWJsZVNlbGVjdENvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vcnB0LXNlYXJjaGFibGUtc2VsZWN0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3JwdC1zZWFyY2hhYmxlLXNlbGVjdC5jb21wb25lbnQuY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLmlzLW9wZW5dJzogJ2lzT3BlbigpJyxcbiAgICAnW2NsYXNzLm9wZW5zLWFib3ZlXSc6ICdvcGVuc0Fib3ZlKCknLFxuICAgICdbY2xhc3MuaXMtZGlzYWJsZWRdJzogJ2lzRGlzYWJsZWQoKScsXG4gICAgJ1tjbGFzcy5zaXplLXNtXSc6ICdzaXplKCkgPT09IFwic21cIicsXG4gICAgJ1tjbGFzcy5zaXplLW1kXSc6ICdzaXplKCkgPT09IFwibWRcIicsXG4gICAgJ1tjbGFzcy5zaXplLWxnXSc6ICdzaXplKCkgPT09IFwibGdcIicsXG4gIH0sXG59KVxuZXhwb3J0IGNsYXNzIFJwdFNlYXJjaGFibGVTZWxlY3RDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIHByaXZhdGUgcmVhZG9ubHkgb3ZlcmxheSA9IGluamVjdChPdmVybGF5KTtcblxuICByZWFkb25seSBwYW5lbElkID0gJ3JwdC1zZWxlY3QtcGFuZWwtJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCA5KTtcbiAgcmVhZG9ubHkgc2Nyb2xsU3RyYXRlZ3k6IFNjcm9sbFN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpO1xuICByZWFkb25seSB0cmlnZ2VyV2lkdGggPSBzaWduYWw8bnVtYmVyIHwgc3RyaW5nPignYXV0bycpO1xuXG4gIHJlYWRvbmx5IG92ZXJsYXlQb3NpdGlvbnM6IENvbm5lY3RlZFBvc2l0aW9uW10gPSBbXG4gICAge1xuICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICBvdmVybGF5WTogJ3RvcCcsXG4gICAgICBvZmZzZXRZOiA0LFxuICAgIH0sXG4gICAge1xuICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgIG9yaWdpblk6ICd0b3AnLFxuICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICBvdmVybGF5WTogJ2JvdHRvbScsXG4gICAgICBvZmZzZXRZOiAtNCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG9yaWdpblg6ICdlbmQnLFxuICAgICAgb3JpZ2luWTogJ2JvdHRvbScsXG4gICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICBvdmVybGF5WTogJ3RvcCcsXG4gICAgICBvZmZzZXRZOiA0LFxuICAgIH0sXG4gICAge1xuICAgICAgb3JpZ2luWDogJ2VuZCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIG92ZXJsYXlYOiAnZW5kJyxcbiAgICAgIG92ZXJsYXlZOiAnYm90dG9tJyxcbiAgICAgIG9mZnNldFk6IC00LFxuICAgIH0sXG4gIF07XG5cbiAgY29uc3RydWN0b3IoZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4pIHtcbiAgICB0aGlzLmVsZW1lbnRSZWYgPSBlbGVtZW50UmVmO1xuXG4gICAgLy8gU3luYyBpbnB1dCB2YWx1ZSgpIGlmIGV4cGxpY2l0bHkgcHJvdmlkZWRcbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHYgPSB0aGlzLnZhbHVlKCk7XG4gICAgICAgIGlmICh2ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5pbnRlcm5hbFZhbHVlLnNldCh2KSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuICB9XG5cbiAgLy8gLS0tIElucHV0cyAtLS1cbiAgcmVhZG9ubHkgb3B0aW9ucyA9IGlucHV0PFNlYXJjaGFibGVTZWxlY3RPcHRpb25bXSB8IGFueVtdPihbXSk7XG4gIHJlYWRvbmx5IHZhbHVlID0gaW5wdXQ8YW55Pih1bmRlZmluZWQpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGlucHV0PHN0cmluZz4oJy0tIFNlbGVjdCAtLScpO1xuICByZWFkb25seSBzZWFyY2hQbGFjZWhvbGRlciA9IGlucHV0PHN0cmluZz4oJ1NlYXJjaC4uLicpO1xuICByZWFkb25seSBkaXNhYmxlZCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZGluZyA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZGluZ1RleHQgPSBpbnB1dDxzdHJpbmc+KCdMb2FkaW5nLi4uJyk7XG4gIHJlYWRvbmx5IGVtcHR5VGV4dCA9IGlucHV0PHN0cmluZz4oJ05vIG1hdGNoaW5nIG9wdGlvbnMgZm91bmQnKTtcbiAgcmVhZG9ubHkgY2xlYXJhYmxlID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XG4gIHJlYWRvbmx5IHNlYXJjaGFibGUgPSBpbnB1dDxib29sZWFuPih0cnVlKTtcbiAgcmVhZG9ubHkgc2l6ZSA9IGlucHV0PCdzbScgfCAnbWQnIHwgJ2xnJz4oJ3NtJyk7XG4gIHJlYWRvbmx5IGlkID0gaW5wdXQ8c3RyaW5nPignJyk7XG4gIHJlYWRvbmx5IGFyaWFMYWJlbCA9IGlucHV0PHN0cmluZz4oJycpO1xuICByZWFkb25seSB2YWx1ZUtleSA9IGlucHV0PHN0cmluZz4oJ3ZhbHVlJyk7XG4gIHJlYWRvbmx5IGxhYmVsS2V5ID0gaW5wdXQ8c3RyaW5nPignbGFiZWwnKTtcbiAgcmVhZG9ubHkgc3VibGFiZWxLZXkgPSBpbnB1dDxzdHJpbmc+KCdzdWJsYWJlbCcpO1xuICByZWFkb25seSBiYWRnZUtleSA9IGlucHV0PHN0cmluZz4oJ2JhZGdlJyk7XG4gIHJlYWRvbmx5IHBhbmVsTWF4SGVpZ2h0ID0gaW5wdXQ8c3RyaW5nPignMjQwcHgnKTtcbiAgcmVhZG9ubHkgb3BlbkFib3ZlID0gaW5wdXQ8Ym9vbGVhbiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICAvLyAtLS0gT3V0cHV0cyAtLS1cbiAgcmVhZG9ubHkgdmFsdWVDaGFuZ2UgPSBvdXRwdXQ8YW55PigpO1xuICByZWFkb25seSBzZWxlY3Rpb25DaGFuZ2UgPSBvdXRwdXQ8U2VhcmNoYWJsZVNlbGVjdE9wdGlvbj4oKTtcbiAgcmVhZG9ubHkgb3BlbmVkID0gb3V0cHV0PHZvaWQ+KCk7XG4gIHJlYWRvbmx5IGNsb3NlZCA9IG91dHB1dDx2b2lkPigpO1xuXG4gIC8vIC0tLSBWaWV3IENoaWxkcmVuIC0tLVxuICByZWFkb25seSB0cmlnZ2VyQnRuRWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MQnV0dG9uRWxlbWVudD4+KCd0cmlnZ2VyQnRuJyk7XG4gIHJlYWRvbmx5IHNlYXJjaElucHV0RWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50Pj4oJ3NlYXJjaElucHV0Jyk7XG4gIHJlYWRvbmx5IG9wdGlvbnNMaXN0RWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KCdvcHRpb25zTGlzdCcpO1xuXG4gIC8vIC0tLSBJbnRlcm5hbCBTdGF0ZSBTaWduYWxzIC0tLVxuICByZWFkb25seSBpbnRlcm5hbFZhbHVlID0gc2lnbmFsPGFueT4oJycpO1xuICByZWFkb25seSBpc09wZW4gPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBvcGVuc0Fib3ZlID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgc2VhcmNoVGVybSA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcmVhZG9ubHkgZm9jdXNlZEluZGV4ID0gc2lnbmFsPG51bWJlcj4oLTEpO1xuICBwcml2YXRlIHJlYWRvbmx5IGN2YURpc2FibGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICAvLyAtLS0gQ29udHJvbFZhbHVlQWNjZXNzb3IgQ2FsbGJhY2tzIC0tLVxuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICByZWFkb25seSBpc0Rpc2FibGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kaXNhYmxlZCgpIHx8IHRoaXMuY3ZhRGlzYWJsZWQoKSk7XG5cbiAgLy8gTm9ybWFsaXplZCBvcHRpb25zXG4gIHJlYWRvbmx5IG5vcm1hbGl6ZWRPcHRpb25zID0gY29tcHV0ZWQ8U2VhcmNoYWJsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgcmF3ID0gdGhpcy5vcHRpb25zKCk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHJhdykpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHZLZXkgPSB0aGlzLnZhbHVlS2V5KCk7XG4gICAgY29uc3QgbEtleSA9IHRoaXMubGFiZWxLZXkoKTtcbiAgICBjb25zdCBzdWJLZXkgPSB0aGlzLnN1YmxhYmVsS2V5KCk7XG4gICAgY29uc3QgYktleSA9IHRoaXMuYmFkZ2VLZXkoKTtcblxuICAgIHJldHVybiByYXdcbiAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0gIT09IG51bGwgJiYgaXRlbSAhPT0gdW5kZWZpbmVkKVxuICAgICAgLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBpdGVtID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogaXRlbSxcbiAgICAgICAgICAgIGxhYmVsOiBTdHJpbmcoaXRlbSksXG4gICAgICAgICAgICBkYXRhOiBpdGVtLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWx1ZSA9IGl0ZW1bdktleV0gPz8gaXRlbVsndmFsdWUnXSA/PyBpdGVtWydrZXknXSA/PyBpdGVtWydpZCddID8/IGl0ZW1bJ25hbWUnXSA/PyAnJztcbiAgICAgICAgY29uc3QgbGFiZWwgPSBpdGVtW2xLZXldID8/IGl0ZW1bJ2xhYmVsJ10gPz8gaXRlbVsnZGlzcGxheU5hbWUnXSA/PyBpdGVtWyduYW1lJ10gPz8gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgY29uc3Qgc3VibGFiZWwgPSBpdGVtW3N1YktleV0gPz8gaXRlbVsnc3VibGFiZWwnXSA/PyBpdGVtWydzY2hlbWEnXSA/PyBpdGVtWydjYXRlZ29yeSddID8/IGl0ZW1bJ2RhdGFUeXBlJ107XG4gICAgICAgIGNvbnN0IGJhZGdlID0gaXRlbVtiS2V5XSA/PyBpdGVtWydiYWRnZSddID8/IGl0ZW1bJ3R5cGUnXTtcbiAgICAgICAgY29uc3QgZGlzYWJsZWQgPSAhIWl0ZW1bJ2Rpc2FibGVkJ107XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBsYWJlbDogU3RyaW5nKGxhYmVsKSxcbiAgICAgICAgICBzdWJsYWJlbDogc3VibGFiZWwgPyBTdHJpbmcoc3VibGFiZWwpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGJhZGdlOiBiYWRnZSA/IFN0cmluZyhiYWRnZSkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgZGlzYWJsZWQsXG4gICAgICAgICAgZ3JvdXA6IGl0ZW1bJ2dyb3VwJ10gPyBTdHJpbmcoaXRlbVsnZ3JvdXAnXSkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgZGF0YTogaXRlbVsnZGF0YSddID8/IGl0ZW0sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfSk7XG5cbiAgLy8gRmlsdGVyZWQgb3B0aW9ucyB3aXRoIHJlc3BvbnNpdmUgc2VhcmNoXG4gIHJlYWRvbmx5IGZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPFNlYXJjaGFibGVTZWxlY3RPcHRpb25bXT4oKCkgPT4ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMubm9ybWFsaXplZE9wdGlvbnMoKTtcbiAgICBjb25zdCB0ZXJtID0gdGhpcy5zZWFyY2hUZXJtKCkudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKCF0ZXJtKSByZXR1cm4gYWxsO1xuXG4gICAgcmV0dXJuIGFsbC5maWx0ZXIoKG9wdCkgPT4ge1xuICAgICAgY29uc3QgbWF0Y2hMYWJlbCA9IG9wdC5sYWJlbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pO1xuICAgICAgY29uc3QgbWF0Y2hWYWwgPSBTdHJpbmcob3B0LnZhbHVlKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pO1xuICAgICAgY29uc3QgbWF0Y2hTdWIgPSBvcHQuc3VibGFiZWw/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSk7XG4gICAgICBjb25zdCBtYXRjaEJhZGdlID0gb3B0LmJhZGdlPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pO1xuICAgICAgcmV0dXJuIG1hdGNoTGFiZWwgfHwgbWF0Y2hWYWwgfHwgbWF0Y2hTdWIgfHwgbWF0Y2hCYWRnZTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gSW5jcmVtZW50YWwgcmVuZGVyaW5nIGZvciBzbW9vdGggcGVyZm9ybWFuY2Ugd2l0aCB0aG91c2FuZHMgb2YgU1BzL3RhYmxlcyAoMzAwMCspXG4gIHJlYWRvbmx5IE1BWF9WSVNJQkxFX09QVElPTlMgPSAxNTA7XG4gIHJlYWRvbmx5IElOSVRJQUxfVklTSUJMRV9PUFRJT05TID0gMTUwO1xuICByZWFkb25seSByZW5kZXJlZExpbWl0ID0gc2lnbmFsPG51bWJlcj4oMTUwKTtcblxuICByZWFkb25seSB2aXNpYmxlRmlsdGVyZWRPcHRpb25zID0gY29tcHV0ZWQ8U2VhcmNoYWJsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLmZpbHRlcmVkT3B0aW9ucygpO1xuICAgIGNvbnN0IGxpbWl0ID0gdGhpcy5yZW5kZXJlZExpbWl0KCk7XG4gICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA8PSBsaW1pdCkgcmV0dXJuIGZpbHRlcmVkO1xuICAgIHJldHVybiBmaWx0ZXJlZC5zbGljZSgwLCBsaW1pdCk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGV4Y2Vzc0NvdW50ID0gY29tcHV0ZWQ8bnVtYmVyPigoKSA9PiB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRoaXMuZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5yZW5kZXJlZExpbWl0KCkpO1xuICB9KTtcblxuICBvbk9wdGlvbnNTY3JvbGwoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZWwgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgIGlmIChlbC5zY3JvbGxUb3AgKyBlbC5jbGllbnRIZWlnaHQgPj0gZWwuc2Nyb2xsSGVpZ2h0IC0gMTIwKSB7XG4gICAgICB0aGlzLmxvYWRNb3JlKCk7XG4gICAgfVxuICB9XG5cbiAgbG9hZE1vcmUoKTogdm9pZCB7XG4gICAgY29uc3QgdG90YWwgPSB0aGlzLmZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aDtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5yZW5kZXJlZExpbWl0KCk7XG4gICAgaWYgKGN1cnJlbnQgPCB0b3RhbCkge1xuICAgICAgdGhpcy5yZW5kZXJlZExpbWl0LnVwZGF0ZSgoYykgPT4gTWF0aC5taW4odG90YWwsIGMgKyAxNTApKTtcbiAgICB9XG4gIH1cblxuICBsb2FkQWxsKCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZWRMaW1pdC5zZXQodGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGgpO1xuICB9XG5cbiAgcmVhZG9ubHkgc2VsZWN0ZWRPcHRpb24gPSBjb21wdXRlZDxTZWFyY2hhYmxlU2VsZWN0T3B0aW9uIHwgdW5kZWZpbmVkPigoKSA9PiB7XG4gICAgY29uc3QgY3VyID0gdGhpcy5pbnRlcm5hbFZhbHVlKCk7XG4gICAgaWYgKGN1ciA9PT0gbnVsbCB8fCBjdXIgPT09IHVuZGVmaW5lZCB8fCBjdXIgPT09ICcnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ckN1ciA9IFN0cmluZyhjdXIpO1xuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZWRPcHRpb25zKCkuZmluZCgob3B0KSA9PiBTdHJpbmcob3B0LnZhbHVlKSA9PT0gc3RyQ3VyKTtcbiAgfSk7XG5cbiAgLy8gLS0tIENvbnRyb2xWYWx1ZUFjY2Vzc29yIEltcGxlbWVudGF0aW9uIC0tLVxuICB3cml0ZVZhbHVlKG9iajogYW55KTogdm9pZCB7XG4gICAgdGhpcy5pbnRlcm5hbFZhbHVlLnNldChvYmogPz8gJycpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlPyhpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jdmFEaXNhYmxlZC5zZXQoaXNEaXNhYmxlZCk7XG4gIH1cblxuICAvLyAtLS0gSW50ZXJhY3Rpb24gTWV0aG9kcyAtLS1cbiAgdG9nZ2xlKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0Rpc2FibGVkKCkpIHJldHVybjtcblxuICAgIGlmICh0aGlzLmlzT3BlbigpKSB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3BlbigpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW4oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNEaXNhYmxlZCgpIHx8IHRoaXMuaXNPcGVuKCkpIHJldHVybjtcblxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocmVjdC53aWR0aCA+IDApIHtcbiAgICAgIHRoaXMudHJpZ2dlcldpZHRoLnNldChyZWN0LndpZHRoKTtcbiAgICB9XG5cbiAgICBjb25zdCBtYW51YWxQcmVmZXJlbmNlID0gdGhpcy5vcGVuQWJvdmUoKTtcbiAgICBpZiAobWFudWFsUHJlZmVyZW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm9wZW5zQWJvdmUuc2V0KG1hbnVhbFByZWZlcmVuY2UpO1xuICAgIH1cblxuICAgIHRoaXMuaXNPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLnJlbmRlcmVkTGltaXQuc2V0KHRoaXMuSU5JVElBTF9WSVNJQkxFX09QVElPTlMpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5vcGVuZWQuZW1pdCgpO1xuICB9XG5cbiAgb25Qb3NpdGlvbkNoYW5nZShjaGFuZ2U6IENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSk6IHZvaWQge1xuICAgIHRoaXMub3BlbnNBYm92ZS5zZXQoY2hhbmdlLmNvbm5lY3Rpb25QYWlyLm9yaWdpblkgPT09ICd0b3AnKTtcbiAgfVxuXG4gIG9uT3ZlcmxheUF0dGFjaGVkKCk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zZWFyY2hJbnB1dEVsKCk/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9LCAyNSk7XG4gIH1cblxuICBjbG9zZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHJldHVybjtcbiAgICB0aGlzLmlzT3Blbi5zZXQoZmFsc2UpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB0aGlzLmNsb3NlZC5lbWl0KCk7XG4gIH1cblxuICBzZWxlY3RPcHRpb24ob3B0OiBTZWFyY2hhYmxlU2VsZWN0T3B0aW9uKTogdm9pZCB7XG4gICAgaWYgKG9wdC5kaXNhYmxlZCkgcmV0dXJuO1xuICAgIHRoaXMuaW50ZXJuYWxWYWx1ZS5zZXQob3B0LnZhbHVlKTtcbiAgICB0aGlzLm9uQ2hhbmdlKG9wdC52YWx1ZSk7XG4gICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KG9wdC52YWx1ZSk7XG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdChvcHQpO1xuICAgIHRoaXMuY2xvc2UoKTtcbiAgICB0aGlzLnRyaWdnZXJCdG5FbCgpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICBjbGVhclNlbGVjdGlvbihldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuaW50ZXJuYWxWYWx1ZS5zZXQoJycpO1xuICAgIHRoaXMub25DaGFuZ2UoJycpO1xuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCgnJyk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5yZW5kZXJlZExpbWl0LnNldCh0aGlzLklOSVRJQUxfVklTSUJMRV9PUFRJT05TKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICB9XG5cbiAgY2xlYXJTZWFyY2goZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5yZW5kZXJlZExpbWl0LnNldCh0aGlzLklOSVRJQUxfVklTSUJMRV9PUFRJT05TKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICAgIHRoaXMuc2VhcmNoSW5wdXRFbCgpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICBvblNlYXJjaElucHV0KGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHZhbCA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCh2YWwpO1xuICAgIHRoaXMucmVuZGVyZWRMaW1pdC5zZXQodGhpcy5JTklUSUFMX1ZJU0lCTEVfT1BUSU9OUyk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KDApO1xuICB9XG5cbiAgb25UcmlnZ2VyS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd0Rvd24nIHx8IGV2ZW50LmtleSA9PT0gJ0VudGVyJyB8fCBldmVudC5rZXkgPT09ICcgJykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMub3BlbigpO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VhcmNoS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHZpc2libGUgPSB0aGlzLnZpc2libGVGaWx0ZXJlZE9wdGlvbnMoKTtcbiAgICBjb25zdCBjb3VudCA9IHZpc2libGUubGVuZ3RoO1xuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSAodGhpcy5mb2N1c2VkSW5kZXgoKSArIDEpICUgY291bnQ7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KG5leHQpO1xuICAgICAgICAgIHRoaXMuc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdBcnJvd1VwJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgY29uc3QgcHJldiA9IHRoaXMuZm9jdXNlZEluZGV4KCkgPD0gMCA/IGNvdW50IC0gMSA6IHRoaXMuZm9jdXNlZEluZGV4KCkgLSAxO1xuICAgICAgICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldChwcmV2KTtcbiAgICAgICAgICB0aGlzLnNjcm9sbEZvY3VzZWRJbnRvVmlldygpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnRW50ZXInOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IGlkeCA9IHRoaXMuZm9jdXNlZEluZGV4KCk7XG4gICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPCBjb3VudCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0T3B0aW9uKHZpc2libGVbaWR4XSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdE9wdGlvbih2aXNpYmxlWzBdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0VzY2FwZSc6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLnRyaWdnZXJCdG5FbCgpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnVGFiJzoge1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk6IHZvaWQge1xuICAgIGNvbnN0IGxpc3RFbCA9IHRoaXMub3B0aW9uc0xpc3RFbCgpPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghbGlzdEVsKSByZXR1cm47XG4gICAgY29uc3QgaXRlbXMgPSBsaXN0RWwucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oJy5zZWxlY3Qtb3B0aW9uLWl0ZW0nKTtcbiAgICBjb25zdCBpZHggPSB0aGlzLmZvY3VzZWRJbmRleCgpO1xuICAgIGlmIChpdGVtcyAmJiBpdGVtc1tpZHhdKSB7XG4gICAgICBpdGVtc1tpZHhdLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICduZWFyZXN0JyB9KTtcbiAgICB9XG4gIH1cblxuICBpc1NlbGVjdGVkKG9wdDogU2VhcmNoYWJsZVNlbGVjdE9wdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuaW50ZXJuYWxWYWx1ZSgpO1xuICAgIGlmIChjdXIgPT09IG51bGwgfHwgY3VyID09PSB1bmRlZmluZWQgfHwgY3VyID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBTdHJpbmcoY3VyKSA9PT0gU3RyaW5nKG9wdC52YWx1ZSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBOb2RlO1xuICAgIGlmICghdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJylcbiAgb25Fc2NhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJycHQtc2VhcmNoLXNlbGVjdC13cmFwcGVyXCIgI29yaWdpbj1cImNka092ZXJsYXlPcmlnaW5cIiBjZGtPdmVybGF5T3JpZ2luPlxuICA8IS0tIFRyaWdnZXIgQnV0dG9uIC0tPlxuICA8YnV0dG9uXG4gICAgI3RyaWdnZXJCdG5cbiAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICBjbGFzcz1cInNlbGVjdC10cmlnZ2VyXCJcbiAgICBbaWRdPVwiaWQoKVwiXG4gICAgW2Rpc2FibGVkXT1cImlzRGlzYWJsZWQoKVwiXG4gICAgW2NsYXNzLmlzLW9wZW5dPVwiaXNPcGVuKClcIlxuICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiaXNPcGVuKClcIlxuICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ2xpc3Rib3gnXCJcbiAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cInBhbmVsSWRcIlxuICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsKCkgfHwgcGxhY2Vob2xkZXIoKVwiXG4gICAgKGNsaWNrKT1cInRvZ2dsZSgkZXZlbnQpXCJcbiAgICAoa2V5ZG93bik9XCJvblRyaWdnZXJLZXlkb3duKCRldmVudClcIlxuICA+XG4gICAgPGRpdiBjbGFzcz1cInRyaWdnZXItbGFiZWxcIiBbY2xhc3MuaXMtcGxhY2Vob2xkZXJdPVwiIXNlbGVjdGVkT3B0aW9uKClcIj5cbiAgICAgIEBpZiAoc2VsZWN0ZWRPcHRpb24oKSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cInNlbGVjdGVkLXRleHRcIj57eyBzZWxlY3RlZE9wdGlvbigpIS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgQGlmIChzZWxlY3RlZE9wdGlvbigpIS5zdWJsYWJlbCkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2VsZWN0ZWQtc3VibGFiZWxcIj57eyBzZWxlY3RlZE9wdGlvbigpIS5zdWJsYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKHNlbGVjdGVkT3B0aW9uKCkhLmJhZGdlKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzZWxlY3RlZC1iYWRnZVwiPnt7IHNlbGVjdGVkT3B0aW9uKCkhLmJhZGdlIH19PC9zcGFuPlxuICAgICAgICB9XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlci10ZXh0XCI+e3sgcGxhY2Vob2xkZXIoKSB9fTwvc3Bhbj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJ0cmlnZ2VyLWFjdGlvbnNcIj5cbiAgICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic3Bpbm5lci1kb3RcIiB0aXRsZT1cIkxvYWRpbmcgb3B0aW9ucy4uLlwiPjwvc3Bhbj5cbiAgICAgIH1cblxuICAgICAgQGlmIChzZWxlY3RlZE9wdGlvbigpICYmIGNsZWFyYWJsZSgpICYmICFpc0Rpc2FibGVkKCkpIHtcbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwidHJpZ2dlci1jbGVhci1idG5cIlxuICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICAoY2xpY2spPVwiY2xlYXJTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgID5cbiAgICAgICAgICDinJVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICB9XG5cbiAgICAgIDxzcGFuIGNsYXNzPVwidHJpZ2dlci1hcnJvd1wiIFtjbGFzcy5yb3RhdGVkXT1cImlzT3BlbigpXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgIDxzdmcgd2lkdGg9XCIxMFwiIGhlaWdodD1cIjZcIiB2aWV3Qm94PVwiMCAwIDEwIDZcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxTDUgNUw5IDFcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L2J1dHRvbj5cbjwvZGl2PlxuXG48IS0tIERyb3Bkb3duIFBvcG92ZXIgUGFuZWwgaW4gQ0RLIE92ZXJsYXkgKGF0dGFjaGVkIHRvIGJvZHksIG91dHNpZGUgYW55IGNsaXBwZWQgY2FyZCkgLS0+XG48bmctdGVtcGxhdGVcbiAgY2RrQ29ubmVjdGVkT3ZlcmxheVxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJvcmlnaW5cIlxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9wZW5dPVwiaXNPcGVuKClcIlxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uc109XCJvdmVybGF5UG9zaXRpb25zXCJcbiAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlXaWR0aF09XCJ0cmlnZ2VyV2lkdGgoKVwiXG4gIFtjZGtDb25uZWN0ZWRPdmVybGF5RmxleGlibGVEaW1lbnNpb25zXT1cInRydWVcIlxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheVZpZXdwb3J0TWFyZ2luXT1cIjhcIlxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheVB1c2hdPVwidHJ1ZVwiXG4gIFtjZGtDb25uZWN0ZWRPdmVybGF5U2Nyb2xsU3RyYXRlZ3ldPVwic2Nyb2xsU3RyYXRlZ3lcIlxuICAob3ZlcmxheU91dHNpZGVDbGljayk9XCJjbG9zZSgpXCJcbiAgKHBvc2l0aW9uQ2hhbmdlKT1cIm9uUG9zaXRpb25DaGFuZ2UoJGV2ZW50KVwiXG4gIChhdHRhY2gpPVwib25PdmVybGF5QXR0YWNoZWQoKVwiXG4gIChkZXRhY2gpPVwiY2xvc2UoKVwiXG4+XG4gIDxkaXZcbiAgICBjbGFzcz1cInNlbGVjdC1wYW5lbFwiXG4gICAgW2lkXT1cInBhbmVsSWRcIlxuICAgIFtjbGFzcy5vcGVucy1hYm92ZV09XCJvcGVuc0Fib3ZlKClcIlxuICAgIFtzdHlsZS5tYXgtaGVpZ2h0XT1cInBhbmVsTWF4SGVpZ2h0KClcIlxuICAgIHJvbGU9XCJsaXN0Ym94XCJcbiAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgPlxuICAgIDwhLS0gU2VhcmNoIElucHV0IEJveCAtLT5cbiAgICBAaWYgKHNlYXJjaGFibGUoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdC1zZWFyY2gtYm94XCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2VhcmNoLWljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPlxuICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjExXCIgY3k9XCIxMVwiIHI9XCI4XCI+PC9jaXJjbGU+XG4gICAgICAgICAgICA8bGluZSB4MT1cIjIxXCIgeTE9XCIyMVwiIHgyPVwiMTYuNjVcIiB5Mj1cIjE2LjY1XCI+PC9saW5lPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgICNzZWFyY2hJbnB1dFxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBjbGFzcz1cInNlYXJjaC1pbnB1dFwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInNlYXJjaFBsYWNlaG9sZGVyKClcIlxuICAgICAgICAgIFt2YWx1ZV09XCJzZWFyY2hUZXJtKClcIlxuICAgICAgICAgIChpbnB1dCk9XCJvblNlYXJjaElucHV0KCRldmVudClcIlxuICAgICAgICAgIChrZXlkb3duKT1cIm9uU2VhcmNoS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgLz5cbiAgICAgICAgQGlmIChzZWFyY2hUZXJtKCkpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2VhcmNoLWNsZWFyLWJ0blwiXG4gICAgICAgICAgICB0aXRsZT1cIkNsZWFyIHNlYXJjaFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJTZWFyY2goJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAg4pyVXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gT3B0aW9ucyBMaXN0IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Qtb3B0aW9ucy1saXN0XCIgI29wdGlvbnNMaXN0IChzY3JvbGwpPVwib25PcHRpb25zU2Nyb2xsKCRldmVudClcIj5cbiAgICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Qtc3RhdHVzLXJvdyBsb2FkaW5nXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcGlubmVyLWRvdFwiPjwvc3Bhbj5cbiAgICAgICAgICA8c3Bhbj57eyBsb2FkaW5nVGV4dCgpIH19PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH0gQGVsc2UgaWYgKG5vcm1hbGl6ZWRPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Qtc3RhdHVzLXJvdyBlbXB0eVwiPlxuICAgICAgICAgIDxzcGFuPnt7IGVtcHR5VGV4dCgpIH19PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH0gQGVsc2UgaWYgKHZpc2libGVGaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdC1zdGF0dXMtcm93IGVtcHR5XCI+XG4gICAgICAgICAgPHNwYW4+Tm8gb3B0aW9ucyBtYXRjaCBcInt7IHNlYXJjaFRlcm0oKSB9fVwiPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICBAZm9yIChvcHQgb2YgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQudmFsdWU7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgcm9sZT1cIm9wdGlvblwiXG4gICAgICAgICAgICBjbGFzcz1cInNlbGVjdC1vcHRpb24taXRlbVwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtc2VsZWN0ZWRdPVwiaXNTZWxlY3RlZChvcHQpXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1mb2N1c2VkXT1cImZvY3VzZWRJbmRleCgpID09PSBpXCJcbiAgICAgICAgICAgIFtjbGFzcy5pcy1kaXNhYmxlZF09XCJvcHQuZGlzYWJsZWRcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKG9wdClcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdE9wdGlvbihvcHQpXCJcbiAgICAgICAgICAgIChtb3VzZWVudGVyKT1cImZvY3VzZWRJbmRleC5zZXQoaSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcHRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdGlvbi1sYWJlbFwiIFt0aXRsZV09XCJvcHQubGFiZWxcIj57eyBvcHQubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgIEBpZiAob3B0LnN1YmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJvcHRpb24tc3VibGFiZWxcIiBbdGl0bGVdPVwib3B0LnN1YmxhYmVsXCI+e3sgb3B0LnN1YmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9wdGlvbi1tZXRhXCI+XG4gICAgICAgICAgICAgIEBpZiAob3B0LmJhZGdlKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJvcHRpb24tYmFkZ2VcIj57eyBvcHQuYmFkZ2UgfX08L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGlmIChpc1NlbGVjdGVkKG9wdCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdGlvbi1jaGVja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKckzwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKGV4Y2Vzc0NvdW50KCkgPiAwKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdC1leGNlc3MtaGludFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJleGNlc3MtdGV4dFwiPlNob3dpbmcge3sgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCB9fSBvZiB7eyBmaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggfX0gbWF0Y2hlcy4gU2Nyb2xsIGRvd24gdG8gYnJvd3NlIG9yPC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZWxlY3QtbG9hZC1hbGwtYnRuXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImxvYWRBbGwoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIExvYWQgYWxsIHt7IGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
|