valtech-components 2.0.383 → 2.0.385

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.
@@ -1,385 +1,292 @@
1
1
  import { CommonModule } from '@angular/common';
2
- import { ChangeDetectorRef, Component, inject, Input, ViewChild, } from '@angular/core';
2
+ import { Component, inject, Input, ViewChild, signal, computed } from '@angular/core';
3
3
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4
4
  import { IonicModule } from '@ionic/angular';
5
- import { IconService } from '../../../services/icons.service';
6
5
  import { LangService } from '../../../services/lang-provider/lang-provider.service';
7
6
  import { applyDefaultValueToControl } from '../../../shared/utils/form-defaults';
8
7
  import { replaceSpecialChars } from '../../../shared/utils/text';
9
- import { SearchbarComponent } from '../searchbar/searchbar.component';
10
8
  import * as i0 from "@angular/core";
11
9
  import * as i1 from "@angular/common";
12
10
  import * as i2 from "@ionic/angular";
13
11
  import * as i3 from "@angular/forms";
14
- /**
15
- * val-select-search
16
- *
17
- * A searchable select/dropdown input with modal and filtering, integrated with Angular forms.
18
- *
19
- * @example
20
- * <val-select-search [props]="{ control: myControl, label: 'Choose', options: [{ id: '1', name: 'Option 1' }] }"></val-select-search>
21
- *
22
- * @input props: InputMetadata - Configuration for the select input (form control, label, options, etc.)
23
- */
24
12
  export class SelectSearchComponent {
25
13
  constructor() {
26
14
  this.labelProperty = 'name';
27
15
  this.valueProperty = 'id';
28
- this.multiple = false;
16
+ this.placeholder = '';
29
17
  this.langService = inject(LangService);
30
- this.icon = inject(IconService);
31
- this.changeDetector = inject(ChangeDetectorRef);
32
- this.searchTerm = '';
33
- this.filteredItems = [];
34
- this.selectedItems = [];
35
- this.displayValue = '';
36
- this.previousOptions = [];
37
- this.isProcessingChanges = false;
38
- this.label = this.langService.getText('_global', 'select', 'Seleccionar');
18
+ // Signals for reactive state management
19
+ this.isOpen = signal(false);
20
+ this.searchTerm = signal('');
21
+ this.selectedValue = signal(null);
22
+ // Computed signals
23
+ this.displayValue = computed(() => {
24
+ const value = this.selectedValue();
25
+ if (!value)
26
+ return '';
27
+ const option = this.getOptionByValue(value);
28
+ return option ? option[this.labelProperty] : '';
29
+ });
30
+ this.filteredOptions = computed(() => {
31
+ const options = this.props?.options || [];
32
+ const search = this.searchTerm().toLowerCase();
33
+ // Debug
34
+ console.log('[SelectSearch] filteredOptions computed:', {
35
+ optionsCount: options.length,
36
+ searchTerm: search,
37
+ options: options.slice(0, 3) // Primeras 3 opciones
38
+ });
39
+ if (!search) {
40
+ return options;
41
+ }
42
+ return options.filter(option => {
43
+ const label = option[this.labelProperty]
44
+ ? replaceSpecialChars(String(option[this.labelProperty]).toLowerCase())
45
+ : '';
46
+ const value = option[this.valueProperty]
47
+ ? replaceSpecialChars(String(option[this.valueProperty]).toLowerCase())
48
+ : '';
49
+ const searchTerm = replaceSpecialChars(search);
50
+ return label.includes(searchTerm) || value.includes(searchTerm);
51
+ });
52
+ });
39
53
  this.placeholder = this.langService.getText('_global', 'selectOption', 'Seleccione una opción');
54
+ // Close dropdown when clicking outside
55
+ document.addEventListener('click', this.handleClickOutside.bind(this));
40
56
  }
41
57
  ngOnInit() {
42
58
  this.applyDefaultValue();
43
- this.initializeItems();
44
- this.syncControlValueWithSelectedItems();
45
- this.updateDisplayValue();
46
- this.subscribeToValueChanges();
59
+ this.syncSelectedValue();
47
60
  }
48
61
  ngOnDestroy() {
49
- // Limpiar suscripciones para evitar memory leaks
50
- if (this.valueChangesSubscription) {
51
- this.valueChangesSubscription.unsubscribe();
52
- }
62
+ document.removeEventListener('click', this.handleClickOutside.bind(this));
53
63
  }
54
64
  ngOnChanges(changes) {
55
- // Evitar bucles infinitos
56
- if (this.isProcessingChanges) {
57
- return;
58
- }
59
- // Cuando cambia props o props.options
60
- if (changes['props']) {
61
- try {
62
- this.isProcessingChanges = true;
63
- // Desuscribirse del antiguo control si existe
64
- if (this.valueChangesSubscription) {
65
- this.valueChangesSubscription.unsubscribe();
66
- }
67
- if (this.props?.options) {
68
- // Verificar si las opciones han cambiado realmente
69
- const optionsChanged = !this.areOptionsEqual(this.previousOptions, this.props.options);
70
- if (optionsChanged) {
71
- this.previousOptions = [...this.props.options];
72
- this.initializeItems();
73
- }
74
- }
75
- // Sincronizar con el nuevo control si existe
76
- this.syncControlValueWithSelectedItems();
77
- this.updateDisplayValue();
78
- // Suscribirse al nuevo control
79
- this.subscribeToValueChanges();
80
- }
81
- finally {
82
- this.isProcessingChanges = false;
83
- }
84
- }
85
- }
86
- ionViewWillEnter() {
87
- if (this.isProcessingChanges) {
88
- return;
89
- }
90
- try {
91
- this.isProcessingChanges = true;
92
- this.initializeItems();
93
- this.syncControlValueWithSelectedItems();
94
- this.updateDisplayValue();
95
- this.subscribeToValueChanges();
96
- }
97
- finally {
98
- this.isProcessingChanges = false;
99
- }
100
- }
101
- // Suscribirse a cambios en el FormControl
102
- subscribeToValueChanges() {
103
- if (!this.props?.control)
104
- return;
105
- this.valueChangesSubscription = this.props.control.valueChanges.subscribe(value => {
106
- if (this.isProcessingChanges)
107
- return;
108
- try {
109
- this.isProcessingChanges = true;
110
- this.syncControlValueWithSelectedItems();
111
- this.updateDisplayValue();
112
- }
113
- finally {
114
- this.isProcessingChanges = false;
115
- }
116
- });
117
- }
118
- // Compara si dos arrays de opciones son iguales
119
- areOptionsEqual(prevOptions, newOptions) {
120
- // PERF: Use reference equality first for fast path
121
- if (prevOptions === newOptions)
122
- return true;
123
- if (!prevOptions || !newOptions)
124
- return prevOptions === newOptions;
125
- if (prevOptions.length !== newOptions.length)
126
- return false;
127
- // Only compare valueProperty for equality
128
- for (let i = 0; i < prevOptions.length; i++) {
129
- if (prevOptions[i][this.valueProperty] !== newOptions[i][this.valueProperty]) {
130
- return false;
131
- }
65
+ if (changes['props'] && this.props) {
66
+ this.syncSelectedValue();
132
67
  }
133
- return true;
134
- }
135
- initializeItems() {
136
- // PERF: Avoid unnecessary array copies
137
- this.filteredItems = this.props?.options || [];
138
68
  }
139
- syncControlValueWithSelectedItems() {
140
- if (!this.props?.control) {
141
- this.selectedItems = [];
142
- return;
143
- }
144
- const controlValue = this.props.control.value;
145
- if (controlValue === null || controlValue === undefined) {
146
- this.selectedItems = [];
147
- return;
148
- }
149
- // PERF: Use a Map for faster lookup if options are large
150
- if (this.props.options && this.props.options.length > 0) {
151
- const map = new Map(this.props.options.map(opt => [opt[this.valueProperty], opt]));
152
- const selectedOption = map.get(controlValue);
153
- this.selectedItems = selectedOption ? [selectedOption] : [];
154
- }
155
- else {
156
- this.selectedItems = [];
157
- }
158
- }
159
- applyDefaultValue() {
160
- applyDefaultValueToControl(this.props);
161
- }
162
- onFilter(event) {
163
- // If no search term, show all options
164
- if (!event || event.trim() === '') {
165
- this.filteredItems = this.props?.options ? [...this.props.options] : [];
166
- this.changeDetector.detectChanges();
167
- return;
168
- }
169
- // If no options, nothing to filter
170
- if (!this.props?.options || this.props.options.length === 0) {
171
- this.filteredItems = [];
172
- this.changeDetector.detectChanges();
173
- return;
69
+ // Component methods
70
+ toggleDropdown(event) {
71
+ event.stopPropagation();
72
+ this.isOpen.update(value => !value);
73
+ if (this.isOpen()) {
74
+ // Focus search bar when opening if available
75
+ setTimeout(() => {
76
+ const searchbar = this.dropdownRef?.nativeElement?.querySelector('ion-searchbar');
77
+ if (searchbar) {
78
+ searchbar.setFocus();
79
+ }
80
+ }, 100);
174
81
  }
175
- // PERF: Avoid repeated replaceSpecialChars and toLowerCase for each option
176
- const search = replaceSpecialChars(event.toLowerCase());
177
- this.filteredItems = this.props.options.filter(element => {
178
- // Only use labelProperty and valueProperty for filtering (faster)
179
- const label = element[this.labelProperty]
180
- ? replaceSpecialChars(String(element[this.labelProperty]).toLowerCase())
181
- : '';
182
- const value = element[this.valueProperty]
183
- ? replaceSpecialChars(String(element[this.valueProperty]).toLowerCase())
184
- : '';
185
- return label.includes(search) || value.includes(search);
186
- });
187
- this.changeDetector.detectChanges();
188
82
  }
189
- onFocus() {
190
- console.log('onFocus');
83
+ onSearch(event) {
84
+ this.searchTerm.set(event.detail.value || '');
191
85
  }
192
- onBlur() {
193
- console.log('onBlur');
194
- }
195
- openModal() {
196
- if (this.modal) {
197
- this.modal.present();
86
+ selectOption(option) {
87
+ const value = option[this.valueProperty];
88
+ this.selectedValue.set(value);
89
+ this.isOpen.set(false);
90
+ this.searchTerm.set('');
91
+ // Update form control
92
+ if (this.props?.control) {
93
+ this.props.control.setValue(value);
94
+ this.props.control.markAsDirty();
95
+ this.props.control.markAsTouched();
198
96
  }
199
97
  }
200
- preventDefaultBehavior(event) {
201
- event.preventDefault();
202
- event.stopPropagation();
203
- this.openModal();
98
+ isSelected(option) {
99
+ return this.selectedValue() === option[this.valueProperty];
204
100
  }
205
- cancelModal() {
206
- // Reset filter and show all options when closing modal
207
- this.searchTerm = '';
208
- this.filteredItems = this.props?.options ? [...this.props.options] : [];
209
- this.changeDetector.detectChanges();
210
- if (this.modal) {
211
- this.modal.dismiss();
212
- }
101
+ trackByFn(_index, option) {
102
+ return option[this.valueProperty];
213
103
  }
214
- selectItem(item) {
215
- if (this.multiple) {
216
- const index = this.selectedItems.findIndex(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
217
- if (index === -1) {
218
- this.selectedItems.push(item);
219
- }
220
- else {
221
- this.selectedItems.splice(index, 1);
222
- }
223
- }
224
- else {
225
- this.selectedItems = [item];
226
- this.cancelModal();
104
+ handleClickOutside(event) {
105
+ if (this.isOpen() &&
106
+ !this.mainInputRef?.nativeElement?.contains(event.target) &&
107
+ !this.dropdownRef?.nativeElement?.contains(event.target)) {
108
+ this.isOpen.set(false);
109
+ this.searchTerm.set('');
227
110
  }
228
- this.updateDisplayValue();
229
- this.applyChanges();
230
111
  }
231
- isItemSelected(item) {
232
- return this.selectedItems.some(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
233
- }
234
- updateDisplayValue() {
235
- if (this.selectedItems.length === 0) {
236
- this.displayValue = '';
237
- return;
238
- }
239
- if (this.multiple) {
240
- if (this.selectedItems.length === 1) {
241
- this.displayValue = this.selectedItems[0][this.labelProperty];
242
- }
243
- else {
244
- this.displayValue = `${this.selectedItems.length} elementos seleccionados`;
245
- }
246
- }
247
- else {
248
- this.displayValue = this.selectedItems[0][this.labelProperty];
249
- }
112
+ getOptionByValue(value) {
113
+ return this.props?.options?.find(option => option[this.valueProperty] === value);
250
114
  }
251
- applyChanges() {
252
- if (!this.props?.control) {
253
- return;
254
- }
255
- try {
256
- this.isProcessingChanges = true;
257
- if (this.selectedItems.length > 0) {
258
- this.props.control.setValue(this.selectedItems[0][this.valueProperty]);
259
- }
260
- else {
261
- this.props.control.setValue(null);
262
- }
263
- this.props.control.markAsDirty();
264
- this.props.control.updateValueAndValidity();
265
- }
266
- finally {
267
- this.isProcessingChanges = false;
115
+ applyDefaultValue() {
116
+ if (this.props) {
117
+ applyDefaultValueToControl(this.props);
268
118
  }
269
119
  }
270
- // Método público para reiniciar el componente
271
- reset() {
272
- this.selectedItems = [];
273
- this.displayValue = '';
274
- if (this.props?.control) {
275
- this.props.control.setValue(null);
120
+ syncSelectedValue() {
121
+ if (this.props?.control?.value) {
122
+ this.selectedValue.set(this.props.control.value);
276
123
  }
277
- this.changeDetector.detectChanges();
278
124
  }
279
125
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
280
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectSearchComponent, isStandalone: true, selector: "val-select-search", inputs: { label: "label", labelProperty: "labelProperty", valueProperty: "valueProperty", multiple: "multiple", placeholder: "placeholder", props: "props" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
281
- <ion-input
282
- type="text"
283
- [value]="displayValue"
284
- [placeholder]="props?.placeholder || placeholder"
285
- readonly
286
- (mousedown)="preventDefaultBehavior($event)"
287
- />
126
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectSearchComponent, isStandalone: true, selector: "val-select-search", inputs: { props: "props", labelProperty: "labelProperty", valueProperty: "valueProperty", placeholder: "placeholder" }, viewQueries: [{ propertyName: "dropdownRef", first: true, predicate: ["dropdown"], descendants: true }, { propertyName: "mainInputRef", first: true, predicate: ["mainInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
127
+ <div class="select-container" (click)="toggleDropdown($event)">
128
+ <!-- Main input display -->
129
+ <ion-input
130
+ #mainInput
131
+ type="text"
132
+ [value]="displayValue()"
133
+ [placeholder]="props?.placeholder || placeholder"
134
+ readonly
135
+ class="main-input"
136
+ [class.is-open]="isOpen()"
137
+ />
138
+
139
+ <!-- Dropdown icon -->
140
+ <ion-icon
141
+ name="chevron-down-outline"
142
+ class="dropdown-icon"
143
+ [class.rotated]="isOpen()"
144
+ ></ion-icon>
145
+
146
+ <!-- Hidden input for form control -->
147
+ <ion-input
148
+ style="position: absolute; opacity: 0; pointer-events: none;"
149
+ [formControl]="props?.control"
150
+ type="hidden"
151
+ />
152
+ </div>
288
153
 
289
- <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
290
-
291
- <ion-modal
292
- #modal
293
- [initialBreakpoint]="1"
294
- [breakpoints]="[0, 0.5, 0.75, 1]"
295
- (didDismiss)="cancelModal()"
154
+ <!-- Dropdown overlay -->
155
+ <div
156
+ class="dropdown-overlay"
157
+ [class.visible]="isOpen()"
158
+ #dropdown
296
159
  >
297
- <ng-template>
298
- <ion-header>
299
- <ion-toolbar>
300
- <ion-title>{{ label }}</ion-title>
301
- <ion-buttons slot="end">
302
- <ion-button (click)="cancelModal()">Cerrar</ion-button>
303
- </ion-buttons>
304
- </ion-toolbar>
305
- <ion-toolbar>
306
- <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
307
- </ion-toolbar>
308
- </ion-header>
309
- <ion-content>
310
- <ion-list>
311
- <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
312
- <ion-label>{{ item[labelProperty] }}</ion-label>
313
- <ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
314
- </ion-item>
315
- <ion-item *ngIf="filteredItems.length === 0" lines="none">
316
- <ion-label color="dark">No se encontraron resultados</ion-label>
317
- </ion-item>
318
- </ion-list>
319
- </ion-content>
320
- </ng-template>
321
- </ion-modal>
322
- `, isInline: true, styles: ["ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
160
+ <!-- Search bar -->
161
+ <div class="search-container" *ngIf="props?.options && props.options.length > 5">
162
+ <ion-searchbar
163
+ #searchbar
164
+ [placeholder]="'Buscar'"
165
+ (ionInput)="onSearch($event)"
166
+ [value]="searchTerm()"
167
+ show-clear-button="focus"
168
+ [debounce]="200"
169
+ ></ion-searchbar>
170
+ </div>
171
+
172
+ <!-- Options list -->
173
+ <div class="options-container">
174
+ <ion-list class="options-list">
175
+ <ion-item
176
+ *ngFor="let option of filteredOptions(); trackBy: trackByFn"
177
+ button
178
+ (click)="selectOption(option)"
179
+ class="option-item"
180
+ >
181
+ <ion-label>{{ option[labelProperty] }}</ion-label>
182
+ <ion-icon
183
+ *ngIf="isSelected(option)"
184
+ name="checkmark-outline"
185
+ slot="end"
186
+ color="primary"
187
+ ></ion-icon>
188
+ </ion-item>
189
+
190
+ <!-- No results message -->
191
+ <ion-item *ngIf="filteredOptions().length === 0" class="no-results">
192
+ <ion-label color="medium">
193
+ {{ searchTerm() ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
194
+ </ion-label>
195
+ </ion-item>
196
+ </ion-list>
197
+ </div>
198
+ </div>
199
+ `, isInline: true, styles: [":host{display:block;position:relative;width:100%}.select-container{position:relative;display:flex;align-items:center;cursor:pointer}.select-container .main-input{flex:1;cursor:pointer}.select-container .main-input.is-open{--border-color: var(--ion-color-primary)}.select-container .dropdown-icon{position:absolute;right:12px;font-size:16px;color:var(--ion-color-medium);transition:transform .2s ease;pointer-events:none;z-index:2}.select-container .dropdown-icon.rotated{transform:rotate(180deg)}.dropdown-overlay{position:absolute;top:100%;left:0;right:0;background:var(--ion-background-color);border:1px solid var(--ion-color-light);border-radius:8px;box-shadow:0 4px 16px #0000001a;z-index:1000;max-height:300px;opacity:0;transform:translateY(-8px);pointer-events:none;transition:all .2s ease}.dropdown-overlay.visible{opacity:1;transform:translateY(4px);pointer-events:all}.search-container{padding:12px;border-bottom:1px solid var(--ion-color-light)}.search-container ion-searchbar{--background: var(--ion-color-light);--border-radius: 8px;--box-shadow: none;--padding-start: 12px;--padding-end: 12px;height:40px}.options-container{max-height:240px;overflow-y:auto}.options-container .options-list{padding:0}.options-container .option-item{--padding-start: 16px;--padding-end: 16px;--min-height: 48px;cursor:pointer}.options-container .option-item:hover{--background: var(--ion-color-light)}.options-container .option-item ion-label{font-size:16px;line-height:1.4}.options-container .option-item ion-icon{font-size:20px}.options-container .no-results{--padding-start: 16px;--padding-end: 16px;--min-height: 48px;text-align:center}.options-container .no-results ion-label{font-style:italic;font-size:14px}@media (max-width: 768px){.dropdown-overlay{max-height:250px}.options-container{max-height:200px}}@media (prefers-color-scheme: dark){.dropdown-overlay{box-shadow:0 4px 16px #0000004d}}.option-item:focus-within{--background: var(--ion-color-primary-tint);outline:2px solid var(--ion-color-primary);outline-offset:-2px}.option-item{transition:background-color .15s ease}.dropdown-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocapitalize", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "maxlength", "minlength", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
323
200
  }
324
201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectSearchComponent, decorators: [{
325
202
  type: Component,
326
- args: [{ selector: 'val-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, SearchbarComponent, ReactiveFormsModule], template: `
327
- <ion-input
328
- type="text"
329
- [value]="displayValue"
330
- [placeholder]="props?.placeholder || placeholder"
331
- readonly
332
- (mousedown)="preventDefaultBehavior($event)"
333
- />
334
-
335
- <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
203
+ args: [{ selector: 'val-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, ReactiveFormsModule], template: `
204
+ <div class="select-container" (click)="toggleDropdown($event)">
205
+ <!-- Main input display -->
206
+ <ion-input
207
+ #mainInput
208
+ type="text"
209
+ [value]="displayValue()"
210
+ [placeholder]="props?.placeholder || placeholder"
211
+ readonly
212
+ class="main-input"
213
+ [class.is-open]="isOpen()"
214
+ />
215
+
216
+ <!-- Dropdown icon -->
217
+ <ion-icon
218
+ name="chevron-down-outline"
219
+ class="dropdown-icon"
220
+ [class.rotated]="isOpen()"
221
+ ></ion-icon>
222
+
223
+ <!-- Hidden input for form control -->
224
+ <ion-input
225
+ style="position: absolute; opacity: 0; pointer-events: none;"
226
+ [formControl]="props?.control"
227
+ type="hidden"
228
+ />
229
+ </div>
336
230
 
337
- <ion-modal
338
- #modal
339
- [initialBreakpoint]="1"
340
- [breakpoints]="[0, 0.5, 0.75, 1]"
341
- (didDismiss)="cancelModal()"
231
+ <!-- Dropdown overlay -->
232
+ <div
233
+ class="dropdown-overlay"
234
+ [class.visible]="isOpen()"
235
+ #dropdown
342
236
  >
343
- <ng-template>
344
- <ion-header>
345
- <ion-toolbar>
346
- <ion-title>{{ label }}</ion-title>
347
- <ion-buttons slot="end">
348
- <ion-button (click)="cancelModal()">Cerrar</ion-button>
349
- </ion-buttons>
350
- </ion-toolbar>
351
- <ion-toolbar>
352
- <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
353
- </ion-toolbar>
354
- </ion-header>
355
- <ion-content>
356
- <ion-list>
357
- <ion-item *ngFor="let item of filteredItems" button (click)="selectItem(item)" detail="false">
358
- <ion-label>{{ item[labelProperty] }}</ion-label>
359
- <ion-icon *ngIf="isItemSelected(item)" name="checkmark-outline" slot="end" color="primary"></ion-icon>
360
- </ion-item>
361
- <ion-item *ngIf="filteredItems.length === 0" lines="none">
362
- <ion-label color="dark">No se encontraron resultados</ion-label>
363
- </ion-item>
364
- </ion-list>
365
- </ion-content>
366
- </ng-template>
367
- </ion-modal>
368
- `, styles: ["ion-header{padding:8px 8px 0}\n"] }]
369
- }], ctorParameters: () => [], propDecorators: { modal: [{
237
+ <!-- Search bar -->
238
+ <div class="search-container" *ngIf="props?.options && props.options.length > 5">
239
+ <ion-searchbar
240
+ #searchbar
241
+ [placeholder]="'Buscar'"
242
+ (ionInput)="onSearch($event)"
243
+ [value]="searchTerm()"
244
+ show-clear-button="focus"
245
+ [debounce]="200"
246
+ ></ion-searchbar>
247
+ </div>
248
+
249
+ <!-- Options list -->
250
+ <div class="options-container">
251
+ <ion-list class="options-list">
252
+ <ion-item
253
+ *ngFor="let option of filteredOptions(); trackBy: trackByFn"
254
+ button
255
+ (click)="selectOption(option)"
256
+ class="option-item"
257
+ >
258
+ <ion-label>{{ option[labelProperty] }}</ion-label>
259
+ <ion-icon
260
+ *ngIf="isSelected(option)"
261
+ name="checkmark-outline"
262
+ slot="end"
263
+ color="primary"
264
+ ></ion-icon>
265
+ </ion-item>
266
+
267
+ <!-- No results message -->
268
+ <ion-item *ngIf="filteredOptions().length === 0" class="no-results">
269
+ <ion-label color="medium">
270
+ {{ searchTerm() ? 'No se encontraron resultados' : 'No hay opciones disponibles' }}
271
+ </ion-label>
272
+ </ion-item>
273
+ </ion-list>
274
+ </div>
275
+ </div>
276
+ `, styles: [":host{display:block;position:relative;width:100%}.select-container{position:relative;display:flex;align-items:center;cursor:pointer}.select-container .main-input{flex:1;cursor:pointer}.select-container .main-input.is-open{--border-color: var(--ion-color-primary)}.select-container .dropdown-icon{position:absolute;right:12px;font-size:16px;color:var(--ion-color-medium);transition:transform .2s ease;pointer-events:none;z-index:2}.select-container .dropdown-icon.rotated{transform:rotate(180deg)}.dropdown-overlay{position:absolute;top:100%;left:0;right:0;background:var(--ion-background-color);border:1px solid var(--ion-color-light);border-radius:8px;box-shadow:0 4px 16px #0000001a;z-index:1000;max-height:300px;opacity:0;transform:translateY(-8px);pointer-events:none;transition:all .2s ease}.dropdown-overlay.visible{opacity:1;transform:translateY(4px);pointer-events:all}.search-container{padding:12px;border-bottom:1px solid var(--ion-color-light)}.search-container ion-searchbar{--background: var(--ion-color-light);--border-radius: 8px;--box-shadow: none;--padding-start: 12px;--padding-end: 12px;height:40px}.options-container{max-height:240px;overflow-y:auto}.options-container .options-list{padding:0}.options-container .option-item{--padding-start: 16px;--padding-end: 16px;--min-height: 48px;cursor:pointer}.options-container .option-item:hover{--background: var(--ion-color-light)}.options-container .option-item ion-label{font-size:16px;line-height:1.4}.options-container .option-item ion-icon{font-size:20px}.options-container .no-results{--padding-start: 16px;--padding-end: 16px;--min-height: 48px;text-align:center}.options-container .no-results ion-label{font-style:italic;font-size:14px}@media (max-width: 768px){.dropdown-overlay{max-height:250px}.options-container{max-height:200px}}@media (prefers-color-scheme: dark){.dropdown-overlay{box-shadow:0 4px 16px #0000004d}}.option-item:focus-within{--background: var(--ion-color-primary-tint);outline:2px solid var(--ion-color-primary);outline-offset:-2px}.option-item{transition:background-color .15s ease}.dropdown-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}\n"] }]
277
+ }], ctorParameters: () => [], propDecorators: { dropdownRef: [{
370
278
  type: ViewChild,
371
- args: ['modal']
372
- }], label: [{
279
+ args: ['dropdown']
280
+ }], mainInputRef: [{
281
+ type: ViewChild,
282
+ args: ['mainInput']
283
+ }], props: [{
373
284
  type: Input
374
285
  }], labelProperty: [{
375
286
  type: Input
376
287
  }], valueProperty: [{
377
288
  type: Input
378
- }], multiple: [{
379
- type: Input
380
289
  }], placeholder: [{
381
290
  type: Input
382
- }], props: [{
383
- type: Input
384
291
  }] } });
385
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LXNlYXJjaC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92YWx0ZWNoLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL21vbGVjdWxlcy9zZWxlY3Qtc2VhcmNoL3NlbGVjdC1zZWFyY2guY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxNQUFNLEVBQ04sS0FBSyxFQUlMLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFdBQVcsRUFBWSxNQUFNLGdCQUFnQixDQUFDO0FBRXZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdURBQXVELENBQUM7QUFDcEYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDakYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7Ozs7O0FBeUR0RTs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8scUJBQXFCO0lBV2hDO1FBUFMsa0JBQWEsR0FBVyxNQUFNLENBQUM7UUFDL0Isa0JBQWEsR0FBVyxJQUFJLENBQUM7UUFDN0IsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUczQixnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQWdCMUMsU0FBSSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNuQixtQkFBYyxHQUFHLE1B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Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFnQkcsS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIGluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBJb25pY01vZHVsZSwgSW9uTW9kYWwgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEljb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaWNvbnMuc2VydmljZSc7XG5pbXBvcnQgeyBMYW5nU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2xhbmctcHJvdmlkZXIvbGFuZy1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IGFwcGx5RGVmYXVsdFZhbHVlVG9Db250cm9sIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3V0aWxzL2Zvcm0tZGVmYXVsdHMnO1xuaW1wb3J0IHsgcmVwbGFjZVNwZWNpYWxDaGFycyB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC91dGlscy90ZXh0JztcbmltcG9ydCB7IElucHV0TWV0YWRhdGEsIElucHV0T3B0aW9uIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgU2VhcmNoYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vc2VhcmNoYmFyL3NlYXJjaGJhci5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtc2VsZWN0LXNlYXJjaCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIElvbmljTW9kdWxlLCBGb3Jtc01vZHVsZSwgU2VhcmNoYmFyQ29tcG9uZW50LCBSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8aW9uLWlucHV0XG4gICAgICB0eXBlPVwidGV4dFwiXG4gICAgICBbdmFsdWVdPVwiZGlzcGxheVZhbHVlXCJcbiAgICAgIFtwbGFjZWhvbGRlcl09XCJwcm9wcz8ucGxhY2Vob2xkZXIgfHwgcGxhY2Vob2xkZXJcIlxuICAgICAgcmVhZG9ubHlcbiAgICAgIChtb3VzZWRvd24pPVwicHJldmVudERlZmF1bHRCZWhhdmlvcigkZXZlbnQpXCJcbiAgICAvPlxuXG4gICAgPGlvbi1pbnB1dCBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTtcIiBbZm9ybUNvbnRyb2xdPVwicHJvcHMuY29udHJvbFwiIHR5cGU9XCJoaWRkZW5cIj48L2lvbi1pbnB1dD5cblxuICAgIDxpb24tbW9kYWxcbiAgICAgICNtb2RhbFxuICAgICAgW2luaXRpYWxCcmVha3BvaW50XT1cIjFcIlxuICAgICAgW2JyZWFrcG9pbnRzXT1cIlswLCAwLjUsIDAuNzUsIDFdXCJcbiAgICAgIChkaWREaXNtaXNzKT1cImNhbmNlbE1vZGFsKClcIlxuICAgID5cbiAgICAgIDxuZy10ZW1wbGF0ZT5cbiAgICAgICAgPGlvbi1oZWFkZXI+XG4gICAgICAgICAgPGlvbi10b29sYmFyPlxuICAgICAgICAgICAgPGlvbi10aXRsZT57eyBsYWJlbCB9fTwvaW9uLXRpdGxlPlxuICAgICAgICAgICAgPGlvbi1idXR0b25zIHNsb3Q9XCJlbmRcIj5cbiAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cImNhbmNlbE1vZGFsKClcIj5DZXJyYXI8L2lvbi1idXR0b24+XG4gICAgICAgICAgICA8L2lvbi1idXR0b25zPlxuICAgICAgICAgIDwvaW9uLXRvb2xiYXI+XG4gICAgICAgICAgPGlvbi10b29sYmFyPlxuICAgICAgICAgICAgPHZhbC1zZWFyY2hiYXIgKGZpbHRlckV2ZW50KT1cIm9uRmlsdGVyKCRldmVudClcIiAoZm9jdXNFdmVudCk9XCJvbkZvY3VzKClcIiAoYmx1ckV2ZW50KT1cIm9uQmx1cigpXCIgLz5cbiAgICAgICAgICA8L2lvbi10b29sYmFyPlxuICAgICAgICA8L2lvbi1oZWFkZXI+XG4gICAgICAgIDxpb24tY29udGVudD5cbiAgICAgICAgICA8aW9uLWxpc3Q+XG4gICAgICAgICAgICA8aW9uLWl0ZW0gKm5nRm9yPVwibGV0IGl0ZW0gb2YgZmlsdGVyZWRJdGVtc1wiIGJ1dHRvbiAoY2xpY2spPVwic2VsZWN0SXRlbShpdGVtKVwiIGRldGFpbD1cImZhbHNlXCI+XG4gICAgICAgICAgICAgIDxpb24tbGFiZWw+e3sgaXRlbVtsYWJlbFByb3BlcnR5XSB9fTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICA8aW9uLWljb24gKm5nSWY9XCJpc0l0ZW1TZWxlY3RlZChpdGVtKVwiIG5hbWU9XCJjaGVja21hcmstb3V0bGluZVwiIHNsb3Q9XCJlbmRcIiBjb2xvcj1cInByaW1hcnlcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICAgIDxpb24taXRlbSAqbmdJZj1cImZpbHRlcmVkSXRlbXMubGVuZ3RoID09PSAwXCIgbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYXJrXCI+Tm8gc2UgZW5jb250cmFyb24gcmVzdWx0YWRvczwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICA8L2lvbi1saXN0PlxuICAgICAgICA8L2lvbi1jb250ZW50PlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L2lvbi1tb2RhbD5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgaW9uLWhlYWRlciB7XG4gICAgICAgIHBhZGRpbmc6IDhweCA4cHggMHB4IDhweDtcbiAgICAgIH1cbiAgICBgLFxuICBdLFxufSlcbi8qKlxuICogdmFsLXNlbGVjdC1zZWFyY2hcbiAqXG4gKiBBIHNlYXJjaGFibGUgc2VsZWN0L2Ryb3Bkb3duIGlucHV0IHdpdGggbW9kYWwgYW5kIGZpbHRlcmluZywgaW50ZWdyYXRlZCB3aXRoIEFuZ3VsYXIgZm9ybXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIDx2YWwtc2VsZWN0LXNlYXJjaCBbcHJvcHNdPVwieyBjb250cm9sOiBteUNvbnRyb2wsIGxhYmVsOiAnQ2hvb3NlJywgb3B0aW9uczogW3sgaWQ6ICcxJywgbmFtZTogJ09wdGlvbiAxJyB9XSB9XCI+PC92YWwtc2VsZWN0LXNlYXJjaD5cbiAqXG4gKiBAaW5wdXQgcHJvcHM6IElucHV0TWV0YWRhdGEgLSBDb25maWd1cmF0aW9uIGZvciB0aGUgc2VsZWN0IGlucHV0IChmb3JtIGNvbnRyb2wsIGxhYmVsLCBvcHRpb25zLCBldGMuKVxuICovXG5leHBvcnQgY2xhc3MgU2VsZWN0U2VhcmNoQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBAVmlld0NoaWxkKCdtb2RhbCcpIG1vZGFsITogSW9uTW9kYWw7XG5cbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZztcbiAgQElucHV0KCkgbGFiZWxQcm9wZXJ0eTogc3RyaW5nID0gJ25hbWUnO1xuICBASW5wdXQoKSB2YWx1ZVByb3BlcnR5OiBzdHJpbmcgPSAnaWQnO1xuICBASW5wdXQoKSBtdWx0aXBsZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nO1xuXG4gIHByaXZhdGUgbGFuZ1NlcnZpY2UgPSBpbmplY3QoTGFuZ1NlcnZpY2UpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubGFiZWwgPSB0aGlzLmxhbmdTZXJ2aWNlLmdldFRleHQoJ19nbG9iYWwnLCAnc2VsZWN0JywgJ1NlbGVjY2lvbmFyJyk7XG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IHRoaXMubGFuZ1NlcnZpY2UuZ2V0VGV4dCgnX2dsb2JhbCcsICdzZWxlY3RPcHRpb24nLCAnU2VsZWNjaW9uZSB1bmEgb3BjacOzbicpO1xuICB9XG4gIC8qKlxuICAgKiBJbnB1dCBjb25maWd1cmF0aW9uIG9iamVjdC5cbiAgICogQHR5cGUge0lucHV0TWV0YWRhdGF9XG4gICAqIEBwcm9wZXJ0eSBjb250cm9sIC0gVGhlIEFuZ3VsYXIgRm9ybUNvbnRyb2wgZm9yIHRoZSBzZWxlY3QgaW5wdXQuXG4gICAqIEBwcm9wZXJ0eSBsYWJlbCAtIFRoZSBsYWJlbCBmb3IgdGhlIHNlbGVjdC5cbiAgICogQHByb3BlcnR5IG9wdGlvbnMgLSBUaGUgYXZhaWxhYmxlIG9wdGlvbnMgZm9yIHRoZSBzZWxlY3QuXG4gICAqIEBwcm9wZXJ0eSBwbGFjZWhvbGRlciAtIFRoZSBwbGFjZWhvbGRlciB0ZXh0LlxuICAgKi9cbiAgQElucHV0KCkgcHJvcHM6IElucHV0TWV0YWRhdGE7XG5cbiAgaWNvbiA9IGluamVjdChJY29uU2VydmljZSk7XG4gIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3IgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuXG4gIHNlYXJjaFRlcm06IHN0cmluZyA9ICcnO1xuICBmaWx0ZXJlZEl0ZW1zOiBJbnB1dE9wdGlvbltdID0gW107XG4gIHNlbGVjdGVkSXRlbXM6IElucHV0T3B0aW9uW10gPSBbXTtcbiAgZGlzcGxheVZhbHVlOiBzdHJpbmcgPSAnJztcblxuICBwcml2YXRlIHByZXZpb3VzT3B0aW9uczogYW55W10gPSBbXTtcbiAgcHJpdmF0ZSBpc1Byb2Nlc3NpbmdDaGFuZ2VzID0gZmFsc2U7XG4gIHByaXZhdGUgdmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuYXBwbHlEZWZhdWx0VmFsdWUoKTtcbiAgICB0aGlzLmluaXRpYWxpemVJdGVtcygpO1xuICAgIHRoaXMuc3luY0NvbnRyb2xWYWx1ZVdpdGhTZWxlY3RlZEl0ZW1zKCk7XG4gICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICB0aGlzLnN1YnNjcmliZVRvVmFsdWVDaGFuZ2VzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICAvLyBMaW1waWFyIHN1c2NyaXBjaW9uZXMgcGFyYSBldml0YXIgbWVtb3J5IGxlYWtzXG4gICAgaWYgKHRoaXMudmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBFdml0YXIgYnVjbGVzIGluZmluaXRvc1xuICAgIGlmICh0aGlzLmlzUHJvY2Vzc2luZ0NoYW5nZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDdWFuZG8gY2FtYmlhIHByb3BzIG8gcHJvcHMub3B0aW9uc1xuICAgIGlmIChjaGFuZ2VzWydwcm9wcyddKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZ0NoYW5nZXMgPSB0cnVlO1xuXG4gICAgICAgIC8vIERlc3VzY3JpYmlyc2UgZGVsIGFudGlndW8gY29udHJvbCBzaSBleGlzdGVcbiAgICAgICAgaWYgKHRoaXMudmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZXNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnByb3BzPy5vcHRpb25zKSB7XG4gICAgICAgICAgLy8gVmVyaWZpY2FyIHNpIGxhcyBvcGNpb25lcyBoYW4gY2FtYmlhZG8gcmVhbG1lbnRlXG4gICAgICAgICAgY29uc3Qgb3B0aW9uc0NoYW5nZWQgPSAhdGhpcy5hcmVPcHRpb25zRXF1YWwodGhpcy5wcmV2aW91c09wdGlvbnMsIHRoaXMucHJvcHMub3B0aW9ucyk7XG5cbiAgICAgICAgICBpZiAob3B0aW9uc0NoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMucHJldmlvdXNPcHRpb25zID0gWy4uLnRoaXMucHJvcHMub3B0aW9uc107XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVJdGVtcygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNpbmNyb25pemFyIGNvbiBlbCBudWV2byBjb250cm9sIHNpIGV4aXN0ZVxuICAgICAgICB0aGlzLnN5bmNDb250cm9sVmFsdWVXaXRoU2VsZWN0ZWRJdGVtcygpO1xuICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlWYWx1ZSgpO1xuXG4gICAgICAgIC8vIFN1c2NyaWJpcnNlIGFsIG51ZXZvIGNvbnRyb2xcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVUb1ZhbHVlQ2hhbmdlcygpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmdDaGFuZ2VzID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaW9uVmlld1dpbGxFbnRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1Byb2Nlc3NpbmdDaGFuZ2VzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuaXNQcm9jZXNzaW5nQ2hhbmdlcyA9IHRydWU7XG4gICAgICB0aGlzLmluaXRpYWxpemVJdGVtcygpO1xuICAgICAgdGhpcy5zeW5jQ29udHJvbFZhbHVlV2l0aFNlbGVjdGVkSXRlbXMoKTtcbiAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICB0aGlzLnN1YnNjcmliZVRvVmFsdWVDaGFuZ2VzKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaXNQcm9jZXNzaW5nQ2hhbmdlcyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN1c2NyaWJpcnNlIGEgY2FtYmlvcyBlbiBlbCBGb3JtQ29udHJvbFxuICBwcml2YXRlIHN1YnNjcmliZVRvVmFsdWVDaGFuZ2VzKCkge1xuICAgIGlmICghdGhpcy5wcm9wcz8uY29udHJvbCkgcmV0dXJuO1xuXG4gICAgdGhpcy52YWx1ZUNoYW5nZXNTdWJzY3JpcHRpb24gPSB0aGlzLnByb3BzLmNvbnRyb2wudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1Byb2Nlc3NpbmdDaGFuZ2VzKSByZXR1cm47XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nQ2hhbmdlcyA9IHRydWU7XG4gICAgICAgIHRoaXMuc3luY0NvbnRyb2xWYWx1ZVdpdGhTZWxlY3RlZEl0ZW1zKCk7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZ0NoYW5nZXMgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIENvbXBhcmEgc2kgZG9zIGFycmF5cyBkZSBvcGNpb25lcyBzb24gaWd1YWxlc1xuICBwcml2YXRlIGFyZU9wdGlvbnNFcXVhbChwcmV2T3B0aW9uczogYW55W10sIG5ld09wdGlvbnM6IGFueVtdKTogYm9vbGVhbiB7XG4gICAgLy8gUEVSRjogVXNlIHJlZmVyZW5jZSBlcXVhbGl0eSBmaXJzdCBmb3IgZmFzdCBwYXRoXG4gICAgaWYgKHByZXZPcHRpb25zID09PSBuZXdPcHRpb25zKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoIXByZXZPcHRpb25zIHx8ICFuZXdPcHRpb25zKSByZXR1cm4gcHJldk9wdGlvbnMgPT09IG5ld09wdGlvbnM7XG4gICAgaWYgKHByZXZPcHRpb25zLmxlbmd0aCAhPT0gbmV3T3B0aW9ucy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICAvLyBPbmx5IGNvbXBhcmUgdmFsdWVQcm9wZXJ0eSBmb3IgZXF1YWxpdHlcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZPcHRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocHJldk9wdGlvbnNbaV1bdGhpcy52YWx1ZVByb3BlcnR5XSAhPT0gbmV3T3B0aW9uc1tpXVt0aGlzLnZhbHVlUHJvcGVydHldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVJdGVtcygpOiB2b2lkIHtcbiAgICAvLyBQRVJGOiBBdm9pZCB1bm5lY2Vzc2FyeSBhcnJheSBjb3BpZXNcbiAgICB0aGlzLmZpbHRlcmVkSXRlbXMgPSB0aGlzLnByb3BzPy5vcHRpb25zIHx8IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jQ29udHJvbFZhbHVlV2l0aFNlbGVjdGVkSXRlbXMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnByb3BzPy5jb250cm9sKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbXMgPSBbXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29udHJvbFZhbHVlID0gdGhpcy5wcm9wcy5jb250cm9sLnZhbHVlO1xuICAgIGlmIChjb250cm9sVmFsdWUgPT09IG51bGwgfHwgY29udHJvbFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBQRVJGOiBVc2UgYSBNYXAgZm9yIGZhc3RlciBsb29rdXAgaWYgb3B0aW9ucyBhcmUgbGFyZ2VcbiAgICBpZiAodGhpcy5wcm9wcy5vcHRpb25zICYmIHRoaXMucHJvcHMub3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBtYXAgPSBuZXcgTWFwKHRoaXMucHJvcHMub3B0aW9ucy5tYXAob3B0ID0+IFtvcHRbdGhpcy52YWx1ZVByb3BlcnR5XSwgb3B0XSkpO1xuICAgICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSBtYXAuZ2V0KGNvbnRyb2xWYWx1ZSk7XG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbXMgPSBzZWxlY3RlZE9wdGlvbiA/IFtzZWxlY3RlZE9wdGlvbl0gOiBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zID0gW107XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBseURlZmF1bHRWYWx1ZSgpOiB2b2lkIHtcbiAgICBhcHBseURlZmF1bHRWYWx1ZVRvQ29udHJvbCh0aGlzLnByb3BzKTtcbiAgfVxuXG4gIG9uRmlsdGVyKGV2ZW50KSB7XG4gICAgLy8gSWYgbm8gc2VhcmNoIHRlcm0sIHNob3cgYWxsIG9wdGlvbnNcbiAgICBpZiAoIWV2ZW50IHx8IGV2ZW50LnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHRoaXMuZmlsdGVyZWRJdGVtcyA9IHRoaXMucHJvcHM/Lm9wdGlvbnMgPyBbLi4udGhpcy5wcm9wcy5vcHRpb25zXSA6IFtdO1xuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSWYgbm8gb3B0aW9ucywgbm90aGluZyB0byBmaWx0ZXJcbiAgICBpZiAoIXRoaXMucHJvcHM/Lm9wdGlvbnMgfHwgdGhpcy5wcm9wcy5vcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5maWx0ZXJlZEl0ZW1zID0gW107XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBQRVJGOiBBdm9pZCByZXBlYXRlZCByZXBsYWNlU3BlY2lhbENoYXJzIGFuZCB0b0xvd2VyQ2FzZSBmb3IgZWFjaCBvcHRpb25cbiAgICBjb25zdCBzZWFyY2ggPSByZXBsYWNlU3BlY2lhbENoYXJzKGV2ZW50LnRvTG93ZXJDYXNlKCkpO1xuICAgIHRoaXMuZmlsdGVyZWRJdGVtcyA9IHRoaXMucHJvcHMub3B0aW9ucy5maWx0ZXIoZWxlbWVudCA9PiB7XG4gICAgICAvLyBPbmx5IHVzZSBsYWJlbFByb3BlcnR5IGFuZCB2YWx1ZVByb3BlcnR5IGZvciBmaWx0ZXJpbmcgKGZhc3RlcilcbiAgICAgIGNvbnN0IGxhYmVsID0gZWxlbWVudFt0aGlzLmxhYmVsUHJvcGVydHldXG4gICAgICAgID8gcmVwbGFjZVNwZWNpYWxDaGFycyhTdHJpbmcoZWxlbWVudFt0aGlzLmxhYmVsUHJvcGVydHldKS50b0xvd2VyQ2FzZSgpKVxuICAgICAgICA6ICcnO1xuICAgICAgY29uc3QgdmFsdWUgPSBlbGVtZW50W3RoaXMudmFsdWVQcm9wZXJ0eV1cbiAgICAgICAgPyByZXBsYWNlU3BlY2lhbENoYXJzKFN0cmluZyhlbGVtZW50W3RoaXMudmFsdWVQcm9wZXJ0eV0pLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgIDogJyc7XG4gICAgICByZXR1cm4gbGFiZWwuaW5jbHVkZXMoc2VhcmNoKSB8fCB2YWx1ZS5pbmNsdWRlcyhzZWFyY2gpO1xuICAgIH0pO1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgb25Gb2N1cygpIHtcbiAgICBjb25zb2xlLmxvZygnb25Gb2N1cycpO1xuICB9XG5cbiAgb25CbHVyKCkge1xuICAgIGNvbnNvbGUubG9nKCdvbkJsdXInKTtcbiAgfVxuXG4gIG9wZW5Nb2RhbCgpIHtcbiAgICBpZiAodGhpcy5tb2RhbCkge1xuICAgICAgdGhpcy5tb2RhbC5wcmVzZW50KCk7XG4gICAgfVxuICB9XG5cbiAgcHJldmVudERlZmF1bHRCZWhhdmlvcihldmVudDogTW91c2VFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5vcGVuTW9kYWwoKTtcbiAgfVxuXG4gIGNhbmNlbE1vZGFsKCkge1xuICAgIC8vIFJlc2V0IGZpbHRlciBhbmQgc2hvdyBhbGwgb3B0aW9ucyB3aGVuIGNsb3NpbmcgbW9kYWxcbiAgICB0aGlzLnNlYXJjaFRlcm0gPSAnJztcbiAgICB0aGlzLmZpbHRlcmVkSXRlbXMgPSB0aGlzLnByb3BzPy5vcHRpb25zID8gWy4uLnRoaXMucHJvcHMub3B0aW9uc10gOiBbXTtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICBpZiAodGhpcy5tb2RhbCkge1xuICAgICAgdGhpcy5tb2RhbC5kaXNtaXNzKCk7XG4gICAgfVxuICB9XG5cbiAgc2VsZWN0SXRlbShpdGVtOiBhbnkpIHtcbiAgICBpZiAodGhpcy5tdWx0aXBsZSkge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnNlbGVjdGVkSXRlbXMuZmluZEluZGV4KFxuICAgICAgICBzZWxlY3RlZEl0ZW0gPT4gc2VsZWN0ZWRJdGVtW3RoaXMudmFsdWVQcm9wZXJ0eV0gPT09IGl0ZW1bdGhpcy52YWx1ZVByb3BlcnR5XVxuICAgICAgKTtcblxuICAgICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbXMucHVzaChpdGVtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbXMgPSBbaXRlbV07XG4gICAgICB0aGlzLmNhbmNlbE1vZGFsKCk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICB0aGlzLmFwcGx5Q2hhbmdlcygpO1xuICB9XG5cbiAgaXNJdGVtU2VsZWN0ZWQoaXRlbTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJdGVtcy5zb21lKHNlbGVjdGVkSXRlbSA9PiBzZWxlY3RlZEl0ZW1bdGhpcy52YWx1ZVByb3BlcnR5XSA9PT0gaXRlbVt0aGlzLnZhbHVlUHJvcGVydHldKTtcbiAgfVxuXG4gIHVwZGF0ZURpc3BsYXlWYWx1ZSgpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEl0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5kaXNwbGF5VmFsdWUgPSAnJztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tdWx0aXBsZSkge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUgPSB0aGlzLnNlbGVjdGVkSXRlbXNbMF1bdGhpcy5sYWJlbFByb3BlcnR5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlzcGxheVZhbHVlID0gYCR7dGhpcy5zZWxlY3RlZEl0ZW1zLmxlbmd0aH0gZWxlbWVudG9zIHNlbGVjY2lvbmFkb3NgO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRpc3BsYXlWYWx1ZSA9IHRoaXMuc2VsZWN0ZWRJdGVtc1swXVt0aGlzLmxhYmVsUHJvcGVydHldO1xuICAgIH1cbiAgfVxuXG4gIGFwcGx5Q2hhbmdlcygpIHtcbiAgICBpZiAoIXRoaXMucHJvcHM/LmNvbnRyb2wpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5pc1Byb2Nlc3NpbmdDaGFuZ2VzID0gdHJ1ZTtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMucHJvcHMuY29udHJvbC5zZXRWYWx1ZSh0aGlzLnNlbGVjdGVkSXRlbXNbMF1bdGhpcy52YWx1ZVByb3BlcnR5XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByb3BzLmNvbnRyb2wuc2V0VmFsdWUobnVsbCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucHJvcHMuY29udHJvbC5tYXJrQXNEaXJ0eSgpO1xuICAgICAgdGhpcy5wcm9wcy5jb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pc1Byb2Nlc3NpbmdDaGFuZ2VzID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gTcOpdG9kbyBww7pibGljbyBwYXJhIHJlaW5pY2lhciBlbCBjb21wb25lbnRlXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuc2VsZWN0ZWRJdGVtcyA9IFtdO1xuICAgIHRoaXMuZGlzcGxheVZhbHVlID0gJyc7XG4gICAgaWYgKHRoaXMucHJvcHM/LmNvbnRyb2wpIHtcbiAgICAgIHRoaXMucHJvcHMuY29udHJvbC5zZXRWYWx1ZShudWxsKTtcbiAgICB9XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cbn1cbiJdfQ==
292
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LXNlYXJjaC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92YWx0ZWNoLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL21vbGVjdWxlcy9zZWxlY3Qtc2VhcmNoL3NlbGVjdC1zZWFyY2guY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsU0FBUyxFQUVULE1BQU0sRUFDTixLQUFLLEVBS0wsU0FBUyxFQUNULE1BQU0sRUFDTixRQUFRLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdURBQXVELENBQUM7QUFDcEYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDakYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7O0FBbUZqRSxNQUFNLE9BQU8scUJBQXFCO0lBb0RoQztRQS9DUyxrQkFBYSxHQUFXLE1BQU0sQ0FBQztRQUMvQixrQkFBYSxHQUFXLElBQUksQ0FBQztRQUM3QixnQkFBVyxHQUFXLEVBQUUsQ0FBQztRQUUxQixnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxQyx3Q0FBd0M7UUFDeEMsV0FBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixlQUFVLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLGtCQUFhLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztRQUU1QyxtQkFBbUI7UUFDbkIsaUJBQVksR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUV0QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILG9CQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUM5QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBRS9DLFFBQVE7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxFQUFFO2dCQUN0RCxZQUFZLEVBQUUsT0FBTyxDQUFDLE1BQU07Z0JBQzVCLFVBQVUsRUFBRSxNQUFNO2dCQUNsQixPQUFPLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsc0JBQXNCO2FBQ3BELENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDWixPQUFPLE9BQU8sQ0FBQztZQUNqQixDQUFDO1lBRUQsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUM3QixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztvQkFDdEMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQ3ZFLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ1AsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7b0JBQ3RDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN2RSxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNQLE1BQU0sVUFBVSxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMvQyxPQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNsRSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBR0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsY0FBYyxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFFaEcsdUNBQXVDO1FBQ3ZDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELFdBQVc7UUFDVCxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixjQUFjLENBQUMsS0FBWTtRQUN6QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDbEIsNkNBQTZDO1lBQzdDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNsRixJQUFJLFNBQVMsRUFBRSxDQUFDO29CQUNkLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDdkIsQ0FBQztZQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNWLENBQUM7SUFDSCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQVU7UUFDakIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFtQjtRQUM5QixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXhCLHNCQUFzQjtRQUN0QixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JDLENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUFDLE1BQW1CO1FBQzVCLE9BQU8sSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVELFNBQVMsQ0FBQyxNQUFjLEVBQUUsTUFBbUI7UUFDM0MsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxLQUFZO1FBQ3JDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxhQUFhLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDekQsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDN0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxLQUFhO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsMEJBQTBCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUM7SUFDSCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7K0dBM0lVLHFCQUFxQjttR0FBckIscUJBQXFCLCtaQTVFdEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5RVQseXFFQTFFUyxZQUFZLCtQQUFFLFdBQVcsaW1EQUFFLFdBQVcsc0lBQUUsbUJBQW1COzs0RkE2RTFELHFCQUFxQjtrQkFoRmpDLFNBQVM7K0JBQ0UsbUJBQW1CLGNBQ2pCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixDQUFDLFlBQzVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUVUO3dEQUlzQixXQUFXO3NCQUFqQyxTQUFTO3VCQUFDLFVBQVU7Z0JBQ0csWUFBWTtzQkFBbkMsU0FBUzt1QkFBQyxXQUFXO2dCQUViLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIGluamVjdCxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT25EZXN0cm95LFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgc2lnbmFsLFxuICBjb21wdXRlZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW9uaWNNb2R1bGUgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBMYW5nU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2xhbmctcHJvdmlkZXIvbGFuZy1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IGFwcGx5RGVmYXVsdFZhbHVlVG9Db250cm9sIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3V0aWxzL2Zvcm0tZGVmYXVsdHMnO1xuaW1wb3J0IHsgcmVwbGFjZVNwZWNpYWxDaGFycyB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC91dGlscy90ZXh0JztcbmltcG9ydCB7IElucHV0TWV0YWRhdGEsIElucHV0T3B0aW9uIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtc2VsZWN0LXNlYXJjaCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIElvbmljTW9kdWxlLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cInNlbGVjdC1jb250YWluZXJcIiAoY2xpY2spPVwidG9nZ2xlRHJvcGRvd24oJGV2ZW50KVwiPlxuICAgICAgPCEtLSBNYWluIGlucHV0IGRpc3BsYXkgLS0+XG4gICAgICA8aW9uLWlucHV0XG4gICAgICAgICNtYWluSW5wdXRcbiAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICBbdmFsdWVdPVwiZGlzcGxheVZhbHVlKClcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwicHJvcHM/LnBsYWNlaG9sZGVyIHx8IHBsYWNlaG9sZGVyXCJcbiAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgY2xhc3M9XCJtYWluLWlucHV0XCJcbiAgICAgICAgW2NsYXNzLmlzLW9wZW5dPVwiaXNPcGVuKClcIlxuICAgICAgLz5cbiAgICAgIFxuICAgICAgPCEtLSBEcm9wZG93biBpY29uIC0tPlxuICAgICAgPGlvbi1pY29uIFxuICAgICAgICBuYW1lPVwiY2hldnJvbi1kb3duLW91dGxpbmVcIiBcbiAgICAgICAgY2xhc3M9XCJkcm9wZG93bi1pY29uXCIgXG4gICAgICAgIFtjbGFzcy5yb3RhdGVkXT1cImlzT3BlbigpXCJcbiAgICAgID48L2lvbi1pY29uPlxuICAgICAgXG4gICAgICA8IS0tIEhpZGRlbiBpbnB1dCBmb3IgZm9ybSBjb250cm9sIC0tPlxuICAgICAgPGlvbi1pbnB1dCBcbiAgICAgICAgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IG9wYWNpdHk6IDA7IHBvaW50ZXItZXZlbnRzOiBub25lO1wiIFxuICAgICAgICBbZm9ybUNvbnRyb2xdPVwicHJvcHM/LmNvbnRyb2xcIiBcbiAgICAgICAgdHlwZT1cImhpZGRlblwiXG4gICAgICAvPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBEcm9wZG93biBvdmVybGF5IC0tPlxuICAgIDxkaXYgXG4gICAgICBjbGFzcz1cImRyb3Bkb3duLW92ZXJsYXlcIiBcbiAgICAgIFtjbGFzcy52aXNpYmxlXT1cImlzT3BlbigpXCJcbiAgICAgICNkcm9wZG93blxuICAgID5cbiAgICAgIDwhLS0gU2VhcmNoIGJhciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtY29udGFpbmVyXCIgKm5nSWY9XCJwcm9wcz8ub3B0aW9ucyAmJiBwcm9wcy5vcHRpb25zLmxlbmd0aCA+IDVcIj5cbiAgICAgICAgPGlvbi1zZWFyY2hiYXJcbiAgICAgICAgICAjc2VhcmNoYmFyXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidCdXNjYXInXCJcbiAgICAgICAgICAoaW9uSW5wdXQpPVwib25TZWFyY2goJGV2ZW50KVwiXG4gICAgICAgICAgW3ZhbHVlXT1cInNlYXJjaFRlcm0oKVwiXG4gICAgICAgICAgc2hvdy1jbGVhci1idXR0b249XCJmb2N1c1wiXG4gICAgICAgICAgW2RlYm91bmNlXT1cIjIwMFwiXG4gICAgICAgID48L2lvbi1zZWFyY2hiYXI+XG4gICAgICA8L2Rpdj5cbiAgICAgIFxuICAgICAgPCEtLSBPcHRpb25zIGxpc3QgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwib3B0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgPGlvbi1saXN0IGNsYXNzPVwib3B0aW9ucy1saXN0XCI+XG4gICAgICAgICAgPGlvbi1pdGVtIFxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBmaWx0ZXJlZE9wdGlvbnMoKTsgdHJhY2tCeTogdHJhY2tCeUZuXCIgXG4gICAgICAgICAgICBidXR0b24gXG4gICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0T3B0aW9uKG9wdGlvbilcIlxuICAgICAgICAgICAgY2xhc3M9XCJvcHRpb24taXRlbVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGlvbi1sYWJlbD57eyBvcHRpb25bbGFiZWxQcm9wZXJ0eV0gfX08L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDxpb24taWNvbiBcbiAgICAgICAgICAgICAgKm5nSWY9XCJpc1NlbGVjdGVkKG9wdGlvbilcIiBcbiAgICAgICAgICAgICAgbmFtZT1cImNoZWNrbWFyay1vdXRsaW5lXCIgXG4gICAgICAgICAgICAgIHNsb3Q9XCJlbmRcIiBcbiAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgID48L2lvbi1pY29uPlxuICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgXG4gICAgICAgICAgPCEtLSBObyByZXN1bHRzIG1lc3NhZ2UgLS0+XG4gICAgICAgICAgPGlvbi1pdGVtICpuZ0lmPVwiZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJuby1yZXN1bHRzXCI+XG4gICAgICAgICAgICA8aW9uLWxhYmVsIGNvbG9yPVwibWVkaXVtXCI+XG4gICAgICAgICAgICAgIHt7IHNlYXJjaFRlcm0oKSA/ICdObyBzZSBlbmNvbnRyYXJvbiByZXN1bHRhZG9zJyA6ICdObyBoYXkgb3BjaW9uZXMgZGlzcG9uaWJsZXMnIH19XG4gICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICA8L2lvbi1saXN0PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlVXJsczogWycuL3NlbGVjdC1zZWFyY2guY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBTZWxlY3RTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgQFZpZXdDaGlsZCgnZHJvcGRvd24nKSBkcm9wZG93blJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ21haW5JbnB1dCcpIG1haW5JbnB1dFJlZiE6IEVsZW1lbnRSZWY7XG5cbiAgQElucHV0KCkgcHJvcHMhOiBJbnB1dE1ldGFkYXRhO1xuICBASW5wdXQoKSBsYWJlbFByb3BlcnR5OiBzdHJpbmcgPSAnbmFtZSc7XG4gIEBJbnB1dCgpIHZhbHVlUHJvcGVydHk6IHN0cmluZyA9ICdpZCc7XG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnJztcblxuICBwcml2YXRlIGxhbmdTZXJ2aWNlID0gaW5qZWN0KExhbmdTZXJ2aWNlKTtcbiAgXG4gIC8vIFNpZ25hbHMgZm9yIHJlYWN0aXZlIHN0YXRlIG1hbmFnZW1lbnRcbiAgaXNPcGVuID0gc2lnbmFsKGZhbHNlKTtcbiAgc2VhcmNoVGVybSA9IHNpZ25hbCgnJyk7XG4gIHNlbGVjdGVkVmFsdWUgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIFxuICAvLyBDb21wdXRlZCBzaWduYWxzXG4gIGRpc3BsYXlWYWx1ZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuc2VsZWN0ZWRWYWx1ZSgpO1xuICAgIGlmICghdmFsdWUpIHJldHVybiAnJztcbiAgICBcbiAgICBjb25zdCBvcHRpb24gPSB0aGlzLmdldE9wdGlvbkJ5VmFsdWUodmFsdWUpO1xuICAgIHJldHVybiBvcHRpb24gPyBvcHRpb25bdGhpcy5sYWJlbFByb3BlcnR5XSA6ICcnO1xuICB9KTtcblxuICBmaWx0ZXJlZE9wdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucHJvcHM/Lm9wdGlvbnMgfHwgW107XG4gICAgY29uc3Qgc2VhcmNoID0gdGhpcy5zZWFyY2hUZXJtKCkudG9Mb3dlckNhc2UoKTtcbiAgICBcbiAgICAvLyBEZWJ1Z1xuICAgIGNvbnNvbGUubG9nKCdbU2VsZWN0U2VhcmNoXSBmaWx0ZXJlZE9wdGlvbnMgY29tcHV0ZWQ6Jywge1xuICAgICAgb3B0aW9uc0NvdW50OiBvcHRpb25zLmxlbmd0aCxcbiAgICAgIHNlYXJjaFRlcm06IHNlYXJjaCxcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMuc2xpY2UoMCwgMykgLy8gUHJpbWVyYXMgMyBvcGNpb25lc1xuICAgIH0pO1xuICAgIFxuICAgIGlmICghc2VhcmNoKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIG9wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiB7XG4gICAgICBjb25zdCBsYWJlbCA9IG9wdGlvblt0aGlzLmxhYmVsUHJvcGVydHldXG4gICAgICAgID8gcmVwbGFjZVNwZWNpYWxDaGFycyhTdHJpbmcob3B0aW9uW3RoaXMubGFiZWxQcm9wZXJ0eV0pLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgIDogJyc7XG4gICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvblt0aGlzLnZhbHVlUHJvcGVydHldXG4gICAgICAgID8gcmVwbGFjZVNwZWNpYWxDaGFycyhTdHJpbmcob3B0aW9uW3RoaXMudmFsdWVQcm9wZXJ0eV0pLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgIDogJyc7XG4gICAgICBjb25zdCBzZWFyY2hUZXJtID0gcmVwbGFjZVNwZWNpYWxDaGFycyhzZWFyY2gpO1xuICAgICAgcmV0dXJuIGxhYmVsLmluY2x1ZGVzKHNlYXJjaFRlcm0pIHx8IHZhbHVlLmluY2x1ZGVzKHNlYXJjaFRlcm0pO1xuICAgIH0pO1xuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnBsYWNlaG9sZGVyID0gdGhpcy5sYW5nU2VydmljZS5nZXRUZXh0KCdfZ2xvYmFsJywgJ3NlbGVjdE9wdGlvbicsICdTZWxlY2Npb25lIHVuYSBvcGNpw7NuJyk7XG4gICAgXG4gICAgLy8gQ2xvc2UgZHJvcGRvd24gd2hlbiBjbGlja2luZyBvdXRzaWRlXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLmhhbmRsZUNsaWNrT3V0c2lkZS5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuYXBwbHlEZWZhdWx0VmFsdWUoKTtcbiAgICB0aGlzLnN5bmNTZWxlY3RlZFZhbHVlKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuaGFuZGxlQ2xpY2tPdXRzaWRlLmJpbmQodGhpcykpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydwcm9wcyddICYmIHRoaXMucHJvcHMpIHtcbiAgICAgIHRoaXMuc3luY1NlbGVjdGVkVmFsdWUoKTtcbiAgICB9XG4gIH1cblxuICAvLyBDb21wb25lbnQgbWV0aG9kc1xuICB0b2dnbGVEcm9wZG93bihldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmlzT3Blbi51cGRhdGUodmFsdWUgPT4gIXZhbHVlKTtcbiAgICBcbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgLy8gRm9jdXMgc2VhcmNoIGJhciB3aGVuIG9wZW5pbmcgaWYgYXZhaWxhYmxlXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY29uc3Qgc2VhcmNoYmFyID0gdGhpcy5kcm9wZG93blJlZj8ubmF0aXZlRWxlbWVudD8ucXVlcnlTZWxlY3RvcignaW9uLXNlYXJjaGJhcicpO1xuICAgICAgICBpZiAoc2VhcmNoYmFyKSB7XG4gICAgICAgICAgc2VhcmNoYmFyLnNldEZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0sIDEwMCk7XG4gICAgfVxuICB9XG5cbiAgb25TZWFyY2goZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXQoZXZlbnQuZGV0YWlsLnZhbHVlIHx8ICcnKTtcbiAgfVxuXG4gIHNlbGVjdE9wdGlvbihvcHRpb246IElucHV0T3B0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25bdGhpcy52YWx1ZVByb3BlcnR5XTtcbiAgICB0aGlzLnNlbGVjdGVkVmFsdWUuc2V0KHZhbHVlKTtcbiAgICB0aGlzLmlzT3Blbi5zZXQoZmFsc2UpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXQoJycpO1xuICAgIFxuICAgIC8vIFVwZGF0ZSBmb3JtIGNvbnRyb2xcbiAgICBpZiAodGhpcy5wcm9wcz8uY29udHJvbCkge1xuICAgICAgdGhpcy5wcm9wcy5jb250cm9sLnNldFZhbHVlKHZhbHVlKTtcbiAgICAgIHRoaXMucHJvcHMuY29udHJvbC5tYXJrQXNEaXJ0eSgpO1xuICAgICAgdGhpcy5wcm9wcy5jb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB9XG4gIH1cblxuICBpc1NlbGVjdGVkKG9wdGlvbjogSW5wdXRPcHRpb24pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFZhbHVlKCkgPT09IG9wdGlvblt0aGlzLnZhbHVlUHJvcGVydHldO1xuICB9XG5cbiAgdHJhY2tCeUZuKF9pbmRleDogbnVtYmVyLCBvcHRpb246IElucHV0T3B0aW9uKTogYW55IHtcbiAgICByZXR1cm4gb3B0aW9uW3RoaXMudmFsdWVQcm9wZXJ0eV07XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNsaWNrT3V0c2lkZShldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc09wZW4oKSAmJiBcbiAgICAgICAgIXRoaXMubWFpbklucHV0UmVmPy5uYXRpdmVFbGVtZW50Py5jb250YWlucyhldmVudC50YXJnZXQpICYmXG4gICAgICAgICF0aGlzLmRyb3Bkb3duUmVmPy5uYXRpdmVFbGVtZW50Py5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICB0aGlzLmlzT3Blbi5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRPcHRpb25CeVZhbHVlKHZhbHVlOiBzdHJpbmcpOiBJbnB1dE9wdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucHJvcHM/Lm9wdGlvbnM/LmZpbmQob3B0aW9uID0+IG9wdGlvblt0aGlzLnZhbHVlUHJvcGVydHldID09PSB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5RGVmYXVsdFZhbHVlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnByb3BzKSB7XG4gICAgICBhcHBseURlZmF1bHRWYWx1ZVRvQ29udHJvbCh0aGlzLnByb3BzKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN5bmNTZWxlY3RlZFZhbHVlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnByb3BzPy5jb250cm9sPy52YWx1ZSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFZhbHVlLnNldCh0aGlzLnByb3BzLmNvbnRyb2wudmFsdWUpO1xuICAgIH1cbiAgfVxufVxuIl19