UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

210 lines 30.7 kB
/** * Copyright (c) 2025 Visa, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ import { Injectable } from '@angular/core'; import { AppReadyService } from '../_utilities/services/app-stable-check.service'; import { ComboboxFilterType } from './combobox.constants'; import * as i0 from "@angular/core"; import * as i1 from "../_utilities/services/app-stable-check.service"; /** * Service containing optional functions for the ComboboxDirective. */ export class ComboboxService { constructor(appReadyService) { this.appReadyService = appReadyService; } /** * The closeMenuOnItemClick method automatically closes the menu when an item is selected. <br /> * To keep the menu open after an item is selected, you must provide <code>[closeOnClick]="false"</code> to the combobox component. * @param combobox Combobox to apply behavior to. */ closeMenuOnItemClick(combobox) { combobox.listbox?.listItems?.forEach((item) => { item.clicked.subscribe(() => { combobox.floatingContainer?.floatingUIService?.hidefloatingUI(); }); }); // subscribe to changes in items and apply service function to these items as well combobox.listbox?.listItems?.changes.subscribe(() => { combobox.listbox?.listItems.forEach((item) => { item.clicked.subscribe(() => { combobox.floatingContainer?.floatingUIService?.hidefloatingUI(); }); }); }); } /** * The selectHighlightedOnMenuClose method selects the last highlighted item when the menu is closed. * This method is called by default within <code>autoSelectItem</code>. <br /> * @param combobox Combobox to apply behavior to. */ selectHighlightedOnMenuClose(combobox) { combobox.floatingContainer?.floatingUIService?.isShownEmitter.subscribe((isShown) => { if (!this.appReadyService.isBrowserAndDomAvailable()) return; // return if app is not ready to access nativeElement if (!isShown && combobox._lastHighlightedOnClose !== null) { combobox.selectItem(combobox._lastHighlightedOnClose); } }); } /** * The autoFilterDisplayedItems method automatically filters the items shown in the combobox on initial render. * If the items displayed on page load are not the full list you want to filter, please use a different function. This method filters items based on selection and input value changes. <br /> * To access the filtered list of <code>ListboxItemsDirective[]</code>, subscribe to the <code>filteredListEmitter</code>. * @param combobox Combobox to apply behavior to. */ autoFilterDisplayedItems(combobox) { if (!combobox.input || !combobox.listbox) return; let filteredListItems = []; // filter list with defaultValue if (combobox.value) { if (combobox.listbox?.multiselect) { combobox.value['value'].forEach((selectedValue) => { const selectedItem = combobox.initialListItems.find((item) => item.value === selectedValue); if (selectedItem) { filteredListItems.push(selectedItem); // combobox._prevActiveItem = selectedItem; } }); // don't update list on initial render for multiselect, only on input } else { const selectedItem = combobox.initialListItems.find((item) => item.value === combobox.value['value']); if (selectedItem) { filteredListItems.push(selectedItem); combobox._prevActiveItem = selectedItem; } this.updateList(combobox, filteredListItems); } } combobox.input.inputEvent.subscribe((value) => { if (!this.appReadyService.isBrowserAndDomAvailable()) return; // return if app is not ready to access nativeElement // input value filteredListItems = []; combobox.initialListItems.forEach((item) => { if (item.el.nativeElement.innerText.trim().toLowerCase().includes(value.toLowerCase())) { // keep item in list if it includes the input value filteredListItems.push(item); } }); this.updateList(combobox, filteredListItems); }); combobox.itemSelected.subscribe((value) => { if (combobox.listbox?.multiselect) { // reset list on multiselect when option is selected filteredListItems = combobox.initialListItems; // if (filteredListItems && filteredListItems.length > 0) // combobox._prevActiveItem = filteredListItems[filteredListItems.length - 1]; } else { // listbox item value filteredListItems = []; const selectedItem = combobox.initialListItems.find((item) => value?.includes(item.value)); if (selectedItem) { filteredListItems.push(selectedItem); combobox._prevActiveItem = selectedItem; } if (selectedItem) filteredListItems.push(selectedItem); } this.updateList(combobox, filteredListItems); }); } /** * The autoFilterBasedOnList method filters items in the combobox based on a specified list, which can differ from the initial list rendered. <br /> * This method allows customization of the filtering criteria, enabling you to filter items based on properties such as id, label, value, etc. To access the filtered list, subscribe to <code>the filteredListEmitter</code>, which emits the filtered list in the same shape as <code>fullList</code>. <br /> * This method is recommended over <code>autoFilterDisplayedItems</code> and can achieve the same functionality by calling <code>autoFilterBasedOnList(combobox, list, 'label')</code>. * @param combobox Combobox to apply filter function to. * @param fullList Full list of items to filter. * @param condition Condition on which to filter items in fullList (this would be a property you've provided to the items in fullList). */ autoFilterBasedOnList(combobox, fullList, condition) { const listData = fullList; let filteredData = fullList; if (!combobox) return; combobox.filter.subscribe((filterEvent) => { filteredData = []; if (filterEvent.type === ComboboxFilterType.SELECTION) { if (combobox.listbox?.multiselect) { filteredData = listData; // if (filteredData && filteredData.length > 0) combobox._prevActiveItem = filteredData[filteredData.length - 1]; } else { // if an item is selected, the list should only include that item filteredData = listData?.filter((item) => item[condition].toLowerCase() == filterEvent.input.toLowerCase()); if (filteredData && filteredData.length === 1) combobox._prevActiveItem = filteredData[0]; } } else if (filterEvent.type === ComboboxFilterType.INPUT) { listData.forEach((item) => { if (item[condition].toLowerCase().includes(filterEvent.input.toLowerCase())) filteredData.push(item); }); } else if (filterEvent.type === ComboboxFilterType.RESET) { filteredData = listData; } this.updateList(combobox, filteredData); }); } /** * The updateList method updates the combobox component with the given filtered list items, setting the active and highlighted index appropriately. <br /> * This method is called by default within <code>autoFilterDisplayedItems</code> and <code>autoFilterBasedOnList</code>. * @param combobox Combobox to update. * @param filteredListItems Filtered array of listbox items. */ updateList(combobox, filteredListItems) { if (combobox.listbox?.multiselect) { // reset multiselect keyboard traversal altogether combobox._activeIndex = null; combobox._highlightedIndex = null; } else if (combobox._prevActiveItem && filteredListItems.includes(combobox._prevActiveItem)) { combobox._activeIndex = filteredListItems.findIndex((item) => item === combobox._prevActiveItem); } else { combobox._activeIndex = null; combobox._highlightedIndex = null; } combobox.filteredListEmitter.emit(filteredListItems); } /** * The autoSelectItem method highlights the first list item based on user input. <br /> * This ensures that when the menu closes, if an input value was entered, an item is selected. * @param combobox Combobox to apply automatic selection to. */ autoSelectItem(combobox) { this.selectHighlightedOnMenuClose(combobox); combobox.input?.inputEvent.subscribe(() => { if (combobox.input.value) combobox.highlightIndex(0); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxService, deps: [{ token: i1.AppReadyService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.AppReadyService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm9ib3guc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbm92YS1saWIvc3JjL2xpYi9jb21ib2JveC9jb21ib2JveC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7SUFlSTtBQUNKLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlEQUFpRCxDQUFDO0FBRWxGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7QUFHMUQ7O0dBRUc7QUFJSCxNQUFNLE9BQU8sZUFBZTtJQUMxQixZQUFvQixlQUFnQztRQUFoQyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7SUFBRyxDQUFDO0lBQ3hEOzs7O09BSUc7SUFDSCxvQkFBb0IsQ0FBQyxRQUEyQjtRQUM5QyxRQUFRLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQzFCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsQ0FBQztZQUNsRSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsa0ZBQWtGO1FBQ2xGLFFBQVEsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2xELFFBQVEsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7b0JBQzFCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsQ0FBQztn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TTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICAgICAgICAgICAgICBDb3B5cmlnaHQgKGMpIDIwMjUgVmlzYSwgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICoqL1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXBwUmVhZHlTZXJ2aWNlIH0gZnJvbSAnLi4vX3V0aWxpdGllcy9zZXJ2aWNlcy9hcHAtc3RhYmxlLWNoZWNrLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGlzdGJveEl0ZW1Db21wb25lbnQgfSBmcm9tICcuLi9saXN0Ym94LWl0ZW0vbGlzdGJveC1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21ib2JveEZpbHRlclR5cGUgfSBmcm9tICcuL2NvbWJvYm94LmNvbnN0YW50cyc7XG5pbXBvcnQgeyBDb21ib2JveERpcmVjdGl2ZSB9IGZyb20gJy4vY29tYm9ib3guZGlyZWN0aXZlJztcblxuLyoqXG4gKiBTZXJ2aWNlIGNvbnRhaW5pbmcgb3B0aW9uYWwgZnVuY3Rpb25zIGZvciB0aGUgQ29tYm9ib3hEaXJlY3RpdmUuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIENvbWJvYm94U2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwUmVhZHlTZXJ2aWNlOiBBcHBSZWFkeVNlcnZpY2UpIHt9XG4gIC8qKlxuICAgKiBUaGXCoGNsb3NlTWVudU9uSXRlbUNsaWNrwqBtZXRob2QgYXV0b21hdGljYWxseSBjbG9zZXMgdGhlIG1lbnUgd2hlbiBhbiBpdGVtIGlzIHNlbGVjdGVkLiA8YnIgLz5cbiAgICogVG8ga2VlcCB0aGUgbWVudSBvcGVuIGFmdGVyIGFuIGl0ZW0gaXMgc2VsZWN0ZWQsIHlvdSBtdXN0IHByb3ZpZGUgPGNvZGU+W2Nsb3NlT25DbGlja109XCJmYWxzZVwiPC9jb2RlPiB0byB0aGUgY29tYm9ib3ggY29tcG9uZW50LlxuICAgKiBAcGFyYW0gY29tYm9ib3ggQ29tYm9ib3ggdG8gYXBwbHkgYmVoYXZpb3IgdG8uXG4gICAqL1xuICBjbG9zZU1lbnVPbkl0ZW1DbGljayhjb21ib2JveDogQ29tYm9ib3hEaXJlY3RpdmUpIHtcbiAgICBjb21ib2JveC5saXN0Ym94Py5saXN0SXRlbXM/LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGl0ZW0uY2xpY2tlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBjb21ib2JveC5mbG9hdGluZ0NvbnRhaW5lcj8uZmxvYXRpbmdVSVNlcnZpY2U/LmhpZGVmbG9hdGluZ1VJKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIHN1YnNjcmliZSB0byBjaGFuZ2VzIGluIGl0ZW1zIGFuZCBhcHBseSBzZXJ2aWNlIGZ1bmN0aW9uIHRvIHRoZXNlIGl0ZW1zIGFzIHdlbGxcbiAgICBjb21ib2JveC5saXN0Ym94Py5saXN0SXRlbXM/LmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbWJvYm94Lmxpc3Rib3g/Lmxpc3RJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgIGl0ZW0uY2xpY2tlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGNvbWJvYm94LmZsb2F0aW5nQ29udGFpbmVyPy5mbG9hdGluZ1VJU2VydmljZT8uaGlkZWZsb2F0aW5nVUkoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGXCoHNlbGVjdEhpZ2hsaWdodGVkT25NZW51Q2xvc2XCoG1ldGhvZCBzZWxlY3RzIHRoZSBsYXN0IGhpZ2hsaWdodGVkIGl0ZW0gd2hlbiB0aGUgbWVudSBpcyBjbG9zZWQuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBkZWZhdWx0IHdpdGhpbiA8Y29kZT5hdXRvU2VsZWN0SXRlbTwvY29kZT4uIDxiciAvPlxuICAgKiBAcGFyYW0gY29tYm9ib3ggQ29tYm9ib3ggdG8gYXBwbHkgYmVoYXZpb3IgdG8uXG4gICAqL1xuICBzZWxlY3RIaWdobGlnaHRlZE9uTWVudUNsb3NlKGNvbWJvYm94OiBDb21ib2JveERpcmVjdGl2ZSkge1xuICAgIGNvbWJvYm94LmZsb2F0aW5nQ29udGFpbmVyPy5mbG9hdGluZ1VJU2VydmljZT8uaXNTaG93bkVtaXR0ZXIuc3Vic2NyaWJlKChpc1Nob3duKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuYXBwUmVhZHlTZXJ2aWNlLmlzQnJvd3NlckFuZERvbUF2YWlsYWJsZSgpKSByZXR1cm47IC8vIHJldHVybiBpZiBhcHAgaXMgbm90IHJlYWR5IHRvIGFjY2VzcyBuYXRpdmVFbGVtZW50XG4gICAgICBpZiAoIWlzU2hvd24gJiYgY29tYm9ib3guX2xhc3RIaWdobGlnaHRlZE9uQ2xvc2UgIT09IG51bGwpIHtcbiAgICAgICAgY29tYm9ib3guc2VsZWN0SXRlbShjb21ib2JveC5fbGFzdEhpZ2hsaWdodGVkT25DbG9zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlwqBhdXRvRmlsdGVyRGlzcGxheWVkSXRlbXPCoG1ldGhvZCBhdXRvbWF0aWNhbGx5IGZpbHRlcnMgdGhlIGl0ZW1zIHNob3duIGluIHRoZSBjb21ib2JveCBvbiBpbml0aWFsIHJlbmRlci5cbiAgICogSWYgdGhlIGl0ZW1zIGRpc3BsYXllZCBvbiBwYWdlIGxvYWQgYXJlIG5vdCB0aGUgZnVsbCBsaXN0IHlvdSB3YW50IHRvIGZpbHRlciwgcGxlYXNlIHVzZSBhIGRpZmZlcmVudCBmdW5jdGlvbi4gVGhpcyBtZXRob2QgZmlsdGVycyBpdGVtcyBiYXNlZCBvbiBzZWxlY3Rpb24gYW5kIGlucHV0IHZhbHVlIGNoYW5nZXMuIDxiciAvPlxuICAgKiBUbyBhY2Nlc3MgdGhlIGZpbHRlcmVkIGxpc3Qgb2bCoDxjb2RlPkxpc3Rib3hJdGVtc0RpcmVjdGl2ZVtdPC9jb2RlPiwgc3Vic2NyaWJlIHRvIHRoZSA8Y29kZT5maWx0ZXJlZExpc3RFbWl0dGVyPC9jb2RlPi5cbiAgICogQHBhcmFtIGNvbWJvYm94IENvbWJvYm94IHRvIGFwcGx5IGJlaGF2aW9yIHRvLlxuICAgKi9cbiAgYXV0b0ZpbHRlckRpc3BsYXllZEl0ZW1zKGNvbWJvYm94OiBDb21ib2JveERpcmVjdGl2ZSkge1xuICAgIGlmICghY29tYm9ib3guaW5wdXQgfHwgIWNvbWJvYm94Lmxpc3Rib3gpIHJldHVybjtcbiAgICBsZXQgZmlsdGVyZWRMaXN0SXRlbXM6IExpc3Rib3hJdGVtQ29tcG9uZW50W10gPSBbXTtcblxuICAgIC8vIGZpbHRlciBsaXN0IHdpdGggZGVmYXVsdFZhbHVlXG4gICAgaWYgKGNvbWJvYm94LnZhbHVlKSB7XG4gICAgICBpZiAoY29tYm9ib3gubGlzdGJveD8ubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgY29tYm9ib3gudmFsdWVbJ3ZhbHVlJ10uZm9yRWFjaCgoc2VsZWN0ZWRWYWx1ZTogc3RyaW5nIHwgbnVtYmVyKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gY29tYm9ib3guaW5pdGlhbExpc3RJdGVtcy5maW5kKChpdGVtKSA9PiBpdGVtLnZhbHVlID09PSBzZWxlY3RlZFZhbHVlKTtcbiAgICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtKSB7XG4gICAgICAgICAgICBmaWx0ZXJlZExpc3RJdGVtcy5wdXNoKHNlbGVjdGVkSXRlbSk7XG4gICAgICAgICAgICAvLyBjb21ib2JveC5fcHJldkFjdGl2ZUl0ZW0gPSBzZWxlY3RlZEl0ZW07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gZG9uJ3QgdXBkYXRlIGxpc3Qgb24gaW5pdGlhbCByZW5kZXIgZm9yIG11bHRpc2VsZWN0LCBvbmx5IG9uIGlucHV0XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSBjb21ib2JveC5pbml0aWFsTGlzdEl0ZW1zLmZpbmQoKGl0ZW0pID0+IGl0ZW0udmFsdWUgPT09IGNvbWJvYm94LnZhbHVlWyd2YWx1ZSddKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgIGZpbHRlcmVkTGlzdEl0ZW1zLnB1c2goc2VsZWN0ZWRJdGVtKTtcbiAgICAgICAgICBjb21ib2JveC5fcHJldkFjdGl2ZUl0ZW0gPSBzZWxlY3RlZEl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVMaXN0KGNvbWJvYm94LCBmaWx0ZXJlZExpc3RJdGVtcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29tYm9ib3guaW5wdXQuaW5wdXRFdmVudC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuYXBwUmVhZHlTZXJ2aWNlLmlzQnJvd3NlckFuZERvbUF2YWlsYWJsZSgpKSByZXR1cm47IC8vIHJldHVybiBpZiBhcHAgaXMgbm90IHJlYWR5IHRvIGFjY2VzcyBuYXRpdmVFbGVtZW50XG4gICAgICAvLyBpbnB1dCB2YWx1ZVxuICAgICAgZmlsdGVyZWRMaXN0SXRlbXMgPSBbXTtcbiAgICAgIGNvbWJvYm94LmluaXRpYWxMaXN0SXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICBpZiAoaXRlbS5lbC5uYXRpdmVFbGVtZW50LmlubmVyVGV4dC50cmltKCkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZS50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICAgIC8vIGtlZXAgaXRlbSBpbiBsaXN0IGlmIGl0IGluY2x1ZGVzIHRoZSBpbnB1dCB2YWx1ZVxuICAgICAgICAgIGZpbHRlcmVkTGlzdEl0ZW1zLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy51cGRhdGVMaXN0KGNvbWJvYm94LCBmaWx0ZXJlZExpc3RJdGVtcyk7XG4gICAgfSk7XG5cbiAgICBjb21ib2JveC5pdGVtU2VsZWN0ZWQuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKGNvbWJvYm94Lmxpc3Rib3g/Lm11bHRpc2VsZWN0KSB7XG4gICAgICAgIC8vIHJlc2V0IGxpc3Qgb24gbXVsdGlzZWxlY3Qgd2hlbiBvcHRpb24gaXMgc2VsZWN0ZWRcbiAgICAgICAgZmlsdGVyZWRMaXN0SXRlbXMgPSBjb21ib2JveC5pbml0aWFsTGlzdEl0ZW1zO1xuICAgICAgICAvLyBpZiAoZmlsdGVyZWRMaXN0SXRlbXMgJiYgZmlsdGVyZWRMaXN0SXRlbXMubGVuZ3RoID4gMClcbiAgICAgICAgLy8gICBjb21ib2JveC5fcHJldkFjdGl2ZUl0ZW0gPSBmaWx0ZXJlZExpc3RJdGVtc1tmaWx0ZXJlZExpc3RJdGVtcy5sZW5ndGggLSAxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGxpc3Rib3ggaXRlbSB2YWx1ZVxuICAgICAgICBmaWx0ZXJlZExpc3RJdGVtcyA9IFtdO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSBjb21ib2JveC5pbml0aWFsTGlzdEl0ZW1zLmZpbmQoKGl0ZW0pID0+XG4gICAgICAgICAgKHZhbHVlIGFzIChzdHJpbmcgfCBudW1iZXIpW10pPy5pbmNsdWRlcyhpdGVtLnZhbHVlKVxuICAgICAgICApO1xuICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtKSB7XG4gICAgICAgICAgZmlsdGVyZWRMaXN0SXRlbXMucHVzaChzZWxlY3RlZEl0ZW0pO1xuICAgICAgICAgIGNvbWJvYm94Ll9wcmV2QWN0aXZlSXRlbSA9IHNlbGVjdGVkSXRlbTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtKSBmaWx0ZXJlZExpc3RJdGVtcy5wdXNoKHNlbGVjdGVkSXRlbSk7XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZUxpc3QoY29tYm9ib3gsIGZpbHRlcmVkTGlzdEl0ZW1zKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGXCoGF1dG9GaWx0ZXJCYXNlZE9uTGlzdMKgbWV0aG9kIGZpbHRlcnMgaXRlbXMgaW4gdGhlIGNvbWJvYm94IGJhc2VkIG9uIGEgc3BlY2lmaWVkIGxpc3QsIHdoaWNoIGNhbiBkaWZmZXIgZnJvbSB0aGUgaW5pdGlhbCBsaXN0IHJlbmRlcmVkLiA8YnIgLz5cbiAgICogVGhpcyBtZXRob2QgYWxsb3dzIGN1c3RvbWl6YXRpb24gb2YgdGhlIGZpbHRlcmluZyBjcml0ZXJpYSwgZW5hYmxpbmcgeW91IHRvIGZpbHRlciBpdGVtcyBiYXNlZCBvbiBwcm9wZXJ0aWVzIHN1Y2ggYXMgaWQsIGxhYmVsLCB2YWx1ZSwgZXRjLiBUbyBhY2Nlc3MgdGhlIGZpbHRlcmVkIGxpc3QsIHN1YnNjcmliZSB0byA8Y29kZT50aGXCoGZpbHRlcmVkTGlzdEVtaXR0ZXI8L2NvZGU+LCB3aGljaCBlbWl0cyB0aGUgZmlsdGVyZWQgbGlzdCBpbiB0aGUgc2FtZSBzaGFwZSBhcyA8Y29kZT5mdWxsTGlzdDwvY29kZT4uIDxiciAvPlxuICAgKiBUaGlzIG1ldGhvZCBpcyByZWNvbW1lbmRlZCBvdmVyIDxjb2RlPmF1dG9GaWx0ZXJEaXNwbGF5ZWRJdGVtczwvY29kZT4gYW5kIGNhbiBhY2hpZXZlIHRoZSBzYW1lIGZ1bmN0aW9uYWxpdHkgYnkgY2FsbGluZyA8Y29kZT5hdXRvRmlsdGVyQmFzZWRPbkxpc3QoY29tYm9ib3gsIGxpc3QsICdsYWJlbCcpPC9jb2RlPi5cbiAgICogQHBhcmFtIGNvbWJvYm94IENvbWJvYm94IHRvIGFwcGx5IGZpbHRlciBmdW5jdGlvbiB0by5cbiAgICogQHBhcmFtIGZ1bGxMaXN0IEZ1bGwgbGlzdCBvZiBpdGVtcyB0byBmaWx0ZXIuXG4gICAqIEBwYXJhbSBjb25kaXRpb24gQ29uZGl0aW9uIG9uIHdoaWNoIHRvIGZpbHRlciBpdGVtcyBpbiBmdWxsTGlzdCAodGhpcyB3b3VsZCBiZSBhIHByb3BlcnR5IHlvdSd2ZSBwcm92aWRlZCB0byB0aGUgaXRlbXMgaW4gZnVsbExpc3QpLlxuICAgKi9cbiAgYXV0b0ZpbHRlckJhc2VkT25MaXN0KGNvbWJvYm94OiBDb21ib2JveERpcmVjdGl2ZSwgZnVsbExpc3Q6IGFueVtdLCBjb25kaXRpb246IHN0cmluZykge1xuICAgIGNvbnN0IGxpc3REYXRhID0gZnVsbExpc3Q7XG4gICAgbGV0IGZpbHRlcmVkRGF0YTogYW55W10gPSBmdWxsTGlzdDtcblxuICAgIGlmICghY29tYm9ib3gpIHJldHVybjtcblxuICAgIGNvbWJvYm94LmZpbHRlci5zdWJzY3JpYmUoKGZpbHRlckV2ZW50KSA9PiB7XG4gICAgICBmaWx0ZXJlZERhdGEgPSBbXTtcbiAgICAgIGlmIChmaWx0ZXJFdmVudC50eXBlID09PSBDb21ib2JveEZpbHRlclR5cGUuU0VMRUNUSU9OKSB7XG4gICAgICAgIGlmIChjb21ib2JveC5saXN0Ym94Py5tdWx0aXNlbGVjdCkge1xuICAgICAgICAgIGZpbHRlcmVkRGF0YSA9IGxpc3REYXRhO1xuICAgICAgICAgIC8vIGlmIChmaWx0ZXJlZERhdGEgJiYgZmlsdGVyZWREYXRhLmxlbmd0aCA+IDApIGNvbWJvYm94Ll9wcmV2QWN0aXZlSXRlbSA9IGZpbHRlcmVkRGF0YVtmaWx0ZXJlZERhdGEubGVuZ3RoIC0gMV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgYW4gaXRlbSBpcyBzZWxlY3RlZCwgdGhlIGxpc3Qgc2hvdWxkIG9ubHkgaW5jbHVkZSB0aGF0IGl0ZW1cbiAgICAgICAgICBmaWx0ZXJlZERhdGEgPSBsaXN0RGF0YT8uZmlsdGVyKChpdGVtKSA9PiBpdGVtW2NvbmRpdGlvbl0udG9Mb3dlckNhc2UoKSA9PSBmaWx0ZXJFdmVudC5pbnB1dC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgICBpZiAoZmlsdGVyZWREYXRhICYmIGZpbHRlcmVkRGF0YS5sZW5ndGggPT09IDEpIGNvbWJvYm94Ll9wcmV2QWN0aXZlSXRlbSA9IGZpbHRlcmVkRGF0YVswXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChmaWx0ZXJFdmVudC50eXBlID09PSBDb21ib2JveEZpbHRlclR5cGUuSU5QVVQpIHtcbiAgICAgICAgbGlzdERhdGEuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgIGlmIChpdGVtW2NvbmRpdGlvbl0udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhmaWx0ZXJFdmVudC5pbnB1dC50b0xvd2VyQ2FzZSgpKSkgZmlsdGVyZWREYXRhLnB1c2goaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChmaWx0ZXJFdmVudC50eXBlID09PSBDb21ib2JveEZpbHRlclR5cGUuUkVTRVQpIHtcbiAgICAgICAgZmlsdGVyZWREYXRhID0gbGlzdERhdGE7XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZUxpc3QoY29tYm9ib3gsIGZpbHRlcmVkRGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlwqB1cGRhdGVMaXN0wqBtZXRob2QgdXBkYXRlcyB0aGUgY29tYm9ib3ggY29tcG9uZW50IHdpdGggdGhlIGdpdmVuIGZpbHRlcmVkIGxpc3QgaXRlbXMsXG4gICBzZXR0aW5nIHRoZSBhY3RpdmUgYW5kIGhpZ2hsaWdodGVkIGluZGV4IGFwcHJvcHJpYXRlbHkuIDxiciAvPlxuICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgZGVmYXVsdCB3aXRoaW4gPGNvZGU+YXV0b0ZpbHRlckRpc3BsYXllZEl0ZW1zPC9jb2RlPiBhbmQgPGNvZGU+YXV0b0ZpbHRlckJhc2VkT25MaXN0PC9jb2RlPi5cbiAgICogQHBhcmFtIGNvbWJvYm94IENvbWJvYm94IHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIGZpbHRlcmVkTGlzdEl0ZW1zIEZpbHRlcmVkIGFycmF5IG9mIGxpc3Rib3ggaXRlbXMuXG4gICAqL1xuICB1cGRhdGVMaXN0KGNvbWJvYm94OiBDb21ib2JveERpcmVjdGl2ZSwgZmlsdGVyZWRMaXN0SXRlbXM6IExpc3Rib3hJdGVtQ29tcG9uZW50W10pIHtcbiAgICBpZiAoY29tYm9ib3gubGlzdGJveD8ubXVsdGlzZWxlY3QpIHtcbiAgICAgIC8vIHJlc2V0IG11bHRpc2VsZWN0IGtleWJvYXJkIHRyYXZlcnNhbCBhbHRvZ2V0aGVyXG4gICAgICBjb21ib2JveC5fYWN0aXZlSW5kZXggPSBudWxsO1xuICAgICAgY29tYm9ib3guX2hpZ2hsaWdodGVkSW5kZXggPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoY29tYm9ib3guX3ByZXZBY3RpdmVJdGVtICYmIGZpbHRlcmVkTGlzdEl0ZW1zLmluY2x1ZGVzKGNvbWJvYm94Ll9wcmV2QWN0aXZlSXRlbSkpIHtcbiAgICAgIGNvbWJvYm94Ll9hY3RpdmVJbmRleCA9IGZpbHRlcmVkTGlzdEl0ZW1zLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbSA9PT0gY29tYm9ib3guX3ByZXZBY3RpdmVJdGVtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tYm9ib3guX2FjdGl2ZUluZGV4ID0gbnVsbDtcbiAgICAgIGNvbWJvYm94Ll9oaWdobGlnaHRlZEluZGV4ID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb21ib2JveC5maWx0ZXJlZExpc3RFbWl0dGVyLmVtaXQoZmlsdGVyZWRMaXN0SXRlbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZcKgYXV0b1NlbGVjdEl0ZW3CoG1ldGhvZCBoaWdobGlnaHRzIHRoZSBmaXJzdCBsaXN0IGl0ZW0gYmFzZWQgb24gdXNlciBpbnB1dC4gPGJyIC8+XG4gICAqIFRoaXMgZW5zdXJlcyB0aGF0IHdoZW4gdGhlIG1lbnUgY2xvc2VzLCBpZiBhbiBpbnB1dCB2YWx1ZSB3YXMgZW50ZXJlZCwgYW4gaXRlbSBpcyBzZWxlY3RlZC5cbiAgICogQHBhcmFtIGNvbWJvYm94IENvbWJvYm94IHRvIGFwcGx5IGF1dG9tYXRpYyBzZWxlY3Rpb24gdG8uXG4gICAqL1xuICBhdXRvU2VsZWN0SXRlbShjb21ib2JveDogQ29tYm9ib3hEaXJlY3RpdmUpIHtcbiAgICB0aGlzLnNlbGVjdEhpZ2hsaWdodGVkT25NZW51Q2xvc2UoY29tYm9ib3gpO1xuXG4gICAgY29tYm9ib3guaW5wdXQ/LmlucHV0RXZlbnQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGlmIChjb21ib2JveC5pbnB1dC52YWx1ZSkgY29tYm9ib3guaGlnaGxpZ2h0SW5kZXgoMCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==