UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

250 lines 40.5 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { Injectable } from "@angular/core"; import _forEach from "lodash/forEach"; import _get from "lodash/get"; import _intersection from "lodash/intersection"; import _isEqual from "lodash/isEqual"; import _orderBy from "lodash/orderBy"; import { DataSourceService } from "./data-source.service"; import { SorterDirection } from "../../lib/sorter/public-api"; import { SearchService } from "../search.service"; import * as i0 from "@angular/core"; import * as i1 from "../search.service"; /** * <example-url>./../examples/index.html#/common/data-source-service/deprecated-client-side</example-url> * @deprecated in v11 - use ClientSideDataSource instead - Removal: NUI-5796 */ export class LocalFilteringDataSource extends DataSourceService { constructor(searchService) { super(); this.searchService = searchService; this._allCategoriesResult = {}; this._searchProps = []; // cache used to store our previous fetched results while scrolling // and more data is automatically fetched from the backend this.virtualScrollData = []; } setData(initialData = []) { this._allData = initialData; } setSearchProperties(properties) { this._searchProps = properties; } async getFilteredData(filters) { let nextChunk = this.prepareData(); // APPLY SEARCH USING CHECKBOX VALUES const searchTerm = filters?.search?.value; // APPLY SEARCH if (searchTerm) { nextChunk = this.searchHandler(searchTerm); } const multiFiltersArr = this.extractMultiFilters(filters); // APPLY FILTERS with type 'string[]' if any if (multiFiltersArr?.length) { nextChunk = this.multiFilterHandler(nextChunk, multiFiltersArr); } const numberOfItems = nextChunk.length; // RESET PAGINATION if needed const filtersChanged = this.filtersChanged(filters, this.setItemsToCompare(filters, nextChunk, searchTerm, multiFiltersArr)); if (filtersChanged) { if (filters?.paginator) { const size = filters.paginator.value.end - filters.paginator.value.start; filters.paginator.value.start = 0; filters.paginator.value.end = size; } if (filters.virtualScroll) { // reset virtual scroll items this.virtualScrollData = []; } } nextChunk = this.sortingHandler(filters, nextChunk); nextChunk = this.paginationHandler(filters, nextChunk); nextChunk = this.virtualScrollHandler(filters, nextChunk); return { repeat: { itemsSource: nextChunk, }, paginator: { total: numberOfItems, reset: filtersChanged, }, ...this._allCategoriesResult, }; } prepareData() { return this._allData; } searchHandler(searchTerm) { return this.searchService.search(this._allData, this._searchProps, searchTerm); } multiFilterHandler(nextChunk, multiFiltersArr) { const allCategoriesArr = multiFiltersArr.map((el) => this.getAllCategories(el)); if (multiFiltersArr.length) { const filteredResult = this.searchThru(multiFiltersArr, nextChunk); const selectedFilters = this.getSelectedFilters(multiFiltersArr); // if some filters selected and filter result = 0, returning empty array if (filteredResult.length || selectedFilters.length) { nextChunk = _intersection(...filteredResult); } } // count number of occurrences of every item this._allCategoriesResult = this.countAvailableResults(allCategoriesArr, nextChunk); return nextChunk; } sortingHandler(filters, nextChunk) { if (_get(filters, "sorter.value.sortBy") && _get(filters, "sorter.value.direction")) { // Original direction means that sorting is not needed if (filters.sorter.value.direction !== SorterDirection.original) { return _orderBy(nextChunk, filters.sorter.value.sortBy, filters.sorter.value.direction); } } return nextChunk; } paginationHandler(filters, nextChunk) { if (filters?.paginator) { return nextChunk.slice(filters.paginator.value.start, filters.paginator.value.end); } return nextChunk; } virtualScrollHandler(filters, nextChunk) { let data = nextChunk; if (filters?.virtualScroll) { data = nextChunk.slice(filters.virtualScroll.value.start, filters.virtualScroll.value.end); // for virtual scroll we must always append current chunk to the previous ones data = this.virtualScrollData = this.virtualScrollData.concat(data); } return data; } /** * @deprecated in v11 - Use filtersChanged instead - Removal: NUI-5796 */ paginationReset(filters, itemsToCompare) { return this.filtersChanged(filters, itemsToCompare); } filtersChanged(filters, itemsToCompare) { if (this._previousFilters) { if (this.isValueChanged(itemsToCompare)) { return true; } } return false; } setItemsToCompare(filters, nextChunk, searchTerm, multiFiltersArr) { // GET FILTERS from previous filtering const previousSortBy = _get(this._previousFilters, "sorter.value.sortBy"); const previousDirection = _get(this._previousFilters, "sorter.value.direction"); const previousSearchTerm = _get(this._previousFilters, "search.value"); const previousMultiFiltersArr = this.extractMultiFilters(this._previousFilters); const sortBy = _get(filters, "sorter.value.sortBy"); const direction = _get(filters, "sorter.value.direction"); const itemsToCompare = []; itemsToCompare.push({ previousValue: previousSortBy, currentValue: sortBy, }); itemsToCompare.push({ previousValue: previousDirection, currentValue: direction, }); itemsToCompare.push({ previousValue: previousSearchTerm, currentValue: searchTerm, }); itemsToCompare.push({ previousValue: previousMultiFiltersArr, currentValue: multiFiltersArr, }); return itemsToCompare; } extractMultiFilters(filters) { const multiFilterArr = []; _forEach(filters, (value, key) => { if (value?.type === "string[]") { multiFilterArr.push({ [key]: value }); } }); return multiFilterArr; } getSelectedFilters(multiFiltersArr) { return multiFiltersArr.reduce((prev, curr) => prev.concat(curr[Object.keys(curr)[0]].value), []); } countAvailableResults(allCategoriesArr, nextChunk) { const allCategoriesResult = allCategoriesArr.map((el, index) => { const key = Object.keys(el)[0]; const valuesArr = allCategoriesArr[index][key]; const resultArr = valuesArr.map((element) => { const r = this.searchService.search(nextChunk, [key], element); return { [element]: r.length }; }); return { [key]: resultArr }; }); return (allCategoriesResult // convert array to an object .reduce((prev, curr) => { const [prop] = Object.keys(curr); // convert array to an object const newObj = curr[prop].reduce((previous, current) => { const [property] = Object.keys(current); previous[property] = current[property]; return previous; }, {}); prev[prop] = newObj; return prev; }, {})); } searchThru(arrToMap, arrToSearchIn) { // We are filtering out filter groups which doesn't have selected filters. If filters are not present, // it means that filtered data with this filters should not participate in intersection return arrToMap .filter((arr) => !!arr[Object.keys(arr)[0]].value.length) .map((multiFilter) => { const [prop] = Object.keys(multiFilter); return (multiFilter[prop].value // extract value array // find matches .map((el) => this.searchService.search(arrToSearchIn, [prop], el)) // flatten returned multidimensional arrays .reduce((prev, curr) => prev.concat(curr), [])); }); } getAllCategories(multiFilter) { if (!multiFilter) { return; } const [prop] = Object.keys(multiFilter); const { metadata } = multiFilter[prop]; return { [prop]: metadata?.allCategories }; } isValueChanged(valuesArr) { for (const { previousValue, currentValue } of valuesArr) { if (!_isEqual(previousValue, currentValue)) { return true; } } return false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalFilteringDataSource, deps: [{ token: i1.SearchService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalFilteringDataSource }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocalFilteringDataSource, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.SearchService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtZmlsdGVyaW5nLWRhdGEtc291cmNlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvZGF0YS1zb3VyY2UvbG9jYWwtZmlsdGVyaW5nLWRhdGEtc291cmNlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sYUFBYSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBRXRDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBVTFELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7OztBQVFsRDs7O0dBR0c7QUFFSCxNQUFNLE9BQU8sd0JBR1gsU0FBUSxpQkFBdUI7SUFTN0IsWUFBc0IsYUFBNEI7UUFDOUMsS0FBSyxFQUFFLENBQUM7UUFEVSxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQVB4Qyx5QkFBb0IsR0FBc0IsRUFBRSxD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O2dCQUMxQyxlQUFlO2lCQUNkLEdBQUcsQ0FBQyxDQUFDLEVBQVUsRUFBRSxFQUFFLENBQ2hCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUNyQixhQUFhLEVBQ2IsQ0FBQyxJQUFJLENBQUMsRUFDTixFQUFFLENBQ0wsQ0FDSjtnQkFDRCwyQ0FBMkM7aUJBQzFDLE1BQU0sQ0FDSCxDQUFDLElBQVMsRUFBRSxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQzNDLEVBQUUsQ0FDTCxDQUNSLENBQUM7UUFDTixDQUFDLENBQ0osQ0FBQztJQUNWLENBQUM7SUFFTyxnQkFBZ0IsQ0FDcEIsV0FBa0U7UUFFbEUsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNkLE9BQU87U0FDVjtRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FDZCxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQy9DLENBQUM7SUFFTyxjQUFjLENBQUMsU0FBNEI7UUFDL0MsS0FBSyxNQUFNLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxJQUFJLFNBQVMsRUFBRTtZQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsRUFBRTtnQkFDeEMsT0FBTyxJQUFJLENBQUM7YUFDZjtTQUNKO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQzsrR0FsVlEsd0JBQXdCO21IQUF4Qix3QkFBd0I7OzRGQUF4Qix3QkFBd0I7a0JBRHBDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgX2ZvckVhY2ggZnJvbSBcImxvZGFzaC9mb3JFYWNoXCI7XG5pbXBvcnQgX2dldCBmcm9tIFwibG9kYXNoL2dldFwiO1xuaW1wb3J0IF9pbnRlcnNlY3Rpb24gZnJvbSBcImxvZGFzaC9pbnRlcnNlY3Rpb25cIjtcbmltcG9ydCBfaXNFcXVhbCBmcm9tIFwibG9kYXNoL2lzRXF1YWxcIjtcbmltcG9ydCBfb3JkZXJCeSBmcm9tIFwibG9kYXNoL29yZGVyQnlcIjtcblxuaW1wb3J0IHsgRGF0YVNvdXJjZVNlcnZpY2UgfSBmcm9tIFwiLi9kYXRhLXNvdXJjZS5zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICAgIElGaWx0ZXIsXG4gICAgSUZpbHRlckdyb3VwLFxuICAgIElGaWx0ZXJpbmdPdXRwdXRzLFxuICAgIElGaWx0ZXJJdGVtLFxuICAgIElNdWx0aUZpbHRlck1ldGFkYXRhLFxuICAgIElOb3ZhRmlsdGVyaW5nT3V0cHV0cyxcbiAgICBJTm92YUZpbHRlcnMsXG59IGZyb20gXCIuL3B1YmxpYy1hcGlcIjtcbmltcG9ydCB7IFNvcnRlckRpcmVjdGlvbiB9IGZyb20gXCIuLi8uLi9saWIvc29ydGVyL3B1YmxpYy1hcGlcIjtcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tIFwiLi4vc2VhcmNoLnNlcnZpY2VcIjtcblxuLyoqIEBpZ25vcmUgKi9cbmludGVyZmFjZSBDb21wYXJpc29uSXRlbXMge1xuICAgIHByZXZpb3VzVmFsdWU6IGFueTtcbiAgICBjdXJyZW50VmFsdWU6IGFueTtcbn1cblxuLyoqXG4gKiA8ZXhhbXBsZS11cmw+Li8uLi9leGFtcGxlcy9pbmRleC5odG1sIy9jb21tb24vZGF0YS1zb3VyY2Utc2VydmljZS9kZXByZWNhdGVkLWNsaWVudC1zaWRlPC9leGFtcGxlLXVybD5cbiAqIEBkZXByZWNhdGVkIGluIHYxMSAtIHVzZSBDbGllbnRTaWRlRGF0YVNvdXJjZSBpbnN0ZWFkIC0gUmVtb3ZhbDogTlVJLTU3OTZcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIExvY2FsRmlsdGVyaW5nRGF0YVNvdXJjZTxcbiAgICBULFxuICAgIEYgZXh0ZW5kcyBJTm92YUZpbHRlcnMgPSBJTm92YUZpbHRlcnNcbj4gZXh0ZW5kcyBEYXRhU291cmNlU2VydmljZTxULCBGPiB7XG4gICAgcHJvdGVjdGVkIF9hbGxEYXRhOiBUW107XG4gICAgcHJvdGVjdGVkIF9hbGxDYXRlZ29yaWVzUmVzdWx0OiBJRmlsdGVyaW5nT3V0cHV0cyA9IHt9O1xuICAgIHByb3RlY3RlZCBfc2VhcmNoUHJvcHM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBjYWNoZSB1c2VkIHRvIHN0b3JlIG91ciBwcmV2aW91cyBmZXRjaGVkIHJlc3VsdHMgd2hpbGUgc2Nyb2xsaW5nXG4gICAgLy8gYW5kIG1vcmUgZGF0YSBpcyBhdXRvbWF0aWNhbGx5IGZldGNoZWQgZnJvbSB0aGUgYmFja2VuZFxuICAgIHByb3RlY3RlZCB2aXJ0dWFsU2Nyb2xsRGF0YTogVFtdID0gW107XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgc2VhcmNoU2VydmljZTogU2VhcmNoU2VydmljZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXREYXRhKGluaXRpYWxEYXRhOiBUW10gPSBbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9hbGxEYXRhID0gaW5pdGlhbERhdGE7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFNlYXJjaFByb3BlcnRpZXMocHJvcGVydGllczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fc2VhcmNoUHJvcHMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRGaWx0ZXJlZERhdGEoZmlsdGVyczogRik6IFByb21pc2U8SU5vdmFGaWx0ZXJpbmdPdXRwdXRzPiB7XG4gICAgICAgIGxldCBuZXh0Q2h1bms6IFRbXSA9IHRoaXMucHJlcGFyZURhdGEoKTtcblxuICAgICAgICAvLyBBUFBMWSBTRUFSQ0ggVVNJTkcgQ0hFQ0tCT1ggVkFMVUVTXG4gICAgICAgIGNvbnN0IHNlYXJjaFRlcm06IHN0cmluZyB8IHVuZGVmaW5lZCA9IGZpbHRlcnM/LnNlYXJjaD8udmFsdWU7XG4gICAgICAgIC8vIEFQUExZIFNFQVJDSFxuICAgICAgICBpZiAoc2VhcmNoVGVybSkge1xuICAgICAgICAgICAgbmV4dENodW5rID0gdGhpcy5zZWFyY2hIYW5kbGVyKHNlYXJjaFRlcm0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbXVsdGlGaWx0ZXJzQXJyOiBJRmlsdGVyR3JvdXA8XG4gICAgICAgICAgICBJRmlsdGVyPHN0cmluZ1tdLCBJTXVsdGlGaWx0ZXJNZXRhZGF0YT5cbiAgICAgICAgPltdID0gdGhpcy5leHRyYWN0TXVsdGlGaWx0ZXJzKGZpbHRlcnMpO1xuICAgICAgICAvLyBBUFBMWSBGSUxURVJTIHdpdGggdHlwZSAnc3RyaW5nW10nIGlmIGFueVxuICAgICAgICBpZiAobXVsdGlGaWx0ZXJzQXJyPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIG5leHRDaHVuayA9IHRoaXMubXVsdGlGaWx0ZXJIYW5kbGVyKG5leHRDaHVuaywgbXVsdGlGaWx0ZXJzQXJyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG51bWJlck9mSXRlbXMgPSBuZXh0Q2h1bmsubGVuZ3RoO1xuXG4gICAgICAgIC8vIFJFU0VUIFBBR0lOQVRJT04gaWYgbmVlZGVkXG4gICAgICAgIGNvbnN0IGZpbHRlcnNDaGFuZ2VkID0gdGhpcy5maWx0ZXJzQ2hhbmdlZChcbiAgICAgICAgICAgIGZpbHRlcnMsXG4gICAgICAgICAgICB0aGlzLnNldEl0ZW1zVG9Db21wYXJlKFxuICAgICAgICAgICAgICAgIGZpbHRlcnMsXG4gICAgICAgICAgICAgICAgbmV4dENodW5rLFxuICAgICAgICAgICAgICAgIHNlYXJjaFRlcm0sXG4gICAgICAgICAgICAgICAgbXVsdGlGaWx0ZXJzQXJyXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGZpbHRlcnNDaGFuZ2VkKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVycz8ucGFnaW5hdG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2l6ZSA9XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcnMucGFnaW5hdG9yLnZhbHVlLmVuZCAtIGZpbHRlcnMucGFnaW5hdG9yLnZhbHVlLnN0YXJ0O1xuICAgICAgICAgICAgICAgIGZpbHRlcnMucGFnaW5hdG9yLnZhbHVlLnN0YXJ0ID0gMDtcbiAgICAgICAgICAgICAgICBmaWx0ZXJzLnBhZ2luYXRvci52YWx1ZS5lbmQgPSBzaXplO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZmlsdGVycy52aXJ0dWFsU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVzZXQgdmlydHVhbCBzY3JvbGwgaXRlbXNcbiAgICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxTY3JvbGxEYXRhID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBuZXh0Q2h1bmsgPSA8VFtdPnRoaXMuc29ydGluZ0hhbmRsZXIoZmlsdGVycywgbmV4dENodW5rKTtcbiAgICAgICAgbmV4dENodW5rID0gdGhpcy5wYWdpbmF0aW9uSGFuZGxlcihmaWx0ZXJzLCBuZXh0Q2h1bmspO1xuICAgICAgICBuZXh0Q2h1bmsgPSB0aGlzLnZpcnR1YWxTY3JvbGxIYW5kbGVyKGZpbHRlcnMsIG5leHRDaHVuayk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlcGVhdDoge1xuICAgICAgICAgICAgICAgIGl0ZW1zU291cmNlOiBuZXh0Q2h1bmssXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFnaW5hdG9yOiB7XG4gICAgICAgICAgICAgICAgdG90YWw6IG51bWJlck9mSXRlbXMsXG4gICAgICAgICAgICAgICAgcmVzZXQ6IGZpbHRlcnNDaGFuZ2VkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC4uLnRoaXMuX2FsbENhdGVnb3JpZXNSZXN1bHQsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHByZXBhcmVEYXRhKCk6IFRbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbGxEYXRhO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzZWFyY2hIYW5kbGVyKHNlYXJjaFRlcm06IGFueSk6IFRbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoKFxuICAgICAgICAgICAgdGhpcy5fYWxsRGF0YSxcbiAgICAgICAgICAgIHRoaXMuX3NlYXJjaFByb3BzLFxuICAgICAgICAgICAgc2VhcmNoVGVybVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBtdWx0aUZpbHRlckhhbmRsZXIobmV4dENodW5rOiBUW10sIG11bHRpRmlsdGVyc0FycjogYW55KTogVFtdIHtcbiAgICAgICAgY29uc3QgYWxsQ2F0ZWdvcmllc0FycjogSUZpbHRlckl0ZW08c3RyaW5nW10+W10gPSBtdWx0aUZpbHRlcnNBcnIubWFwKFxuICAgICAgICAgICAgKGVsOiBJRmlsdGVyR3JvdXA8SUZpbHRlcjxzdHJpbmdbXSwgSU11bHRpRmlsdGVyTWV0YWRhdGE+PikgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmdldEFsbENhdGVnb3JpZXMoZWwpXG4gICAgICAgICk7XG4gICAgICAgIGlmIChtdWx0aUZpbHRlcnNBcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJlZFJlc3VsdCA9IHRoaXMuc2VhcmNoVGhydShtdWx0aUZpbHRlcnNBcnIsIG5leHRDaHVuayk7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpbHRlcnMgPSB0aGlzLmdldFNlbGVjdGVkRmlsdGVycyhtdWx0aUZpbHRlcnNBcnIpO1xuICAgICAgICAgICAgLy8gaWYgc29tZSBmaWx0ZXJzIHNlbGVjdGVkIGFuZCBmaWx0ZXIgcmVzdWx0ID0gMCwgcmV0dXJuaW5nIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAoZmlsdGVyZWRSZXN1bHQubGVuZ3RoIHx8IHNlbGVjdGVkRmlsdGVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBuZXh0Q2h1bmsgPSBfaW50ZXJzZWN0aW9uKC4uLmZpbHRlcmVkUmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBjb3VudCBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgb2YgZXZlcnkgaXRlbVxuICAgICAgICB0aGlzLl9hbGxDYXRlZ29yaWVzUmVzdWx0ID0gdGhpcy5jb3VudEF2YWlsYWJsZVJlc3VsdHMoXG4gICAgICAgICAgICBhbGxDYXRlZ29yaWVzQXJyLFxuICAgICAgICAgICAgbmV4dENodW5rXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBuZXh0Q2h1bms7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNvcnRpbmdIYW5kbGVyKGZpbHRlcnM6IGFueSwgbmV4dENodW5rOiBUW10pOiBUW10ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBfZ2V0KGZpbHRlcnMsIFwic29ydGVyLnZhbHVlLnNvcnRCeVwiKSAmJlxuICAgICAgICAgICAgX2dldChmaWx0ZXJzLCBcInNvcnRlci52YWx1ZS5kaXJlY3Rpb25cIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBPcmlnaW5hbCBkaXJlY3Rpb24gbWVhbnMgdGhhdCBzb3J0aW5nIGlzIG5vdCBuZWVkZWRcbiAgICAgICAgICAgIGlmIChmaWx0ZXJzLnNvcnRlci52YWx1ZS5kaXJlY3Rpb24gIT09IFNvcnRlckRpcmVjdGlvbi5vcmlnaW5hbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfb3JkZXJCeShcbiAgICAgICAgICAgICAgICAgICAgbmV4dENodW5rLFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJzLnNvcnRlci52YWx1ZS5zb3J0QnksXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcnMuc29ydGVyLnZhbHVlLmRpcmVjdGlvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5leHRDaHVuaztcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcGFnaW5hdGlvbkhhbmRsZXIoZmlsdGVyczogYW55LCBuZXh0Q2h1bms6IFRbXSk6IFRbXSB7XG4gICAgICAgIGlmIChmaWx0ZXJzPy5wYWdpbmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXh0Q2h1bmsuc2xpY2UoXG4gICAgICAgICAgICAgICAgZmlsdGVycy5wYWdpbmF0b3IudmFsdWUuc3RhcnQsXG4gICAgICAgICAgICAgICAgZmlsdGVycy5wYWdpbmF0b3IudmFsdWUuZW5kXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXh0Q2h1bms7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHZpcnR1YWxTY3JvbGxIYW5kbGVyKGZpbHRlcnM6IGFueSwgbmV4dENodW5rOiBUW10pOiBUW10ge1xuICAgICAgICBsZXQgZGF0YSA9IG5leHRDaHVuaztcbiAgICAgICAgaWYgKGZpbHRlcnM/LnZpcnR1YWxTY3JvbGwpIHtcbiAgICAgICAgICAgIGRhdGEgPSBuZXh0Q2h1bmsuc2xpY2UoXG4gICAgICAgICAgICAgICAgZmlsdGVycy52aXJ0dWFsU2Nyb2xsLnZhbHVlLnN0YXJ0LFxuICAgICAgICAgICAgICAgIGZpbHRlcnMudmlydHVhbFNjcm9sbC52YWx1ZS5lbmRcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGZvciB2aXJ0dWFsIHNjcm9sbCB3ZSBtdXN0IGFsd2F5cyBhcHBlbmQgY3VycmVudCBjaHVuayB0byB0aGUgcHJldmlvdXMgb25lc1xuICAgICAgICAgICAgZGF0YSA9IHRoaXMudmlydHVhbFNjcm9sbERhdGEgPSB0aGlzLnZpcnR1YWxTY3JvbGxEYXRhLmNvbmNhdChkYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkIGluIHYxMSAtIFVzZSBmaWx0ZXJzQ2hhbmdlZCBpbnN0ZWFkIC0gUmVtb3ZhbDogTlVJLTU3OTZcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcGFnaW5hdGlvblJlc2V0KGZpbHRlcnM6IGFueSwgaXRlbXNUb0NvbXBhcmU6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXJzQ2hhbmdlZChmaWx0ZXJzLCBpdGVtc1RvQ29tcGFyZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGZpbHRlcnNDaGFuZ2VkKGZpbHRlcnM6IGFueSwgaXRlbXNUb0NvbXBhcmU6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5fcHJldmlvdXNGaWx0ZXJzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbHVlQ2hhbmdlZChpdGVtc1RvQ29tcGFyZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNldEl0ZW1zVG9Db21wYXJlKFxuICAgICAgICBmaWx0ZXJzOiBGLFxuICAgICAgICBuZXh0Q2h1bms6IFRbXSxcbiAgICAgICAgc2VhcmNoVGVybTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgICBtdWx0aUZpbHRlcnNBcnI6IElGaWx0ZXJHcm91cDxJRmlsdGVyPHN0cmluZ1tdLCBJTXVsdGlGaWx0ZXJNZXRhZGF0YT4+W11cbiAgICApOiBDb21wYXJpc29uSXRlbXNbXSB7XG4gICAgICAgIC8vIEdFVCBGSUxURVJTIGZyb20gcHJldmlvdXMgZmlsdGVyaW5nXG4gICAgICAgIGNvbnN0IHByZXZpb3VzU29ydEJ5ID0gX2dldChcbiAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzRmlsdGVycyxcbiAgICAgICAgICAgIFwic29ydGVyLnZhbHVlLnNvcnRCeVwiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRGlyZWN0aW9uID0gX2dldChcbiAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzRmlsdGVycyxcbiAgICAgICAgICAgIFwic29ydGVyLnZhbHVlLmRpcmVjdGlvblwiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzU2VhcmNoVGVybSA9IF9nZXQodGhpcy5fcHJldmlvdXNGaWx0ZXJzLCBcInNlYXJjaC52YWx1ZVwiKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNNdWx0aUZpbHRlcnNBcnIgPSB0aGlzLmV4dHJhY3RNdWx0aUZpbHRlcnMoXG4gICAgICAgICAgICB0aGlzLl9wcmV2aW91c0ZpbHRlcnNcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBzb3J0QnkgPSBfZ2V0KGZpbHRlcnMsIFwic29ydGVyLnZhbHVlLnNvcnRCeVwiKTtcbiAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gX2dldChmaWx0ZXJzLCBcInNvcnRlci52YWx1ZS5kaXJlY3Rpb25cIik7XG5cbiAgICAgICAgY29uc3QgaXRlbXNUb0NvbXBhcmU6IENvbXBhcmlzb25JdGVtc1tdID0gW107XG4gICAgICAgIGl0ZW1zVG9Db21wYXJlLnB1c2goe1xuICAgICAgICAgICAgcHJldmlvdXNWYWx1ZTogcHJldmlvdXNTb3J0QnksXG4gICAgICAgICAgICBjdXJyZW50VmFsdWU6IHNvcnRCeSxcbiAgICAgICAgfSk7XG4gICAgICAgIGl0ZW1zVG9Db21wYXJlLnB1c2goe1xuICAgICAgICAgICAgcHJldmlvdXNWYWx1ZTogcHJldmlvdXNEaXJlY3Rpb24sXG4gICAgICAgICAgICBjdXJyZW50VmFsdWU6IGRpcmVjdGlvbixcbiAgICAgICAgfSk7XG4gICAgICAgIGl0ZW1zVG9Db21wYXJlLnB1c2goe1xuICAgICAgICAgICAgcHJldmlvdXNWYWx1ZTogcHJldmlvdXNTZWFyY2hUZXJtLFxuICAgICAgICAgICAgY3VycmVudFZhbHVlOiBzZWFyY2hUZXJtLFxuICAgICAgICB9KTtcbiAgICAgICAgaXRlbXNUb0NvbXBhcmUucHVzaCh7XG4gICAgICAgICAgICBwcmV2aW91c1ZhbHVlOiBwcmV2aW91c011bHRpRmlsdGVyc0FycixcbiAgICAgICAgICAgIGN1cnJlbnRWYWx1ZTogbXVsdGlGaWx0ZXJzQXJyLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGl0ZW1zVG9Db21wYXJlO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBleHRyYWN0TXVsdGlGaWx0ZXJzKFxuICAgICAgICBmaWx0ZXJzOiBGXG4gICAgKTogSUZpbHRlckdyb3VwPElGaWx0ZXI8c3RyaW5nW10sIElNdWx0aUZpbHRlck1ldGFkYXRhPj5bXSB7XG4gICAgICAgIGNvbnN0IG11bHRpRmlsdGVyQXJyOiBJRmlsdGVyR3JvdXA8XG4gICAgICAgICAgICBJRmlsdGVyPHN0cmluZ1tdLCBJTXVsdGlGaWx0ZXJNZXRhZGF0YT5cbiAgICAgICAgPltdID0gW107XG4gICAgICAgIF9mb3JFYWNoKGZpbHRlcnMsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWU/LnR5cGUgPT09IFwic3RyaW5nW11cIikge1xuICAgICAgICAgICAgICAgIG11bHRpRmlsdGVyQXJyLnB1c2goeyBba2V5XTogdmFsdWUgfSBhcyBhbnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG11bHRpRmlsdGVyQXJyO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U2VsZWN0ZWRGaWx0ZXJzKFxuICAgICAgICBtdWx0aUZpbHRlcnNBcnI6IElGaWx0ZXJHcm91cDxJRmlsdGVyPHN0cmluZ1tdLCBJTXVsdGlGaWx0ZXJNZXRhZGF0YT4+W11cbiAgICApOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiBtdWx0aUZpbHRlcnNBcnIucmVkdWNlKFxuICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgIHByZXY6IHN0cmluZ1tdLFxuICAgICAgICAgICAgICAgIGN1cnI6IElGaWx0ZXJHcm91cDxJRmlsdGVyPHN0cmluZ1tdLCBJTXVsdGlGaWx0ZXJNZXRhZGF0YT4+XG4gICAgICAgICAgICApID0+IHByZXYuY29uY2F0KGN1cnJbT2JqZWN0LmtleXMoY3VycilbMF1dLnZhbHVlKSxcbiAgICAgICAgICAgIFtdXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb3VudEF2YWlsYWJsZVJlc3VsdHMoXG4gICAgICAgIGFsbENhdGVnb3JpZXNBcnI6IElGaWx0ZXJJdGVtPHN0cmluZ1tdPltdLFxuICAgICAgICBuZXh0Q2h1bms6IFRbXVxuICAgICk6IElGaWx0ZXJHcm91cDxJRmlsdGVySXRlbTxudW1iZXI+PiB7XG4gICAgICAgIGNvbnN0IGFsbENhdGVnb3JpZXNSZXN1bHQ6IElGaWx0ZXJHcm91cDxJRmlsdGVySXRlbTxudW1iZXI+W10+W10gPVxuICAgICAgICAgICAgYWxsQ2F0ZWdvcmllc0Fyci5tYXAoKGVsLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleTogc3RyaW5nID0gT2JqZWN0LmtleXMoZWwpWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlc0Fycjogc3RyaW5nW10gPSBhbGxDYXRlZ29yaWVzQXJyW2luZGV4XVtrZXldO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdEFyciA9IHZhbHVlc0Fyci5tYXAoKGVsZW1lbnQ6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByOiBUW10gPSB0aGlzLnNlYXJjaFNlcnZpY2Uuc2VhcmNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENodW5rLFxuICAgICAgICAgICAgICAgICAgICAgICAgW2tleV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IFtlbGVtZW50XTogci5sZW5ndGggfTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBba2V5XTogcmVzdWx0QXJyIH07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYWxsQ2F0ZWdvcmllc1Jlc3VsdFxuICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgYXJyYXkgdG8gYW4gb2JqZWN0XG4gICAgICAgICAgICAgICAgLnJlZHVjZSgocHJldjogYW55LCBjdXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgW3Byb3BdID0gT2JqZWN0LmtleXMoY3Vycik7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgYXJyYXkgdG8gYW4gb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld09iaiA9IGN1cnJbcHJvcF0ucmVkdWNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgKHByZXZpb3VzOiBhbnksIGN1cnJlbnQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFtwcm9wZXJ0eV0gPSBPYmplY3Qua2V5cyhjdXJyZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1twcm9wZXJ0eV0gPSBjdXJyZW50W3Byb3BlcnR5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJldmlvdXM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcHJldltwcm9wXSA9IG5ld09iajtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXY7XG4gICAgICAgICAgICAgICAgfSwge30pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZWFyY2hUaHJ1KFxuICAgICAgICBhcnJUb01hcDogSUZpbHRlckdyb3VwPElGaWx0ZXI8c3RyaW5nW10sIElNdWx0aUZpbHRlck1ldGFkYXRhPj5bXSxcbiAgICAgICAgYXJyVG9TZWFyY2hJbjogVFtdXG4gICAgKSB7XG4gICAgICAgIC8vIFdlIGFyZSBmaWx0ZXJpbmcgb3V0IGZpbHRlciBncm91cHMgd2hpY2ggZG9lc24ndCBoYXZlIHNlbGVjdGVkIGZpbHRlcnMuIElmIGZpbHRlcnMgYXJlIG5vdCBwcmVzZW50LFxuICAgICAgICAvLyBpdCBtZWFucyB0aGF0IGZpbHRlcmVkIGRhdGEgd2l0aCB0aGlzIGZpbHRlcnMgc2hvdWxkIG5vdCBwYXJ0aWNpcGF0ZSBpbiBpbnRlcnNlY3Rpb25cbiAgICAgICAgcmV0dXJuIGFyclRvTWFwXG4gICAgICAgICAgICAuZmlsdGVyKChhcnIpID0+ICEhYXJyW09iamVjdC5rZXlzKGFycilbMF1dLnZhbHVlLmxlbmd0aClcbiAgICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICBtdWx0aUZpbHRlcjogSUZpbHRlckdyb3VwPFxuICAgICAgICAgICAgICAgICAgICAgICAgSUZpbHRlcjxzdHJpbmdbXSwgSU11bHRpRmlsdGVyTWV0YWRhdGE+XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICApID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgW3Byb3BdID0gT2JqZWN0LmtleXMobXVsdGlGaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlGaWx0ZXJbcHJvcF0udmFsdWUgLy8gZXh0cmFjdCB2YWx1ZSBhcnJheVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgbWF0Y2hlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoKGVsOiBzdHJpbmcpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VhcmNoU2VydmljZS5zZWFyY2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJUb1NlYXJjaEluLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmbGF0dGVuIHJldHVybmVkIG11bHRpZGltZW5zaW9uYWwgYXJyYXlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByZXY6IFRbXSwgY3VycjogVFtdKSA9PiBwcmV2LmNvbmNhdChjdXJyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEFsbENhdGVnb3JpZXMoXG4gICAgICAgIG11bHRpRmlsdGVyOiBJRmlsdGVyR3JvdXA8SUZpbHRlcjxzdHJpbmdbXSwgSU11bHRpRmlsdGVyTWV0YWRhdGE+PlxuICAgICkge1xuICAgICAgICBpZiAoIW11bHRpRmlsdGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgW3Byb3BdID0gT2JqZWN0LmtleXMobXVsdGlGaWx0ZXIpO1xuICAgICAgICBjb25zdCB7IG1ldGFkYXRhIH06IElGaWx0ZXI8c3RyaW5nW10sIElNdWx0aUZpbHRlck1ldGFkYXRhPiA9XG4gICAgICAgICAgICBtdWx0aUZpbHRlcltwcm9wXTtcbiAgICAgICAgcmV0dXJuIHsgW3Byb3BdOiBtZXRhZGF0YT8uYWxsQ2F0ZWdvcmllcyB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNWYWx1ZUNoYW5nZWQodmFsdWVzQXJyOiBDb21wYXJpc29uSXRlbXNbXSkge1xuICAgICAgICBmb3IgKGNvbnN0IHsgcHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlIH0gb2YgdmFsdWVzQXJyKSB7XG4gICAgICAgICAgICBpZiAoIV9pc0VxdWFsKHByZXZpb3VzVmFsdWUsIGN1cnJlbnRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIl19