@seniorsistemas/angular-components 17.27.1-feature-sds-110-1bb20c20 → 17.27.1-feature-sds-110-57186492
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/autocomplete/index.d.ts +5 -0
- package/autocomplete/lib/autocomplete/autocomplete.component.d.ts +250 -0
- package/autocomplete/lib/autocomplete/components/autocomplete-chip/autocomplete-chip.component.d.ts +9 -0
- package/autocomplete/public-api.d.ts +1 -0
- package/button/lib/button/button.component.d.ts +1 -1
- package/dynamic-form/lib/dynamic-form/components/lookup/lookup.component.d.ts +1 -2
- package/dynamic-form/lib/dynamic-form/dynamic-form.module.d.ts +3 -2
- package/dynamic-form/lib/dynamic-form/form-field/fields/currency/currency-field.component.d.ts +3 -2
- package/esm2022/autocomplete/lib/autocomplete/autocomplete.component.mjs +554 -0
- package/esm2022/autocomplete/lib/autocomplete/components/autocomplete-chip/autocomplete-chip.component.mjs +17 -0
- package/esm2022/autocomplete/public-api.mjs +2 -0
- package/esm2022/autocomplete/seniorsistemas-angular-components-autocomplete.mjs +5 -0
- package/esm2022/button/lib/button/button.component.mjs +4 -10
- package/esm2022/chips/lib/chips/chips/chips.component.mjs +2 -2
- package/esm2022/control-errors/lib/control-errors/control-errors.component.mjs +2 -2
- package/esm2022/country-phone-picker/lib/country-phone-picker/country-phone-picker.component.mjs +2 -2
- package/esm2022/dynamic-form/lib/dynamic-form/components/lookup/lookup.component.mjs +16 -10
- package/esm2022/dynamic-form/lib/dynamic-form/dynamic-form.module.mjs +5 -1
- package/esm2022/dynamic-form/lib/dynamic-form/form-field/fields/autocomplete/autocomplete-field.component.mjs +7 -6
- package/esm2022/dynamic-form/lib/dynamic-form/form-field/fields/currency/currency-field.component.mjs +18 -8
- package/esm2022/dynamic-form/lib/dynamic-form/form-field/fields/lookup/lookup-field.component.mjs +1 -1
- package/esm2022/dynamic-form/lib/dynamic-form/form-field/fields/password/password-field.component.mjs +2 -2
- package/esm2022/dynamic-form/lib/dynamic-form/form-field/fields/select/select-field.component.mjs +1 -1
- package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-lookup/inline-edit-lookup.component.mjs +1 -1
- package/esm2022/lib/locale/fallback.mjs +2 -1
- package/esm2022/object-card/lib/object-card/object-card.component.mjs +3 -3
- package/esm2022/paginator/lib/paginator/paginator.component.mjs +2 -2
- package/esm2022/panel/lib/panel/panel.component.mjs +3 -3
- package/esm2022/select/lib/select/select.component.mjs +234 -336
- package/esm2022/text-area/lib/text-area/text-area.component.mjs +4 -4
- package/esm2022/text-area-ia/lib/text-area-ia/text-area-ia.component.mjs +4 -4
- package/esm2022/toast/lib/toast/toast.component.mjs +13 -13
- package/esm2022/token-list/lib/token-list/token-list.component.mjs +3 -3
- package/fesm2022/seniorsistemas-angular-components-autocomplete.mjs +575 -0
- package/fesm2022/seniorsistemas-angular-components-autocomplete.mjs.map +1 -0
- package/fesm2022/seniorsistemas-angular-components-button.mjs +3 -9
- package/fesm2022/seniorsistemas-angular-components-button.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-chips.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-chips.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-control-errors.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-control-errors.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-country-phone-picker.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-country-phone-picker.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +38 -19
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-object-card.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-object-card.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-paginator.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-paginator.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-panel.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-panel.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-select.mjs +232 -334
- package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-text-area-ia.mjs +3 -3
- package/fesm2022/seniorsistemas-angular-components-text-area-ia.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-text-area.mjs +3 -3
- package/fesm2022/seniorsistemas-angular-components-text-area.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-toast.mjs +12 -12
- package/fesm2022/seniorsistemas-angular-components-toast.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-token-list.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-token-list.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components.mjs +1 -0
- package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
- package/package.json +19 -13
- package/select/lib/select/select.component.d.ts +148 -157
- package/styles.css +1 -0
- package/text-area-ia/lib/text-area-ia/text-area-ia.component.d.ts +1 -1
- package/toast/lib/toast/toast.component.d.ts +4 -4
- package/src/lib/styles/tailwind.scss +0 -3
- package/tailwind.css +0 -1167
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OverlayModule } from '@angular/cdk/overlay';
|
|
2
2
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
3
|
-
import { CommonModule
|
|
4
|
-
import { Component, computed,
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { Component, computed, forwardRef, inject, input, model, signal, viewChild, } from '@angular/core';
|
|
5
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
6
|
import { FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
|
6
7
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
7
|
-
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
8
|
-
import { SelectOptionComponent } from './components/select-option/select-option.component';
|
|
9
|
-
import { Subject } from 'rxjs';
|
|
10
8
|
import { CheckboxComponent } from '@seniorsistemas/angular-components/checkbox';
|
|
9
|
+
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
10
|
+
import { SelectOptionComponent } from './components/select-option/select-option.component';
|
|
11
11
|
import * as i0 from "@angular/core";
|
|
12
12
|
import * as i1 from "@angular/common";
|
|
13
13
|
import * as i2 from "@angular/forms";
|
|
14
14
|
import * as i3 from "@angular/cdk/scrolling";
|
|
15
15
|
import * as i4 from "@ngx-translate/core";
|
|
16
|
+
import * as i5 from "@angular/cdk/overlay";
|
|
16
17
|
export class SelectComponent {
|
|
18
|
+
static nextId = 0;
|
|
17
19
|
placeholder = input('');
|
|
18
20
|
multiple = input(false);
|
|
19
21
|
options = input.required();
|
|
@@ -27,65 +29,49 @@ export class SelectComponent {
|
|
|
27
29
|
virtualScroll = input(false);
|
|
28
30
|
virtualScrollItemSize = input(37);
|
|
29
31
|
emptyMessage = input(null);
|
|
30
|
-
useRawValue = input(false);
|
|
31
|
-
dataKey = input();
|
|
32
32
|
disabled = model(false);
|
|
33
|
-
showOptions =
|
|
33
|
+
showOptions = model(false);
|
|
34
34
|
value = signal(null);
|
|
35
35
|
values = signal([]);
|
|
36
36
|
filterValue = signal('');
|
|
37
37
|
focusedIndex = signal(-1);
|
|
38
|
-
|
|
39
|
-
dropLeft = 0;
|
|
40
|
-
dropWidth = 0;
|
|
41
|
-
_portalHost = null;
|
|
38
|
+
componentId = `select${SelectComponent.nextId++}`;
|
|
42
39
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* - Usa `_getCompareValueExtractor()` para comparar os valores de forma consistente.
|
|
48
|
-
*
|
|
49
|
-
* Esse estado é usado para controlar o checkbox de "Selecionar todos" quando todas as opções visíveis estão marcadas.
|
|
40
|
+
* Computed que indica se todas as opções filtradas estão selecionadas.
|
|
41
|
+
* Retorna `true` se todas as opções disponíveis (excluindo agrupadores) estiverem presentes
|
|
42
|
+
* na lista de valores selecionados, e `false` caso contrário.
|
|
43
|
+
* @returns {boolean} `true` se todas as opções filtradas estão selecionadas, `false` caso contrário.
|
|
50
44
|
*/
|
|
51
45
|
allSelected = computed(() => {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
const options = this.filteredOptions().filter((option) => !option.grouper);
|
|
47
|
+
const selectedIds = this.values().map((option) => option.id);
|
|
48
|
+
const ret = options.length > 0 && options.every((option) => selectedIds.includes(option.id));
|
|
49
|
+
return ret;
|
|
56
50
|
});
|
|
51
|
+
/**
|
|
52
|
+
* Retorna o item atualmente focado na lista de opções filtradas.
|
|
53
|
+
* @returns O dado do item focado ou `null` caso nenhum item esteja focado.
|
|
54
|
+
*/
|
|
57
55
|
focusedItem = computed(() => this.filteredOptions().at(this.focusedIndex())?.data ?? null);
|
|
58
56
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* -
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* Essa estrutura é usada internamente para renderização, filtragem e controle de seleção.
|
|
57
|
+
* Computa e retorna a lista interna de opções do dropdown.
|
|
58
|
+
* - Se as opções estiverem agrupadas (`group()` retorna verdadeiro),
|
|
59
|
+
* utiliza `_grouperToFlat` para transformar as opções agrupadas em uma lista plana.
|
|
60
|
+
* - Caso contrário, retorna as opções com IDs adicionados.
|
|
61
|
+
* @returns Um array de `InternalDropdownOption<T>` representando as opções disponíveis para o componente select.
|
|
66
62
|
*/
|
|
67
63
|
internalOptions = computed(() => {
|
|
68
64
|
const opts = this.options();
|
|
69
|
-
const optionsWithId = this.
|
|
70
|
-
? opts.map((value, index) => ({
|
|
71
|
-
id: `id_primitive_${index}`,
|
|
72
|
-
grouper: false,
|
|
73
|
-
data: value,
|
|
74
|
-
}))
|
|
75
|
-
: this._addIdToOptions(opts);
|
|
65
|
+
const optionsWithId = this._addIdToOptions(opts);
|
|
76
66
|
return this.group() ? this._grouperToFlat(optionsWithId) : optionsWithId;
|
|
77
67
|
});
|
|
78
68
|
/**
|
|
79
|
-
* Retorna
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* - Exibe o label do valor selecionado. *
|
|
86
|
-
* - Se nenhum valor estiver selecionado, retorna uma string vazia.
|
|
87
|
-
*
|
|
88
|
-
* Essa lógica é usada para mostrar o conteúdo atual do campo de seleção.
|
|
69
|
+
* Retorna uma string representando a seleção atual do componente.
|
|
70
|
+
* - Se o modo múltiplo estiver ativado e mais de um item estiver selecionado,
|
|
71
|
+
* retorna uma mensagem traduzida indicando o número total de registros selecionados.
|
|
72
|
+
* - Se apenas um item estiver selecionado, retorna o rótulo desse item.
|
|
73
|
+
* - Se o modo múltiplo não estiver ativado, retorna o rótulo do item selecionado ou uma string vazia caso nenhum item esteja selecionado.
|
|
74
|
+
* @returns {string} Texto representando a seleção atual.
|
|
89
75
|
*/
|
|
90
76
|
print = computed(() => {
|
|
91
77
|
if (this.multiple()) {
|
|
@@ -96,46 +82,45 @@ export class SelectComponent {
|
|
|
96
82
|
});
|
|
97
83
|
}
|
|
98
84
|
else if (selected.length === 1) {
|
|
99
|
-
return this._getLabelFromOption(selected[0]);
|
|
85
|
+
return this._getLabelFromOption(selected[0].data);
|
|
100
86
|
}
|
|
101
87
|
}
|
|
102
|
-
else
|
|
103
|
-
|
|
88
|
+
else {
|
|
89
|
+
const selected = this.value();
|
|
90
|
+
return selected ? this._getLabelFromOption(selected.data) : '';
|
|
104
91
|
}
|
|
105
92
|
return '';
|
|
106
93
|
});
|
|
94
|
+
/**
|
|
95
|
+
* Indica se o seletor está "limpo", ou seja, sem nenhum valor selecionado.
|
|
96
|
+
* - No modo múltiplo (`multiple`), retorna `true` se não houver nenhum valor selecionado (`values` está vazio).
|
|
97
|
+
* - No modo simples, retorna `true` se não houver valor selecionado (`value` é falsy).
|
|
98
|
+
* @returns `true` se não houver seleção, `false` caso contrário.
|
|
99
|
+
*/
|
|
107
100
|
isClean = computed(() => {
|
|
108
101
|
return this.multiple() ? !this.values().length : !this.value();
|
|
109
102
|
});
|
|
110
|
-
TIsPrimitive = computed(() => {
|
|
111
|
-
const opts = this.options();
|
|
112
|
-
if (!opts.length)
|
|
113
|
-
return false;
|
|
114
|
-
return ['string', 'number', 'boolean'].includes(typeof opts[0]);
|
|
115
|
-
});
|
|
116
103
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* - Ignora opções marcadas como `grouper`.
|
|
122
|
-
*
|
|
123
|
-
* Esse estado é usado, por exemplo, para exibir o checkbox de "Selecionar todos" em modo indeterminado.
|
|
104
|
+
* Computed que indica se o estado de seleção "Selecionar Todos" está indeterminado.
|
|
105
|
+
* Retorna `true` quando nem todos os itens filtrados estão selecionados e nem todos estão desmarcados,
|
|
106
|
+
* ou seja, quando há uma seleção parcial dos itens disponíveis.
|
|
107
|
+
* @returns {boolean} `true` se a seleção for parcial, `false` caso contrário.
|
|
124
108
|
*/
|
|
125
109
|
selectAllIsIndeterminate = computed(() => {
|
|
126
|
-
const selected = this.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
110
|
+
const selected = this.internalOptions().filter((option) => {
|
|
111
|
+
return this.values().some((o) => o.id === option.id);
|
|
112
|
+
});
|
|
113
|
+
const options = this.filteredOptions().filter((option) => !option.grouper);
|
|
114
|
+
const all = options.length > 0 && options.every((option) => selected.includes(option));
|
|
115
|
+
const none = options.every((option) => !selected.includes(option));
|
|
130
116
|
return !all && !none;
|
|
131
117
|
});
|
|
132
118
|
/**
|
|
133
|
-
* Retorna
|
|
134
|
-
*
|
|
135
|
-
* -
|
|
136
|
-
* -
|
|
137
|
-
*
|
|
138
|
-
* - Usa o extrator de label para comparar os valores com o texto buscado.
|
|
119
|
+
* Retorna uma lista de opções filtradas com base no valor de busca (`filterValue`) e nos critérios definidos.
|
|
120
|
+
* - Se o filtro estiver desabilitado ou o valor de busca estiver vazio, retorna todas as opções.
|
|
121
|
+
* - Caso contrário, filtra as opções utilizando o(s) campo(s) especificado(s) em `filterBy`.
|
|
122
|
+
* - Ignora opções que possuem a propriedade `grouper` definida.
|
|
123
|
+
* @returns As opções filtradas conforme o valor de busca e critérios de filtro.
|
|
139
124
|
*/
|
|
140
125
|
filteredOptions = computed(() => {
|
|
141
126
|
const allOptions = this.internalOptions();
|
|
@@ -148,10 +133,10 @@ export class SelectComponent {
|
|
|
148
133
|
if (option.grouper) {
|
|
149
134
|
return false;
|
|
150
135
|
}
|
|
151
|
-
const labelExtractor = this._getLabelExtractor();
|
|
152
136
|
let label = '';
|
|
137
|
+
const optionLabel = this.optionLabel();
|
|
153
138
|
if (!filterBy) {
|
|
154
|
-
label =
|
|
139
|
+
label = optionLabel ? String(option.data[optionLabel]) : String(option.data);
|
|
155
140
|
}
|
|
156
141
|
else if (Array.isArray(filterBy)) {
|
|
157
142
|
label = filterBy.map((by) => String(option.data[by] ?? '')).join(' ');
|
|
@@ -165,89 +150,88 @@ export class SelectComponent {
|
|
|
165
150
|
filterForm = new FormGroup({
|
|
166
151
|
filter: new FormControl('', { nonNullable: true }),
|
|
167
152
|
});
|
|
168
|
-
_elementRef = inject((ElementRef));
|
|
169
|
-
_dropdownTemplate = viewChild('dropdownTemplate');
|
|
170
153
|
_containerDiv = viewChild('containerDiv');
|
|
171
154
|
_onChange = () => { };
|
|
172
155
|
_onTouched = () => { };
|
|
173
|
-
platformId = inject(PLATFORM_ID);
|
|
174
|
-
_viewContainerRef = inject(ViewContainerRef);
|
|
175
156
|
_translateService = inject(TranslateService);
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Inicializa o componente, validando os inputs e configurando o filtro com debounce.
|
|
179
|
-
*/
|
|
180
|
-
ngOnInit() {
|
|
181
|
-
this._validateInputs();
|
|
157
|
+
constructor() {
|
|
182
158
|
this.filterForm
|
|
183
159
|
.get('filter')
|
|
184
|
-
.valueChanges.pipe(debounceTime(300), distinctUntilChanged(),
|
|
160
|
+
.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed())
|
|
185
161
|
.subscribe((value) => {
|
|
186
162
|
this.filterValue.set(value);
|
|
187
163
|
});
|
|
188
164
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
*/
|
|
192
|
-
ngOnDestroy() {
|
|
193
|
-
this._destroyDropdownPortal();
|
|
194
|
-
if (this._portalHost) {
|
|
195
|
-
this._portalHost.dispose();
|
|
196
|
-
this._portalHost = null;
|
|
197
|
-
}
|
|
198
|
-
this.destroy$.next();
|
|
199
|
-
this.destroy$.complete();
|
|
165
|
+
ngOnInit() {
|
|
166
|
+
this._validateInputs();
|
|
200
167
|
}
|
|
201
168
|
/**
|
|
202
|
-
* Define o valor
|
|
203
|
-
* @param value
|
|
169
|
+
* Define o valor selecionado do componente select.
|
|
170
|
+
* @param value O valor a ser definido. Pode ser um objeto do tipo `T`, um array de `T` (quando múltipla seleção está habilitada), ou `null`.
|
|
171
|
+
* @throws Se o modo múltiplo estiver ativado e o valor não for um array, lança um erro.
|
|
172
|
+
* @throws Se o modo múltiplo estiver desativado e o valor for um array, lança um erro.
|
|
173
|
+
* Este método mapeia o(s) valor(es) fornecido(s) para as opções internas do componente,
|
|
174
|
+
* garantindo que apenas opções válidas sejam selecionadas conforme o modo de seleção (único ou múltiplo).
|
|
204
175
|
*/
|
|
205
176
|
writeValue(value) {
|
|
206
|
-
if (this.multiple()) {
|
|
177
|
+
if (value && this.multiple()) {
|
|
207
178
|
if (Array.isArray(value)) {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
179
|
+
const mapped = value
|
|
180
|
+
.map((val) => {
|
|
181
|
+
return this.internalOptions().find((option) => {
|
|
182
|
+
return JSON.stringify(option.data) === JSON.stringify(val);
|
|
183
|
+
});
|
|
184
|
+
})
|
|
185
|
+
.filter((option) => !!option);
|
|
186
|
+
this.values.set(mapped);
|
|
214
187
|
}
|
|
215
188
|
else {
|
|
216
|
-
|
|
189
|
+
throw new Error('Value must be an array when "multiple" is true.');
|
|
217
190
|
}
|
|
218
191
|
}
|
|
219
192
|
else {
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
193
|
+
const optionValue = this.optionValue();
|
|
194
|
+
let mapped = null;
|
|
195
|
+
if (Array.isArray(value)) {
|
|
196
|
+
throw new Error('Value must not be an array when "multiple" is false.');
|
|
197
|
+
}
|
|
198
|
+
if (optionValue && value) {
|
|
199
|
+
mapped =
|
|
200
|
+
this.internalOptions().find((option) => option.data[optionValue] === value[optionValue]) ?? null;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
mapped =
|
|
204
|
+
this.internalOptions().find((option) => JSON.stringify(option.data) === JSON.stringify(value)) ??
|
|
205
|
+
null;
|
|
206
|
+
}
|
|
207
|
+
this.value.set(mapped ?? null);
|
|
226
208
|
}
|
|
227
209
|
}
|
|
228
210
|
/**
|
|
229
|
-
* Registra
|
|
230
|
-
* @param onChange Função callback.
|
|
211
|
+
* Registra uma função de callback que será chamada sempre que o valor do componente mudar.
|
|
212
|
+
* @param onChange Função de callback que recebe o novo valor selecionado ou null.
|
|
231
213
|
*/
|
|
232
214
|
registerOnChange(onChange) {
|
|
233
215
|
this._onChange = onChange;
|
|
234
216
|
}
|
|
235
217
|
/**
|
|
236
|
-
* Registra
|
|
237
|
-
* @param onTouched Função callback.
|
|
218
|
+
* Registra uma função de callback que será chamada quando o componente for tocado (perder o foco).
|
|
219
|
+
* @param onTouched Função de callback a ser executada quando o componente for marcado como "tocado".
|
|
238
220
|
*/
|
|
239
221
|
registerOnTouched(onTouched) {
|
|
240
222
|
this._onTouched = onTouched;
|
|
241
223
|
}
|
|
242
224
|
/**
|
|
243
225
|
* Define o estado de desabilitado do componente.
|
|
244
|
-
* @param disabled Indica se o componente
|
|
226
|
+
* @param disabled Indica se o componente deve ser desabilitado (`true`) ou habilitado (`false`).
|
|
245
227
|
*/
|
|
246
228
|
setDisabledState(disabled) {
|
|
247
229
|
this.disabled.set(disabled);
|
|
248
230
|
}
|
|
249
231
|
/**
|
|
250
|
-
* Alterna a exibição
|
|
232
|
+
* Alterna a exibição das opções do componente select.
|
|
233
|
+
* Se o componente estiver desabilitado, não realiza nenhuma ação.
|
|
234
|
+
* Caso contrário, inverte o estado de exibição das opções.
|
|
251
235
|
*/
|
|
252
236
|
toggle() {
|
|
253
237
|
if (this.disabled()) {
|
|
@@ -255,29 +239,24 @@ export class SelectComponent {
|
|
|
255
239
|
}
|
|
256
240
|
const shouldOpen = !this.showOptions();
|
|
257
241
|
this.showOptions.set(shouldOpen);
|
|
258
|
-
if (shouldOpen) {
|
|
259
|
-
setTimeout(() => {
|
|
260
|
-
this._createDropdownPortal();
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
this._destroyDropdownPortal();
|
|
265
|
-
}
|
|
266
242
|
}
|
|
267
243
|
/**
|
|
268
|
-
* Seleciona
|
|
269
|
-
* @param item
|
|
244
|
+
* Seleciona um item no componente de seleção.
|
|
245
|
+
* @param item O item a ser selecionado ou desmarcado.
|
|
246
|
+
* Se o componente estiver desabilitado, a função retorna imediatamente.
|
|
247
|
+
* No modo múltiplo, adiciona ou remove o item da lista de valores selecionados.
|
|
248
|
+
* No modo simples, define o item como valor selecionado e fecha o dropdown.
|
|
249
|
+
* Sempre notifica as mudanças e marca o componente como tocado.
|
|
270
250
|
*/
|
|
271
251
|
selectItem(item) {
|
|
272
252
|
if (this.disabled()) {
|
|
273
253
|
return;
|
|
274
254
|
}
|
|
275
|
-
const
|
|
255
|
+
const optionValue = this.optionValue();
|
|
276
256
|
if (this.multiple()) {
|
|
277
257
|
const store = [...this.values()];
|
|
278
|
-
const itemValue = getCompareValue(item);
|
|
279
258
|
const index = store.findIndex((selectedItem) => {
|
|
280
|
-
return
|
|
259
|
+
return selectedItem === item;
|
|
281
260
|
});
|
|
282
261
|
if (index !== -1) {
|
|
283
262
|
store.splice(index, 1);
|
|
@@ -286,20 +265,25 @@ export class SelectComponent {
|
|
|
286
265
|
store.push(item);
|
|
287
266
|
}
|
|
288
267
|
this.values.set(store);
|
|
289
|
-
const result =
|
|
268
|
+
const result = optionValue ? store.map((item) => item.data[optionValue]) : store;
|
|
290
269
|
this._onChange(result);
|
|
291
270
|
}
|
|
292
271
|
else {
|
|
293
272
|
this.value.set(item);
|
|
294
|
-
const result =
|
|
273
|
+
const result = optionValue ? item.data[optionValue] : item.data;
|
|
295
274
|
this._onChange(result);
|
|
296
275
|
this._closeDropdown();
|
|
297
276
|
}
|
|
298
277
|
this._onTouched();
|
|
299
278
|
}
|
|
300
279
|
/**
|
|
301
|
-
* Limpa
|
|
302
|
-
*
|
|
280
|
+
* Limpa o valor selecionado no componente select.
|
|
281
|
+
* Se o componente estiver desabilitado, não executa nenhuma ação.
|
|
282
|
+
* Para seleção múltipla, remove todos os valores selecionados e notifica a alteração.
|
|
283
|
+
* Para seleção única, define o valor como nulo e notifica a alteração.
|
|
284
|
+
* Fecha o dropdown e marca o componente como "tocado".
|
|
285
|
+
* Impede a propagação do evento do mouse.
|
|
286
|
+
* @param event Evento do mouse que acionou a limpeza da seleção.
|
|
303
287
|
*/
|
|
304
288
|
clear(event) {
|
|
305
289
|
if (this.disabled()) {
|
|
@@ -307,7 +291,7 @@ export class SelectComponent {
|
|
|
307
291
|
}
|
|
308
292
|
if (this.multiple()) {
|
|
309
293
|
this.values.set([]);
|
|
310
|
-
this._onChange(this.
|
|
294
|
+
this._onChange(this.values());
|
|
311
295
|
}
|
|
312
296
|
else {
|
|
313
297
|
this.value.set(null);
|
|
@@ -318,25 +302,17 @@ export class SelectComponent {
|
|
|
318
302
|
event.stopPropagation();
|
|
319
303
|
}
|
|
320
304
|
/**
|
|
321
|
-
* Limpa o filtro
|
|
305
|
+
* Limpa o filtro do formulário, resetando o campo 'filter' do formulário de filtro.
|
|
306
|
+
* Este método redefine o valor do campo 'filter' para seu estado inicial,
|
|
307
|
+
* removendo qualquer texto ou valor previamente inserido pelo usuário.
|
|
322
308
|
*/
|
|
323
309
|
clearFilter() {
|
|
324
310
|
this.filterForm.get('filter')?.reset();
|
|
325
311
|
}
|
|
326
312
|
/**
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
|
|
330
|
-
onDocumentClick(event) {
|
|
331
|
-
const clickTarget = event.target;
|
|
332
|
-
const clickedInsideComponent = this._elementRef.nativeElement.contains(clickTarget);
|
|
333
|
-
const dropdownInBody = document.querySelector('.dropdown-body-class')?.contains(clickTarget);
|
|
334
|
-
if (!clickedInsideComponent && !dropdownInBody) {
|
|
335
|
-
this._closeDropdown();
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Fecha o dropdown em eventos de redimensionamento de janela.
|
|
313
|
+
* Manipula o evento de redimensionamento da janela.
|
|
314
|
+
* Fecha o dropdown de opções caso ele esteja visível ao redimensionar a janela.
|
|
315
|
+
* @param _ Evento de redimensionamento da janela (não utilizado).
|
|
340
316
|
*/
|
|
341
317
|
onWindowResize(_) {
|
|
342
318
|
if (this.showOptions()) {
|
|
@@ -344,15 +320,24 @@ export class SelectComponent {
|
|
|
344
320
|
}
|
|
345
321
|
}
|
|
346
322
|
/**
|
|
347
|
-
*
|
|
323
|
+
* Manipula o evento de clique no elemento container da seleção.
|
|
324
|
+
* Este método alterna o estado de exibição do componente select e,
|
|
325
|
+
* em seguida, define o foco no elemento container correspondente.
|
|
348
326
|
*/
|
|
349
327
|
onContainerDivClick() {
|
|
350
328
|
this.toggle();
|
|
351
329
|
this._containerDiv()?.nativeElement.focus();
|
|
352
330
|
}
|
|
353
331
|
/**
|
|
354
|
-
*
|
|
355
|
-
*
|
|
332
|
+
* Manipula eventos de teclado para navegação e seleção de opções no componente select.
|
|
333
|
+
* - 'ArrowDown': Move o foco para a próxima opção disponível.
|
|
334
|
+
* - 'ArrowUp': Move o foco para a opção anterior.
|
|
335
|
+
* - 'Tab': Seleciona a opção atualmente focada e fecha o dropdown.
|
|
336
|
+
* - 'Enter': Seleciona a opção focada se o dropdown estiver aberto, ou alterna a abertura do dropdown.
|
|
337
|
+
* - 'Escape': Fecha o dropdown.
|
|
338
|
+
* - ' ': (barra de espaço) Seleciona a opção focada se o dropdown estiver aberto, ou alterna a abertura do dropdown.
|
|
339
|
+
* Previne o comportamento padrão do navegador quando necessário para garantir a navegação adequada pelo teclado.
|
|
340
|
+
* @param event O evento de teclado disparado pelo usuário.
|
|
356
341
|
*/
|
|
357
342
|
onKeyDown(event) {
|
|
358
343
|
const options = this.filteredOptions();
|
|
@@ -362,7 +347,7 @@ export class SelectComponent {
|
|
|
362
347
|
const _selectOption = () => {
|
|
363
348
|
if (this.focusedIndex() >= 0 && this.focusedIndex() < options.length) {
|
|
364
349
|
event.preventDefault();
|
|
365
|
-
this.selectItem(options[this.focusedIndex()]
|
|
350
|
+
this.selectItem(options[this.focusedIndex()]);
|
|
366
351
|
}
|
|
367
352
|
};
|
|
368
353
|
switch (event.key) {
|
|
@@ -390,166 +375,113 @@ export class SelectComponent {
|
|
|
390
375
|
this._closeDropdown();
|
|
391
376
|
break;
|
|
392
377
|
case ' ':
|
|
393
|
-
|
|
378
|
+
event.preventDefault();
|
|
379
|
+
if (this.showOptions()) {
|
|
380
|
+
_selectOption();
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
this.toggle();
|
|
384
|
+
}
|
|
394
385
|
break;
|
|
395
386
|
}
|
|
396
387
|
}
|
|
397
388
|
/**
|
|
398
|
-
* Retorna o rótulo
|
|
399
|
-
* @param option
|
|
400
|
-
* @returns
|
|
389
|
+
* Retorna o rótulo (label) associado a uma opção fornecida.
|
|
390
|
+
* @param option - A opção do tipo T para a qual o rótulo deve ser obtido.
|
|
391
|
+
* @returns O rótulo da opção como uma string.
|
|
401
392
|
*/
|
|
402
393
|
getOptionLabel(option) {
|
|
403
394
|
return this._getLabelFromOption(option);
|
|
404
395
|
}
|
|
405
396
|
/**
|
|
406
|
-
* Função
|
|
407
|
-
*
|
|
408
|
-
* @param item
|
|
409
|
-
* @
|
|
397
|
+
* Função de trackBy utilizada em diretivas *ngFor para otimizar a renderização de listas.
|
|
398
|
+
* Retorna o identificador único (`id`) de cada item do tipo `InternalDropdownOption<T>`.
|
|
399
|
+
* @param _ - Índice do item na lista (não utilizado).
|
|
400
|
+
* @param item - O item atual da lista do tipo `InternalDropdownOption<T>`.
|
|
401
|
+
* @returns O identificador único do item como uma string.
|
|
410
402
|
*/
|
|
411
403
|
trackById(_, item) {
|
|
412
404
|
return item.id;
|
|
413
405
|
}
|
|
414
406
|
/**
|
|
415
|
-
* Verifica se
|
|
416
|
-
* @param option
|
|
417
|
-
* @returns
|
|
407
|
+
* Verifica se a opção fornecida está selecionada.
|
|
408
|
+
* @param option - A opção interna do dropdown a ser verificada.
|
|
409
|
+
* @returns `true` se a opção estiver selecionada, caso contrário `false`.
|
|
418
410
|
*/
|
|
419
411
|
isOptionSelected(option) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
return selectedValues.includes(getCompareValue(option));
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
const currentValue = this.value();
|
|
427
|
-
return currentValue !== null && getCompareValue(currentValue) === getCompareValue(option);
|
|
428
|
-
}
|
|
412
|
+
return (this.values().find((o) => {
|
|
413
|
+
return o === option;
|
|
414
|
+
}) !== undefined);
|
|
429
415
|
}
|
|
430
416
|
/**
|
|
431
|
-
* Alterna a seleção de todos os itens
|
|
417
|
+
* Alterna a seleção de todos os itens disponíveis.
|
|
418
|
+
* Se o modo múltiplo estiver ativado, seleciona todos os itens filtrados que não são agrupadores
|
|
419
|
+
* caso nem todos estejam selecionados, ou limpa a seleção caso todos já estejam selecionados.
|
|
420
|
+
* Após a alteração, notifica a mudança de valor.
|
|
432
421
|
*/
|
|
433
422
|
toggleSelectAll() {
|
|
434
423
|
if (!this.multiple()) {
|
|
435
424
|
return;
|
|
436
425
|
}
|
|
437
|
-
const options = this.filteredOptions().filter((
|
|
426
|
+
const options = this.filteredOptions().filter((option) => !option.grouper);
|
|
438
427
|
if (this.allSelected()) {
|
|
439
428
|
this.values.set([]);
|
|
440
429
|
}
|
|
441
430
|
else {
|
|
442
|
-
this.values.set(options
|
|
431
|
+
this.values.set(options);
|
|
443
432
|
}
|
|
444
|
-
this._onChange(this.
|
|
433
|
+
this._onChange(this.values());
|
|
445
434
|
}
|
|
446
435
|
/**
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
* @
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
return this.internalOptions().find((opt) => opt.data === value)?.data ?? null;
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Remove propriedades internas adicionadas pelo componente, retornando apenas os dados crus.
|
|
457
|
-
*
|
|
458
|
-
* Usado para garantir que apenas os objetos de dados reais sejam emitidos ao formulário,
|
|
459
|
-
* especialmente no modo múltiplo.
|
|
460
|
-
*
|
|
461
|
-
* @param value Valor armazenado internamente (com ou sem `InternalDropdownOption`).
|
|
462
|
-
* @returns Os dados "puros", sem propriedades adicionais.
|
|
463
|
-
*/
|
|
464
|
-
_removeInternalProperties(value) {
|
|
465
|
-
if (this.TIsPrimitive()) {
|
|
466
|
-
return value;
|
|
467
|
-
}
|
|
468
|
-
return Array.isArray(value)
|
|
469
|
-
? value.map((opt) => opt.data)
|
|
470
|
-
: value.data;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Retorna o texto (label) correspondente a uma determinada opção.
|
|
474
|
-
* Usa a propriedade definida em `optionLabel`, ou tenta usar uma propriedade padrão (`label`).
|
|
475
|
-
*
|
|
476
|
-
* @param option A opção a ser exibida.
|
|
477
|
-
* @returns O texto legível da opção para exibição no componente.
|
|
436
|
+
* Retorna o rótulo (label) de uma opção fornecida.
|
|
437
|
+
* Este método utiliza a propriedade definida por `optionLabel` para extrair o valor do rótulo da opção.
|
|
438
|
+
* Caso `optionLabel` não esteja definido, retorna a representação em string da própria opção.
|
|
439
|
+
* @private
|
|
440
|
+
* @param option A opção da qual o rótulo será extraído.
|
|
441
|
+
* @returns O rótulo da opção como uma string.
|
|
478
442
|
*/
|
|
479
443
|
_getLabelFromOption(option) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
const labelKey = this.optionLabel();
|
|
484
|
-
if (!labelKey) {
|
|
485
|
-
return String(option.label ?? '');
|
|
486
|
-
}
|
|
487
|
-
return String(option[labelKey]);
|
|
444
|
+
const optionLabel = this.optionLabel();
|
|
445
|
+
return optionLabel ? String(option[optionLabel]) : String(option);
|
|
488
446
|
}
|
|
489
447
|
/**
|
|
490
|
-
* Valida
|
|
448
|
+
* Valida as entradas do componente de seleção.
|
|
449
|
+
* Este método verifica se as opções fornecidas são válidas. Caso as opções sejam objetos,
|
|
450
|
+
* garante que a propriedade `optionLabel` esteja definida, lançando um erro caso contrário.
|
|
451
|
+
* Se não houver opções, a validação é ignorada.
|
|
452
|
+
* @private
|
|
453
|
+
* @throws {Error} Se as opções forem objetos e `optionLabel` não estiver definido.
|
|
491
454
|
*/
|
|
492
455
|
_validateInputs() {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
if (!this.TIsPrimitive() && !this.optionValue() && !this.dataKey()) {
|
|
497
|
-
throw new Error('Either the optionValue or dataKey input must be provided for non-primitive options.');
|
|
498
|
-
}
|
|
499
|
-
if (!this.TIsPrimitive() && !this.optionLabel()) {
|
|
500
|
-
throw new Error(`The 'optionLabel' input must be provided for non-primitive options.`);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
_findOptionByValue(value) {
|
|
504
|
-
if (this.useRawValue()) {
|
|
505
|
-
return this.options().find((option) => option === value) ?? null;
|
|
506
|
-
}
|
|
507
|
-
const getValue = this._getValueExtractor();
|
|
508
|
-
return this.options().find((option) => getValue(option) === value) ?? null;
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Extrai o valor final de uma opção, com base em `optionValue`.
|
|
512
|
-
* @returns Função que retorna o valor da opção.
|
|
513
|
-
*/
|
|
514
|
-
_getValueExtractor() {
|
|
515
|
-
if (this.TIsPrimitive()) {
|
|
516
|
-
return (option) => option;
|
|
517
|
-
}
|
|
518
|
-
if (this.useRawValue()) {
|
|
519
|
-
return (option) => option;
|
|
520
|
-
}
|
|
521
|
-
const valueInput = this.optionValue();
|
|
522
|
-
if (valueInput) {
|
|
523
|
-
return (option) => option[valueInput];
|
|
524
|
-
}
|
|
525
|
-
throw new Error(`optionValue is required for non-primitive options.`);
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Extrai o valor comparável de uma opção.
|
|
529
|
-
* @returns Função que retorna a chave de comparação.
|
|
530
|
-
*/
|
|
531
|
-
_getCompareValueExtractor() {
|
|
532
|
-
if (this.TIsPrimitive()) {
|
|
533
|
-
return (option) => option;
|
|
456
|
+
const options = this.options();
|
|
457
|
+
if (!options.length) {
|
|
458
|
+
return;
|
|
534
459
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
460
|
+
const hasObjectOptions = options.some((option) => typeof option === 'object' && option !== null);
|
|
461
|
+
if (hasObjectOptions) {
|
|
462
|
+
if (!this.optionLabel()) {
|
|
463
|
+
throw new Error('The "optionLabel" input is required when options are objects.');
|
|
464
|
+
}
|
|
538
465
|
}
|
|
539
|
-
return this._getValueExtractor();
|
|
540
466
|
}
|
|
541
467
|
/**
|
|
542
|
-
* Fecha o dropdown
|
|
468
|
+
* Fecha o dropdown de opções do componente select.
|
|
469
|
+
* Este método oculta as opções disponíveis e redefine o índice do item focado para -1,
|
|
470
|
+
* indicando que nenhum item está atualmente focado.
|
|
471
|
+
* @private
|
|
543
472
|
*/
|
|
544
473
|
_closeDropdown() {
|
|
545
474
|
this.showOptions.set(false);
|
|
546
|
-
this._destroyDropdownPortal();
|
|
547
475
|
this.focusedIndex.set(-1);
|
|
548
476
|
}
|
|
549
477
|
/**
|
|
550
|
-
* Adiciona
|
|
551
|
-
*
|
|
552
|
-
*
|
|
478
|
+
* Adiciona um identificador único a cada opção fornecida.
|
|
479
|
+
* Para cada item no array de opções, gera um objeto `InternalDropdownOption` contendo o dado original
|
|
480
|
+
* e um campo `id` único baseado no timestamp atual e no índice do item. Caso a opção seja um grupo
|
|
481
|
+
* (detectado pela presença de um array `items`), adiciona também a propriedade `grouper: true`.
|
|
482
|
+
* @private
|
|
483
|
+
* @param options Array de opções do tipo `T` a serem processadas.
|
|
484
|
+
* @returns Um array de objetos `InternalDropdownOption<T>` com identificadores únicos.
|
|
553
485
|
*/
|
|
554
486
|
_addIdToOptions(options) {
|
|
555
487
|
const timestamp = Date.now();
|
|
@@ -568,9 +500,14 @@ export class SelectComponent {
|
|
|
568
500
|
});
|
|
569
501
|
}
|
|
570
502
|
/**
|
|
571
|
-
* Converte uma
|
|
572
|
-
*
|
|
573
|
-
*
|
|
503
|
+
* Converte uma lista de opções possivelmente agrupadas em uma lista plana de opções.
|
|
504
|
+
* Para cada opção que possui um agrupador (`grouper`) e um array de itens em `data.items`,
|
|
505
|
+
* adiciona a opção do agrupador e, em seguida, adiciona cada item do grupo como uma nova opção
|
|
506
|
+
* individual, atribuindo um `id` único para cada item do grupo.
|
|
507
|
+
* Caso a opção não seja um agrupador, ela é adicionada diretamente ao resultado.
|
|
508
|
+
* @private
|
|
509
|
+
* @param options Lista de opções internas do dropdown, podendo conter agrupadores.
|
|
510
|
+
* @returns Lista plana de opções, incluindo agrupadores e seus itens expandidos.
|
|
574
511
|
*/
|
|
575
512
|
_grouperToFlat(options) {
|
|
576
513
|
const result = [];
|
|
@@ -590,8 +527,9 @@ export class SelectComponent {
|
|
|
590
527
|
return result;
|
|
591
528
|
}
|
|
592
529
|
/**
|
|
593
|
-
* Move o foco para a próxima opção.
|
|
594
|
-
* @
|
|
530
|
+
* Move o foco para a próxima opção disponível na lista, ignorando opções que sejam agrupadores.
|
|
531
|
+
* @private
|
|
532
|
+
* @param options Lista de opções internas do dropdown.
|
|
595
533
|
*/
|
|
596
534
|
_focusNextOption(options) {
|
|
597
535
|
let nextIndex = this.focusedIndex() + 1;
|
|
@@ -604,8 +542,9 @@ export class SelectComponent {
|
|
|
604
542
|
}
|
|
605
543
|
}
|
|
606
544
|
/**
|
|
607
|
-
* Move o foco para a opção anterior.
|
|
608
|
-
* @
|
|
545
|
+
* Move o foco para a opção anterior na lista, ignorando opções do tipo "grouper".
|
|
546
|
+
* @private
|
|
547
|
+
* @param options Lista de opções internas do dropdown.
|
|
609
548
|
*/
|
|
610
549
|
_focusPreviousOption(options) {
|
|
611
550
|
let prevIndex = this.focusedIndex() - 1;
|
|
@@ -618,7 +557,11 @@ export class SelectComponent {
|
|
|
618
557
|
}
|
|
619
558
|
}
|
|
620
559
|
/**
|
|
621
|
-
* Rola
|
|
560
|
+
* Rola a lista de opções para garantir que a opção atualmente focada esteja visível.
|
|
561
|
+
* Este método obtém o ID da opção atualmente focada a partir da lista de opções filtradas.
|
|
562
|
+
* Se um ID válido for encontrado, busca o elemento correspondente no DOM e utiliza
|
|
563
|
+
* `scrollIntoView` para rolar até a opção, alinhando-a ao bloco mais próximo.
|
|
564
|
+
* @private
|
|
622
565
|
*/
|
|
623
566
|
_scrollToFocusedOption() {
|
|
624
567
|
const id = this.filteredOptions()[this.focusedIndex()]?.id;
|
|
@@ -628,66 +571,14 @@ export class SelectComponent {
|
|
|
628
571
|
const el = document.getElementById(id);
|
|
629
572
|
el?.scrollIntoView({ block: 'nearest' });
|
|
630
573
|
}
|
|
631
|
-
/**
|
|
632
|
-
* Extrai o texto de uma opção, com base em `optionLabel`.
|
|
633
|
-
* @returns Função que retorna o label da opção.
|
|
634
|
-
*/
|
|
635
|
-
_getLabelExtractor() {
|
|
636
|
-
if (this.TIsPrimitive()) {
|
|
637
|
-
return (option) => String(option);
|
|
638
|
-
}
|
|
639
|
-
const labelInput = this.optionLabel();
|
|
640
|
-
if (labelInput) {
|
|
641
|
-
return (option) => String(option[labelInput] ?? '');
|
|
642
|
-
}
|
|
643
|
-
else {
|
|
644
|
-
throw new Error(`optionLabel is required for non-primitive options.`);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* Cria e posiciona dinamicamente o dropdown como portal.
|
|
649
|
-
*/
|
|
650
|
-
_createDropdownPortal() {
|
|
651
|
-
if (!isPlatformBrowser(this.platformId)) {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
const container = this._containerDiv();
|
|
655
|
-
const template = this._dropdownTemplate();
|
|
656
|
-
if (!container || !template) {
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
const dropElementRect = container.nativeElement.getBoundingClientRect();
|
|
660
|
-
this.dropTop = dropElementRect.bottom + window.scrollY;
|
|
661
|
-
this.dropLeft = dropElementRect.left + window.scrollX;
|
|
662
|
-
this.dropWidth = dropElementRect.width;
|
|
663
|
-
this._destroyDropdownPortal();
|
|
664
|
-
this._portalHost = new DomPortalOutlet(document.body);
|
|
665
|
-
const portal = new TemplatePortal(template, this._viewContainerRef);
|
|
666
|
-
this._portalHost.attach(portal);
|
|
667
|
-
const dropdownEl = document.querySelector('.dropdown-body-class');
|
|
668
|
-
if (dropdownEl) {
|
|
669
|
-
dropdownEl.style.position = 'absolute';
|
|
670
|
-
dropdownEl.style.top = `${this.dropTop + 4}px`;
|
|
671
|
-
dropdownEl.style.left = `${this.dropLeft}px`;
|
|
672
|
-
dropdownEl.style.width = `${this.dropWidth}px`;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
/**
|
|
676
|
-
* Remove o portal do dropdown do DOM.
|
|
677
|
-
*/
|
|
678
|
-
_destroyDropdownPortal() {
|
|
679
|
-
if (this._portalHost?.hasAttached()) {
|
|
680
|
-
this._portalHost.detach();
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
574
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
684
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectComponent, isStandalone: true, selector: "s-select", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null },
|
|
575
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectComponent, isStandalone: true, selector: "s-select", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", showOptions: "showOptionsChange" }, host: { attributes: { "role": "combobox" }, listeners: { "window:resize": "onWindowResize($event)" }, properties: { "attr.aria-expanded": "showOptions()", "attr.aria-haspopup": "\"listbox\"", "attr.aria-owns": "showOptions() ? componentId + \"-listbox\" : null", "attr.aria-activedescendant": "focusedIndex() >= 0 ? filteredOptions()[focusedIndex()]?.id : null", "attr.aria-label": "placeholder() || \"Select option\"", "attr.aria-disabled": "disabled()" } }, providers: [
|
|
685
576
|
{
|
|
686
577
|
provide: NG_VALUE_ACCESSOR,
|
|
687
578
|
useExisting: forwardRef(() => SelectComponent),
|
|
688
579
|
multi: true,
|
|
689
580
|
},
|
|
690
|
-
], viewQueries: [{ propertyName: "
|
|
581
|
+
], viewQueries: [{ propertyName: "_containerDiv", first: true, predicate: ["containerDiv"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [ngClass]=\"{\n 'pointer-events-none border-grayscale-20 bg-grayscale-5': disabled(),\n 'pointer-events-auto border-grayscale-30 bg-grayscale-0': !disabled(),\n }\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-owns]=\"'dropdown-container-' + componentId\"\n [attr.aria-labelledby]=\"componentId + '-label'\"\n role=\"combobox\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [ngClass]=\"{\n 'text-grayscale-90': !disabled() && !isClean(),\n 'text-grayscale-60': !disabled() && isClean(),\n 'text-grayscale-30': disabled(),\n }\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n >\n <i class=\"fas fa-times flex items-center\"></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [ngClass]=\"{ 'border-grayscale-20': disabled(), 'border-grayscale-30': !disabled() }\"\n >\n <i\n class=\"fas\"\n [ngClass]=\"{\n 'text-grayscale-30': disabled(),\n 'text-grayscale-90': !disabled(),\n 'fa-caret-down': !showOptions(),\n 'fa-caret-up': showOptions(),\n }\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"'dropdown-container-' + componentId\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n />\n </form>\n <i class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"></i>\n </div>\n <button (click)=\"clearFilter()\">\n <i class=\"fas fa-times flex items-center\"></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">{{\n emptyMessage() ?? 'platform.angular_components.no_records_found' | translate\n }}</span>\n }\n </div>\n</ng-template>\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: SelectOptionComponent, selector: "s-select-option", inputs: ["id", "label", "multiple", "checkmark", "isGrouper", "isFocused", "isSelected"], outputs: ["isSelectedChange", "selected"] }, { kind: "component", type: CheckboxComponent, selector: "s-checkbox", inputs: ["disabled", "checked", "indeterminate", "label"], outputs: ["disabledChange", "checkedChange", "indeterminateChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i5.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: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }] });
|
|
691
582
|
}
|
|
692
583
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, decorators: [{
|
|
693
584
|
type: Component,
|
|
@@ -698,15 +589,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
698
589
|
SelectOptionComponent,
|
|
699
590
|
CheckboxComponent,
|
|
700
591
|
TranslateModule,
|
|
592
|
+
OverlayModule,
|
|
701
593
|
], host: {
|
|
702
|
-
'(document:click)': 'onDocumentClick($event)',
|
|
703
594
|
'(window:resize)': 'onWindowResize($event)',
|
|
595
|
+
'[attr.aria-expanded]': 'showOptions()',
|
|
596
|
+
'[attr.aria-haspopup]': '"listbox"',
|
|
597
|
+
'[attr.aria-owns]': 'showOptions() ? componentId + "-listbox" : null',
|
|
598
|
+
'[attr.aria-activedescendant]': 'focusedIndex() >= 0 ? filteredOptions()[focusedIndex()]?.id : null',
|
|
599
|
+
'[attr.aria-label]': 'placeholder() || "Select option"',
|
|
600
|
+
'[attr.aria-disabled]': 'disabled()',
|
|
601
|
+
role: 'combobox',
|
|
704
602
|
}, providers: [
|
|
705
603
|
{
|
|
706
604
|
provide: NG_VALUE_ACCESSOR,
|
|
707
605
|
useExisting: forwardRef(() => SelectComponent),
|
|
708
606
|
multi: true,
|
|
709
607
|
},
|
|
710
|
-
], template: "<
|
|
711
|
-
}] });
|
|
712
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zZWxlY3Qvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zZWxlY3Qvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRSxPQUFPLEVBQ0gsU0FBUyxFQUNULFFBQVEsRUFDUixVQUFVLEVBQ1YsVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsS0FBSyxFQUdMLFdBQVcsRUFDWCxNQUFNLEVBRU4sU0FBUyxFQUNULGdCQUFnQixHQUNuQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLFdBQVcsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0SCxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDeEUsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUvRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUMzRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZDQUE2QyxDQUFDOzs7Ozs7QUEr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Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDO2dCQUM5QyxLQUFLLEVBQUUsSUFBSTthQUNkO1NBQ0osaVJDdkRMLGd3S0F1SUEsMkNEakdRLFlBQVksNEhBQ1osbUJBQW1CLDQ4QkFDbkIsZUFBZSw0akJBQ2YscUJBQXFCLGlNQUNyQixpQkFBaUIsc0xBQ2pCLGVBQWU7OzRGQWNWLGVBQWU7a0JBeEIzQixTQUFTOytCQUNJLFVBQVUsY0FFUixJQUFJLFdBQ1A7d0JBQ0wsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLGVBQWU7d0JBQ2YscUJBQXFCO3dCQUNyQixpQkFBaUI7d0JBQ2pCLGVBQWU7cUJBQ2xCLFFBQ0s7d0JBQ0Ysa0JBQWtCLEVBQUUseUJBQXlCO3dCQUM3QyxpQkFBaUIsRUFBRSx3QkFBd0I7cUJBQzlDLGFBQ1U7d0JBQ1A7NEJBQ0ksT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLENBQUM7NEJBQzlDLEtBQUssRUFBRSxJQUFJO3lCQUNkO3FCQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRG9tUG9ydGFsT3V0bGV0LCBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgU2Nyb2xsaW5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3Njcm9sbGluZyc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIGNvbXB1dGVkLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgZm9yd2FyZFJlZixcbiAgICBpbmplY3QsXG4gICAgaW5wdXQsXG4gICAgbW9kZWwsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBQTEFURk9STV9JRCxcbiAgICBzaWduYWwsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgdmlld0NoaWxkLFxuICAgIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIE5HX1ZBTFVFX0FDQ0VTU09SLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUsIFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgU2VsZWN0T3B0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL3NlbGVjdC1vcHRpb24vc2VsZWN0LW9wdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2hlY2tib3hDb21wb25lbnQgfSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL2NoZWNrYm94JztcblxuaW50ZXJmYWNlIEludGVybmFsRHJvcGRvd25PcHRpb248VD4ge1xuICAgIGRhdGE6IFQ7XG4gICAgaWQ6IHN0cmluZztcbiAgICBncm91cGVyPzogYm9vbGVhbjtcbn1cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncy1zZWxlY3QnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zZWxlY3QuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW1xuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgICAgIFNjcm9sbGluZ01vZHVsZSxcbiAgICAgICAgU2VsZWN0T3B0aW9uQ29tcG9uZW50LFxuICAgICAgICBDaGVja2JveENvbXBvbmVudCxcbiAgICAgICAgVHJhbnNsYXRlTW9kdWxlLFxuICAgIF0sXG4gICAgaG9zdDoge1xuICAgICAgICAnKGRvY3VtZW50OmNsaWNrKSc6ICdvbkRvY3VtZW50Q2xpY2soJGV2ZW50KScsXG4gICAgICAgICcod2luZG93OnJlc2l6ZSknOiAnb25XaW5kb3dSZXNpemUoJGV2ZW50KScsXG4gICAgfSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBTZWxlY3RDb21wb25lbnQpLFxuICAgICAgICAgICAgbXVsdGk6IHRydWUsXG4gICAgICAgIH0sXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgU2VsZWN0Q29tcG9uZW50PFQ+IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBwdWJsaWMgcGxhY2Vob2xkZXIgPSBpbnB1dCgnJyk7XG4gICAgcHVibGljIG11bHRpcGxlID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyBvcHRpb25zID0gaW5wdXQucmVxdWlyZWQ8VFtdPigpO1xuICAgIHB1YmxpYyBvcHRpb25MYWJlbCA9IGlucHV0PGtleW9mIFQ+KCk7XG4gICAgcHVibGljIG9wdGlvblZhbHVlID0gaW5wdXQ8a2V5b2YgVD4oKTtcbiAgICBwdWJsaWMgc2hvd0NsZWFyID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyBmaWx0ZXIgPSBpbnB1dChmYWxzZSk7XG4gICAgcHVibGljIGNoZWNrbWFyayA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgZmlsdGVyQnkgPSBpbnB1dDxrZXlvZiBUIHwgKGtleW9mIFQpW10+KCk7XG4gICAgcHVibGljIGdyb3VwID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyB2aXJ0dWFsU2Nyb2xsID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyB2aXJ0dWFsU2Nyb2xsSXRlbVNpemUgPSBpbnB1dCgzNyk7XG4gICAgcHVibGljIGVtcHR5TWVzc2FnZSA9IGlucHV0PHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAgIHB1YmxpYyB1c2VSYXdWYWx1ZSA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgZGF0YUtleSA9IGlucHV0PGtleW9mIFQ+KCk7XG5cbiAgICBwdWJsaWMgZGlzYWJsZWQgPSBtb2RlbChmYWxzZSk7XG4gICAgcHVibGljIHNob3dPcHRpb25zID0gc2lnbmFsKGZhbHNlKTtcblxuICAgIHB1YmxpYyB2YWx1ZSA9IHNpZ25hbDxUIHwgbnVsbD4obnVsbCk7XG4gICAgcHVibGljIHZhbHVlcyA9IHNpZ25hbDxUW10+KFtdKTtcbiAgICBwdWJsaWMgZmlsdGVyVmFsdWUgPSBzaWduYWwoJycpO1xuICAgIHB1YmxpYyBmb2N1c2VkSW5kZXggPSBzaWduYWwoLTEpO1xuXG4gICAgcHVibGljIGRyb3BUb3AgPSAwO1xuICAgIHB1YmxpYyBkcm9wTGVmdCA9IDA7XG4gICAgcHVibGljIGRyb3BXaWR0aCA9IDA7XG5cbiAgICBwcml2YXRlIF9wb3J0YWxIb3N0OiBEb21Qb3J0YWxPdXRsZXQgfCBudWxsID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWNhIHNlIHRvZGFzIGFzIG9ww6fDtWVzIHZpc8OtdmVpcyAoZmlsdHJhZGFzIGUgbsOjbyBhZ3J1cGFkb3JhcykgZXN0w6NvIHNlbGVjaW9uYWRhcy5cbiAgICAgKlxuICAgICAqIC0gUmV0b3JuYSBgdHJ1ZWAgc2UgdG9kYXMgYXMgb3DDp8O1ZXMgZmlsdHJhZGFzIGVzdGl2ZXJlbSBwcmVzZW50ZXMgZW0gYHZhbHVlcygpYC5cbiAgICAgKiAtIElnbm9yYSBvcMOnw7VlcyBtYXJjYWRhcyBjb21vIGBncm91cGVyYC5cbiAgICAgKiAtIFVzYSBgX2dldENvbXBhcmVWYWx1ZUV4dHJhY3RvcigpYCBwYXJhIGNvbXBhcmFyIG9zIHZhbG9yZXMgZGUgZm9ybWEgY29uc2lzdGVudGUuXG4gICAgICpcbiAgICAgKiBFc3NlIGVzdGFkbyDDqSB1c2FkbyBwYXJhIGNvbnRyb2xhciBvIGNoZWNrYm94IGRlIFwiU2VsZWNpb25hciB0b2Rvc1wiIHF1YW5kbyB0b2RhcyBhcyBvcMOnw7VlcyB2aXPDrXZlaXMgZXN0w6NvIG1hcmNhZGFzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhbGxTZWxlY3RlZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnZhbHVlcygpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5maWx0ZXIoKG8pID0+ICFvLmdyb3VwZXIpO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgb3B0aW9ucy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICBvcHRpb25zLmV2ZXJ5KChvcHRpb24pID0+XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQuc29tZShcbiAgICAgICAgICAgICAgICAgICAgKHMpID0+IHRoaXMuX2dldENvbXBhcmVWYWx1ZUV4dHJhY3RvcigpKHMpID09PSB0aGlzLl9nZXRDb21wYXJlVmFsdWVFeHRyYWN0b3IoKShvcHRpb24gYXMgVCksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyBmb2N1c2VkSXRlbSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZmlsdGVyZWRPcHRpb25zKCkuYXQodGhpcy5mb2N1c2VkSW5kZXgoKSk/LmRhdGEgPz8gbnVsbCk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0ZSBhcyBvcMOnw7VlcyBleHRlcm5hcyAoYG9wdGlvbnMoKWApIGVtIHVtYSBlc3RydXR1cmEgaW50ZXJuYSBwYWRyb25pemFkYSAoYEludGVybmFsRHJvcGRvd25PcHRpb248VD5gKS5cbiAgICAgKlxuICAgICAqIC0gU2Ugb3MgZGFkb3MgZm9yZW0gcHJpbWl0aXZvcyAoc3RyaW5nLCBudW1iZXIsIGV0Yy4pLCBnZXJhIG9ww6fDtWVzIGNvbSBJRHMgYmFzZWFkb3Mgbm8gw61uZGljZS5cbiAgICAgKiAtIFNlIG9zIGRhZG9zIGZvcmVtIG9iamV0b3MsIGRlbGVnYSBhIGNyaWHDp8OjbyBkYXMgb3DDp8O1ZXMgcGFyYSBgX2FkZElkVG9PcHRpb25zKClgLCBxdWUgYWRpY2lvbmEgSURzIGUgbWFyY2EgYWdydXBhZG9yZXMuXG4gICAgICogLSBTZSBvIG1vZG8gYWdydXBhZG8gZXN0aXZlciBhdGl2byAoYGdyb3VwKClgKSwgdHJhbnNmb3JtYSBhcyBvcMOnw7VlcyBlbSB1bWEgbGlzdGEgYWNoYXRhZGEgY29tIGFncnVwYWRvcmVzIHZpYSBgX2dyb3VwZXJUb0ZsYXQoKWAuXG4gICAgICpcbiAgICAgKiBFc3NhIGVzdHJ1dHVyYSDDqSB1c2FkYSBpbnRlcm5hbWVudGUgcGFyYSByZW5kZXJpemHDp8OjbywgZmlsdHJhZ2VtIGUgY29udHJvbGUgZGUgc2VsZcOnw6NvLlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnRlcm5hbE9wdGlvbnMgPSBjb21wdXRlZDxJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10+KCgpID0+IHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucygpO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnNXaXRoSWQ6IEludGVybmFsRHJvcGRvd25PcHRpb248VD5bXSA9IHRoaXMuVElzUHJpbWl0aXZlKClcbiAgICAgICAgICAgID8gb3B0cy5tYXAoKHZhbHVlLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICAgICAgICBpZDogYGlkX3ByaW1pdGl2ZV8ke2luZGV4fWAsXG4gICAgICAgICAgICAgICAgZ3JvdXBlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGF0YTogdmFsdWUgYXMgVCxcbiAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgOiB0aGlzLl9hZGRJZFRvT3B0aW9ucyhvcHRzKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5ncm91cCgpID8gdGhpcy5fZ3JvdXBlclRvRmxhdChvcHRpb25zV2l0aElkKSA6IG9wdGlvbnNXaXRoSWQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBSZXRvcm5hIG8gdGV4dG8gcXVlIGRldmUgc2VyIGV4aWJpZG8gbm8gY29tcG9uZW50ZSBjb20gYmFzZSBub3MgdmFsb3JlcyBzZWxlY2lvbmFkb3MuXG4gICAgICpcbiAgICAgKiAtIE5vIG1vZG8gbcO6bHRpcGxvOlxuICAgICAqICAgLSBTZSBob3V2ZXIgbWFpcyBkZSB1bSBpdGVtIHNlbGVjaW9uYWRvLCBleGliZSB1bWEgbWVuc2FnZW0gdHJhZHV6aWRhIGNvbSBvIHRvdGFsIGRlIHJlZ2lzdHJvcy5cbiAgICAgKiAgIC0gU2UgaG91dmVyIGFwZW5hcyB1bSBpdGVtIHNlbGVjaW9uYWRvLCBleGliZSBvIGxhYmVsIGNvcnJlc3BvbmRlbnRlLlxuICAgICAqIC0gTm8gbW9kbyBzaW1wbGVzOlxuICAgICAqICAgLSBFeGliZSBvIGxhYmVsIGRvIHZhbG9yIHNlbGVjaW9uYWRvLiAgICAgKlxuICAgICAqIC0gU2UgbmVuaHVtIHZhbG9yIGVzdGl2ZXIgc2VsZWNpb25hZG8sIHJldG9ybmEgdW1hIHN0cmluZyB2YXppYS5cbiAgICAgKlxuICAgICAqIEVzc2EgbMOzZ2ljYSDDqSB1c2FkYSBwYXJhIG1vc3RyYXIgbyBjb250ZcO6ZG8gYXR1YWwgZG8gY2FtcG8gZGUgc2VsZcOnw6NvLlxuICAgICAqL1xuXG4gICAgcHVibGljIHByaW50ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMudmFsdWVzKCk7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWQubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoYHBsYXRmb3JtLmFuZ3VsYXJfY29tcG9uZW50cy50b3RhbF9yZWNvcmRzX3NlbGVjdGVkYCwge1xuICAgICAgICAgICAgICAgICAgICBjb3VudDogc2VsZWN0ZWQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TGFiZWxGcm9tT3B0aW9uKHNlbGVjdGVkWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZhbHVlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRMYWJlbEZyb21PcHRpb24odGhpcy52YWx1ZSgpIGFzIFQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH0pO1xuXG4gICAgcHVibGljIGlzQ2xlYW4gPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLm11bHRpcGxlKCkgPyAhdGhpcy52YWx1ZXMoKS5sZW5ndGggOiAhdGhpcy52YWx1ZSgpO1xuICAgIH0pO1xuXG4gICAgcHVibGljIFRJc1ByaW1pdGl2ZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucygpO1xuICAgICAgICBpZiAoIW9wdHMubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiBbJ3N0cmluZycsICdudW1iZXInLCAnYm9vbGVhbiddLmluY2x1ZGVzKHR5cGVvZiBvcHRzWzBdKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEluZGljYSBzZSBvIGVzdGFkbyBkZSBzZWxlw6fDo28gZXN0w6EgaW5kZXRlcm1pbmFkby5cbiAgICAgKlxuICAgICAqIC0gUmV0b3JuYSBgdHJ1ZWAgcXVhbmRvICoqYWxndW1hcyoqLCBtYXMgbsOjbyB0b2Rhcywgb3DDp8O1ZXMgdmlzw612ZWlzIGVzdMOjbyBzZWxlY2lvbmFkYXMuXG4gICAgICogLSBSZXRvcm5hIGBmYWxzZWAgcXVhbmRvICoqdG9kYXMqKiBvdSAqKm5lbmh1bWEqKiBkYXMgb3DDp8O1ZXMgdmlzw612ZWlzIGVzdMOjbyBzZWxlY2lvbmFkYXMuXG4gICAgICogLSBJZ25vcmEgb3DDp8O1ZXMgbWFyY2FkYXMgY29tbyBgZ3JvdXBlcmAuXG4gICAgICpcbiAgICAgKiBFc3NlIGVzdGFkbyDDqSB1c2FkbywgcG9yIGV4ZW1wbG8sIHBhcmEgZXhpYmlyIG8gY2hlY2tib3ggZGUgXCJTZWxlY2lvbmFyIHRvZG9zXCIgZW0gbW9kbyBpbmRldGVybWluYWRvLlxuICAgICAqL1xuXG4gICAgcHVibGljIHNlbGVjdEFsbElzSW5kZXRlcm1pbmF0ZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnZhbHVlcygpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5maWx0ZXIoKG8pID0+ICFvLmdyb3VwZXIpO1xuXG4gICAgICAgIGNvbnN0IGFsbCA9IG9wdGlvbnMubGVuZ3RoID4gMCAmJiBvcHRpb25zLmV2ZXJ5KChvKSA9PiBzZWxlY3RlZC5pbmNsdWRlcyhvLmRhdGEpKTtcbiAgICAgICAgY29uc3Qgbm9uZSA9IG9wdGlvbnMuZXZlcnkoKG8pID0+ICFzZWxlY3RlZC5pbmNsdWRlcyhvLmRhdGEpKTtcblxuICAgICAgICByZXR1cm4gIWFsbCAmJiAhbm9uZTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJldG9ybmEgYSBsaXN0YSBkZSBvcMOnw7VlcyBmaWx0cmFkYXMgY29tIGJhc2Ugbm8gdmFsb3IgZGlnaXRhZG8gcGVsbyB1c3XDoXJpby5cbiAgICAgKlxuICAgICAqIC0gU2UgbyBmaWx0cm8gZXN0aXZlciBkZXNhdGl2YWRvIG91IHZhemlvLCByZXRvcm5hIHRvZGFzIGFzIG9ww6fDtWVzLlxuICAgICAqIC0gQ2FzbyBjb250csOhcmlvLCBhcGxpY2EgbyBmaWx0cm8gdXNhbmRvIG8ocykgY2FtcG8ocykgZGVmaW5pZG9zIGVtIGBmaWx0ZXJCeWAuXG4gICAgICogLSBJZ25vcmEgb3DDp8O1ZXMgbWFyY2FkYXMgY29tbyBgZ3JvdXBlcmAuXG4gICAgICogLSBVc2EgbyBleHRyYXRvciBkZSBsYWJlbCBwYXJhIGNvbXBhcmFyIG9zIHZhbG9yZXMgY29tIG8gdGV4dG8gYnVzY2Fkby5cbiAgICAgKi9cblxuICAgIHB1YmxpYyBmaWx0ZXJlZE9wdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsbE9wdGlvbnMgPSB0aGlzLmludGVybmFsT3B0aW9ucygpO1xuICAgICAgICBjb25zdCBzZWFyY2ggPSB0aGlzLmZpbHRlclZhbHVlKCkudG9Mb3dlckNhc2UoKS50cmltKCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmZpbHRlcigpIHx8ICFzZWFyY2gpIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxPcHRpb25zO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlsdGVyQnkgPSB0aGlzLmZpbHRlckJ5KCk7XG4gICAgICAgIHJldHVybiBhbGxPcHRpb25zLmZpbHRlcigob3B0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uLmdyb3VwZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGxhYmVsRXh0cmFjdG9yID0gdGhpcy5fZ2V0TGFiZWxFeHRyYWN0b3IoKTtcbiAgICAgICAgICAgIGxldCBsYWJlbCA9ICcnO1xuXG4gICAgICAgICAgICBpZiAoIWZpbHRlckJ5KSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSBsYWJlbEV4dHJhY3RvcihvcHRpb24uZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZmlsdGVyQnkpKSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSBmaWx0ZXJCeS5tYXAoKGJ5KSA9PiBTdHJpbmcob3B0aW9uLmRhdGFbYnldID8/ICcnKSkuam9pbignICcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsYWJlbCA9IFN0cmluZyhvcHRpb24uZGF0YVtmaWx0ZXJCeV0gPz8gJycpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2gpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyByZWFkb25seSBmaWx0ZXJGb3JtID0gbmV3IEZvcm1Hcm91cDx7IGZpbHRlcjogRm9ybUNvbnRyb2w8c3RyaW5nPiB9Pih7XG4gICAgICAgIGZpbHRlcjogbmV3IEZvcm1Db250cm9sPHN0cmluZz4oJycsIHsgbm9uTnVsbGFibGU6IHRydWUgfSksXG4gICAgfSk7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+KTtcbiAgICBwcml2YXRlIF9kcm9wZG93blRlbXBsYXRlID0gdmlld0NoaWxkPFRlbXBsYXRlUmVmPGFueT4+KCdkcm9wZG93blRlbXBsYXRlJyk7XG4gICAgcHJpdmF0ZSBfY29udGFpbmVyRGl2ID0gdmlld0NoaWxkPEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+PignY29udGFpbmVyRGl2Jyk7XG4gICAgcHJpdmF0ZSBfb25DaGFuZ2U6ICh2YWx1ZTogVCB8IFRbXSB8IG51bGwpID0+IHZvaWQgPSAoKSA9PiB7IH07XG4gICAgcHJpdmF0ZSBfb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4geyB9O1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybUlkID0gaW5qZWN0KFBMQVRGT1JNX0lEKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF92aWV3Q29udGFpbmVyUmVmID0gaW5qZWN0KFZpZXdDb250YWluZXJSZWYpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3RyYW5zbGF0ZVNlcnZpY2UgPSBpbmplY3QoVHJhbnNsYXRlU2VydmljZSk7XG5cbiAgICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKlxuICAgICAqIEluaWNpYWxpemEgbyBjb21wb25lbnRlLCB2YWxpZGFuZG8gb3MgaW5wdXRzIGUgY29uZmlndXJhbmRvIG8gZmlsdHJvIGNvbSBkZWJvdW5jZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlSW5wdXRzKCk7XG5cbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtXG4gICAgICAgICAgICAuZ2V0KCdmaWx0ZXInKSFcbiAgICAgICAgICAgIC52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoMzAwKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZhbHVlLnNldCh2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRhIGxpbXBlemEgZGUgcmVjdXJzb3MgYW8gZGVzdHJ1aXIgbyBjb21wb25lbnRlLlxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveURyb3Bkb3duUG9ydGFsKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3BvcnRhbEhvc3QpIHtcbiAgICAgICAgICAgIHRoaXMuX3BvcnRhbEhvc3QuZGlzcG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5fcG9ydGFsSG9zdCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmluZSBvIHZhbG9yIG5vIGNvbXBvbmVudGUgdmluZG8gZG8gZm9ybXVsw6FyaW8gZXh0ZXJuby5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVmFsb3IgYXRyaWJ1w61kbyBwZWxvIEFuZ3VsYXIgZm9ybXMuXG4gICAgICovXG4gICAgcHVibGljIHdyaXRlVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuVElzUHJpbWl0aXZlKClcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZS5tYXAoKHYpID0+IHRoaXMuX2ZpbmRPcHRpb25CeVByaW1pdGl2ZVZhbHVlKHYpKS5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnVzZVJhd1ZhbHVlKClcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdmFsdWUubWFwKCh2KSA9PiB0aGlzLl9maW5kT3B0aW9uQnlWYWx1ZSh2KSkuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMuc2V0KGl0ZW1zIGFzIFRbXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzLnNldChbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gdGhpcy5USXNQcmltaXRpdmUoKVxuICAgICAgICAgICAgICAgID8gdGhpcy5fZmluZE9wdGlvbkJ5UHJpbWl0aXZlVmFsdWUodmFsdWUpXG4gICAgICAgICAgICAgICAgOiB0aGlzLnVzZVJhd1ZhbHVlKClcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2ZpbmRPcHRpb25CeVZhbHVlKHZhbHVlKTtcblxuICAgICAgICAgICAgdGhpcy52YWx1ZS5zZXQoaXRlbSA/PyBudWxsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZ2lzdHJhIGEgZnVuw6fDo28gcXVlIHNlcsOhIGNoYW1hZGEgcXVhbmRvIG8gdmFsb3IgbXVkYXIuXG4gICAgICogQHBhcmFtIG9uQ2hhbmdlIEZ1bsOnw6NvIGNhbGxiYWNrLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKG9uQ2hhbmdlOiAodmFsdWU6IFQgfCBUW10gfCBudWxsKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29uQ2hhbmdlID0gb25DaGFuZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVnaXN0cmEgYSBmdW7Dp8OjbyBxdWUgc2Vyw6EgY2hhbWFkYSBxdWFuZG8gbyBjb21wb25lbnRlIGZvciBcInRvY2Fkb1wiLlxuICAgICAqIEBwYXJhbSBvblRvdWNoZWQgRnVuw6fDo28gY2FsbGJhY2suXG4gICAgICovXG4gICAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKG9uVG91Y2hlZDogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vblRvdWNoZWQgPSBvblRvdWNoZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmaW5lIG8gZXN0YWRvIGRlIGRlc2FiaWxpdGFkbyBkbyBjb21wb25lbnRlLlxuICAgICAqIEBwYXJhbSBkaXNhYmxlZCBJbmRpY2Egc2UgbyBjb21wb25lbnRlIGVzdMOhIGRlc2FiaWxpdGFkby5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0RGlzYWJsZWRTdGF0ZShkaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc2FibGVkLnNldChkaXNhYmxlZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWx0ZXJuYSBhIGV4aWJpw6fDo28gZGEgbGlzdGEgZGUgb3DDp8O1ZXMgKGRyb3Bkb3duKS5cbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzaG91bGRPcGVuID0gIXRoaXMuc2hvd09wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5zaG93T3B0aW9ucy5zZXQoc2hvdWxkT3Blbik7XG5cbiAgICAgICAgaWYgKHNob3VsZE9wZW4pIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZURyb3Bkb3duUG9ydGFsKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lEcm9wZG93blBvcnRhbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VsZWNpb25hIG91IGRlc3NlbGVjaW9uYSB1bSBpdGVtIG5hIGxpc3RhLlxuICAgICAqIEBwYXJhbSBpdGVtIEl0ZW0gYSBzZXIgc2VsZWNpb25hZG8gb3UgZGVzbWFyY2Fkby5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0SXRlbShpdGVtOiBUKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdldENvbXBhcmVWYWx1ZSA9IHRoaXMuX2dldENvbXBhcmVWYWx1ZUV4dHJhY3RvcigpO1xuXG4gICAgICAgIGlmICh0aGlzLm11bHRpcGxlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gWy4uLnRoaXMudmFsdWVzKCldO1xuICAgICAgICAgICAgY29uc3QgaXRlbVZhbHVlID0gZ2V0Q29tcGFyZVZhbHVlKGl0ZW0pO1xuXG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmZpbmRJbmRleCgoc2VsZWN0ZWRJdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldENvbXBhcmVWYWx1ZShzZWxlY3RlZEl0ZW0pID09PSBpdGVtVmFsdWU7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN0b3JlLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0b3JlLnB1c2goaXRlbSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudmFsdWVzLnNldChzdG9yZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMudXNlUmF3VmFsdWUoKSA/IHN0b3JlIDogc3RvcmUubWFwKChpKSA9PiB0aGlzLl9nZXRWYWx1ZUV4dHJhY3RvcigpKGkpKTtcblxuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UocmVzdWx0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUuc2V0KGl0ZW0pO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnVzZVJhd1ZhbHVlKCkgPyBpdGVtIDogdGhpcy5fZ2V0VmFsdWVFeHRyYWN0b3IoKShpdGVtKTtcblxuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UocmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX29uVG91Y2hlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExpbXBhIGEgc2VsZcOnw6NvIGF0dWFsLlxuICAgICAqIEBwYXJhbSBldmVudCBFdmVudG8gZG8gY2xpcXVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBjbGVhcihldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlcy5zZXQoW10pO1xuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy5fcmVtb3ZlSW50ZXJuYWxQcm9wZXJ0aWVzKHRoaXMudmFsdWVzKCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUuc2V0KG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy52YWx1ZSgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Nsb3NlRHJvcGRvd24oKTtcblxuICAgICAgICB0aGlzLl9vblRvdWNoZWQoKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGltcGEgbyBmaWx0cm8gYXBsaWNhZG8gw6AgbGlzdGEgZGUgb3DDp8O1ZXMuXG4gICAgICovXG4gICAgcHVibGljIGNsZWFyRmlsdGVyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZpbHRlckZvcm0uZ2V0KCdmaWx0ZXInKT8ucmVzZXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGZWNoYSBvIGRyb3Bkb3duIHNlIG8gY2xpcXVlIG9jb3JyZXIgZm9yYSBkbyBjb21wb25lbnRlLlxuICAgICAqIEBwYXJhbSBldmVudCBFdmVudG8gZG8gY2xpcXVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY2xpY2tUYXJnZXQgPSBldmVudC50YXJnZXQgYXMgTm9kZTtcblxuICAgICAgICBjb25zdCBjbGlja2VkSW5zaWRlQ29tcG9uZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGNsaWNrVGFyZ2V0KTtcbiAgICAgICAgY29uc3QgZHJvcGRvd25JbkJvZHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZHJvcGRvd24tYm9keS1jbGFzcycpPy5jb250YWlucyhjbGlja1RhcmdldCk7XG5cbiAgICAgICAgaWYgKCFjbGlja2VkSW5zaWRlQ29tcG9uZW50ICYmICFkcm9wZG93bkluQm9keSkge1xuICAgICAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmVjaGEgbyBkcm9wZG93biBlbSBldmVudG9zIGRlIHJlZGltZW5zaW9uYW1lbnRvIGRlIGphbmVsYS5cbiAgICAgKi9cbiAgICBwdWJsaWMgb25XaW5kb3dSZXNpemUoXzogRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvd09wdGlvbnMoKSkge1xuICAgICAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlzcGFyYSBhIGFiZXJ0dXJhL2ZlY2hhbWVudG8gZG8gZHJvcGRvd24gYW8gY2xpY2FyIG5vIGNvbnRhaW5lci5cbiAgICAgKi9cbiAgICBwdWJsaWMgb25Db250YWluZXJEaXZDbGljaygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50b2dnbGUoKTtcbiAgICAgICAgdGhpcy5fY29udGFpbmVyRGl2KCk/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmF0YSBldmVudG9zIGRlIHRlY2xhZG8gcGFyYSBuYXZlZ2HDp8OjbyBlIHNlbGXDp8Ojby5cbiAgICAgKiBAcGFyYW0gZXZlbnQgRXZlbnRvIGRvIHRlY2xhZG8uXG4gICAgICovXG4gICAgcHVibGljIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKTtcblxuICAgICAgICBpZiAoIW9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBfc2VsZWN0T3B0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9jdXNlZEluZGV4KCkgPj0gMCAmJiB0aGlzLmZvY3VzZWRJbmRleCgpIDwgb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0SXRlbShvcHRpb25zW3RoaXMuZm9jdXNlZEluZGV4KCldLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICAgICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNOZXh0T3B0aW9uKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9mb2N1c1ByZXZpb3VzT3B0aW9uKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnVGFiJzpcbiAgICAgICAgICAgICAgICBfc2VsZWN0T3B0aW9uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNob3dPcHRpb25zKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgX3NlbGVjdE9wdGlvbigpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnRXNjYXBlJzpcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICcgJzpcbiAgICAgICAgICAgICAgICBfc2VsZWN0T3B0aW9uKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXRvcm5hIG8gcsOzdHVsbyBkZSBleGliacOnw6NvIGRlIHVtYSBvcMOnw6NvLlxuICAgICAqIEBwYXJhbSBvcHRpb24gSXRlbSBkYSBsaXN0YSBkZSBvcMOnw7Vlcy5cbiAgICAgKiBAcmV0dXJucyBUZXh0byBxdWUgc2Vyw6EgZXhpYmlkbyBubyBkcm9wZG93bi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0T3B0aW9uTGFiZWwob3B0aW9uOiBUKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldExhYmVsRnJvbU9wdGlvbihvcHRpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bsOnw6NvIHVzYWRhIHBhcmEgbyB0cmFja0J5IG5vIGZvciBkbyB0ZW1wbGF0ZS5cbiAgICAgKiBAcGFyYW0gXyDDjW5kaWNlIGRvIGl0ZW0uXG4gICAgICogQHBhcmFtIGl0ZW0gSXRlbSBkYSBsaXN0YS5cbiAgICAgKiBAcmV0dXJucyBJRCDDum5pY28gZGEgb3DDp8Ojby5cbiAgICAgKi9cbiAgICBwdWJsaWMgdHJhY2tCeUlkKF86IG51bWJlciwgaXRlbTogSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPik6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBpdGVtLmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWNhIHNlIHVtYSBvcMOnw6NvIGVzdMOhIHNlbGVjaW9uYWRhLlxuICAgICAqIEBwYXJhbSBvcHRpb24gT3DDp8OjbyBhIHNlciB2ZXJpZmljYWRhLlxuICAgICAqIEByZXR1cm5zIFZlcmRhZGVpcm8gc2UgYSBvcMOnw6NvIGVzdGl2ZXIgc2VsZWNpb25hZGEuXG4gICAgICovXG4gICAgcHVibGljIGlzT3B0aW9uU2VsZWN0ZWQob3B0aW9uOiBUKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGdldENvbXBhcmVWYWx1ZSA9IHRoaXMuX2dldENvbXBhcmVWYWx1ZUV4dHJhY3RvcigpO1xuXG4gICAgICAgIGlmICh0aGlzLm11bHRpcGxlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkVmFsdWVzID0gdGhpcy52YWx1ZXMoKS5tYXAoZ2V0Q29tcGFyZVZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBzZWxlY3RlZFZhbHVlcy5pbmNsdWRlcyhnZXRDb21wYXJlVmFsdWUob3B0aW9uKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLnZhbHVlKCk7XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFZhbHVlICE9PSBudWxsICYmIGdldENvbXBhcmVWYWx1ZShjdXJyZW50VmFsdWUpID09PSBnZXRDb21wYXJlVmFsdWUob3B0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsdGVybmEgYSBzZWxlw6fDo28gZGUgdG9kb3Mgb3MgaXRlbnMgZmlsdHJhZG9zLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGVTZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5maWx0ZXIoKG8pID0+ICFvLmdyb3VwZXIpO1xuXG4gICAgICAgIGlmICh0aGlzLmFsbFNlbGVjdGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWVzLnNldChbXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlcy5zZXQob3B0aW9ucy5tYXAoKG8pID0+IG8uZGF0YSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy5fcmVtb3ZlSW50ZXJuYWxQcm9wZXJ0aWVzKHRoaXMudmFsdWVzKCkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9jdXJhIGUgcmV0b3JuYSB1bWEgb3DDp8OjbyBjb20gdmFsb3IgcHJpbWl0aXZvIGlndWFsIGFvIGluZm9ybWFkby5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZSBWYWxvciBwcmltaXRpdm8gKHN0cmluZywgbnVtYmVyIG91IGJvb2xlYW4pLlxuICAgICAqIEByZXR1cm5zIEEgb3DDp8OjbyBjb3JyZXNwb25kZW50ZSwgb3UgYG51bGxgIHNlIG7Do28gZW5jb250cmFkYS5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9maW5kT3B0aW9uQnlQcmltaXRpdmVWYWx1ZSh2YWx1ZTogYW55KTogVCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm5hbE9wdGlvbnMoKS5maW5kKChvcHQpID0+IG9wdC5kYXRhID09PSB2YWx1ZSk/LmRhdGEgPz8gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgcHJvcHJpZWRhZGVzIGludGVybmFzIGFkaWNpb25hZGFzIHBlbG8gY29tcG9uZW50ZSwgcmV0b3JuYW5kbyBhcGVuYXMgb3MgZGFkb3MgY3J1cy5cbiAgICAgKlxuICAgICAqIFVzYWRvIHBhcmEgZ2FyYW50aXIgcXVlIGFwZW5hcyBvcyBvYmpldG9zIGRlIGRhZG9zIHJlYWlzIHNlamFtIGVtaXRpZG9zIGFvIGZvcm11bMOhcmlvLFxuICAgICAqIGVzcGVjaWFsbWVudGUgbm8gbW9kbyBtw7psdGlwbG8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgVmFsb3IgYXJtYXplbmFkbyBpbnRlcm5hbWVudGUgKGNvbSBvdSBzZW0gYEludGVybmFsRHJvcGRvd25PcHRpb25gKS5cbiAgICAgKiBAcmV0dXJucyBPcyBkYWRvcyBcInB1cm9zXCIsIHNlbSBwcm9wcmllZGFkZXMgYWRpY2lvbmFpcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9yZW1vdmVJbnRlcm5hbFByb3BlcnRpZXModmFsdWU6IGFueSkge1xuICAgICAgICBpZiAodGhpcy5USXNQcmltaXRpdmUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgICA/IHZhbHVlLm1hcCgob3B0OiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+KSA9PiBvcHQuZGF0YSlcbiAgICAgICAgICAgIDogKHZhbHVlIGFzIEludGVybmFsRHJvcGRvd25PcHRpb248VD4pLmRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0b3JuYSBvIHRleHRvIChsYWJlbCkgY29ycmVzcG9uZGVudGUgYSB1bWEgZGV0ZXJtaW5hZGEgb3DDp8Ojby5cbiAgICAgKiBVc2EgYSBwcm9wcmllZGFkZSBkZWZpbmlkYSBlbSBgb3B0aW9uTGFiZWxgLCBvdSB0ZW50YSB1c2FyIHVtYSBwcm9wcmllZGFkZSBwYWRyw6NvIChgbGFiZWxgKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb24gQSBvcMOnw6NvIGEgc2VyIGV4aWJpZGEuXG4gICAgICogQHJldHVybnMgTyB0ZXh0byBsZWfDrXZlbCBkYSBvcMOnw6NvIHBhcmEgZXhpYmnDp8OjbyBubyBjb21wb25lbnRlLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2dldExhYmVsRnJvbU9wdGlvbihvcHRpb246IFQpOiBzdHJpbmcge1xuICAgICAgICBpZiAoWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXS5pbmNsdWRlcyh0eXBlb2Ygb3B0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhvcHRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGFiZWxLZXkgPSB0aGlzLm9wdGlvbkxhYmVsKCk7XG5cbiAgICAgICAgaWYgKCFsYWJlbEtleSkge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZygob3B0aW9uIGFzIGFueSkubGFiZWwgPz8gJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFN0cmluZyhvcHRpb25bbGFiZWxLZXldKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGEgb3MgaW5wdXRzIG9icmlnYXTDs3Jpb3MgZG8gY29tcG9uZW50ZS5cbiAgICAgKi9cbiAgICBwcml2YXRlIF92YWxpZGF0ZUlucHV0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnVzZVJhd1ZhbHVlKCkgJiYgIXRoaXMuVElzUHJpbWl0aXZlKCkgJiYgIXRoaXMub3B0aW9uVmFsdWUoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBUaGUgJ29wdGlvblZhbHVlJyBpbnB1dCBtdXN0IGJlIHByb3ZpZGVkIGZvciBub24tcHJpbWl0aXZlIG9wdGlvbnMgd2hlbiB1c2VSYXdWYWx1ZSBpcyBmYWxzZS5gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5USXNQcmltaXRpdmUoKSAmJiAhdGhpcy5vcHRpb25WYWx1ZSgpICYmICF0aGlzLmRhdGFLZXkoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgdGhlIG9wdGlvblZhbHVlIG9yIGRhdGFLZXkgaW5wdXQgbXVzdCBiZSBwcm92aWRlZCBmb3Igbm9uLXByaW1pdGl2ZSBvcHRpb25zLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLlRJc1ByaW1pdGl2ZSgpICYmICF0aGlzLm9wdGlvbkxhYmVsKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlICdvcHRpb25MYWJlbCcgaW5wdXQgbXVzdCBiZSBwcm92aWRlZCBmb3Igbm9uLXByaW1pdGl2ZSBvcHRpb25zLmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZmluZE9wdGlvbkJ5VmFsdWUodmFsdWU6IGFueSk6IFQgfCBudWxsIHtcbiAgICAgICAgaWYgKHRoaXMudXNlUmF3VmFsdWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucygpLmZpbmQoKG9wdGlvbikgPT4gb3B0aW9uID09PSB2YWx1ZSkgPz8gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdldFZhbHVlID0gdGhpcy5fZ2V0VmFsdWVFeHRyYWN0b3IoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucygpLmZpbmQoKG9wdGlvbikgPT4gZ2V0VmFsdWUob3B0aW9uKSA9PT0gdmFsdWUpID8/IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFpIG8gdmFsb3IgZmluYWwgZGUgdW1hIG9ww6fDo28sIGNvbSBiYXNlIGVtIGBvcHRpb25WYWx1ZWAuXG4gICAgICogQHJldHVybnMgRnVuw6fDo28gcXVlIHJldG9ybmEgbyB2YWxvciBkYSBvcMOnw6NvLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2dldFZhbHVlRXh0cmFjdG9yKCk6IChvcHRpb246IFQpID0+IGFueSB7XG4gICAgICAgIGlmICh0aGlzLlRJc1ByaW1pdGl2ZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gKG9wdGlvbjogYW55KSA9PiBvcHRpb247XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy51c2VSYXdWYWx1ZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gKG9wdGlvbjogVCkgPT4gb3B0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmFsdWVJbnB1dCA9IHRoaXMub3B0aW9uVmFsdWUoKTtcblxuICAgICAgICBpZiAodmFsdWVJbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIChvcHRpb246IFQpID0+IG9wdGlvblt2YWx1ZUlucHV0XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgb3B0aW9uVmFsdWUgaXMgcmVxdWlyZWQgZm9yIG5vbi1wcmltaXRpdmUgb3B0aW9ucy5gKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWkgbyB2YWxvciBjb21wYXLDoXZlbCBkZSB1bWEgb3DDp8Ojby5cbiAgICAgKiBAcmV0dXJucyBGdW7Dp8OjbyBxdWUgcmV0b3JuYSBhIGNoYXZlIGRlIGNvbXBhcmHDp8Ojby5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9nZXRDb21wYXJlVmFsdWVFeHRyYWN0b3IoKTogKG9wdGlvbjogVCkgPT4gYW55IHtcbiAgICAgICAgaWYgKHRoaXMuVElzUHJpbWl0aXZlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAob3B0aW9uOiBhbnkpID0+IG9wdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRhdGFLZXkoKSkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5kYXRhS2V5KCkhO1xuICAgICAgICAgICAgcmV0dXJuIChvcHRpb246IFQpID0+IG9wdGlvbltrZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFZhbHVlRXh0cmFjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmVjaGEgbyBkcm9wZG93biBlIHJlZGVmaW5lIG8gZm9jby5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9jbG9zZURyb3Bkb3duKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNob3dPcHRpb25zLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lEcm9wZG93blBvcnRhbCgpO1xuICAgICAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkaWNpb25hIGlkZW50aWZpY2Fkb3JlcyDDum5pY29zIMOgcyBvcMOnw7Vlcy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBMaXN0YSBvcmlnaW5hbCBkZSBvcMOnw7Vlcy5cbiAgICAgKiBAcmV0dXJucyBMaXN0YSBjb20gSURzIGFkaWNpb25hZG9zLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2FkZElkVG9PcHRpb25zKG9wdGlvbnM6IFRbXSk6IEludGVybmFsRHJvcGRvd25PcHRpb248VD5bXSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnMubWFwKChvcHRpb24sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5ncm91cCgpICYmIEFycmF5LmlzQXJyYXkoKG9wdGlvbiBhcyBhbnkpLml0ZW1zKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IG9wdGlvbixcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGBpZF8ke3RpbWVzdGFtcH1fJHtpbmRleCsrfWAsXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwZXI6IHRydWUsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkYXRhOiBvcHRpb24sXG4gICAgICAgICAgICAgICAgaWQ6IGBpZF8ke3RpbWVzdGFtcH1fJHtpbmRleCsrfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0ZSB1bWEgZXN0cnV0dXJhIGFncnVwYWRhIGVtIHVtYSBsaXN0YSBhY2hhdGFkYS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBMaXN0YSBkZSBvcMOnw7VlcyBjb20gYWdydXBhZG9yZXMuXG4gICAgICogQHJldHVybnMgTGlzdGEgYWNoYXRhZGEgZGUgb3DDp8O1ZXMgZSBncnVwb3MuXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZ3JvdXBlclRvRmxhdChvcHRpb25zOiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10pOiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10ge1xuICAgICAgICBjb25zdCByZXN1bHQ6IEludGVybmFsRHJvcGRvd25PcHRpb248VD5bXSA9IFtdO1xuXG4gICAgICAgIG9wdGlvbnMuZm9yRWFjaCgob3B0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uLmdyb3VwZXIgJiYgQXJyYXkuaXNBcnJheSgob3B0aW9uLmRhdGEgYXMgYW55KS5pdGVtcykpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChvcHRpb24pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGdyb3VwSXRlbXMgPSAob3B0aW9uLmRhdGEgYXMgYW55KS5pdGVtcy5tYXAoKGl0ZW06IFQsIGluZGV4OiBudW1iZXIpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGl0ZW0sXG4gICAgICAgICAgICAgICAgICAgIGlkOiBgJHtvcHRpb24uaWR9X2l0ZW1fJHtpbmRleH1gLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaCguLi5ncm91cEl0ZW1zKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gob3B0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNb3ZlIG8gZm9jbyBwYXJhIGEgcHLDs3hpbWEgb3DDp8Ojby5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBMaXN0YSBkZSBvcMOnw7VlcyB2aXPDrXZlaXMuXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZm9jdXNOZXh0T3B0aW9uKG9wdGlvbnM6IEludGVybmFsRHJvcGRvd25PcHRpb248VD5bXSkge1xuICAgICAgICBsZXQgbmV4dEluZGV4ID0gdGhpcy5mb2N1c2VkSW5kZXgoKSArIDE7XG5cbiAgICAgICAgd2hpbGUgKG5leHRJbmRleCA8IG9wdGlvbnMubGVuZ3RoICYmIG9wdGlvbnNbbmV4dEluZGV4XS5ncm91cGVyKSB7XG4gICAgICAgICAgICBuZXh0SW5kZXgrKztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuZXh0SW5kZXggPCBvcHRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KG5leHRJbmRleCk7XG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxUb0ZvY3VzZWRPcHRpb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1vdmUgbyBmb2NvIHBhcmEgYSBvcMOnw6NvIGFudGVyaW9yLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIExpc3RhIGRlIG9ww6fDtWVzIHZpc8OtdmVpcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9mb2N1c1ByZXZpb3VzT3B0aW9uKG9wdGlvbnM6IEludGVybmFsRHJvcGRvd25PcHRpb248VD5bXSkge1xuICAgICAgICBsZXQgcHJldkluZGV4ID0gdGhpcy5mb2N1c2VkSW5kZXgoKSAtIDE7XG5cbiAgICAgICAgd2hpbGUgKHByZXZJbmRleCA+PSAwICYmIG9wdGlvbnNbcHJldkluZGV4XS5ncm91cGVyKSB7XG4gICAgICAgICAgICBwcmV2SW5kZXgtLTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcmV2SW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KHByZXZJbmRleCk7XG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxUb0ZvY3VzZWRPcHRpb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJvbGEgbyBkcm9wZG93biBhdMOpIGEgb3DDp8OjbyBhdHVhbG1lbnRlIGZvY2FkYS5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9zY3JvbGxUb0ZvY3VzZWRPcHRpb24oKSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKVt0aGlzLmZvY3VzZWRJbmRleCgpXT8uaWQ7XG5cbiAgICAgICAgaWYgKCFpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIGVsPy5zY3JvbGxJbnRvVmlldyh7IGJsb2NrOiAnbmVhcmVzdCcgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFpIG8gdGV4dG8gZGUgdW1hIG9ww6fDo28sIGNvbSBiYXNlIGVtIGBvcHRpb25MYWJlbGAuXG4gICAgICogQHJldHVybnMgRnVuw6fDo28gcXVlIHJldG9ybmEgbyBsYWJlbCBkYSBvcMOnw6NvLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2dldExhYmVsRXh0cmFjdG9yKCk6IChvcHRpb246IFQpID0+IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLlRJc1ByaW1pdGl2ZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gKG9wdGlvbjogYW55KSA9PiBTdHJpbmcob3B0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhYmVsSW5wdXQgPSB0aGlzLm9wdGlvbkxhYmVsKCk7XG5cbiAgICAgICAgaWYgKGxhYmVsSW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybiAob3B0aW9uOiBUKSA9PiBTdHJpbmcob3B0aW9uW2xhYmVsSW5wdXRdID8/ICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgb3B0aW9uTGFiZWwgaXMgcmVxdWlyZWQgZm9yIG5vbi1wcmltaXRpdmUgb3B0aW9ucy5gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyaWEgZSBwb3NpY2lvbmEgZGluYW1pY2FtZW50ZSBvIGRyb3Bkb3duIGNvbW8gcG9ydGFsLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2NyZWF0ZURyb3Bkb3duUG9ydGFsKCk6IHZvaWQge1xuICAgICAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lckRpdigpO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuX2Ryb3Bkb3duVGVtcGxhdGUoKTtcblxuICAgICAgICBpZiAoIWNvbnRhaW5lciB8fCAhdGVtcGxhdGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRyb3BFbGVtZW50UmVjdCA9IGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICAgIHRoaXMuZHJvcFRvcCA9IGRyb3BFbGVtZW50UmVjdC5ib3R0b20gKyB3aW5kb3cuc2Nyb2xsWTtcbiAgICAgICAgdGhpcy5kcm9wTGVmdCA9IGRyb3BFbGVtZW50UmVjdC5sZWZ0ICsgd2luZG93LnNjcm9sbFg7XG4gICAgICAgIHRoaXMuZHJvcFdpZHRoID0gZHJvcEVsZW1lbnRSZWN0LndpZHRoO1xuXG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lEcm9wZG93blBvcnRhbCgpO1xuXG4gICAgICAgIHRoaXMuX3BvcnRhbEhvc3QgPSBuZXcgRG9tUG9ydGFsT3V0bGV0KGRvY3VtZW50LmJvZHkpO1xuXG4gICAgICAgIGNvbnN0IHBvcnRhbCA9IG5ldyBUZW1wbGF0ZVBvcnRhbCh0ZW1wbGF0ZSwgdGhpcy5fdmlld0NvbnRhaW5lclJlZik7XG5cbiAgICAgICAgdGhpcy5fcG9ydGFsSG9zdC5hdHRhY2gocG9ydGFsKTtcblxuICAgICAgICBjb25zdCBkcm9wZG93bkVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmRyb3Bkb3duLWJvZHktY2xhc3MnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmIChkcm9wZG93bkVsKSB7XG4gICAgICAgICAgICBkcm9wZG93bkVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgIGRyb3Bkb3duRWwuc3R5bGUudG9wID0gYCR7dGhpcy5kcm9wVG9wICsgNH1weGA7XG4gICAgICAgICAgICBkcm9wZG93bkVsLnN0eWxlLmxlZnQgPSBgJHt0aGlzLmRyb3BMZWZ0fXB4YDtcbiAgICAgICAgICAgIGRyb3Bkb3duRWwuc3R5bGUud2lkdGggPSBgJHt0aGlzLmRyb3BXaWR0aH1weGA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgbyBwb3J0YWwgZG8gZHJvcGRvd24gZG8gRE9NLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2Rlc3Ryb3lEcm9wZG93blBvcnRhbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX3BvcnRhbEhvc3Q/Lmhhc0F0dGFjaGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3BvcnRhbEhvc3QuZGV0YWNoKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8bmctdGVtcGxhdGUgI3BvcnRhbEFuY2hvcj48L25nLXRlbXBsYXRlPlxuXG48ZGl2XG4gICAgI2NvbnRhaW5lckRpdlxuICAgIGNsYXNzPVwiZ3JvdXAgZmxleCB3LWZ1bGwgb3ZlcmZsb3ctaGlkZGVuIHJvdW5kZWQtWzNweF0gYm9yZGVyIG91dGxpbmUtMSBvdXRsaW5lLXByaW1hcnkgZm9jdXM6b3V0bGluZVwiXG4gICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAncG9pbnRlci1ldmVudHMtbm9uZSBib3JkZXItZ3JheXNjYWxlLTIwIGJnLWdyYXlzY2FsZS01JzogZGlzYWJsZWQoKSxcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzLWF1dG8gYm9yZGVyLWdyYXlzY2FsZS0zMCBiZy1ncmF5c2NhbGUtMCc6ICFkaXNhYmxlZCgpLFxuICAgIH1cIlxuICAgIFthdHRyLmFyaWEtZGlzYWJsZWRdPVwiZGlzYWJsZWQoKVwiXG4gICAgKGNsaWNrKT1cIm9uQ29udGFpbmVyRGl2Q2xpY2soKVwiXG4gICAgKGtleWRvd24pPVwib25LZXlEb3duKCRldmVudClcIlxuICAgIHRhYmluZGV4PVwiMFwiXG4+XG4gICAgPHNwYW5cbiAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtZ3JvdyBzZWxlY3Qtbm9uZSBweC0zIHB5LVs3cHhdXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgJ3RleHQtZ3JheXNjYWxlLTkwJzogIWRpc2FibGVkKCkgJiYgIWlzQ2xlYW4oKSxcbiAgICAgICAgICAgICd0ZXh0LWdyYXlzY2FsZS02MCc6ICFkaXNhYmxlZCgpICYmIGlzQ2xlYW4oKSxcbiAgICAgICAgICAgICd0ZXh0LWdyYXlzY2FsZS0zMCc6IGRpc2FibGVkKCksXG4gICAgICAgIH1cIlxuICAgID5cbiAgICAgICAge3sgcHJpbnQoKSB8fCBwbGFjZWhvbGRlcigpIH19XG4gICAgPC9zcGFuPlxuXG4gICAgQGlmICghZGlzYWJsZWQoKSAmJiBzaG93Q2xlYXIoKSAmJiAhaXNDbGVhbigpKSB7XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGNsYXNzPVwibXgtM1wiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2xlYXIoJGV2ZW50KVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXRpbWVzIGZsZXggaXRlbXMtY2VudGVyXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICB9XG5cbiAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgYm9yZGVyLWwgcHgtMyBncm91cC1ob3ZlcjpiZy1ncmF5c2NhbGUtMTAgZ3JvdXAtZm9jdXM6Ym9yZGVyLXByaW1hcnlcIlxuICAgICAgICBbbmdDbGFzc109XCJ7ICdib3JkZXItZ3JheXNjYWxlLTIwJzogZGlzYWJsZWQoKSwgJ2JvcmRlci1ncmF5c2NhbGUtMzAnOiAhZGlzYWJsZWQoKSB9XCJcbiAgICA+XG4gICAgICAgIDxpXG4gICAgICAgICAgICBjbGFzcz1cImZhc1wiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgJ3RleHQtZ3JheXNjYWxlLTMwJzogZGlzYWJsZWQoKSxcbiAgICAgICAgICAgICAgICAndGV4dC1ncmF5c2NhbGUtOTAnOiAhZGlzYWJsZWQoKSxcbiAgICAgICAgICAgICAgICAnZmEtY2FyZXQtZG93bic6ICFzaG93T3B0aW9ucygpLFxuICAgICAgICAgICAgICAgICdmYS1jYXJldC11cCc6IHNob3dPcHRpb25zKCksXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgPjwvaT5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2Ryb3Bkb3duVGVtcGxhdGU+XG4gICAgPGRpdlxuICAgICAgICBjbGFzcz1cImRyb3Bkb3duLWJvZHktY2xhc3Mgei1bMTAwMF0gcm91bmRlZC1bM3B4XSBiZy1ncmF5c2NhbGUtMCBweS0xIHNoYWRvdy1tZFwiXG4gICAgICAgIFtzdHlsZS5wb3NpdGlvbl09XCInYWJzb2x1dGUnXCJcbiAgICAgICAgW3N0eWxlLnRvcC5weF09XCJkcm9wVG9wXCJcbiAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiZHJvcExlZnRcIlxuICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICA+XG4gICAgICAgIEBpZiAoZmlsdGVyKCkpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IHctZnVsbCBpdGVtcy1jZW50ZXIgZ2FwLTMgcHgtMyBweS0xLjVcIj5cbiAgICAgICAgICAgICAgICBAaWYgKG11bHRpcGxlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHMtY2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICNzZWxlY3RBbGxDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiYWxsU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJzZWxlY3RBbGxJc0luZGV0ZXJtaW5hdGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hlY2tlZENoYW5nZSk9XCJ0b2dnbGVTZWxlY3RBbGwoKVwiXG4gICAgICAgICAgICAgICAgICAgID48L3MtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIGZsZXggaC1bMzVweF0gZ3Jvd1wiPlxuICAgICAgICAgICAgICAgICAgICA8Zm9ybVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IGdyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Hcm91cF09XCJmaWx0ZXJGb3JtXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LWZ1bGwgZ3JvdyByb3VuZGVkLVszcHhdIGJvcmRlciBib3JkZXItZ3JheXNjYWxlLTMwIHBsLTIuNSBwci03IG91dGxpbmUtMSBvdXRsaW5lLXByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJmaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zZWFyY2ggYWJzb2x1dGUgcmlnaHQtMi41IHRvcC0yLjUgdGV4dC1ncmF5c2NhbGUtOTBcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiY2xlYXJGaWx0ZXIoKVwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS10aW1lcyBmbGV4IGl0ZW1zLWNlbnRlclwiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSBWaXJ0dWFsIHNjcm9sbCAtLT5cbiAgICAgICAgQGlmICh2aXJ0dWFsU2Nyb2xsKCkgJiYgZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnRcbiAgICAgICAgICAgICAgICBbaXRlbVNpemVdPVwidmlydHVhbFNjcm9sbEl0ZW1TaXplKClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiaC01MiBvdmVyZmxvdy1hdXRvXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpjZGtWaXJ0dWFsRm9yPVwibGV0IG9wdGlvbiBvZiBmaWx0ZXJlZE9wdGlvbnMoKTsgdHJhY2tCeTogdHJhY2tCeUlkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzLXNlbGVjdC1vcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJvcHRpb24uaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cImdldE9wdGlvbkxhYmVsKG9wdGlvbi5kYXRhKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlwbGVdPVwibXVsdGlwbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2ttYXJrXT1cImNoZWNrbWFyaygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpc1NlbGVjdGVkXT1cImlzT3B0aW9uU2VsZWN0ZWQob3B0aW9uLmRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZCk9XCJzZWxlY3RJdGVtKG9wdGlvbi5kYXRhKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNHcm91cGVyXT1cIm9wdGlvbi5ncm91cGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpc0ZvY3VzZWRdPVwib3B0aW9uLmRhdGEgPT09IGZvY3VzZWRJdGVtKClcIlxuICAgICAgICAgICAgICAgICAgICA+PC9zLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydD5cbiAgICAgICAgfVxuXG4gICAgICAgIDwhLS0gTm9ybWFsIGxpc3QgLS0+XG4gICAgICAgIEBpZiAoIXZpcnR1YWxTY3JvbGwoKSB8fCBmaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggPD0gMTApIHtcbiAgICAgICAgICAgIDx1bCBjbGFzcz1cIm1heC1oLTUyIG92ZXJmbG93LWF1dG9cIj5cbiAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZmlsdGVyZWRPcHRpb25zKCk7IHRyYWNrIG9wdGlvbi5pZCkge1xuICAgICAgICAgICAgICAgICAgICA8cy1zZWxlY3Qtb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwib3B0aW9uLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJnZXRPcHRpb25MYWJlbChvcHRpb24uZGF0YSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpcGxlXT1cIm11bHRpcGxlKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrbWFya109XCJjaGVja21hcmsoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNTZWxlY3RlZF09XCJpc09wdGlvblNlbGVjdGVkKG9wdGlvbi5kYXRhKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoc2VsZWN0ZWQpPVwic2VsZWN0SXRlbShvcHRpb24uZGF0YSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzR3JvdXBlcl09XCJvcHRpb24uZ3JvdXBlciA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNGb2N1c2VkXT1cIm9wdGlvbi5kYXRhID09PSBmb2N1c2VkSXRlbSgpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcy1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtLTMgdGV4dC1ncmF5c2NhbGUtNjBcIj57e1xuICAgICAgICAgICAgICAgIGVtcHR5TWVzc2FnZSgpID8/ICdwbGF0Zm9ybS5hbmd1bGFyX2NvbXBvbmVudHMubm9fcmVjb3Jkc19mb3VuZCcgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICB9XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
|
|
608
|
+
], template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [ngClass]=\"{\n 'pointer-events-none border-grayscale-20 bg-grayscale-5': disabled(),\n 'pointer-events-auto border-grayscale-30 bg-grayscale-0': !disabled(),\n }\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-owns]=\"'dropdown-container-' + componentId\"\n [attr.aria-labelledby]=\"componentId + '-label'\"\n role=\"combobox\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [ngClass]=\"{\n 'text-grayscale-90': !disabled() && !isClean(),\n 'text-grayscale-60': !disabled() && isClean(),\n 'text-grayscale-30': disabled(),\n }\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n >\n <i class=\"fas fa-times flex items-center\"></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [ngClass]=\"{ 'border-grayscale-20': disabled(), 'border-grayscale-30': !disabled() }\"\n >\n <i\n class=\"fas\"\n [ngClass]=\"{\n 'text-grayscale-30': disabled(),\n 'text-grayscale-90': !disabled(),\n 'fa-caret-down': !showOptions(),\n 'fa-caret-up': showOptions(),\n }\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"'dropdown-container-' + componentId\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n />\n </form>\n <i class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"></i>\n </div>\n <button (click)=\"clearFilter()\">\n <i class=\"fas fa-times flex items-center\"></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">{{\n emptyMessage() ?? 'platform.angular_components.no_records_found' | translate\n }}</span>\n }\n </div>\n</ng-template>\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"] }]
|
|
609
|
+
}], ctorParameters: () => [] });
|
|
610
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zZWxlY3Qvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY29tcG9uZW50cy9zZWxlY3Qvc3JjL2xpYi9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDSCxTQUFTLEVBQ1QsUUFBUSxFQUVSLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBd0IsV0FBVyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRILE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNoRixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sb0RBQW9ELENBQUM7Ozs7Ozs7QUFrRDNGLE1BQU0sT0FBTyxlQUFlO0lBQ2hCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRW5C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akIsZUFBZSwyRkFDZixhQUFhOzs0RkFnQ1IsZUFBZTtrQkEzQzNCLFNBQVM7K0JBQ0ksVUFBVSxjQUVSLElBQUksV0FDUDt3QkFDTCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsZUFBZTt3QkFDZixxQkFBcUI7d0JBQ3JCLGlCQUFpQjt3QkFDakIsZUFBZTt3QkFDZixhQUFhO3FCQUNoQixRQUNLO3dCQUNGLGlCQUFpQixFQUFFLHdCQUF3Qjt3QkFDM0Msc0JBQXNCLEVBQUUsZUFBZTt3QkFDdkMsc0JBQXNCLEVBQUUsV0FBVzt3QkFDbkMsa0JBQWtCLEVBQUUsaURBQWlEO3dCQUNyRSw4QkFBOEIsRUFBRSxvRUFBb0U7d0JBQ3BHLG1CQUFtQixFQUFFLGtDQUFrQzt3QkFDdkQsc0JBQXNCLEVBQUUsWUFBWTt3QkFDcEMsSUFBSSxFQUFFLFVBQVU7cUJBQ25CLGFBYVU7d0JBQ1A7NEJBQ0ksT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLENBQUM7NEJBQzlDLEtBQUssRUFBRSxJQUFJO3lCQUNkO3FCQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT3ZlcmxheU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IFNjcm9sbGluZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIGNvbXB1dGVkLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgZm9yd2FyZFJlZixcbiAgICBpbmplY3QsXG4gICAgaW5wdXQsXG4gICAgbW9kZWwsXG4gICAgT25Jbml0LFxuICAgIHNpZ25hbCxcbiAgICB2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIE5HX1ZBTFVFX0FDQ0VTU09SLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUsIFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IENoZWNrYm94Q29tcG9uZW50IH0gZnJvbSAnQHNlbmlvcnNpc3RlbWFzL2FuZ3VsYXItY29tcG9uZW50cy9jaGVja2JveCc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBTZWxlY3RPcHRpb25Db21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvc2VsZWN0LW9wdGlvbi9zZWxlY3Qtb3B0aW9uLmNvbXBvbmVudCc7XG5cbmludGVyZmFjZSBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+IHtcbiAgICBkYXRhOiBUO1xuICAgIGlkOiBzdHJpbmc7XG4gICAgZ3JvdXBlcj86IGJvb2xlYW47XG59XG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3Mtc2VsZWN0JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VsZWN0LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQ29tbW9uTW9kdWxlLFxuICAgICAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgICAgICBTY3JvbGxpbmdNb2R1bGUsXG4gICAgICAgIFNlbGVjdE9wdGlvbkNvbXBvbmVudCxcbiAgICAgICAgQ2hlY2tib3hDb21wb25lbnQsXG4gICAgICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgICAgICAgT3ZlcmxheU1vZHVsZSxcbiAgICBdLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyh3aW5kb3c6cmVzaXplKSc6ICdvbldpbmRvd1Jlc2l6ZSgkZXZlbnQpJyxcbiAgICAgICAgJ1thdHRyLmFyaWEtZXhwYW5kZWRdJzogJ3Nob3dPcHRpb25zKCknLFxuICAgICAgICAnW2F0dHIuYXJpYS1oYXNwb3B1cF0nOiAnXCJsaXN0Ym94XCInLFxuICAgICAgICAnW2F0dHIuYXJpYS1vd25zXSc6ICdzaG93T3B0aW9ucygpID8gY29tcG9uZW50SWQgKyBcIi1saXN0Ym94XCIgOiBudWxsJyxcbiAgICAgICAgJ1thdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF0nOiAnZm9jdXNlZEluZGV4KCkgPj0gMCA/IGZpbHRlcmVkT3B0aW9ucygpW2ZvY3VzZWRJbmRleCgpXT8uaWQgOiBudWxsJyxcbiAgICAgICAgJ1thdHRyLmFyaWEtbGFiZWxdJzogJ3BsYWNlaG9sZGVyKCkgfHwgXCJTZWxlY3Qgb3B0aW9uXCInLFxuICAgICAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnZGlzYWJsZWQoKScsXG4gICAgICAgIHJvbGU6ICdjb21ib2JveCcsXG4gICAgfSxcbiAgICBzdHlsZXM6IFtcbiAgICAgICAgYFxuICAgICAgICAgICAgOmhvc3QubmctZGlydHkubmctaW52YWxpZCB7XG4gICAgICAgICAgICAgICAgLmRyb3Bkb3duLWNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAuc2VsZWN0LWNvbnRhaW5lciB7XG4gICAgICAgICAgICAgICAgICAgIGJvcmRlci1jb2xvcjogI2MxMzAxODtcbiAgICAgICAgICAgICAgICAgICAgb3V0bGluZTogbm9uZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgXSxcblxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFNlbGVjdENvbXBvbmVudCksXG4gICAgICAgICAgICBtdWx0aTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZWxlY3RDb21wb25lbnQ8VD4gaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0IHtcbiAgICBwcml2YXRlIHN0YXRpYyBuZXh0SWQgPSAwO1xuXG4gICAgcHVibGljIHBsYWNlaG9sZGVyID0gaW5wdXQoJycpO1xuICAgIHB1YmxpYyBtdWx0aXBsZSA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgb3B0aW9ucyA9IGlucHV0LnJlcXVpcmVkPFRbXT4oKTtcbiAgICBwdWJsaWMgb3B0aW9uTGFiZWwgPSBpbnB1dDxrZXlvZiBUPigpO1xuICAgIHB1YmxpYyBvcHRpb25WYWx1ZSA9IGlucHV0PGtleW9mIFQ+KCk7XG4gICAgcHVibGljIHNob3dDbGVhciA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgZmlsdGVyID0gaW5wdXQoZmFsc2UpO1xuICAgIHB1YmxpYyBjaGVja21hcmsgPSBpbnB1dChmYWxzZSk7XG4gICAgcHVibGljIGZpbHRlckJ5ID0gaW5wdXQ8a2V5b2YgVCB8IChrZXlvZiBUKVtdPigpO1xuICAgIHB1YmxpYyBncm91cCA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgdmlydHVhbFNjcm9sbCA9IGlucHV0KGZhbHNlKTtcbiAgICBwdWJsaWMgdmlydHVhbFNjcm9sbEl0ZW1TaXplID0gaW5wdXQoMzcpO1xuICAgIHB1YmxpYyBlbXB0eU1lc3NhZ2UgPSBpbnB1dDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAgIHB1YmxpYyBkaXNhYmxlZCA9IG1vZGVsKGZhbHNlKTtcbiAgICBwdWJsaWMgc2hvd09wdGlvbnMgPSBtb2RlbChmYWxzZSk7XG5cbiAgICBwdWJsaWMgdmFsdWUgPSBzaWduYWw8SW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPiB8IG51bGw+KG51bGwpO1xuICAgIHB1YmxpYyB2YWx1ZXMgPSBzaWduYWw8SW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPltdPihbXSk7XG4gICAgcHVibGljIGZpbHRlclZhbHVlID0gc2lnbmFsKCcnKTtcbiAgICBwdWJsaWMgZm9jdXNlZEluZGV4ID0gc2lnbmFsKC0xKTtcblxuICAgIHB1YmxpYyBjb21wb25lbnRJZCA9IGBzZWxlY3Qke1NlbGVjdENvbXBvbmVudC5uZXh0SWQrK31gO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZWQgcXVlIGluZGljYSBzZSB0b2RhcyBhcyBvcMOnw7VlcyBmaWx0cmFkYXMgZXN0w6NvIHNlbGVjaW9uYWRhcy5cbiAgICAgKiBSZXRvcm5hIGB0cnVlYCBzZSB0b2RhcyBhcyBvcMOnw7VlcyBkaXNwb27DrXZlaXMgKGV4Y2x1aW5kbyBhZ3J1cGFkb3JlcykgZXN0aXZlcmVtIHByZXNlbnRlc1xuICAgICAqIG5hIGxpc3RhIGRlIHZhbG9yZXMgc2VsZWNpb25hZG9zLCBlIGBmYWxzZWAgY2FzbyBjb250csOhcmlvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgc2UgdG9kYXMgYXMgb3DDp8O1ZXMgZmlsdHJhZGFzIGVzdMOjbyBzZWxlY2lvbmFkYXMsIGBmYWxzZWAgY2FzbyBjb250csOhcmlvLlxuICAgICAqL1xuICAgIHB1YmxpYyBhbGxTZWxlY3RlZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZmlsdGVyZWRPcHRpb25zKCkuZmlsdGVyKChvcHRpb24pID0+ICFvcHRpb24uZ3JvdXBlcik7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkSWRzID0gdGhpcy52YWx1ZXMoKS5tYXAoKG9wdGlvbikgPT4gb3B0aW9uLmlkKTtcblxuICAgICAgICBjb25zdCByZXQgPSBvcHRpb25zLmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5ldmVyeSgob3B0aW9uKSA9PiBzZWxlY3RlZElkcy5pbmNsdWRlcyhvcHRpb24uaWQpKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJldG9ybmEgbyBpdGVtIGF0dWFsbWVudGUgZm9jYWRvIG5hIGxpc3RhIGRlIG9ww6fDtWVzIGZpbHRyYWRhcy5cbiAgICAgKiBAcmV0dXJucyBPIGRhZG8gZG8gaXRlbSBmb2NhZG8gb3UgYG51bGxgIGNhc28gbmVuaHVtIGl0ZW0gZXN0ZWphIGZvY2Fkby5cbiAgICAgKi9cbiAgICBwdWJsaWMgZm9jdXNlZEl0ZW0gPSBjb21wdXRlZCgoKSA9PiB0aGlzLmZpbHRlcmVkT3B0aW9ucygpLmF0KHRoaXMuZm9jdXNlZEluZGV4KCkpPy5kYXRhID8/IG51bGwpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0YSBlIHJldG9ybmEgYSBsaXN0YSBpbnRlcm5hIGRlIG9ww6fDtWVzIGRvIGRyb3Bkb3duLlxuICAgICAqIC0gU2UgYXMgb3DDp8O1ZXMgZXN0aXZlcmVtIGFncnVwYWRhcyAoYGdyb3VwKClgIHJldG9ybmEgdmVyZGFkZWlybyksXG4gICAgICogICB1dGlsaXphIGBfZ3JvdXBlclRvRmxhdGAgcGFyYSB0cmFuc2Zvcm1hciBhcyBvcMOnw7VlcyBhZ3J1cGFkYXMgZW0gdW1hIGxpc3RhIHBsYW5hLlxuICAgICAqIC0gQ2FzbyBjb250csOhcmlvLCByZXRvcm5hIGFzIG9ww6fDtWVzIGNvbSBJRHMgYWRpY2lvbmFkb3MuXG4gICAgICogQHJldHVybnMgVW0gYXJyYXkgZGUgYEludGVybmFsRHJvcGRvd25PcHRpb248VD5gIHJlcHJlc2VudGFuZG8gYXMgb3DDp8O1ZXMgZGlzcG9uw612ZWlzIHBhcmEgbyBjb21wb25lbnRlIHNlbGVjdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaW50ZXJuYWxPcHRpb25zID0gY29tcHV0ZWQ8SW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPltdPigoKSA9PiB7XG4gICAgICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnMoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uc1dpdGhJZCA9IHRoaXMuX2FkZElkVG9PcHRpb25zKG9wdHMpO1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cCgpID8gdGhpcy5fZ3JvdXBlclRvRmxhdChvcHRpb25zV2l0aElkKSA6IG9wdGlvbnNXaXRoSWQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBSZXRvcm5hIHVtYSBzdHJpbmcgcmVwcmVzZW50YW5kbyBhIHNlbGXDp8OjbyBhdHVhbCBkbyBjb21wb25lbnRlLlxuICAgICAqIC0gU2UgbyBtb2RvIG3Dumx0aXBsbyBlc3RpdmVyIGF0aXZhZG8gZSBtYWlzIGRlIHVtIGl0ZW0gZXN0aXZlciBzZWxlY2lvbmFkbyxcbiAgICAgKiAgIHJldG9ybmEgdW1hIG1lbnNhZ2VtIHRyYWR1emlkYSBpbmRpY2FuZG8gbyBuw7ptZXJvIHRvdGFsIGRlIHJlZ2lzdHJvcyBzZWxlY2lvbmFkb3MuXG4gICAgICogLSBTZSBhcGVuYXMgdW0gaXRlbSBlc3RpdmVyIHNlbGVjaW9uYWRvLCByZXRvcm5hIG8gcsOzdHVsbyBkZXNzZSBpdGVtLlxuICAgICAqIC0gU2UgbyBtb2RvIG3Dumx0aXBsbyBuw6NvIGVzdGl2ZXIgYXRpdmFkbywgcmV0b3JuYSBvIHLDs3R1bG8gZG8gaXRlbSBzZWxlY2lvbmFkbyBvdSB1bWEgc3RyaW5nIHZhemlhIGNhc28gbmVuaHVtIGl0ZW0gZXN0ZWphIHNlbGVjaW9uYWRvLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRleHRvIHJlcHJlc2VudGFuZG8gYSBzZWxlw6fDo28gYXR1YWwuXG4gICAgICovXG4gICAgcHVibGljIHByaW50ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMudmFsdWVzKCk7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWQubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoYHBsYXRmb3JtLmFuZ3VsYXJfY29tcG9uZW50cy50b3RhbF9yZWNvcmRzX3NlbGVjdGVkYCwge1xuICAgICAgICAgICAgICAgICAgICBjb3VudDogc2VsZWN0ZWQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TGFiZWxGcm9tT3B0aW9uKHNlbGVjdGVkWzBdLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnZhbHVlKCk7XG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWQgPyB0aGlzLl9nZXRMYWJlbEZyb21PcHRpb24oc2VsZWN0ZWQuZGF0YSkgOiAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAnJztcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEluZGljYSBzZSBvIHNlbGV0b3IgZXN0w6EgXCJsaW1wb1wiLCBvdSBzZWphLCBzZW0gbmVuaHVtIHZhbG9yIHNlbGVjaW9uYWRvLlxuICAgICAqIC0gTm8gbW9kbyBtw7psdGlwbG8gKGBtdWx0aXBsZWApLCByZXRvcm5hIGB0cnVlYCBzZSBuw6NvIGhvdXZlciBuZW5odW0gdmFsb3Igc2VsZWNpb25hZG8gKGB2YWx1ZXNgIGVzdMOhIHZhemlvKS5cbiAgICAgKiAtIE5vIG1vZG8gc2ltcGxlcywgcmV0b3JuYSBgdHJ1ZWAgc2UgbsOjbyBob3V2ZXIgdmFsb3Igc2VsZWNpb25hZG8gKGB2YWx1ZWAgw6kgZmFsc3kpLlxuICAgICAqIEByZXR1cm5zIGB0cnVlYCBzZSBuw6NvIGhvdXZlciBzZWxlw6fDo28sIGBmYWxzZWAgY2FzbyBjb250csOhcmlvLlxuICAgICAqL1xuICAgIHB1YmxpYyBpc0NsZWFuID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsZSgpID8gIXRoaXMudmFsdWVzKCkubGVuZ3RoIDogIXRoaXMudmFsdWUoKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVkIHF1ZSBpbmRpY2Egc2UgbyBlc3RhZG8gZGUgc2VsZcOnw6NvIFwiU2VsZWNpb25hciBUb2Rvc1wiIGVzdMOhIGluZGV0ZXJtaW5hZG8uXG4gICAgICogUmV0b3JuYSBgdHJ1ZWAgcXVhbmRvIG5lbSB0b2RvcyBvcyBpdGVucyBmaWx0cmFkb3MgZXN0w6NvIHNlbGVjaW9uYWRvcyBlIG5lbSB0b2RvcyBlc3TDo28gZGVzbWFyY2Fkb3MsXG4gICAgICogb3Ugc2VqYSwgcXVhbmRvIGjDoSB1bWEgc2VsZcOnw6NvIHBhcmNpYWwgZG9zIGl0ZW5zIGRpc3BvbsOtdmVpcy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIHNlIGEgc2VsZcOnw6NvIGZvciBwYXJjaWFsLCBgZmFsc2VgIGNhc28gY29udHLDoXJpby5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0QWxsSXNJbmRldGVybWluYXRlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuaW50ZXJuYWxPcHRpb25zKCkuZmlsdGVyKChvcHRpb24pID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlcygpLnNvbWUoKG8pID0+IG8uaWQgPT09IG9wdGlvbi5pZCk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5maWx0ZXIoKG9wdGlvbikgPT4gIW9wdGlvbi5ncm91cGVyKTtcbiAgICAgICAgY29uc3QgYWxsID0gb3B0aW9ucy5sZW5ndGggPiAwICYmIG9wdGlvbnMuZXZlcnkoKG9wdGlvbikgPT4gc2VsZWN0ZWQuaW5jbHVkZXMob3B0aW9uKSk7XG4gICAgICAgIGNvbnN0IG5vbmUgPSBvcHRpb25zLmV2ZXJ5KChvcHRpb24pID0+ICFzZWxlY3RlZC5pbmNsdWRlcyhvcHRpb24pKTtcblxuICAgICAgICByZXR1cm4gIWFsbCAmJiAhbm9uZTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJldG9ybmEgdW1hIGxpc3RhIGRlIG9ww6fDtWVzIGZpbHRyYWRhcyBjb20gYmFzZSBubyB2YWxvciBkZSBidXNjYSAoYGZpbHRlclZhbHVlYCkgZSBub3MgY3JpdMOpcmlvcyBkZWZpbmlkb3MuXG4gICAgICogLSBTZSBvIGZpbHRybyBlc3RpdmVyIGRlc2FiaWxpdGFkbyBvdSBvIHZhbG9yIGRlIGJ1c2NhIGVzdGl2ZXIgdmF6aW8sIHJldG9ybmEgdG9kYXMgYXMgb3DDp8O1ZXMuXG4gICAgICogLSBDYXNvIGNvbnRyw6FyaW8sIGZpbHRyYSBhcyBvcMOnw7VlcyB1dGlsaXphbmRvIG8ocykgY2FtcG8ocykgZXNwZWNpZmljYWRvKHMpIGVtIGBmaWx0ZXJCeWAuXG4gICAgICogLSBJZ25vcmEgb3DDp8O1ZXMgcXVlIHBvc3N1ZW0gYSBwcm9wcmllZGFkZSBgZ3JvdXBlcmAgZGVmaW5pZGEuXG4gICAgICogQHJldHVybnMgQXMgb3DDp8O1ZXMgZmlsdHJhZGFzIGNvbmZvcm1lIG8gdmFsb3IgZGUgYnVzY2EgZSBjcml0w6lyaW9zIGRlIGZpbHRyby5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVyZWRPcHRpb25zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBhbGxPcHRpb25zID0gdGhpcy5pbnRlcm5hbE9wdGlvbnMoKTtcbiAgICAgICAgY29uc3Qgc2VhcmNoID0gdGhpcy5maWx0ZXJWYWx1ZSgpLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuXG4gICAgICAgIGlmICghdGhpcy5maWx0ZXIoKSB8fCAhc2VhcmNoKSB7XG4gICAgICAgICAgICByZXR1cm4gYWxsT3B0aW9ucztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpbHRlckJ5ID0gdGhpcy5maWx0ZXJCeSgpO1xuICAgICAgICByZXR1cm4gYWxsT3B0aW9ucy5maWx0ZXIoKG9wdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbi5ncm91cGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgbGFiZWwgPSAnJztcblxuICAgICAgICAgICAgY29uc3Qgb3B0aW9uTGFiZWwgPSB0aGlzLm9wdGlvbkxhYmVsKCk7XG5cbiAgICAgICAgICAgIGlmICghZmlsdGVyQnkpIHtcbiAgICAgICAgICAgICAgICBsYWJlbCA9IG9wdGlvbkxhYmVsID8gU3RyaW5nKG9wdGlvbi5kYXRhW29wdGlvbkxhYmVsXSkgOiBTdHJpbmcob3B0aW9uLmRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGZpbHRlckJ5KSkge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gZmlsdGVyQnkubWFwKChieSkgPT4gU3RyaW5nKG9wdGlvbi5kYXRhW2J5XSA/PyAnJykpLmpvaW4oJyAnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSBTdHJpbmcob3B0aW9uLmRhdGFbZmlsdGVyQnldID8/ICcnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgZmlsdGVyRm9ybSA9IG5ldyBGb3JtR3JvdXA8eyBmaWx0ZXI6IEZvcm1Db250cm9sPHN0cmluZz4gfT4oe1xuICAgICAgICBmaWx0ZXI6IG5ldyBGb3JtQ29udHJvbDxzdHJpbmc+KCcnLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pLFxuICAgIH0pO1xuXG4gICAgcHJpdmF0ZSBfY29udGFpbmVyRGl2ID0gdmlld0NoaWxkPEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+PignY29udGFpbmVyRGl2Jyk7XG4gICAgcHJpdmF0ZSBfb25DaGFuZ2U6ICh2YWx1ZTogYW55IHwgYW55W10gfCBudWxsKSA9PiB2b2lkID0gKCkgPT4ge307XG4gICAgcHJpdmF0ZSBfb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF90cmFuc2xhdGVTZXJ2aWNlID0gaW5qZWN0KFRyYW5zbGF0ZVNlcnZpY2UpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZmlsdGVyRm9ybVxuICAgICAgICAgICAgLmdldCgnZmlsdGVyJykhXG4gICAgICAgICAgICAudmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKDMwMCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksIHRha2VVbnRpbERlc3Ryb3llZCgpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZhbHVlLnNldCh2YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlSW5wdXRzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmaW5lIG8gdmFsb3Igc2VsZWNpb25hZG8gZG8gY29tcG9uZW50ZSBzZWxlY3QuXG4gICAgICogQHBhcmFtIHZhbHVlIE8gdmFsb3IgYSBzZXIgZGVmaW5pZG8uIFBvZGUgc2VyIHVtIG9iamV0byBkbyB0aXBvIGBUYCwgdW0gYXJyYXkgZGUgYFRgIChxdWFuZG8gbcO6bHRpcGxhIHNlbGXDp8OjbyBlc3TDoSBoYWJpbGl0YWRhKSwgb3UgYG51bGxgLlxuICAgICAqIEB0aHJvd3MgU2UgbyBtb2RvIG3Dumx0aXBsbyBlc3RpdmVyIGF0aXZhZG8gZSBvIHZhbG9yIG7Do28gZm9yIHVtIGFycmF5LCBsYW7Dp2EgdW0gZXJyby5cbiAgICAgKiBAdGhyb3dzIFNlIG8gbW9kbyBtw7psdGlwbG8gZXN0aXZlciBkZXNhdGl2YWRvIGUgbyB2YWxvciBmb3IgdW0gYXJyYXksIGxhbsOnYSB1bSBlcnJvLlxuICAgICAqIEVzdGUgbcOpdG9kbyBtYXBlaWEgbyhzKSB2YWxvcihlcykgZm9ybmVjaWRvKHMpIHBhcmEgYXMgb3DDp8O1ZXMgaW50ZXJuYXMgZG8gY29tcG9uZW50ZSxcbiAgICAgKiBnYXJhbnRpbmRvIHF1ZSBhcGVuYXMgb3DDp8O1ZXMgdsOhbGlkYXMgc2VqYW0gc2VsZWNpb25hZGFzIGNvbmZvcm1lIG8gbW9kbyBkZSBzZWxlw6fDo28gKMO6bmljbyBvdSBtw7psdGlwbG8pLlxuICAgICAqL1xuICAgIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBUIHwgVFtdIHwgbnVsbCk6IHZvaWQge1xuICAgICAgICBpZiAodmFsdWUgJiYgdGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXBwZWQgPSB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAubWFwKCh2YWwpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVybmFsT3B0aW9ucygpLmZpbmQoKG9wdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShvcHRpb24uZGF0YSkgPT09IEpTT04uc3RyaW5naWZ5KHZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigob3B0aW9uKTogb3B0aW9uIGlzIEludGVybmFsRHJvcGRvd25PcHRpb248VD4gPT4gISFvcHRpb24pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMuc2V0KG1hcHBlZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVmFsdWUgbXVzdCBiZSBhbiBhcnJheSB3aGVuIFwibXVsdGlwbGVcIiBpcyB0cnVlLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9uVmFsdWUgPSB0aGlzLm9wdGlvblZhbHVlKCk7XG4gICAgICAgICAgICBsZXQgbWFwcGVkOiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVmFsdWUgbXVzdCBub3QgYmUgYW4gYXJyYXkgd2hlbiBcIm11bHRpcGxlXCIgaXMgZmFsc2UuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25WYWx1ZSAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG1hcHBlZCA9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJuYWxPcHRpb25zKCkuZmluZCgob3B0aW9uKSA9PiBvcHRpb24uZGF0YVtvcHRpb25WYWx1ZV0gPT09IHZhbHVlW29wdGlvblZhbHVlXSkgPz8gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWFwcGVkID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcm5hbE9wdGlvbnMoKS5maW5kKChvcHRpb24pID0+IEpTT04uc3RyaW5naWZ5KG9wdGlvbi5kYXRhKSA9PT0gSlNPTi5zdHJpbmdpZnkodmFsdWUpKSA/P1xuICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnZhbHVlLnNldChtYXBwZWQgPz8gbnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RyYSB1bWEgZnVuw6fDo28gZGUgY2FsbGJhY2sgcXVlIHNlcsOhIGNoYW1hZGEgc2VtcHJlIHF1ZSBvIHZhbG9yIGRvIGNvbXBvbmVudGUgbXVkYXIuXG4gICAgICogQHBhcmFtIG9uQ2hhbmdlIEZ1bsOnw6NvIGRlIGNhbGxiYWNrIHF1ZSByZWNlYmUgbyBub3ZvIHZhbG9yIHNlbGVjaW9uYWRvIG91IG51bGwuXG4gICAgICovXG4gICAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2Uob25DaGFuZ2U6ICh2YWx1ZTogVCB8IFRbXSB8IG51bGwpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fb25DaGFuZ2UgPSBvbkNoYW5nZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RyYSB1bWEgZnVuw6fDo28gZGUgY2FsbGJhY2sgcXVlIHNlcsOhIGNoYW1hZGEgcXVhbmRvIG8gY29tcG9uZW50ZSBmb3IgdG9jYWRvIChwZXJkZXIgbyBmb2NvKS5cbiAgICAgKiBAcGFyYW0gb25Ub3VjaGVkIEZ1bsOnw6NvIGRlIGNhbGxiYWNrIGEgc2VyIGV4ZWN1dGFkYSBxdWFuZG8gbyBjb21wb25lbnRlIGZvciBtYXJjYWRvIGNvbW8gXCJ0b2NhZG9cIi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQob25Ub3VjaGVkOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29uVG91Y2hlZCA9IG9uVG91Y2hlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmUgbyBlc3RhZG8gZGUgZGVzYWJpbGl0YWRvIGRvIGNvbXBvbmVudGUuXG4gICAgICogQHBhcmFtIGRpc2FibGVkIEluZGljYSBzZSBvIGNvbXBvbmVudGUgZGV2ZSBzZXIgZGVzYWJpbGl0YWRvIChgdHJ1ZWApIG91IGhhYmlsaXRhZG8gKGBmYWxzZWApLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXREaXNhYmxlZFN0YXRlKGRpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQuc2V0KGRpc2FibGVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbHRlcm5hIGEgZXhpYmnDp8OjbyBkYXMgb3DDp8O1ZXMgZG8gY29tcG9uZW50ZSBzZWxlY3QuXG4gICAgICogU2UgbyBjb21wb25lbnRlIGVzdGl2ZXIgZGVzYWJpbGl0YWRvLCBuw6NvIHJlYWxpemEgbmVuaHVtYSBhw6fDo28uXG4gICAgICogQ2FzbyBjb250csOhcmlvLCBpbnZlcnRlIG8gZXN0YWRvIGRlIGV4aWJpw6fDo28gZGFzIG9ww6fDtWVzLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGUoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNob3VsZE9wZW4gPSAhdGhpcy5zaG93T3B0aW9ucygpO1xuICAgICAgICB0aGlzLnNob3dPcHRpb25zLnNldChzaG91bGRPcGVuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY2lvbmEgdW0gaXRlbSBubyBjb21wb25lbnRlIGRlIHNlbGXDp8Ojby5cbiAgICAgKiBAcGFyYW0gaXRlbSBPIGl0ZW0gYSBzZXIgc2VsZWNpb25hZG8gb3UgZGVzbWFyY2Fkby5cbiAgICAgKiBTZSBvIGNvbXBvbmVudGUgZXN0aXZlciBkZXNhYmlsaXRhZG8sIGEgZnVuw6fDo28gcmV0b3JuYSBpbWVkaWF0YW1lbnRlLlxuICAgICAqIE5vIG1vZG8gbcO6bHRpcGxvLCBhZGljaW9uYSBvdSByZW1vdmUgbyBpdGVtIGRhIGxpc3RhIGRlIHZhbG9yZXMgc2VsZWNpb25hZG9zLlxuICAgICAqIE5vIG1vZG8gc2ltcGxlcywgZGVmaW5lIG8gaXRlbSBjb21vIHZhbG9yIHNlbGVjaW9uYWRvIGUgZmVjaGEgbyBkcm9wZG93bi5cbiAgICAgKiBTZW1wcmUgbm90aWZpY2EgYXMgbXVkYW7Dp2FzIGUgbWFyY2EgbyBjb21wb25lbnRlIGNvbW8gdG9jYWRvLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZWxlY3RJdGVtKGl0ZW06IEludGVybmFsRHJvcGRvd25PcHRpb248VD4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uVmFsdWUgPSB0aGlzLm9wdGlvblZhbHVlKCk7XG5cbiAgICAgICAgaWYgKHRoaXMubXVsdGlwbGUoKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSBbLi4udGhpcy52YWx1ZXMoKV07XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmZpbmRJbmRleCgoc2VsZWN0ZWRJdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkSXRlbSA9PT0gaXRlbTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgc3RvcmUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcmUucHVzaChpdGVtKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy52YWx1ZXMuc2V0KHN0b3JlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvblZhbHVlID8gc3RvcmUubWFwKChpdGVtKSA9PiBpdGVtLmRhdGFbb3B0aW9uVmFsdWVdKSA6IHN0b3JlO1xuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UocmVzdWx0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUuc2V0KGl0ZW0pO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gb3B0aW9uVmFsdWUgPyBpdGVtLmRhdGFbb3B0aW9uVmFsdWVdIDogaXRlbS5kYXRhO1xuICAgICAgICAgICAgdGhpcy5fb25DaGFuZ2UocmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX29uVG91Y2hlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExpbXBhIG8gdmFsb3Igc2VsZWNpb25hZG8gbm8gY29tcG9uZW50ZSBzZWxlY3QuXG4gICAgICogU2UgbyBjb21wb25lbnRlIGVzdGl2ZXIgZGVzYWJpbGl0YWRvLCBuw6NvIGV4ZWN1dGEgbmVuaHVtYSBhw6fDo28uXG4gICAgICogUGFyYSBzZWxlw6fDo28gbcO6bHRpcGxhLCByZW1vdmUgdG9kb3Mgb3MgdmFsb3JlcyBzZWxlY2lvbmFkb3MgZSBub3RpZmljYSBhIGFsdGVyYcOnw6NvLlxuICAgICAqIFBhcmEgc2VsZcOnw6NvIMO6bmljYSwgZGVmaW5lIG8gdmFsb3IgY29tbyBudWxvIGUgbm90aWZpY2EgYSBhbHRlcmHDp8Ojby5cbiAgICAgKiBGZWNoYSBvIGRyb3Bkb3duIGUgbWFyY2EgbyBjb21wb25lbnRlIGNvbW8gXCJ0b2NhZG9cIi5cbiAgICAgKiBJbXBlZGUgYSBwcm9wYWdhw6fDo28gZG8gZXZlbnRvIGRvIG1vdXNlLlxuICAgICAqIEBwYXJhbSBldmVudCBFdmVudG8gZG8gbW91c2UgcXVlIGFjaW9ub3UgYSBsaW1wZXphIGRhIHNlbGXDp8Ojby5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2xlYXIoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubXVsdGlwbGUoKSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZXMuc2V0KFtdKTtcbiAgICAgICAgICAgIHRoaXMuX29uQ2hhbmdlKHRoaXMudmFsdWVzKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52YWx1ZS5zZXQobnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9vbkNoYW5nZSh0aGlzLnZhbHVlKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuXG4gICAgICAgIHRoaXMuX29uVG91Y2hlZCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMaW1wYSBvIGZpbHRybyBkbyBmb3JtdWzDoXJpbywgcmVzZXRhbmRvIG8gY2FtcG8gJ2ZpbHRlcicgZG8gZm9ybXVsw6FyaW8gZGUgZmlsdHJvLlxuICAgICAqIEVzdGUgbcOpdG9kbyByZWRlZmluZSBvIHZhbG9yIGRvIGNhbXBvICdmaWx0ZXInIHBhcmEgc2V1IGVzdGFkbyBpbmljaWFsLFxuICAgICAqIHJlbW92ZW5kbyBxdWFscXVlciB0ZXh0byBvdSB2YWxvciBwcmV2aWFtZW50ZSBpbnNlcmlkbyBwZWxvIHVzdcOhcmlvLlxuICAgICAqL1xuICAgIHB1YmxpYyBjbGVhckZpbHRlcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5maWx0ZXJGb3JtLmdldCgnZmlsdGVyJyk/LnJlc2V0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFuaXB1bGEgbyBldmVudG8gZGUgcmVkaW1lbnNpb25hbWVudG8gZGEgamFuZWxhLlxuICAgICAqIEZlY2hhIG8gZHJvcGRvd24gZGUgb3DDp8O1ZXMgY2FzbyBlbGUgZXN0ZWphIHZpc8OtdmVsIGFvIHJlZGltZW5zaW9uYXIgYSBqYW5lbGEuXG4gICAgICogQHBhcmFtIF8gRXZlbnRvIGRlIHJlZGltZW5zaW9uYW1lbnRvIGRhIGphbmVsYSAobsOjbyB1dGlsaXphZG8pLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbldpbmRvd1Jlc2l6ZShfOiBFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zaG93T3B0aW9ucygpKSB7XG4gICAgICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYW5pcHVsYSBvIGV2ZW50byBkZSBjbGlxdWUgbm8gZWxlbWVudG8gY29udGFpbmVyIGRhIHNlbGXDp8Ojby5cbiAgICAgKiBFc3RlIG3DqXRvZG8gYWx0ZXJuYSBvIGVzdGFkbyBkZSBleGliacOnw6NvIGRvIGNvbXBvbmVudGUgc2VsZWN0IGUsXG4gICAgICogZW0gc2VndWlkYSwgZGVmaW5lIG8gZm9jbyBubyBlbGVtZW50byBjb250YWluZXIgY29ycmVzcG9uZGVudGUuXG4gICAgICovXG4gICAgcHVibGljIG9uQ29udGFpbmVyRGl2Q2xpY2soKTogdm9pZCB7XG4gICAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lckRpdigpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFuaXB1bGEgZXZlbnRvcyBkZSB0ZWNsYWRvIHBhcmEgbmF2ZWdhw6fDo28gZSBzZWxlw6fDo28gZGUgb3DDp8O1ZXMgbm8gY29tcG9uZW50ZSBzZWxlY3QuXG4gICAgICogLSAnQXJyb3dEb3duJzogTW92ZSBvIGZvY28gcGFyYSBhIHByw7N4aW1hIG9ww6fDo28gZGlzcG9uw612ZWwuXG4gICAgICogLSAnQXJyb3dVcCc6IE1vdmUgbyBmb2NvIHBhcmEgYSBvcMOnw6NvIGFudGVyaW9yLlxuICAgICAqIC0gJ1RhYic6IFNlbGVjaW9uYSBhIG9ww6fDo28gYXR1YWxtZW50ZSBmb2NhZGEgZSBmZWNoYSBvIGRyb3Bkb3duLlxuICAgICAqIC0gJ0VudGVyJzogU2VsZWNpb25hIGEgb3DDp8OjbyBmb2NhZGEgc2UgbyBkcm9wZG93biBlc3RpdmVyIGFiZXJ0bywgb3UgYWx0ZXJuYSBhIGFiZXJ0dXJhIGRvIGRyb3Bkb3duLlxuICAgICAqIC0gJ0VzY2FwZSc6IEZlY2hhIG8gZHJvcGRvd24uXG4gICAgICogLSAnICc6IChiYXJyYSBkZSBlc3Bhw6dvKSBTZWxlY2lvbmEgYSBvcMOnw6NvIGZvY2FkYSBzZSBvIGRyb3Bkb3duIGVzdGl2ZXIgYWJlcnRvLCBvdSBhbHRlcm5hIGEgYWJlcnR1cmEgZG8gZHJvcGRvd24uXG4gICAgICogUHJldmluZSBvIGNvbXBvcnRhbWVudG8gcGFkcsOjbyBkbyBuYXZlZ2Fkb3IgcXVhbmRvIG5lY2Vzc8OhcmlvIHBhcmEgZ2FyYW50aXIgYSBuYXZlZ2HDp8OjbyBhZGVxdWFkYSBwZWxvIHRlY2xhZG8uXG4gICAgICogQHBhcmFtIGV2ZW50IE8gZXZlbnRvIGRlIHRlY2xhZG8gZGlzcGFyYWRvIHBlbG8gdXN1w6FyaW8uXG4gICAgICovXG4gICAgcHVibGljIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKTtcblxuICAgICAgICBpZiAoIW9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBfc2VsZWN0T3B0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9jdXNlZEluZGV4KCkgPj0gMCAmJiB0aGlzLmZvY3VzZWRJbmRleCgpIDwgb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0SXRlbShvcHRpb25zW3RoaXMuZm9jdXNlZEluZGV4KCldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2ZvY3VzTmV4dE9wdGlvbihvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNQcmV2aW91c09wdGlvbihvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ1RhYic6XG4gICAgICAgICAgICAgICAgX3NlbGVjdE9wdGlvbigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Nsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zaG93T3B0aW9ucygpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9zZWxlY3RPcHRpb24oKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnICc6XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zaG93T3B0aW9ucygpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9zZWxlY3RPcHRpb24oKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldG9ybmEgbyByw7N0dWxvIChsYWJlbCkgYXNzb2NpYWRvIGEgdW1hIG9ww6fDo28gZm9ybmVjaWRhLlxuICAgICAqIEBwYXJhbSBvcHRpb24gLSBBIG9ww6fDo28gZG8gdGlwbyBUIHBhcmEgYSBxdWFsIG8gcsOzdHVsbyBkZXZlIHNlciBvYnRpZG8uXG4gICAgICogQHJldHVybnMgTyByw7N0dWxvIGRhIG9ww6fDo28gY29tbyB1bWEgc3RyaW5nLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRPcHRpb25MYWJlbChvcHRpb246IFQpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TGFiZWxGcm9tT3B0aW9uKG9wdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnVuw6fDo28gZGUgdHJhY2tCeSB1dGlsaXphZGEgZW0gZGlyZXRpdmFzICpuZ0ZvciBwYXJhIG90aW1pemFyIGEgcmVuZGVyaXphw6fDo28gZGUgbGlzdGFzLlxuICAgICAqIFJldG9ybmEgbyBpZGVudGlmaWNhZG9yIMO6bmljbyAoYGlkYCkgZGUgY2FkYSBpdGVtIGRvIHRpcG8gYEludGVybmFsRHJvcGRvd25PcHRpb248VD5gLlxuICAgICAqIEBwYXJhbSBfIC0gw41uZGljZSBkbyBpdGVtIG5hIGxpc3RhIChuw6NvIHV0aWxpemFkbykuXG4gICAgICogQHBhcmFtIGl0ZW0gLSBPIGl0ZW0gYXR1YWwgZGEgbGlzdGEgZG8gdGlwbyBgSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPmAuXG4gICAgICogQHJldHVybnMgTyBpZGVudGlmaWNhZG9yIMO6bmljbyBkbyBpdGVtIGNvbW8gdW1hIHN0cmluZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgdHJhY2tCeUlkKF86IG51bWJlciwgaXRlbTogSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPik6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBpdGVtLmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWNhIHNlIGEgb3DDp8OjbyBmb3JuZWNpZGEgZXN0w6Egc2VsZWNpb25hZGEuXG4gICAgICogQHBhcmFtIG9wdGlvbiAtIEEgb3DDp8OjbyBpbnRlcm5hIGRvIGRyb3Bkb3duIGEgc2VyIHZlcmlmaWNhZGEuXG4gICAgICogQHJldHVybnMgYHRydWVgIHNlIGEgb3DDp8OjbyBlc3RpdmVyIHNlbGVjaW9uYWRhLCBjYXNvIGNvbnRyw6FyaW8gYGZhbHNlYC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNPcHRpb25TZWxlY3RlZChvcHRpb246IEludGVybmFsRHJvcGRvd25PcHRpb248VD4pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMudmFsdWVzKCkuZmluZCgobykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBvID09PSBvcHRpb247XG4gICAgICAgICAgICB9KSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWx0ZXJuYSBhIHNlbGXDp8OjbyBkZSB0b2RvcyBvcyBpdGVucyBkaXNwb27DrXZlaXMuXG4gICAgICogU2UgbyBtb2RvIG3Dumx0aXBsbyBlc3RpdmVyIGF0aXZhZG8sIHNlbGVjaW9uYSB0b2RvcyBvcyBpdGVucyBmaWx0cmFkb3MgcXVlIG7Do28gc8OjbyBhZ3J1cGFkb3Jlc1xuICAgICAqIGNhc28gbmVtIHRvZG9zIGVzdGVqYW0gc2VsZWNpb25hZG9zLCBvdSBsaW1wYSBhIHNlbGXDp8OjbyBjYXNvIHRvZG9zIGrDoSBlc3RlamFtIHNlbGVjaW9uYWRvcy5cbiAgICAgKiBBcMOzcyBhIGFsdGVyYcOnw6NvLCBub3RpZmljYSBhIG11ZGFuw6dhIGRlIHZhbG9yLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGVTZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5tdWx0aXBsZSgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKS5maWx0ZXIoKG9wdGlvbikgPT4gIW9wdGlvbi5ncm91cGVyKTtcblxuICAgICAgICBpZiAodGhpcy5hbGxTZWxlY3RlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlcy5zZXQoW10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52YWx1ZXMuc2V0KG9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy52YWx1ZXMoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0b3JuYSBvIHLDs3R1bG8gKGxhYmVsKSBkZSB1bWEgb3DDp8OjbyBmb3JuZWNpZGEuXG4gICAgICogRXN0ZSBtw6l0b2RvIHV0aWxpemEgYSBwcm9wcmllZGFkZSBkZWZpbmlkYSBwb3IgYG9wdGlvbkxhYmVsYCBwYXJhIGV4dHJhaXIgbyB2YWxvciBkbyByw7N0dWxvIGRhIG9ww6fDo28uXG4gICAgICogQ2FzbyBgb3B0aW9uTGFiZWxgIG7Do28gZXN0ZWphIGRlZmluaWRvLCByZXRvcm5hIGEgcmVwcmVzZW50YcOnw6NvIGVtIHN0cmluZyBkYSBwcsOzcHJpYSBvcMOnw6NvLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIG9wdGlvbiBBIG9ww6fDo28gZGEgcXVhbCBvIHLDs3R1bG8gc2Vyw6EgZXh0cmHDrWRvLlxuICAgICAqIEByZXR1cm5zIE8gcsOzdHVsbyBkYSBvcMOnw6NvIGNvbW8gdW1hIHN0cmluZy5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9nZXRMYWJlbEZyb21PcHRpb24ob3B0aW9uOiBUKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uTGFiZWwgPSB0aGlzLm9wdGlvbkxhYmVsKCk7XG4gICAgICAgIHJldHVybiBvcHRpb25MYWJlbCA/IFN0cmluZyhvcHRpb25bb3B0aW9uTGFiZWxdKSA6IFN0cmluZyhvcHRpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZhbGlkYSBhcyBlbnRyYWRhcyBkbyBjb21wb25lbnRlIGRlIHNlbGXDp8Ojby5cbiAgICAgKiBFc3RlIG3DqXRvZG8gdmVyaWZpY2Egc2UgYXMgb3DDp8O1ZXMgZm9ybmVjaWRhcyBzw6NvIHbDoWxpZGFzLiBDYXNvIGFzIG9ww6fDtWVzIHNlamFtIG9iamV0b3MsXG4gICAgICogZ2FyYW50ZSBxdWUgYSBwcm9wcmllZGFkZSBgb3B0aW9uTGFiZWxgIGVzdGVqYSBkZWZpbmlkYSwgbGFuw6dhbmRvIHVtIGVycm8gY2FzbyBjb250csOhcmlvLlxuICAgICAqIFNlIG7Do28gaG91dmVyIG9ww6fDtWVzLCBhIHZhbGlkYcOnw6NvIMOpIGlnbm9yYWRhLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHRocm93cyB7RXJyb3J9IFNlIGFzIG9ww6fDtWVzIGZvcmVtIG9iamV0b3MgZSBgb3B0aW9uTGFiZWxgIG7Do28gZXN0aXZlciBkZWZpbmlkby5cbiAgICAgKi9cbiAgICBwcml2YXRlIF92YWxpZGF0ZUlucHV0cygpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucygpO1xuXG4gICAgICAgIGlmICghb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhhc09iamVjdE9wdGlvbnMgPSBvcHRpb25zLnNvbWUoKG9wdGlvbikgPT4gdHlwZW9mIG9wdGlvbiA9PT0gJ29iamVjdCcgJiYgb3B0aW9uICE9PSBudWxsKTtcblxuICAgICAgICBpZiAoaGFzT2JqZWN0T3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbkxhYmVsKCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBcIm9wdGlvbkxhYmVsXCIgaW5wdXQgaXMgcmVxdWlyZWQgd2hlbiBvcHRpb25zIGFyZSBvYmplY3RzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmVjaGEgbyBkcm9wZG93biBkZSBvcMOnw7VlcyBkbyBjb21wb25lbnRlIHNlbGVjdC5cbiAgICAgKiBFc3RlIG3DqXRvZG8gb2N1bHRhIGFzIG9ww6fDtWVzIGRpc3BvbsOtdmVpcyBlIHJlZGVmaW5lIG8gw61uZGljZSBkbyBpdGVtIGZvY2FkbyBwYXJhIC0xLFxuICAgICAqIGluZGljYW5kbyBxdWUgbmVuaHVtIGl0ZW0gZXN0w6EgYXR1YWxtZW50ZSBmb2NhZG8uXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIF9jbG9zZURyb3Bkb3duKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNob3dPcHRpb25zLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRpY2lvbmEgdW0gaWRlbnRpZmljYWRvciDDum5pY28gYSBjYWRhIG9ww6fDo28gZm9ybmVjaWRhLlxuICAgICAqIFBhcmEgY2FkYSBpdGVtIG5vIGFycmF5IGRlIG9ww6fDtWVzLCBnZXJhIHVtIG9iamV0byBgSW50ZXJuYWxEcm9wZG93bk9wdGlvbmAgY29udGVuZG8gbyBkYWRvIG9yaWdpbmFsXG4gICAgICogZSB1bSBjYW1wbyBgaWRgIMO6bmljbyBiYXNlYWRvIG5vIHRpbWVzdGFtcCBhdHVhbCBlIG5vIMOtbmRpY2UgZG8gaXRlbS4gQ2FzbyBhIG9ww6fDo28gc2VqYSB1bSBncnVwb1xuICAgICAqIChkZXRlY3RhZG8gcGVsYSBwcmVzZW7Dp2EgZGUgdW0gYXJyYXkgYGl0ZW1zYCksIGFkaWNpb25hIHRhbWLDqW0gYSBwcm9wcmllZGFkZSBgZ3JvdXBlcjogdHJ1ZWAuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBcnJheSBkZSBvcMOnw7VlcyBkbyB0aXBvIGBUYCBhIHNlcmVtIHByb2Nlc3NhZGFzLlxuICAgICAqIEByZXR1cm5zIFVtIGFycmF5IGRlIG9iamV0b3MgYEludGVybmFsRHJvcGRvd25PcHRpb248VD5gIGNvbSBpZGVudGlmaWNhZG9yZXMgw7puaWNvcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9hZGRJZFRvT3B0aW9ucyhvcHRpb25zOiBUW10pOiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10ge1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHJldHVybiBvcHRpb25zLm1hcCgob3B0aW9uLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZ3JvdXAoKSAmJiBBcnJheS5pc0FycmF5KChvcHRpb24gYXMgYW55KS5pdGVtcykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBvcHRpb24sXG4gICAgICAgICAgICAgICAgICAgIGlkOiBgaWRfJHt0aW1lc3RhbXB9XyR7aW5kZXgrK31gLFxuICAgICAgICAgICAgICAgICAgICBncm91cGVyOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGF0YTogb3B0aW9uLFxuICAgICAgICAgICAgICAgIGlkOiBgaWRfJHt0aW1lc3RhbXB9XyR7aW5kZXgrK31gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydGUgdW1hIGxpc3RhIGRlIG9ww6fDtWVzIHBvc3NpdmVsbWVudGUgYWdydXBhZGFzIGVtIHVtYSBsaXN0YSBwbGFuYSBkZSBvcMOnw7Vlcy5cbiAgICAgKiBQYXJhIGNhZGEgb3DDp8OjbyBxdWUgcG9zc3VpIHVtIGFncnVwYWRvciAoYGdyb3VwZXJgKSBlIHVtIGFycmF5IGRlIGl0ZW5zIGVtIGBkYXRhLml0ZW1zYCxcbiAgICAgKiBhZGljaW9uYSBhIG9ww6fDo28gZG8gYWdydXBhZG9yIGUsIGVtIHNlZ3VpZGEsIGFkaWNpb25hIGNhZGEgaXRlbSBkbyBncnVwbyBjb21vIHVtYSBub3ZhIG9ww6fDo29cbiAgICAgKiBpbmRpdmlkdWFsLCBhdHJpYnVpbmRvIHVtIGBpZGAgw7puaWNvIHBhcmEgY2FkYSBpdGVtIGRvIGdydXBvLlxuICAgICAqIENhc28gYSBvcMOnw6NvIG7Do28gc2VqYSB1bSBhZ3J1cGFkb3IsIGVsYSDDqSBhZGljaW9uYWRhIGRpcmV0YW1lbnRlIGFvIHJlc3VsdGFkby5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSBvcHRpb25zIExpc3RhIGRlIG9ww6fDtWVzIGludGVybmFzIGRvIGRyb3Bkb3duLCBwb2RlbmRvIGNvbnRlciBhZ3J1cGFkb3Jlcy5cbiAgICAgKiBAcmV0dXJucyBMaXN0YSBwbGFuYSBkZSBvcMOnw7VlcywgaW5jbHVpbmRvIGFncnVwYWRvcmVzIGUgc2V1cyBpdGVucyBleHBhbmRpZG9zLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2dyb3VwZXJUb0ZsYXQob3B0aW9uczogSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPltdKTogSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPltdIHtcbiAgICAgICAgY29uc3QgcmVzdWx0OiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10gPSBbXTtcblxuICAgICAgICBvcHRpb25zLmZvckVhY2goKG9wdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbi5ncm91cGVyICYmIEFycmF5LmlzQXJyYXkoKG9wdGlvbi5kYXRhIGFzIGFueSkuaXRlbXMpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gob3B0aW9uKTtcbiAgICAgICAgICAgICAgICBjb25zdCBncm91cEl0ZW1zID0gKG9wdGlvbi5kYXRhIGFzIGFueSkuaXRlbXMubWFwKChpdGVtOiBULCBpbmRleDogbnVtYmVyKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBpdGVtLFxuICAgICAgICAgICAgICAgICAgICBpZDogYCR7b3B0aW9uLmlkfV9pdGVtXyR7aW5kZXh9YCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goLi4uZ3JvdXBJdGVtcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG9wdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW92ZSBvIGZvY28gcGFyYSBhIHByw7N4aW1hIG9ww6fDo28gZGlzcG9uw612ZWwgbmEgbGlzdGEsIGlnbm9yYW5kbyBvcMOnw7VlcyBxdWUgc2VqYW0gYWdydXBhZG9yZXMuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBMaXN0YSBkZSBvcMOnw7VlcyBpbnRlcm5hcyBkbyBkcm9wZG93bi5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9mb2N1c05leHRPcHRpb24ob3B0aW9uczogSW50ZXJuYWxEcm9wZG93bk9wdGlvbjxUPltdKSB7XG4gICAgICAgIGxldCBuZXh0SW5kZXggPSB0aGlzLmZvY3VzZWRJbmRleCgpICsgMTtcblxuICAgICAgICB3aGlsZSAobmV4dEluZGV4IDwgb3B0aW9ucy5sZW5ndGggJiYgb3B0aW9uc1tuZXh0SW5kZXhdLmdyb3VwZXIpIHtcbiAgICAgICAgICAgIG5leHRJbmRleCsrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5leHRJbmRleCA8IG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQobmV4dEluZGV4KTtcbiAgICAgICAgICAgIHRoaXMuX3Njcm9sbFRvRm9jdXNlZE9wdGlvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW92ZSBvIGZvY28gcGFyYSBhIG9ww6fDo28gYW50ZXJpb3IgbmEgbGlzdGEsIGlnbm9yYW5kbyBvcMOnw7VlcyBkbyB0aXBvIFwiZ3JvdXBlclwiLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIG9wdGlvbnMgTGlzdGEgZGUgb3DDp8O1ZXMgaW50ZXJuYXMgZG8gZHJvcGRvd24uXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZm9jdXNQcmV2aW91c09wdGlvbihvcHRpb25zOiBJbnRlcm5hbERyb3Bkb3duT3B0aW9uPFQ+W10pIHtcbiAgICAgICAgbGV0IHByZXZJbmRleCA9IHRoaXMuZm9jdXNlZEluZGV4KCkgLSAxO1xuXG4gICAgICAgIHdoaWxlIChwcmV2SW5kZXggPj0gMCAmJiBvcHRpb25zW3ByZXZJbmRleF0uZ3JvdXBlcikge1xuICAgICAgICAgICAgcHJldkluZGV4LS07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJldkluZGV4ID49IDApIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldChwcmV2SW5kZXgpO1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsVG9Gb2N1c2VkT3B0aW9uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSb2xhIGEgbGlzdGEgZGUgb3DDp8O1ZXMgcGFyYSBnYXJhbnRpciBxdWUgYSBvcMOnw6NvIGF0dWFsbWVudGUgZm9jYWRhIGVzdGVqYSB2aXPDrXZlbC5cbiAgICAgKiBFc3RlIG3DqXRvZG8gb2J0w6ltIG8gSUQgZGEgb3DDp8OjbyBhdHVhbG1lbnRlIGZvY2FkYSBhIHBhcnRpciBkYSBsaXN0YSBkZSBvcMOnw7VlcyBmaWx0cmFkYXMuXG4gICAgICogU2UgdW0gSUQgdsOhbGlkbyBmb3IgZW5jb250cmFkbywgYnVzY2EgbyBlbGVtZW50byBjb3JyZXNwb25kZW50ZSBubyBET00gZSB1dGlsaXphXG4gICAgICogYHNjcm9sbEludG9WaWV3YCBwYXJhIHJvbGFyIGF0w6kgYSBvcMOnw6NvLCBhbGluaGFuZG8tYSBhbyBibG9jbyBtYWlzIHByw7N4aW1vLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBfc2Nyb2xsVG9Gb2N1c2VkT3B0aW9uKCkge1xuICAgICAgICBjb25zdCBpZCA9IHRoaXMuZmlsdGVyZWRPcHRpb25zKClbdGhpcy5mb2N1c2VkSW5kZXgoKV0/LmlkO1xuXG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgICAgICBlbD8uc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogJ25lYXJlc3QnIH0pO1xuICAgIH1cbn1cbiIsIjxkaXZcbiAgICAjY29udGFpbmVyRGl2XG4gICAgY2RrT3ZlcmxheU9yaWdpblxuICAgICN0cmlnZ2VyPVwiY2RrT3ZlcmxheU9yaWdpblwiXG4gICAgY2xhc3M9XCJzZWxlY3QtY29udGFpbmVyIGdyb3VwIGZsZXggaC1bMzVweF0gdy1mdWxsIG92ZXJmbG93LWhpZGRlbiByb3VuZGVkLVszcHhdIGJvcmRlciBvdXRsaW5lLTEgb3V0bGluZS1wcmltYXJ5IGZvY3VzOm91dGxpbmVcIlxuICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzLW5vbmUgYm9yZGVyLWdyYXlzY2FsZS0yMCBiZy1ncmF5c2NhbGUtNSc6IGRpc2FibGVkKCksXG4gICAgICAgICdwb2ludGVyLWV2ZW50cy1hdXRvIGJvcmRlci1ncmF5c2NhbGUtMzAgYmctZ3JheXNjYWxlLTAnOiAhZGlzYWJsZWQoKSxcbiAgICB9XCJcbiAgICBbYXR0ci5hcmlhLWRpc2FibGVkXT1cImRpc2FibGVkKClcIlxuICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwic2hvd09wdGlvbnMoKVwiXG4gICAgW2F0dHIuYXJpYS1oYXNwb3B1cF09XCInbGlzdGJveCdcIlxuICAgIFthdHRyLmFyaWEtb3duc109XCInZHJvcGRvd24tY29udGFpbmVyLScgKyBjb21wb25lbnRJZFwiXG4gICAgW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cImNvbXBvbmVudElkICsgJy1sYWJlbCdcIlxuICAgIHJvbGU9XCJjb21ib2JveFwiXG4gICAgKGNsaWNrKT1cIm9uQ29udGFpbmVyRGl2Q2xpY2soKVwiXG4gICAgKGtleWRvd24pPVwib25LZXlEb3duKCRldmVudClcIlxuICAgIHRhYmluZGV4PVwiMFwiXG4+XG4gICAgPHNwYW5cbiAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtZ3JvdyBzZWxlY3Qtbm9uZSBweC0zIHB5LVs3cHhdXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgJ3RleHQtZ3JheXNjYWxlLTkwJzogIWRpc2FibGVkKCkgJiYgIWlzQ2xlYW4oKSxcbiAgICAgICAgICAgICd0ZXh0LWdyYXlzY2FsZS02MCc6ICFkaXNhYmxlZCgpICYmIGlzQ2xlYW4oKSxcbiAgICAgICAgICAgICd0ZXh0LWdyYXlzY2FsZS0zMCc6IGRpc2FibGVkKCksXG4gICAgICAgIH1cIlxuICAgID5cbiAgICAgICAge3sgcHJpbnQoKSB8fCBwbGFjZWhvbGRlcigpIH19XG4gICAgPC9zcGFuPlxuXG4gICAgQGlmICghZGlzYWJsZWQoKSAmJiBzaG93Q2xlYXIoKSAmJiAhaXNDbGVhbigpKSB7XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGNsYXNzPVwibXgtM1wiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2xlYXIoJGV2ZW50KVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXRpbWVzIGZsZXggaXRlbXMtY2VudGVyXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICB9XG5cbiAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiZHJvcGRvd24tY29udGFpbmVyIGZsZXggaXRlbXMtY2VudGVyIGJvcmRlci1sIHB4LTMgZ3JvdXAtaG92ZXI6YmctZ3JheXNjYWxlLTEwIGdyb3VwLWZvY3VzOmJvcmRlci1wcmltYXJ5XCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnYm9yZGVyLWdyYXlzY2FsZS0yMCc6IGRpc2FibGVkKCksICdib3JkZXItZ3JheXNjYWxlLTMwJzogIWRpc2FibGVkKCkgfVwiXG4gICAgPlxuICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJmYXNcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICd0ZXh0LWdyYXlzY2FsZS0zMCc6IGRpc2FibGVkKCksXG4gICAgICAgICAgICAgICAgJ3RleHQtZ3JheXNjYWxlLTkwJzogIWRpc2FibGVkKCksXG4gICAgICAgICAgICAgICAgJ2ZhLWNhcmV0LWRvd24nOiAhc2hvd09wdGlvbnMoKSxcbiAgICAgICAgICAgICAgICAnZmEtY2FyZXQtdXAnOiBzaG93T3B0aW9ucygpLFxuICAgICAgICAgICAgfVwiXG4gICAgICAgID48L2k+XG4gICAgPC9kaXY+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlXG4gICAgI2Ryb3Bkb3duVGVtcGxhdGVcbiAgICBjZGtDb25uZWN0ZWRPdmVybGF5XG4gICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW5dPVwidHJpZ2dlclwiXG4gICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcGVuXT1cInNob3dPcHRpb25zKClcIlxuICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5SGFzQmFja2Ryb3BdPVwidHJ1ZVwiXG4gICAgKGJhY2tkcm9wQ2xpY2spPVwic2hvd09wdGlvbnMuc2V0KGZhbHNlKVwiXG4gICAgY2RrQ29ubmVjdGVkT3ZlcmxheUJhY2tkcm9wQ2xhc3M9XCJjZGstb3ZlcmxheS10cmFuc3BhcmVudC1iYWNrZHJvcFwiXG4gICAgKGRldGFjaCk9XCJzaG93T3B0aW9ucy5zZXQoZmFsc2UpXCJcbj5cbiAgICA8ZGl2XG4gICAgICAgIFtpZF09XCInZHJvcGRvd24tY29udGFpbmVyLScgKyBjb21wb25lbnRJZFwiXG4gICAgICAgIGNsYXNzPVwiZHJvcGRvd24tYm9keS1jbGFzcyB6LVsxMDAwXSByb3VuZGVkLVszcHhdIGJnLWdyYXlzY2FsZS0wIHB5LTEgc2hhZG93LW1kXCJcbiAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJjb250YWluZXJEaXYub2Zmc2V0V2lkdGhcIlxuICAgID5cbiAgICAgICAgQGlmIChmaWx0ZXIoKSkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggdy1mdWxsIGl0ZW1zLWNlbnRlciBnYXAtMyBweC0zIHB5LTEuNVwiPlxuICAgICAgICAgICAgICAgIEBpZiAobXVsdGlwbGUoKSkge1xuICAgICAgICAgICAgICAgICAgICA8cy1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgI3NlbGVjdEFsbENoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJhbGxTZWxlY3RlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cInNlbGVjdEFsbElzSW5kZXRlcm1pbmF0ZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGVja2VkQ2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcy1jaGVja2JveD5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgZmxleCBoLVszNXB4XSBncm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxmb3JtXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggZ3Jvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZpbHRlckZvcm1cIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBncm93IHJvdW5kZWQtWzNweF0gYm9yZGVyIGJvcmRlci1ncmF5c2NhbGUtMzAgcGwtMi41IHByLTcgb3V0bGluZS0xIG91dGxpbmUtcHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXNlYXJjaCBhYnNvbHV0ZSByaWdodC0yLjUgdG9wLTIuNSB0ZXh0LWdyYXlzY2FsZS05MFwiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJjbGVhckZpbHRlcigpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXRpbWVzIGZsZXggaXRlbXMtY2VudGVyXCI+PC9pPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIFZpcnR1YWwgc2Nyb2xsIC0tPlxuICAgICAgICBAaWYgKHZpcnR1YWxTY3JvbGwoKSAmJiBmaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggPiAxMCkge1xuICAgICAgICAgICAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydFxuICAgICAgICAgICAgICAgIFtpdGVtU2l6ZV09XCJ2aXJ0dWFsU2Nyb2xsSXRlbVNpemUoKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJoLTUyIG92ZXJmbG93LWF1dG9cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKmNka1ZpcnR1YWxGb3I9XCJsZXQgb3B0aW9uIG9mIGZpbHRlcmVkT3B0aW9ucygpOyB0cmFja0J5OiB0cmFja0J5SWRcIj5cbiAgICAgICAgICAgICAgICAgICAgPHMtc2VsZWN0LW9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cIm9wdGlvbi5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiZ2V0T3B0aW9uTGFiZWwob3B0aW9uLmRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttdWx0aXBsZV09XCJtdWx0aXBsZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja21hcmtdPVwiY2hlY2ttYXJrKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzU2VsZWN0ZWRdPVwiaXNPcHRpb25TZWxlY3RlZChvcHRpb24pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZCk9XCJzZWxlY3RJdGVtKG9wdGlvbilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzR3JvdXBlcl09XCJvcHRpb24uZ3JvdXBlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNGb2N1c2VkXT1cIm9wdGlvbi5kYXRhID09PSBmb2N1c2VkSXRlbSgpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcy1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9jZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQ+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIE5vcm1hbCBsaXN0IC0tPlxuICAgICAgICBAaWYgKCF2aXJ0dWFsU2Nyb2xsKCkgfHwgZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIDw9IDEwKSB7XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJtYXgtaC01MiBvdmVyZmxvdy1hdXRvXCI+XG4gICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGZpbHRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHRpb24uaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgPHMtc2VsZWN0LW9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW2lkXT1cIm9wdGlvbi5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwiZ2V0T3B0aW9uTGFiZWwob3B0aW9uLmRhdGEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttdWx0aXBsZV09XCJtdWx0aXBsZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja21hcmtdPVwiY2hlY2ttYXJrKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzU2VsZWN0ZWRdPVwiaXNPcHRpb25TZWxlY3RlZChvcHRpb24pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZCk9XCJzZWxlY3RJdGVtKG9wdGlvbilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzR3JvdXBlcl09XCJvcHRpb24uZ3JvdXBlciA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNGb2N1c2VkXT1cIm9wdGlvbi5kYXRhID09PSBmb2N1c2VkSXRlbSgpXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvcy1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgIH1cblxuICAgICAgICBAaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtLTMgdGV4dC1ncmF5c2NhbGUtNjBcIj57e1xuICAgICAgICAgICAgICAgIGVtcHR5TWVzc2FnZSgpID8/ICdwbGF0Zm9ybS5hbmd1bGFyX2NvbXBvbmVudHMubm9fcmVjb3Jkc19mb3VuZCcgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICB9XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
|