@marcura/marcura-combobox 6.1.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/esm2020/lib/combobox.injectables.mjs +5 -5
- package/esm2020/lib/combobox.module.mjs +103 -103
- package/esm2020/lib/components/abstract-combobox/abstract-combobox.component.mjs +240 -240
- package/esm2020/lib/components/abstract-dropdown/abstract-dropdown.component.mjs +230 -230
- package/esm2020/lib/components/combobox/combobox.component.mjs +365 -361
- package/esm2020/lib/components/combobox-popup-footer/combobox-popup-footer.component.mjs +38 -38
- package/esm2020/lib/components/dropdown/dropdown.component.mjs +234 -234
- package/esm2020/lib/components/multiselect/multiselect.component.mjs +247 -247
- package/esm2020/lib/directives/combobox-item-template.directive.mjs +13 -13
- package/esm2020/lib/directives/dropdown-item-template.directive.mjs +13 -13
- package/esm2020/lib/directives/dropdown-value-template.directive.mjs +13 -13
- package/esm2020/lib/directives/multiselect-item-template.directive.mjs +13 -13
- package/esm2020/lib/directives/multiselect-tag-template.directive.mjs +13 -13
- package/esm2020/lib/directives/multiselect-tag-wrapper.directive.mjs +60 -60
- package/esm2020/lib/model/combobox-changed.event.mjs +4 -4
- package/esm2020/lib/model/combobox-item.type.mjs +12 -12
- package/esm2020/lib/model/combobox-kendo-component.interface.mjs +2 -2
- package/esm2020/lib/model/combobox-localization.interface.mjs +2 -2
- package/esm2020/lib/model/combobox-search-fn.type.mjs +1 -1
- package/esm2020/lib/model/combobox-search-settings-operator.enum.mjs +6 -6
- package/esm2020/lib/model/combobox-search-settings.interface.mjs +2 -2
- package/esm2020/lib/model/dropdown-changed.event.mjs +4 -4
- package/esm2020/lib/model/dropdown-kendo-component.interface.mjs +2 -2
- package/esm2020/lib/model/dropdown-localization.interface.mjs +2 -2
- package/esm2020/lib/model/dropdown-localizer.interface.mjs +2 -2
- package/esm2020/lib/model/multiselect-changed.event.mjs +4 -4
- package/esm2020/lib/model/multiselect-localization.interface.mjs +2 -2
- package/esm2020/marcura-marcura-combobox.mjs +4 -4
- package/esm2020/public-api.mjs +25 -25
- package/fesm2015/marcura-marcura-combobox.mjs +1482 -1478
- package/fesm2015/marcura-marcura-combobox.mjs.map +1 -1
- package/fesm2020/marcura-marcura-combobox.mjs +1477 -1473
- package/fesm2020/marcura-marcura-combobox.mjs.map +1 -1
- package/index.d.ts +5 -5
- package/lib/combobox.injectables.d.ts +8 -8
- package/lib/combobox.module.d.ts +25 -25
- package/lib/components/abstract-combobox/abstract-combobox.component.d.ts +59 -59
- package/lib/components/abstract-dropdown/abstract-dropdown.component.d.ts +76 -76
- package/lib/components/combobox/combobox.component.d.ts +65 -64
- package/lib/components/combobox-popup-footer/combobox-popup-footer.component.d.ts +13 -13
- package/lib/components/dropdown/dropdown.component.d.ts +45 -45
- package/lib/components/multiselect/multiselect.component.d.ts +51 -51
- package/lib/directives/combobox-item-template.directive.d.ts +5 -5
- package/lib/directives/dropdown-item-template.directive.d.ts +5 -5
- package/lib/directives/dropdown-value-template.directive.d.ts +5 -5
- package/lib/directives/multiselect-item-template.directive.d.ts +5 -5
- package/lib/directives/multiselect-tag-template.directive.d.ts +5 -5
- package/lib/directives/multiselect-tag-wrapper.directive.d.ts +21 -21
- package/lib/model/combobox-changed.event.d.ts +3 -3
- package/lib/model/combobox-item.type.d.ts +4 -4
- package/lib/model/combobox-kendo-component.interface.d.ts +7 -7
- package/lib/model/combobox-localization.interface.d.ts +5 -5
- package/lib/model/combobox-search-fn.type.d.ts +3 -3
- package/lib/model/combobox-search-settings-operator.enum.d.ts +4 -4
- package/lib/model/combobox-search-settings.interface.d.ts +5 -5
- package/lib/model/dropdown-changed.event.d.ts +3 -3
- package/lib/model/dropdown-kendo-component.interface.d.ts +6 -6
- package/lib/model/dropdown-localization.interface.d.ts +3 -3
- package/lib/model/dropdown-localizer.interface.d.ts +5 -5
- package/lib/model/multiselect-changed.event.d.ts +3 -3
- package/lib/model/multiselect-localization.interface.d.ts +5 -5
- package/package.json +1 -1
- package/public-api.d.ts +24 -24
|
@@ -1,241 +1,241 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, Renderer2, } from '@angular/core';
|
|
2
|
-
import { isFalse, Is, Observer, Worker, flatten } from '@marcura/marcura-common';
|
|
3
|
-
import { combineLatest, BehaviorSubject } from 'rxjs';
|
|
4
|
-
import { debounceTime, distinctUntilChanged, filter, map, skip, tap } from 'rxjs/operators';
|
|
5
|
-
import { AbstractDropdownComponent } from '../../components/abstract-dropdown/abstract-dropdown.component';
|
|
6
|
-
import { ComboboxSearchSettingsOperator } from '../../model/combobox-search-settings-operator.enum';
|
|
7
|
-
import * as i0 from "@angular/core";
|
|
8
|
-
export class AbstractComboboxComponent extends AbstractDropdownComponent {
|
|
9
|
-
get debounceTime() {
|
|
10
|
-
return this._debounceTime;
|
|
11
|
-
}
|
|
12
|
-
set debounceTime(value) {
|
|
13
|
-
this._debounceTime = value;
|
|
14
|
-
this._listenToSearched();
|
|
15
|
-
}
|
|
16
|
-
get items() {
|
|
17
|
-
return this._items;
|
|
18
|
-
}
|
|
19
|
-
set items(items) {
|
|
20
|
-
this._isSync = true;
|
|
21
|
-
this._items = items || [];
|
|
22
|
-
this._listenToSearched();
|
|
23
|
-
this._loadedItems.next(this._items);
|
|
24
|
-
}
|
|
25
|
-
get additionalItems() {
|
|
26
|
-
return this._additionalItems.value;
|
|
27
|
-
}
|
|
28
|
-
set additionalItems(additionalItems) {
|
|
29
|
-
this._additionalItems.next(additionalItems || []);
|
|
30
|
-
}
|
|
31
|
-
_disableChromeAutocomplete() {
|
|
32
|
-
if (this._component.searchbar && this._component.searchbar.input) {
|
|
33
|
-
this._renderer.setAttribute(this._component.searchbar.input.nativeElement, 'autocomplete', 'disabled');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
_listenToSearched() {
|
|
37
|
-
this._debounceObserver.clear();
|
|
38
|
-
this._debounceObserver.listen(this._searchText.pipe(distinctUntilChanged(), skip(1), tap((searchText) => {
|
|
39
|
-
this.searched.emit(searchText);
|
|
40
|
-
this._isSearching.next(this.canLoadItems(searchText) && this._isOpen.value.isOpen);
|
|
41
|
-
}), debounceTime(this._isSync ? 0 : this.debounceTime), filter(() => this._isOpen.value.isOpen)), this.loadItems);
|
|
42
|
-
}
|
|
43
|
-
_filterItems(items, searchText) {
|
|
44
|
-
if (!items || !items.length) {
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
// TODO: technical-debt - fix group result case to avoid any
|
|
48
|
-
return items.filter((item) => {
|
|
49
|
-
let itemText = (item[this.textField] || '').toString().trim() ?? '';
|
|
50
|
-
itemText = this.searchSettings.isCaseSensitive ? itemText : itemText.toLowerCase();
|
|
51
|
-
return this.searchSettings.operator === ComboboxSearchSettingsOperator.Contains
|
|
52
|
-
? itemText.indexOf(searchText) !== -1
|
|
53
|
-
: itemText.substring(0, searchText.length) === searchText;
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
_setComponent(component) {
|
|
57
|
-
this._component = component;
|
|
58
|
-
this._disableChromeAutocomplete();
|
|
59
|
-
}
|
|
60
|
-
searchItems(searchText) {
|
|
61
|
-
if (!this.searchSettings || !searchText || !this._items.length) {
|
|
62
|
-
return this._items;
|
|
63
|
-
}
|
|
64
|
-
searchText = this.searchSettings.isCaseSensitive ? searchText : searchText.toLowerCase();
|
|
65
|
-
if (this.isGroupable) {
|
|
66
|
-
const groups = this._items;
|
|
67
|
-
const filteredGroups = groups
|
|
68
|
-
.map((group) => ({
|
|
69
|
-
...group,
|
|
70
|
-
items: this._filterItems(group.items, searchText),
|
|
71
|
-
}))
|
|
72
|
-
.filter((group) => group.items.length > 0);
|
|
73
|
-
return filteredGroups;
|
|
74
|
-
}
|
|
75
|
-
return this._filterItems(this._items, searchText);
|
|
76
|
-
}
|
|
77
|
-
canLoadItems(searchText) {
|
|
78
|
-
return searchText.length >= this.minSearchCharacters && !this._isSync;
|
|
79
|
-
}
|
|
80
|
-
getItem(items, text) {
|
|
81
|
-
text = text.toLowerCase();
|
|
82
|
-
return this._unwrapGroups(items).find((item) => `${item[this.textField]}`.toLowerCase() === text) ?? null;
|
|
83
|
-
}
|
|
84
|
-
_unwrapGroups(items) {
|
|
85
|
-
return flatten(items.map(item => this._isGroupResult(item) ? item.items : [item]));
|
|
86
|
-
}
|
|
87
|
-
_isGroupResult(item) {
|
|
88
|
-
const object = item;
|
|
89
|
-
return object.items !== undefined && object.aggregates !== undefined && object.field !== undefined && object.value !== undefined;
|
|
90
|
-
}
|
|
91
|
-
isItemEqual(item1, item2) {
|
|
92
|
-
const isItem1Empty = item1 === null || item1 === undefined;
|
|
93
|
-
const isItem2Empty = item2 === null || item2 === undefined;
|
|
94
|
-
if (isItem1Empty && isItem2Empty) {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
if (isItem1Empty || isItem2Empty) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
return this.isPrimitiveValue ? item1 === item2 : item1[this.valueField] === item2[this.valueField];
|
|
101
|
-
}
|
|
102
|
-
constructor(changeDetectorRef, _renderer) {
|
|
103
|
-
super(changeDetectorRef);
|
|
104
|
-
this._renderer = _renderer;
|
|
105
|
-
this._debounceTime = 500;
|
|
106
|
-
this._debounceObserver = new Observer();
|
|
107
|
-
this._worker = new Worker();
|
|
108
|
-
this._additionalItems = new BehaviorSubject([]);
|
|
109
|
-
this._valueNormalizerItems = [];
|
|
110
|
-
this._isSync = false;
|
|
111
|
-
this._loadedItems = new BehaviorSubject([]);
|
|
112
|
-
this._hasSearched = new BehaviorSubject(false);
|
|
113
|
-
this._isSearching = new BehaviorSubject(false);
|
|
114
|
-
this._searchText = new BehaviorSubject('');
|
|
115
|
-
this.combinedItems = combineLatest([this._loadedItems, this._additionalItems]).pipe(map(([items, additionalItems]) => [...items, ...additionalItems].filter(Is.truthy)));
|
|
116
|
-
this.isSearchable = true;
|
|
117
|
-
this.minSearchCharacters = 1;
|
|
118
|
-
this.search = null;
|
|
119
|
-
this.areItemsCached = false;
|
|
120
|
-
this.searchSettings = {
|
|
121
|
-
isCaseSensitive: false,
|
|
122
|
-
operator: ComboboxSearchSettingsOperator.Contains,
|
|
123
|
-
};
|
|
124
|
-
this.isGroupable = false;
|
|
125
|
-
this.searched = new EventEmitter();
|
|
126
|
-
this.isNoItemsTextVisible = combineLatest([
|
|
127
|
-
this._isSearching,
|
|
128
|
-
this._hasSearched,
|
|
129
|
-
this._isFocused,
|
|
130
|
-
this.combinedItems,
|
|
131
|
-
]).pipe(map(([isSearching, hasSearched, isFocused, combinedItems]) => {
|
|
132
|
-
return !isSearching && hasSearched && isFocused && combinedItems.length === 0;
|
|
133
|
-
}));
|
|
134
|
-
this.isMinSearchTextVisible = combineLatest([
|
|
135
|
-
this._isSearching,
|
|
136
|
-
this._hasSearched,
|
|
137
|
-
this._isFocused,
|
|
138
|
-
]).pipe(map(([isSearching, hasSearched, isFocused]) => {
|
|
139
|
-
return !this._isSync && !isSearching && !hasSearched && isFocused;
|
|
140
|
-
}));
|
|
141
|
-
this.isLoadingSpinnerVisible = combineLatest([
|
|
142
|
-
this._isLoading,
|
|
143
|
-
this._isSearching,
|
|
144
|
-
]).pipe(map(([isLoading, isSearching]) => isLoading || isSearching));
|
|
145
|
-
// To show loading properly we are to use loadedItems as they don't include additionalItems.
|
|
146
|
-
this.isLoadingTextVisible = combineLatest([
|
|
147
|
-
this.isLoadingSpinnerVisible,
|
|
148
|
-
this._loadedItems,
|
|
149
|
-
]).pipe(map(([isLoadingSpinnerVisible, loadedItems]) => isLoadingSpinnerVisible && loadedItems.length === 0));
|
|
150
|
-
this.loadItems = (searchText) => {
|
|
151
|
-
searchText = (searchText || '').trim();
|
|
152
|
-
if (this._isSync) {
|
|
153
|
-
this._hasSearched.next(!!searchText);
|
|
154
|
-
this._loadedItems.next(this.searchItems(searchText));
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
if (this.canLoadItems(searchText)) {
|
|
158
|
-
this._isSearching.next(true);
|
|
159
|
-
this._worker.handle(this.search ? this.search(searchText) : new BehaviorSubject([]), (items) => {
|
|
160
|
-
this._hasSearched.next(true);
|
|
161
|
-
this._loadedItems.next(items);
|
|
162
|
-
this._valueNormalizerItems = [...items, ...this._additionalItems.value];
|
|
163
|
-
this._isSearching.next(false);
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
this._hasSearched.next(false);
|
|
168
|
-
this._loadedItems.next([]);
|
|
169
|
-
this._valueNormalizerItems = [];
|
|
170
|
-
this._isSearching.next(false);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
ngOnDestroy() {
|
|
176
|
-
this._debounceObserver.destroy();
|
|
177
|
-
this._worker.destroy();
|
|
178
|
-
super.ngOnDestroy();
|
|
179
|
-
}
|
|
180
|
-
init() {
|
|
181
|
-
super.init();
|
|
182
|
-
this._listenToSearched();
|
|
183
|
-
if (this._isSync) {
|
|
184
|
-
this._loadedItems.next(this._items);
|
|
185
|
-
}
|
|
186
|
-
// Closed.
|
|
187
|
-
this._observer.listen(this._isOpen.pipe(filter((event) => !event.isOpen), skip(1)), (event) => {
|
|
188
|
-
if (!this.areItemsCached && !this._isSync) {
|
|
189
|
-
this._loadedItems.next([]);
|
|
190
|
-
}
|
|
191
|
-
this._worker.cancel();
|
|
192
|
-
this._isSearching.next(false);
|
|
193
|
-
if (event.shouldEmit) {
|
|
194
|
-
this.closed.emit();
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
// Blurred.
|
|
198
|
-
this._observer.listen(this._isFocused.pipe(filter(isFalse)), () => {
|
|
199
|
-
// Restore original unfiltered items when the component is blurred
|
|
200
|
-
// after some search text entered. Consider a case:
|
|
201
|
-
// 1. Search with text that gives 0 items.
|
|
202
|
-
// 2. Blur and focus.
|
|
203
|
-
// 3. Search text is cleared, but items remain empty, so the list won't show up.
|
|
204
|
-
this._loadedItems.next(this._items);
|
|
205
|
-
this._hasSearched.next(false);
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
onSearched(searchText) {
|
|
209
|
-
this._searchText.next(searchText);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
AbstractComboboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AbstractComboboxComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
213
|
-
AbstractComboboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: AbstractComboboxComponent, selector: "ng-component", inputs: { isSearchable: "isSearchable", minSearchCharacters: "minSearchCharacters", search: "search", areItemsCached: "areItemsCached", debounceTime: "debounceTime", items: "items", additionalItems: "additionalItems", searchSettings: "searchSettings", isGroupable: "isGroupable" }, outputs: { searched: "searched" }, usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
214
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AbstractComboboxComponent, decorators: [{
|
|
215
|
-
type: Component,
|
|
216
|
-
args: [{
|
|
217
|
-
template: '',
|
|
218
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
219
|
-
}]
|
|
220
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: { isSearchable: [{
|
|
221
|
-
type: Input
|
|
222
|
-
}], minSearchCharacters: [{
|
|
223
|
-
type: Input
|
|
224
|
-
}], search: [{
|
|
225
|
-
type: Input
|
|
226
|
-
}], areItemsCached: [{
|
|
227
|
-
type: Input
|
|
228
|
-
}], debounceTime: [{
|
|
229
|
-
type: Input
|
|
230
|
-
}], items: [{
|
|
231
|
-
type: Input
|
|
232
|
-
}], additionalItems: [{
|
|
233
|
-
type: Input
|
|
234
|
-
}], searchSettings: [{
|
|
235
|
-
type: Input
|
|
236
|
-
}], isGroupable: [{
|
|
237
|
-
type: Input
|
|
238
|
-
}], searched: [{
|
|
239
|
-
type: Output
|
|
240
|
-
}] } });
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, Renderer2, } from '@angular/core';
|
|
2
|
+
import { isFalse, Is, Observer, Worker, flatten } from '@marcura/marcura-common';
|
|
3
|
+
import { combineLatest, BehaviorSubject } from 'rxjs';
|
|
4
|
+
import { debounceTime, distinctUntilChanged, filter, map, skip, tap } from 'rxjs/operators';
|
|
5
|
+
import { AbstractDropdownComponent } from '../../components/abstract-dropdown/abstract-dropdown.component';
|
|
6
|
+
import { ComboboxSearchSettingsOperator } from '../../model/combobox-search-settings-operator.enum';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
export class AbstractComboboxComponent extends AbstractDropdownComponent {
|
|
9
|
+
get debounceTime() {
|
|
10
|
+
return this._debounceTime;
|
|
11
|
+
}
|
|
12
|
+
set debounceTime(value) {
|
|
13
|
+
this._debounceTime = value;
|
|
14
|
+
this._listenToSearched();
|
|
15
|
+
}
|
|
16
|
+
get items() {
|
|
17
|
+
return this._items;
|
|
18
|
+
}
|
|
19
|
+
set items(items) {
|
|
20
|
+
this._isSync = true;
|
|
21
|
+
this._items = items || [];
|
|
22
|
+
this._listenToSearched();
|
|
23
|
+
this._loadedItems.next(this._items);
|
|
24
|
+
}
|
|
25
|
+
get additionalItems() {
|
|
26
|
+
return this._additionalItems.value;
|
|
27
|
+
}
|
|
28
|
+
set additionalItems(additionalItems) {
|
|
29
|
+
this._additionalItems.next(additionalItems || []);
|
|
30
|
+
}
|
|
31
|
+
_disableChromeAutocomplete() {
|
|
32
|
+
if (this._component.searchbar && this._component.searchbar.input) {
|
|
33
|
+
this._renderer.setAttribute(this._component.searchbar.input.nativeElement, 'autocomplete', 'disabled');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
_listenToSearched() {
|
|
37
|
+
this._debounceObserver.clear();
|
|
38
|
+
this._debounceObserver.listen(this._searchText.pipe(distinctUntilChanged(), skip(1), tap((searchText) => {
|
|
39
|
+
this.searched.emit(searchText);
|
|
40
|
+
this._isSearching.next(this.canLoadItems(searchText) && this._isOpen.value.isOpen);
|
|
41
|
+
}), debounceTime(this._isSync ? 0 : this.debounceTime), filter(() => this._isOpen.value.isOpen)), this.loadItems);
|
|
42
|
+
}
|
|
43
|
+
_filterItems(items, searchText) {
|
|
44
|
+
if (!items || !items.length) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
// TODO: technical-debt - fix group result case to avoid any
|
|
48
|
+
return items.filter((item) => {
|
|
49
|
+
let itemText = (item[this.textField] || '').toString().trim() ?? '';
|
|
50
|
+
itemText = this.searchSettings.isCaseSensitive ? itemText : itemText.toLowerCase();
|
|
51
|
+
return this.searchSettings.operator === ComboboxSearchSettingsOperator.Contains
|
|
52
|
+
? itemText.indexOf(searchText) !== -1
|
|
53
|
+
: itemText.substring(0, searchText.length) === searchText;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
_setComponent(component) {
|
|
57
|
+
this._component = component;
|
|
58
|
+
this._disableChromeAutocomplete();
|
|
59
|
+
}
|
|
60
|
+
searchItems(searchText) {
|
|
61
|
+
if (!this.searchSettings || !searchText || !this._items.length) {
|
|
62
|
+
return this._items;
|
|
63
|
+
}
|
|
64
|
+
searchText = this.searchSettings.isCaseSensitive ? searchText : searchText.toLowerCase();
|
|
65
|
+
if (this.isGroupable) {
|
|
66
|
+
const groups = this._items;
|
|
67
|
+
const filteredGroups = groups
|
|
68
|
+
.map((group) => ({
|
|
69
|
+
...group,
|
|
70
|
+
items: this._filterItems(group.items, searchText),
|
|
71
|
+
}))
|
|
72
|
+
.filter((group) => group.items.length > 0);
|
|
73
|
+
return filteredGroups;
|
|
74
|
+
}
|
|
75
|
+
return this._filterItems(this._items, searchText);
|
|
76
|
+
}
|
|
77
|
+
canLoadItems(searchText) {
|
|
78
|
+
return searchText.length >= this.minSearchCharacters && !this._isSync;
|
|
79
|
+
}
|
|
80
|
+
getItem(items, text) {
|
|
81
|
+
text = text.toLowerCase();
|
|
82
|
+
return this._unwrapGroups(items).find((item) => `${item[this.textField]}`.toLowerCase() === text) ?? null;
|
|
83
|
+
}
|
|
84
|
+
_unwrapGroups(items) {
|
|
85
|
+
return flatten(items.map(item => this._isGroupResult(item) ? item.items : [item]));
|
|
86
|
+
}
|
|
87
|
+
_isGroupResult(item) {
|
|
88
|
+
const object = item;
|
|
89
|
+
return object.items !== undefined && object.aggregates !== undefined && object.field !== undefined && object.value !== undefined;
|
|
90
|
+
}
|
|
91
|
+
isItemEqual(item1, item2) {
|
|
92
|
+
const isItem1Empty = item1 === null || item1 === undefined;
|
|
93
|
+
const isItem2Empty = item2 === null || item2 === undefined;
|
|
94
|
+
if (isItem1Empty && isItem2Empty) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
if (isItem1Empty || isItem2Empty) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return this.isPrimitiveValue ? item1 === item2 : item1[this.valueField] === item2[this.valueField];
|
|
101
|
+
}
|
|
102
|
+
constructor(changeDetectorRef, _renderer) {
|
|
103
|
+
super(changeDetectorRef);
|
|
104
|
+
this._renderer = _renderer;
|
|
105
|
+
this._debounceTime = 500;
|
|
106
|
+
this._debounceObserver = new Observer();
|
|
107
|
+
this._worker = new Worker();
|
|
108
|
+
this._additionalItems = new BehaviorSubject([]);
|
|
109
|
+
this._valueNormalizerItems = [];
|
|
110
|
+
this._isSync = false;
|
|
111
|
+
this._loadedItems = new BehaviorSubject([]);
|
|
112
|
+
this._hasSearched = new BehaviorSubject(false);
|
|
113
|
+
this._isSearching = new BehaviorSubject(false);
|
|
114
|
+
this._searchText = new BehaviorSubject('');
|
|
115
|
+
this.combinedItems = combineLatest([this._loadedItems, this._additionalItems]).pipe(map(([items, additionalItems]) => [...items, ...additionalItems].filter(Is.truthy)));
|
|
116
|
+
this.isSearchable = true;
|
|
117
|
+
this.minSearchCharacters = 1;
|
|
118
|
+
this.search = null;
|
|
119
|
+
this.areItemsCached = false;
|
|
120
|
+
this.searchSettings = {
|
|
121
|
+
isCaseSensitive: false,
|
|
122
|
+
operator: ComboboxSearchSettingsOperator.Contains,
|
|
123
|
+
};
|
|
124
|
+
this.isGroupable = false;
|
|
125
|
+
this.searched = new EventEmitter();
|
|
126
|
+
this.isNoItemsTextVisible = combineLatest([
|
|
127
|
+
this._isSearching,
|
|
128
|
+
this._hasSearched,
|
|
129
|
+
this._isFocused,
|
|
130
|
+
this.combinedItems,
|
|
131
|
+
]).pipe(map(([isSearching, hasSearched, isFocused, combinedItems]) => {
|
|
132
|
+
return !isSearching && hasSearched && isFocused && combinedItems.length === 0;
|
|
133
|
+
}));
|
|
134
|
+
this.isMinSearchTextVisible = combineLatest([
|
|
135
|
+
this._isSearching,
|
|
136
|
+
this._hasSearched,
|
|
137
|
+
this._isFocused,
|
|
138
|
+
]).pipe(map(([isSearching, hasSearched, isFocused]) => {
|
|
139
|
+
return !this._isSync && !isSearching && !hasSearched && isFocused;
|
|
140
|
+
}));
|
|
141
|
+
this.isLoadingSpinnerVisible = combineLatest([
|
|
142
|
+
this._isLoading,
|
|
143
|
+
this._isSearching,
|
|
144
|
+
]).pipe(map(([isLoading, isSearching]) => isLoading || isSearching));
|
|
145
|
+
// To show loading properly we are to use loadedItems as they don't include additionalItems.
|
|
146
|
+
this.isLoadingTextVisible = combineLatest([
|
|
147
|
+
this.isLoadingSpinnerVisible,
|
|
148
|
+
this._loadedItems,
|
|
149
|
+
]).pipe(map(([isLoadingSpinnerVisible, loadedItems]) => isLoadingSpinnerVisible && loadedItems.length === 0));
|
|
150
|
+
this.loadItems = (searchText) => {
|
|
151
|
+
searchText = (searchText || '').trim();
|
|
152
|
+
if (this._isSync) {
|
|
153
|
+
this._hasSearched.next(!!searchText);
|
|
154
|
+
this._loadedItems.next(this.searchItems(searchText));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
if (this.canLoadItems(searchText)) {
|
|
158
|
+
this._isSearching.next(true);
|
|
159
|
+
this._worker.handle(this.search ? this.search(searchText) : new BehaviorSubject([]), (items) => {
|
|
160
|
+
this._hasSearched.next(true);
|
|
161
|
+
this._loadedItems.next(items);
|
|
162
|
+
this._valueNormalizerItems = [...items, ...this._additionalItems.value];
|
|
163
|
+
this._isSearching.next(false);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this._hasSearched.next(false);
|
|
168
|
+
this._loadedItems.next([]);
|
|
169
|
+
this._valueNormalizerItems = [];
|
|
170
|
+
this._isSearching.next(false);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
ngOnDestroy() {
|
|
176
|
+
this._debounceObserver.destroy();
|
|
177
|
+
this._worker.destroy();
|
|
178
|
+
super.ngOnDestroy();
|
|
179
|
+
}
|
|
180
|
+
init() {
|
|
181
|
+
super.init();
|
|
182
|
+
this._listenToSearched();
|
|
183
|
+
if (this._isSync) {
|
|
184
|
+
this._loadedItems.next(this._items);
|
|
185
|
+
}
|
|
186
|
+
// Closed.
|
|
187
|
+
this._observer.listen(this._isOpen.pipe(filter((event) => !event.isOpen), skip(1)), (event) => {
|
|
188
|
+
if (!this.areItemsCached && !this._isSync) {
|
|
189
|
+
this._loadedItems.next([]);
|
|
190
|
+
}
|
|
191
|
+
this._worker.cancel();
|
|
192
|
+
this._isSearching.next(false);
|
|
193
|
+
if (event.shouldEmit) {
|
|
194
|
+
this.closed.emit();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
// Blurred.
|
|
198
|
+
this._observer.listen(this._isFocused.pipe(filter(isFalse)), () => {
|
|
199
|
+
// Restore original unfiltered items when the component is blurred
|
|
200
|
+
// after some search text entered. Consider a case:
|
|
201
|
+
// 1. Search with text that gives 0 items.
|
|
202
|
+
// 2. Blur and focus.
|
|
203
|
+
// 3. Search text is cleared, but items remain empty, so the list won't show up.
|
|
204
|
+
this._loadedItems.next(this._items);
|
|
205
|
+
this._hasSearched.next(false);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
onSearched(searchText) {
|
|
209
|
+
this._searchText.next(searchText);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
AbstractComboboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AbstractComboboxComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
213
|
+
AbstractComboboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: AbstractComboboxComponent, selector: "ng-component", inputs: { isSearchable: "isSearchable", minSearchCharacters: "minSearchCharacters", search: "search", areItemsCached: "areItemsCached", debounceTime: "debounceTime", items: "items", additionalItems: "additionalItems", searchSettings: "searchSettings", isGroupable: "isGroupable" }, outputs: { searched: "searched" }, usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: AbstractComboboxComponent, decorators: [{
|
|
215
|
+
type: Component,
|
|
216
|
+
args: [{
|
|
217
|
+
template: '',
|
|
218
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
219
|
+
}]
|
|
220
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: { isSearchable: [{
|
|
221
|
+
type: Input
|
|
222
|
+
}], minSearchCharacters: [{
|
|
223
|
+
type: Input
|
|
224
|
+
}], search: [{
|
|
225
|
+
type: Input
|
|
226
|
+
}], areItemsCached: [{
|
|
227
|
+
type: Input
|
|
228
|
+
}], debounceTime: [{
|
|
229
|
+
type: Input
|
|
230
|
+
}], items: [{
|
|
231
|
+
type: Input
|
|
232
|
+
}], additionalItems: [{
|
|
233
|
+
type: Input
|
|
234
|
+
}], searchSettings: [{
|
|
235
|
+
type: Input
|
|
236
|
+
}], isGroupable: [{
|
|
237
|
+
type: Input
|
|
238
|
+
}], searched: [{
|
|
239
|
+
type: Output
|
|
240
|
+
}] } });
|
|
241
241
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtY29tYm9ib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL2Fic3RyYWN0LWNvbWJvYm94L2Fic3RyYWN0LWNvbWJvYm94LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQXVCLE9BQU8sRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXBHLE9BQU8sRUFBQyxhQUFhLEVBQUUsZUFBZSxFQUFhLE1BQU0sTUFBTSxDQUFDO0FBQ2hFLE9BQU8sRUFBQyxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUYsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sZ0VBQWdFLENBQUM7QUFHekcsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sb0RBQW9ELENBQUM7O0FBUWxHLE1BQU0sT0FBTyx5QkFDWCxTQUFRLHlCQUFnRjtJQXVCeEYsSUFDVyxZQUFZO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBQ0QsSUFBVyxZQUFZLENBQUMsS0FBYTtRQUNuQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFDb0IsS0FBSztRQUN2QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUNELElBQW9CLEtBQUssQ0FBQyxLQUE0QjtR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O2lCQUNoRDtnSUFrQlEsWUFBWTtzQkFEbEIsS0FBSztnQkFHQyxtQkFBbUI7c0JBRHpCLEtBQUs7Z0JBR0MsTUFBTTtzQkFEWixLQUFLO2dCQUdDLGNBQWM7c0JBRHBCLEtBQUs7Z0JBR0ssWUFBWTtzQkFEdEIsS0FBSztnQkFTYyxLQUFLO3NCQUR4QixLQUFLO2dCQVdLLGVBQWU7c0JBRHpCLEtBQUs7Z0JBUUMsY0FBYztzQkFEcEIsS0FBSztnQkFNQyxXQUFXO3NCQURqQixLQUFLO2dCQUdDLFFBQVE7c0JBRGQsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29udHJvbFZhbHVlQWNjZXNzb3J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7aXNGYWxzZSwgSXMsIE9ic2VydmVyLCBXb3JrZXIsIENvbnRyb2xDaGFuZ2VkRXZlbnQsIGZsYXR0ZW59IGZyb20gJ0BtYXJjdXJhL21hcmN1cmEtY29tbW9uJztcbmltcG9ydCB7R3JvdXBSZXN1bHR9IGZyb20gJ0Bwcm9ncmVzcy9rZW5kby1kYXRhLXF1ZXJ5JztcbmltcG9ydCB7Y29tYmluZUxhdGVzdCwgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyLCBtYXAsIHNraXAsIHRhcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtBYnN0cmFjdERyb3Bkb3duQ29tcG9uZW50fSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2Fic3RyYWN0LWRyb3Bkb3duL2Fic3RyYWN0LWRyb3Bkb3duLmNvbXBvbmVudCc7XG5pbXBvcnQge0lDb21ib2JveEtlbmRvQ29tcG9uZW50fSBmcm9tICcuLi8uLi9tb2RlbC9jb21ib2JveC1rZW5kby1jb21wb25lbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7Q29tYm9ib3hTZWFyY2hGbn0gZnJvbSAnLi4vLi4vbW9kZWwvY29tYm9ib3gtc2VhcmNoLWZuLnR5cGUnO1xuaW1wb3J0IHtDb21ib2JveFNlYXJjaFNldHRpbmdzT3BlcmF0b3J9IGZyb20gJy4uLy4uL21vZGVsL2NvbWJvYm94LXNlYXJjaC1zZXR0aW5ncy1vcGVyYXRvci5lbnVtJztcbmltcG9ydCB7SUNvbWJvYm94U2VhcmNoU2V0dGluZ3N9IGZyb20gJy4uLy4uL21vZGVsL2NvbWJvYm94LXNlYXJjaC1zZXR0aW5ncy5pbnRlcmZhY2UnO1xuaW1wb3J0IHtDb21ib2JveEl0ZW19IGZyb20gJy4uLy4uL21vZGVsL2NvbWJvYm94LWl0ZW0udHlwZSc7XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogJycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBBYnN0cmFjdENvbWJvYm94Q29tcG9uZW50PFRJdGVtLCBUVmFsdWUsIFRDaGFuZ2VkRXZlbnQgZXh0ZW5kcyBDb250cm9sQ2hhbmdlZEV2ZW50PFRWYWx1ZT4gPSBDb250cm9sQ2hhbmdlZEV2ZW50PFRWYWx1ZT4+XG4gIGV4dGVuZHMgQWJzdHJhY3REcm9wZG93bkNvbXBvbmVudDxUSXRlbSwgVFZhbHVlLCBJQ29tYm9ib3hLZW5kb0NvbXBvbmVudCwgVENoYW5nZWRFdmVudD5cbiAgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBfZGVib3VuY2VUaW1lOiBudW1iZXIgPSA1MDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlYm91bmNlT2JzZXJ2ZXI6IE9ic2VydmVyID0gbmV3IE9ic2VydmVyKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3dvcmtlcjogV29ya2VyID0gbmV3IFdvcmtlcigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9hZGRpdGlvbmFsSXRlbXM6IEJlaGF2aW9yU3ViamVjdDxDb21ib2JveEl0ZW08VEl0ZW0+W10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDb21ib2JveEl0ZW08VEl0ZW0+W10+KFtdKTtcbiAgcHJvdGVjdGVkIF92YWx1ZU5vcm1hbGl6ZXJJdGVtczogKFRJdGVtIHwgR3JvdXBSZXN1bHQpW10gPSBbXTtcbiAgcHJvdGVjdGVkIF9pc1N5bmM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9sb2FkZWRJdGVtczogQmVoYXZpb3JTdWJqZWN0PENvbWJvYm94SXRlbTxUSXRlbT5bXT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENvbWJvYm94SXRlbTxUSXRlbT5bXT4oW10pO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2hhc1NlYXJjaGVkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9pc1NlYXJjaGluZzogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc2VhcmNoVGV4dDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KCcnKTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbWJpbmVkSXRlbXM6IE9ic2VydmFibGU8KFRJdGVtIHwgR3JvdXBSZXN1bHQpW10+ID0gY29tYmluZUxhdGVzdChbdGhpcy5fbG9hZGVkSXRlbXMsIHRoaXMuX2FkZGl0aW9uYWxJdGVtc10pLnBpcGUoXG4gICAgbWFwKChbaXRlbXMsIGFkZGl0aW9uYWxJdGVtc10pOiAoVEl0ZW0gfCBHcm91cFJlc3VsdClbXSA9PiBbLi4uaXRlbXMsIC4uLmFkZGl0aW9uYWxJdGVtc10uZmlsdGVyKElzLnRydXRoeSkgYXMgKFRJdGVtIHwgR3JvdXBSZXN1bHQpW10pXG4gICk7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBpc1NlYXJjaGFibGU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKVxuICBwdWJsaWMgbWluU2VhcmNoQ2hhcmFjdGVyczogbnVtYmVyID0gMTtcbiAgQElucHV0KClcbiAgcHVibGljIHNlYXJjaDogQ29tYm9ib3hTZWFyY2hGbjxUSXRlbT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KClcbiAgcHVibGljIGFyZUl0ZW1zQ2FjaGVkOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBnZXQgZGVib3VuY2VUaW1lKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2RlYm91bmNlVGltZTtcbiAgfVxuICBwdWJsaWMgc2V0IGRlYm91bmNlVGltZSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fZGVib3VuY2VUaW1lID0gdmFsdWU7XG4gICAgdGhpcy5fbGlzdGVuVG9TZWFyY2hlZCgpO1xuICB9XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBvdmVycmlkZSBnZXQgaXRlbXMoKTogQ29tYm9ib3hJdGVtPFRJdGVtPltdIHtcbiAgICByZXR1cm4gdGhpcy5faXRlbXM7XG4gIH1cbiAgcHVibGljIG92ZXJyaWRlIHNldCBpdGVtcyhpdGVtczogQ29tYm9ib3hJdGVtPFRJdGVtPltdKSB7XG4gICAgdGhpcy5faXNTeW5jID0gdHJ1ZTtcbiAgICB0aGlzLl9pdGVtcyA9IGl0ZW1zIHx8IFtdO1xuICAgIHRoaXMuX2xpc3RlblRvU2VhcmNoZWQoKTtcbiAgICB0aGlzLl9sb2FkZWRJdGVtcy5uZXh0KHRoaXMuX2l0ZW1zKTtcbiAgfVxuICBASW5wdXQoKVxuICBwdWJsaWMgZ2V0IGFkZGl0aW9uYWxJdGVtcygpOiBDb21ib2JveEl0ZW08VEl0ZW0+W10ge1xuICAgIHJldHVybiB0aGlzLl9hZGRpdGlvbmFsSXRlbXMudmFsdWU7XG4gIH1cbiAgcHVibGljIHNldCBhZGRpdGlvbmFsSXRlbXMoYWRkaXRpb25hbEl0ZW1zOiBDb21ib2JveEl0ZW08VEl0ZW0+W10pIHtcbiAgICB0aGlzLl9hZGRpdGlvbmFsSXRlbXMubmV4dChhZGRpdGlvbmFsSXRlbXMgfHwgW10pO1xuICB9XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZWFyY2hTZXR0aW5nczogSUNvbWJvYm94U2VhcmNoU2V0dGluZ3MgPSB7XG4gICAgaXNDYXNlU2Vuc2l0aXZlOiBmYWxzZSxcbiAgICBvcGVyYXRvcjogQ29tYm9ib3hTZWFyY2hTZXR0aW5nc09wZXJhdG9yLkNvbnRhaW5zLFxuICB9O1xuICBASW5wdXQoKVxuICBwdWJsaWMgaXNHcm91cGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQE91dHB1dCgpXG4gIHB1YmxpYyBzZWFyY2hlZDogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIHB1YmxpYyByZWFkb25seSBpc05vSXRlbXNUZXh0VmlzaWJsZTogT2JzZXJ2YWJsZTxib29sZWFuPiA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuX2lzU2VhcmNoaW5nLFxuICAgIHRoaXMuX2hhc1NlYXJjaGVkLFxuICAgIHRoaXMuX2lzRm9jdXNlZCxcbiAgICB0aGlzLmNvbWJpbmVkSXRlbXMsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbaXNTZWFyY2hpbmcsIGhhc1NlYXJjaGVkLCBpc0ZvY3VzZWQsIGNvbWJpbmVkSXRlbXNdKSA9PiB7XG4gICAgICByZXR1cm4gIWlzU2VhcmNoaW5nICYmIGhhc1NlYXJjaGVkICYmIGlzRm9jdXNlZCAmJiBjb21iaW5lZEl0ZW1zLmxlbmd0aCA9PT0gMDtcbiAgICB9KVxuICApO1xuICBwdWJsaWMgcmVhZG9ubHkgaXNNaW5TZWFyY2hUZXh0VmlzaWJsZTogT2JzZXJ2YWJsZTxib29sZWFuPiA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuX2lzU2VhcmNoaW5nLFxuICAgIHRoaXMuX2hhc1NlYXJjaGVkLFxuICAgIHRoaXMuX2lzRm9jdXNlZCxcbiAgXSkucGlwZShcbiAgICBtYXAoKFtpc1NlYXJjaGluZywgaGFzU2VhcmNoZWQsIGlzRm9jdXNlZF0pID0+IHtcbiAgICAgIHJldHVybiAhdGhpcy5faXNTeW5jICYmICFpc1NlYXJjaGluZyAmJiAhaGFzU2VhcmNoZWQgJiYgaXNGb2N1c2VkO1xuICAgIH0pXG4gICk7XG4gIHB1YmxpYyByZWFkb25seSBpc0xvYWRpbmdTcGlubmVyVmlzaWJsZTogT2JzZXJ2YWJsZTxib29sZWFuPiA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuX2lzTG9hZGluZyxcbiAgICB0aGlzLl9pc1NlYXJjaGluZyxcbiAgXSkucGlwZShtYXAoKFtpc0xvYWRpbmcsIGlzU2VhcmNoaW5nXSkgPT4gaXNMb2FkaW5nIHx8IGlzU2VhcmNoaW5nKSk7XG4gIC8vIFRvIHNob3cgbG9hZGluZyBwcm9wZXJseSB3ZSBhcmUgdG8gdXNlIGxvYWRlZEl0ZW1zIGFzIHRoZXkgZG9uJ3QgaW5jbHVkZSBhZGRpdGlvbmFsSXRlbXMuXG4gIHB1YmxpYyByZWFkb25seSBpc0xvYWRpbmdUZXh0VmlzaWJsZTogT2JzZXJ2YWJsZTxib29sZWFuPiA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuaXNMb2FkaW5nU3Bpbm5lclZpc2libGUsXG4gICAgdGhpcy5fbG9hZGVkSXRlbXMsXG4gIF0pLnBpcGUobWFwKChbaXNMb2FkaW5nU3Bpbm5lclZpc2libGUsIGxvYWRlZEl0ZW1zXSkgPT4gaXNMb2FkaW5nU3Bpbm5lclZpc2libGUgJiYgbG9hZGVkSXRlbXMubGVuZ3RoID09PSAwKSk7XG5cbiAgcHJpdmF0ZSBfZGlzYWJsZUNocm9tZUF1dG9jb21wbGV0ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fY29tcG9uZW50LnNlYXJjaGJhciAmJiB0aGlzLl9jb21wb25lbnQuc2VhcmNoYmFyLmlucHV0KSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5fY29tcG9uZW50LnNlYXJjaGJhci5pbnB1dC5uYXRpdmVFbGVtZW50LCAnYXV0b2NvbXBsZXRlJywgJ2Rpc2FibGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbGlzdGVuVG9TZWFyY2hlZCgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZWJvdW5jZU9ic2VydmVyLmNsZWFyKCk7XG4gICAgdGhpcy5fZGVib3VuY2VPYnNlcnZlci5saXN0ZW4oXG4gICAgICB0aGlzLl9zZWFyY2hUZXh0LnBpcGUoXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgIHNraXAoMSksXG4gICAgICAgIHRhcCgoc2VhcmNoVGV4dCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2VhcmNoZWQuZW1pdChzZWFyY2hUZXh0KTtcbiAgICAgICAgICB0aGlzLl9pc1NlYXJjaGluZy5uZXh0KHRoaXMuY2FuTG9hZEl0ZW1zKHNlYXJjaFRleHQpICYmIHRoaXMuX2lzT3Blbi52YWx1ZS5pc09wZW4pO1xuICAgICAgICB9KSxcbiAgICAgICAgZGVib3VuY2VUaW1lKHRoaXMuX2lzU3luYyA/IDAgOiB0aGlzLmRlYm91bmNlVGltZSksXG4gICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLl9pc09wZW4udmFsdWUuaXNPcGVuKVxuICAgICAgKSxcbiAgICAgIHRoaXMubG9hZEl0ZW1zXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2ZpbHRlckl0ZW1zKGl0ZW1zOiBDb21ib2JveEl0ZW08VEl0ZW0+W10sIHNlYXJjaFRleHQ6IHN0cmluZyk6IFRJdGVtW10ge1xuICAgIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHRlY2huaWNhbC1kZWJ0IC0gZml4IGdyb3VwIHJlc3VsdCBjYXNlIHRvIGF2b2lkIGFueVxuICAgIHJldHVybiAoaXRlbXMgYXMgYW55W10pLmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgbGV0IGl0ZW1UZXh0OiBzdHJpbmcgPSAoaXRlbVt0aGlzLnRleHRGaWVsZF0gfHwgJycpLnRvU3RyaW5nKCkudHJpbSgpID8/ICcnO1xuICAgICAgaXRlbVRleHQgPSB0aGlzLnNlYXJjaFNldHRpbmdzLmlzQ2FzZVNlbnNpdGl2ZSA/IGl0ZW1UZXh0IDogaXRlbVRleHQudG9Mb3dlckNhc2UoKTtcblxuICAgICAgcmV0dXJuIHRoaXMuc2VhcmNoU2V0dGluZ3Mub3BlcmF0b3IgPT09IENvbWJvYm94U2VhcmNoU2V0dGluZ3NPcGVyYXRvci5Db250YWluc1xuICAgICAgICA/IGl0ZW1UZXh0LmluZGV4T2Yoc2VhcmNoVGV4dCkgIT09IC0xXG4gICAgICAgIDogaXRlbVRleHQuc3Vic3RyaW5nKDAsIHNlYXJjaFRleHQubGVuZ3RoKSA9PT0gc2VhcmNoVGV4dDtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBfc2V0Q29tcG9uZW50KGNvbXBvbmVudDogSUNvbWJvYm94S2VuZG9Db21wb25lbnQpOiB2b2lkIHtcbiAgICB0aGlzLl9jb21wb25lbnQgPSBjb21wb25lbnQ7XG4gICAgdGhpcy5fZGlzYWJsZUNocm9tZUF1dG9jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNlYXJjaEl0ZW1zKHNlYXJjaFRleHQ6IHN0cmluZyk6IENvbWJvYm94SXRlbTxUSXRlbT5bXSB7XG4gICAgaWYgKCF0aGlzLnNlYXJjaFNldHRpbmdzIHx8ICFzZWFyY2hUZXh0IHx8ICF0aGlzLl9pdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVtcztcbiAgICB9XG5cbiAgICBzZWFyY2hUZXh0ID0gdGhpcy5zZWFyY2hTZXR0aW5ncy5pc0Nhc2VTZW5zaXRpdmUgPyBzZWFyY2hUZXh0IDogc2VhcmNoVGV4dC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKHRoaXMuaXNHcm91cGFibGUpIHtcbiAgICAgIGNvbnN0IGdyb3VwczogR3JvdXBSZXN1bHRbXSA9IDxhbnk+dGhpcy5faXRlbXM7XG4gICAgICBjb25zdCBmaWx0ZXJlZEdyb3VwczogR3JvdXBSZXN1bHRbXSA9IGdyb3Vwc1xuICAgICAgICAubWFwKChncm91cCk6IEdyb3VwUmVzdWx0ID0+ICh7XG4gICAgICAgICAgLi4uZ3JvdXAsXG4gICAgICAgICAgaXRlbXM6IHRoaXMuX2ZpbHRlckl0ZW1zKDxUSXRlbVtdPmdyb3VwLml0ZW1zLCBzZWFyY2hUZXh0KSBhcyBhbnksXG4gICAgICAgIH0pKVxuICAgICAgICAuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAuaXRlbXMubGVuZ3RoID4gMCk7XG5cbiAgICAgIHJldHVybiA8YW55PmZpbHRlcmVkR3JvdXBzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9maWx0ZXJJdGVtcyh0aGlzLl9pdGVtcywgc2VhcmNoVGV4dCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2FuTG9hZEl0ZW1zKHNlYXJjaFRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzZWFyY2hUZXh0Lmxlbmd0aCA+PSB0aGlzLm1pblNlYXJjaENoYXJhY3RlcnMgJiYgIXRoaXMuX2lzU3luYztcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRJdGVtKGl0ZW1zOiAoVEl0ZW0gfCBHcm91cFJlc3VsdClbXSwgdGV4dDogc3RyaW5nKTogVEl0ZW0gfCBudWxsIHtcbiAgICB0ZXh0ID0gdGV4dC50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiB0aGlzLl91bndyYXBHcm91cHMoaXRlbXMpLmZpbmQoKGl0ZW0pID0+IGAke2l0ZW1bdGhpcy50ZXh0RmllbGRdfWAudG9Mb3dlckNhc2UoKSA9PT0gdGV4dCkgPz8gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX3Vud3JhcEdyb3VwcyhpdGVtczogKFRJdGVtIHwgR3JvdXBSZXN1bHQpW10pOiBUSXRlbVtdIHtcbiAgICByZXR1cm4gZmxhdHRlbihcbiAgICAgIGl0ZW1zLm1hcChpdGVtID0+IHRoaXMuX2lzR3JvdXBSZXN1bHQoaXRlbSkgPyBpdGVtLml0ZW1zIGFzIFRJdGVtW10gOiBbaXRlbV0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2lzR3JvdXBSZXN1bHQoaXRlbTogVEl0ZW0gfCBHcm91cFJlc3VsdCk6IGl0ZW0gaXMgR3JvdXBSZXN1bHQge1xuICAgIGNvbnN0IG9iamVjdDogYW55ID0gaXRlbTtcbiAgICByZXR1cm4gb2JqZWN0Lml0ZW1zICE9PSB1bmRlZmluZWQgJiYgb2JqZWN0LmFnZ3JlZ2F0ZXMgIT09IHVuZGVmaW5lZCAmJiBvYmplY3QuZmllbGQgIT09IHVuZGVmaW5lZCAmJiBvYmplY3QudmFsdWUgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBpc0l0ZW1FcXVhbChpdGVtMTogVEl0ZW0gfCBudWxsIHwgdW5kZWZpbmVkLCBpdGVtMjogVEl0ZW0gfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaXNJdGVtMUVtcHR5OiBib29sZWFuID0gaXRlbTEgPT09IG51bGwgfHwgaXRlbTEgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBpc0l0ZW0yRW1wdHk6IGJvb2xlYW4gPSBpdGVtMiA9PT0gbnVsbCB8fCBpdGVtMiA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzSXRlbTFFbXB0eSAmJiBpc0l0ZW0yRW1wdHkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpc0l0ZW0xRW1wdHkgfHwgaXNJdGVtMkVtcHR5KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuaXNQcmltaXRpdmVWYWx1ZSA/IGl0ZW0xID09PSBpdGVtMiA6IGl0ZW0xIVt0aGlzLnZhbHVlRmllbGRdID09PSBpdGVtMiFbdGhpcy52YWx1ZUZpZWxkXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBsb2FkSXRlbXMgPSAoc2VhcmNoVGV4dD86IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIHNlYXJjaFRleHQgPSAoc2VhcmNoVGV4dCB8fCAnJykudHJpbSgpO1xuXG4gICAgaWYgKHRoaXMuX2lzU3luYykge1xuICAgICAgdGhpcy5faGFzU2VhcmNoZWQubmV4dCghIXNlYXJjaFRleHQpO1xuICAgICAgdGhpcy5fbG9hZGVkSXRlbXMubmV4dCh0aGlzLnNlYXJjaEl0ZW1zKHNlYXJjaFRleHQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuY2FuTG9hZEl0ZW1zKHNlYXJjaFRleHQpKSB7XG4gICAgICAgIHRoaXMuX2lzU2VhcmNoaW5nLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuX3dvcmtlci5oYW5kbGUodGhpcy5zZWFyY2ggPyB0aGlzLnNlYXJjaChzZWFyY2hUZXh0KSA6IG5ldyBCZWhhdmlvclN1YmplY3QoW10pLCAoaXRlbXMpID0+IHtcbiAgICAgICAgICB0aGlzLl9oYXNTZWFyY2hlZC5uZXh0KHRydWUpO1xuICAgICAgICAgIHRoaXMuX2xvYWRlZEl0ZW1zLm5leHQoaXRlbXMpO1xuICAgICAgICAgIHRoaXMuX3ZhbHVlTm9ybWFsaXplckl0ZW1zID0gWy4uLml0ZW1zLCAuLi50aGlzLl9hZGRpdGlvbmFsSXRlbXMudmFsdWVdIGFzIChUSXRlbSB8IEdyb3VwUmVzdWx0KVtdO1xuICAgICAgICAgIHRoaXMuX2lzU2VhcmNoaW5nLm5leHQoZmFsc2UpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2hhc1NlYXJjaGVkLm5leHQoZmFsc2UpO1xuICAgICAgICB0aGlzLl9sb2FkZWRJdGVtcy5uZXh0KFtdKTtcbiAgICAgICAgdGhpcy5fdmFsdWVOb3JtYWxpemVySXRlbXMgPSBbXTtcbiAgICAgICAgdGhpcy5faXNTZWFyY2hpbmcubmV4dChmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByb3RlY3RlZCByZWFkb25seSBfcmVuZGVyZXI6IFJlbmRlcmVyMikge1xuICAgIHN1cGVyKGNoYW5nZURldGVjdG9yUmVmKTtcbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZSBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZWJvdW5jZU9ic2VydmVyLmRlc3Ryb3koKTtcbiAgICB0aGlzLl93b3JrZXIuZGVzdHJveSgpO1xuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgaW5pdCgpOiB2b2lkIHtcbiAgICBzdXBlci5pbml0KCk7XG4gICAgdGhpcy5fbGlzdGVuVG9TZWFyY2hlZCgpO1xuXG4gICAgaWYgKHRoaXMuX2lzU3luYykge1xuICAgICAgdGhpcy5fbG9hZGVkSXRlbXMubmV4dCh0aGlzLl9pdGVtcyk7XG4gICAgfVxuXG4gICAgLy8gQ2xvc2VkLlxuICAgIHRoaXMuX29ic2VydmVyLmxpc3RlbihcbiAgICAgIHRoaXMuX2lzT3Blbi5waXBlKFxuICAgICAgICBmaWx0ZXIoKGV2ZW50KSA9PiAhZXZlbnQuaXNPcGVuKSxcbiAgICAgICAgc2tpcCgxKVxuICAgICAgKSxcbiAgICAgIChldmVudCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuYXJlSXRlbXNDYWNoZWQgJiYgIXRoaXMuX2lzU3luYykge1xuICAgICAgICAgIHRoaXMuX2xvYWRlZEl0ZW1zLm5leHQoW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fd29ya2VyLmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl9pc1NlYXJjaGluZy5uZXh0KGZhbHNlKTtcblxuICAgICAgICBpZiAoZXZlbnQuc2hvdWxkRW1pdCkge1xuICAgICAgICAgIHRoaXMuY2xvc2VkLmVtaXQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBCbHVycmVkLlxuICAgIHRoaXMuX29ic2VydmVyLmxpc3Rlbih0aGlzLl9pc0ZvY3VzZWQucGlwZShmaWx0ZXIoaXNGYWxzZSkpLCAoKSA9PiB7XG4gICAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIHVuZmlsdGVyZWQgaXRlbXMgd2hlbiB0aGUgY29tcG9uZW50IGlzIGJsdXJyZWRcbiAgICAgIC8vIGFmdGVyIHNvbWUgc2VhcmNoIHRleHQgZW50ZXJlZC4gQ29uc2lkZXIgYSBjYXNlOlxuICAgICAgLy8gMS4gU2VhcmNoIHdpdGggdGV4dCB0aGF0IGdpdmVzIDAgaXRlbXMuXG4gICAgICAvLyAyLiBCbHVyIGFuZCBmb2N1cy5cbiAgICAgIC8vIDMuIFNlYXJjaCB0ZXh0IGlzIGNsZWFyZWQsIGJ1dCBpdGVtcyByZW1haW4gZW1wdHksIHNvIHRoZSBsaXN0IHdvbid0IHNob3cgdXAuXG4gICAgICB0aGlzLl9sb2FkZWRJdGVtcy5uZXh0KHRoaXMuX2l0ZW1zKTtcbiAgICAgIHRoaXMuX2hhc1NlYXJjaGVkLm5leHQoZmFsc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uU2VhcmNoZWQoc2VhcmNoVGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fc2VhcmNoVGV4dC5uZXh0KHNlYXJjaFRleHQpO1xuICB9XG59XG4iXX0=
|