UNPKG

@alfresco/adf-content-services

Version:
377 lines 52.2 kB
import { AlfrescoApiService } from '../../services/alfresco-api.service'; import { SiteMemberPaging, PeopleApi, SitesApi, SearchApi, FavoritesApi, SharedlinksApi, TrashcanApi, NodesApi, SEARCH_LANGUAGE } from '@alfresco/js-api'; import { Injectable } from '@angular/core'; import { Observable, from, of } from 'rxjs'; import { map } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../../services/alfresco-api.service"; const CREATE_PERMISSION = 'create'; export class CustomResourcesService { get peopleApi() { this._peopleApi = this._peopleApi ?? new PeopleApi(this.apiService.getInstance()); return this._peopleApi; } get sitesApi() { this._sitesApi = this._sitesApi ?? new SitesApi(this.apiService.getInstance()); return this._sitesApi; } get trashcanApi() { this._trashcanApi = this._trashcanApi ?? new TrashcanApi(this.apiService.getInstance()); return this._trashcanApi; } get searchApi() { this._searchApi = this._searchApi ?? new SearchApi(this.apiService.getInstance()); return this._searchApi; } get sharedLinksApi() { this._sharedLinksApi = this._sharedLinksApi ?? new SharedlinksApi(this.apiService.getInstance()); return this._sharedLinksApi; } get favoritesApi() { this._favoritesApi = this._favoritesApi ?? new FavoritesApi(this.apiService.getInstance()); return this._favoritesApi; } get nodesApi() { this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance()); return this._nodesApi; } constructor(apiService) { this.apiService = apiService; } /** * Gets files recently accessed by a user. * * @param personId ID of the user * @param pagination Specifies how to paginate the results * @param filters Specifies additional filters to apply (joined with **AND**) * @returns List of nodes for the recently used files */ getRecentFiles(personId, pagination, filters) { const defaultFilter = [ 'TYPE:"content"', '-PATH:"//cm:wiki/*"', '-TYPE:"app:filelink"', '-TYPE:"cm:thumbnail"', '-TYPE:"cm:failedThumbnail"', '-TYPE:"cm:rating"', '-TYPE:"dl:dataList"', '-TYPE:"dl:todoList"', '-TYPE:"dl:issue"', '-TYPE:"dl:contact"', '-TYPE:"dl:eventAgenda"', '-TYPE:"dl:event"', '-TYPE:"dl:task"', '-TYPE:"dl:simpletask"', '-TYPE:"dl:meetingAgenda"', '-TYPE:"dl:location"', '-TYPE:"fm:topic"', '-TYPE:"fm:post"', '-TYPE:"ia:calendarEvent"', '-TYPE:"lnk:link"' ]; return new Observable((observer) => { this.peopleApi.getPerson(personId).then((person) => { const username = person.entry.id; const filterQueries = [ { query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` }, { query: `cm:modifier:'${username}' OR cm:creator:'${username}'` }, { query: defaultFilter.join(' AND ') } ]; if (filters && filters.length > 0) { filterQueries.push({ query: filters.join() }); } const query = { query: { query: '*', language: SEARCH_LANGUAGE.AFTS }, filterQueries, include: ['path', 'properties', 'allowableOperations', 'aspectNames'], sort: [ { type: 'FIELD', field: 'cm:modified', ascending: false } ], paging: { maxItems: pagination.maxItems, skipCount: pagination.skipCount } }; return this.searchApi.search(query).then((searchResult) => { observer.next(searchResult); observer.complete(); }, (err) => { observer.error(err); observer.complete(); }); }, (err) => { observer.error(err); observer.complete(); }); }); } /** * Gets favorite files for the current user. * * @param pagination Specifies how to paginate the results * @param includeFields List of data field names to include in the results * @param where A string to restrict the returned objects by using a predicate * @returns List of favorite files */ loadFavorites(pagination, includeFields = [], where) { const includeFieldsRequest = this.getIncludesFields(includeFields); const defaultPredicate = '(EXISTS(target/file) OR EXISTS(target/folder))'; const options = { maxItems: pagination.maxItems, skipCount: pagination.skipCount, where: where ? `${where} AND ${defaultPredicate}` : defaultPredicate, include: includeFieldsRequest }; return new Observable((observer) => { this.favoritesApi.listFavorites('-me-', options).then((result) => { const page = { list: { entries: result.list.entries.map(({ entry }) => { const target = entry.target.file || entry.target.folder; target.properties = { ...(target.properties || { 'cm:title': entry.title || target.title, 'cm:description': entry.description || target.description }), ...(entry.properties || {}) }; target.aspectNames = entry?.aspectNames ?? []; target.allowableOperations = entry?.allowableOperations ?? []; return { entry: target }; }), pagination: result.list.pagination } }; observer.next(page); observer.complete(); }, (err) => { observer.error(err); observer.complete(); }); }); } /** * Gets sites that the current user is a member of. * * @param pagination Specifies how to paginate the results * @param where A string to restrict the returned objects by using a predicate * @returns List of sites */ loadMemberSites(pagination, where) { const options = { include: ['properties'], maxItems: pagination.maxItems, skipCount: pagination.skipCount, where }; return new Observable((observer) => { this.sitesApi.listSiteMembershipsForPerson('-me-', options).then((result) => { const page = new SiteMemberPaging({ list: { entries: result.list.entries.map(({ entry: { site } }) => { site.allowableOperations = site.allowableOperations ? site.allowableOperations : [CREATE_PERMISSION]; site.name = site.name || site.title; return { entry: site }; }), pagination: result.list.pagination } }); observer.next(page); observer.complete(); }, (err) => { observer.error(err); observer.complete(); }); }); } /** * Gets all sites in the repository. * * @param pagination Specifies how to paginate the results * @param where A string to restrict the returned objects by using a predicate * @returns List of sites */ loadSites(pagination, where) { const options = { include: ['properties', 'aspectNames'], maxItems: pagination.maxItems, skipCount: pagination.skipCount, where }; return new Observable((observer) => { this.sitesApi.listSites(options).then((page) => { page.list.entries.map(({ entry }) => { entry.name = entry.name || entry.title; return { entry }; }); observer.next(page); observer.complete(); }, (err) => { observer.error(err); observer.complete(); }); }); } /** * Gets all items currently in the trash. * * @param pagination Specifies how to paginate the results * @param includeFields List of data field names to include in the results * @returns List of deleted items */ loadTrashcan(pagination, includeFields = []) { const includeFieldsRequest = this.getIncludesFields(includeFields); const options = { include: includeFieldsRequest, maxItems: pagination.maxItems, skipCount: pagination.skipCount }; return from(this.trashcanApi.listDeletedNodes(options)); } /** * Gets shared links for the current user. * * @param pagination Specifies how to paginate the results * @param includeFields List of data field names to include in the results * @param where A string to restrict the returned objects by using a predicate * @returns List of shared links */ loadSharedLinks(pagination, includeFields = [], where) { const includeFieldsRequest = this.getIncludesFields(includeFields); const options = { include: includeFieldsRequest, maxItems: pagination.maxItems, skipCount: pagination.skipCount, where }; return from(this.sharedLinksApi.listSharedLinks(options)); } /** * Is the folder ID one of the well-known aliases? * * @param folderId Folder ID name to check * @returns True if the ID is a well-known name, false otherwise */ isCustomSource(folderId) { let isCustomSources = false; const sources = ['-trashcan-', '-sharedlinks-', '-sites-', '-mysites-', '-favorites-', '-recent-']; if (sources.indexOf(folderId) > -1) { isCustomSources = true; } return isCustomSources; } /** * Is the folder ID a "-my", "-root-", or "-shared-" alias? * * @param folderId Folder ID name to check * @returns True if the ID is one of the supported sources, false otherwise */ isSupportedSource(folderId) { let isSupportedSources = false; const sources = ['-my-', '-root-', '-shared-']; if (sources.indexOf(folderId) > -1) { isSupportedSources = true; } return isSupportedSources; } /** * Gets a folder's contents. * * @param nodeId ID of the target folder node * @param pagination Specifies how to paginate the results * @param includeFields List of data field names to include in the results * @param where Filters the Node list using the *where* condition of the REST API (for example, isFolder=true). See the REST API documentation for more information. * @returns List of items contained in the folder */ loadFolderByNodeId(nodeId, pagination, includeFields = [], where) { if (nodeId === '-trashcan-') { return this.loadTrashcan(pagination, includeFields); } else if (nodeId === '-sharedlinks-') { return this.loadSharedLinks(pagination, includeFields, where); } else if (nodeId === '-sites-') { return this.loadSites(pagination, where); } else if (nodeId === '-mysites-') { return this.loadMemberSites(pagination, where); } else if (nodeId === '-favorites-') { return this.loadFavorites(pagination, includeFields, where); } else if (nodeId === '-recent-') { return this.getRecentFiles('-me-', pagination); } } // TODO: remove it from here /** * Gets the contents of one of the well-known aliases in the form of node ID strings. * * @param nodeId ID of the target folder node * @param pagination Specifies how to paginate the results * @returns List of node IDs */ getCorrespondingNodeIds(nodeId, pagination = {}) { if (this.isCustomSource(nodeId)) { return this.loadFolderByNodeId(nodeId, pagination).pipe(map((result) => result.list.entries.map((node) => this.getIdFromEntry(node, nodeId)))); } else if (nodeId) { // cases when nodeId is '-my-', '-root-' or '-shared-' return from(this.nodesApi.getNode(nodeId).then((node) => [node.entry.id])); } return of([]); } /** * Chooses the correct ID for a node entry. * * @param node Node object * @param nodeId ID of the node object * @returns ID value */ getIdFromEntry(node, nodeId) { if (nodeId === '-sharedlinks-') { return node.entry.nodeId; } else if (nodeId === '-sites-' || nodeId === '-mysites-') { return node.entry.guid; } else if (nodeId === '-favorites-') { return node.entry.targetGuid; } else { return node.entry.id; } } /** * Does the well-known alias have a corresponding node ID? * * @param nodeId Node to check * @returns True if the alias has a corresponding node ID, false otherwise */ hasCorrespondingNodeIds(nodeId) { return this.isCustomSource(nodeId) || this.isSupportedSource(nodeId); } getIncludesFields(includeFields) { return ['path', 'properties', 'allowableOperations', 'permissions', 'aspectNames', ...includeFields].filter((element, index, array) => index === array.indexOf(element)); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: CustomResourcesService, deps: [{ token: i1.AlfrescoApiService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: CustomResourcesService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: CustomResourcesService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.AlfrescoApiService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLXJlc291cmNlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGliL2NvbnRlbnQtc2VydmljZXMvc3JjL2xpYi9kb2N1bWVudC1saXN0L3NlcnZpY2VzL2N1c3RvbS1yZXNvdXJjZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFrQkEsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUtILGdCQUFnQixFQUVoQixTQUFTLEVBQ1QsUUFBUSxFQUNSLFNBQVMsRUFDVCxZQUFZLEVBQ1osY0FBYyxFQUNkLFdBQVcsRUFDWCxRQUFRLEVBR1IsZUFBZSxFQUNsQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBRXJDLE1BQU0saUJBQWlCLEdBQVcsUUFBUSxDQUFDO0FBRzNDLE1BQU0sT0FBTyxzQkFBc0I7SUFFL0IsSUFBSSxTQUFTO1FBQ1QsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNsRixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUdELElBQUksUUFBUTtRQUNSLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDL0UsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUFHRCxJ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QXNCLGNBRFQsTUFBTTs7MkZBQ25CLHNCQUFzQjtrQkFEbEMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgwqkgMjAwNS0yMDI1IEh5bGFuZCBTb2Z0d2FyZSwgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFBhZ2luYXRpb25Nb2RlbCB9IGZyb20gJ0BhbGZyZXNjby9hZGYtY29yZSc7XG5pbXBvcnQgeyBBbGZyZXNjb0FwaVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hbGZyZXNjby1hcGkuc2VydmljZSc7XG5pbXBvcnQge1xuICAgIERlbGV0ZWROb2Rlc1BhZ2luZyxcbiAgICBTZWFyY2hSZXF1ZXN0LFxuICAgIFNoYXJlZExpbmtQYWdpbmcsXG4gICAgRmF2b3JpdGVQYWdpbmcsXG4gICAgU2l0ZU1lbWJlclBhZ2luZyxcbiAgICBTaXRlUm9sZVBhZ2luZyxcbiAgICBQZW9wbGVBcGksXG4gICAgU2l0ZXNBcGksXG4gICAgU2VhcmNoQXBpLFxuICAgIEZhdm9yaXRlc0FwaSxcbiAgICBTaGFyZWRsaW5rc0FwaSxcbiAgICBUcmFzaGNhbkFwaSxcbiAgICBOb2Rlc0FwaSxcbiAgICBTaXRlUGFnaW5nLFxuICAgIFJlc3VsdFNldFBhZ2luZyxcbiAgICBTRUFSQ0hfTEFOR1VBR0Vcbn0gZnJvbSAnQGFsZnJlc2NvL2pzLWFwaSc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmcm9tLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCBDUkVBVEVfUEVSTUlTU0lPTjogc3RyaW5nID0gJ2NyZWF0ZSc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQ3VzdG9tUmVzb3VyY2VzU2VydmljZSB7XG4gICAgcHJpdmF0ZSBfcGVvcGxlQXBpOiBQZW9wbGVBcGk7XG4gICAgZ2V0IHBlb3BsZUFwaSgpOiBQZW9wbGVBcGkge1xuICAgICAgICB0aGlzLl9wZW9wbGVBcGkgPSB0aGlzLl9wZW9wbGVBcGkgPz8gbmV3IFBlb3BsZUFwaSh0aGlzLmFwaVNlcnZpY2UuZ2V0SW5zdGFuY2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9wZW9wbGVBcGk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2l0ZXNBcGk6IFNpdGVzQXBpO1xuICAgIGdldCBzaXRlc0FwaSgpOiBTaXRlc0FwaSB7XG4gICAgICAgIHRoaXMuX3NpdGVzQXBpID0gdGhpcy5fc2l0ZXNBcGkgPz8gbmV3IFNpdGVzQXBpKHRoaXMuYXBpU2VydmljZS5nZXRJbnN0YW5jZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpdGVzQXBpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3RyYXNoY2FuQXBpOiBUcmFzaGNhbkFwaTtcbiAgICBnZXQgdHJhc2hjYW5BcGkoKTogVHJhc2hjYW5BcGkge1xuICAgICAgICB0aGlzLl90cmFzaGNhbkFwaSA9IHRoaXMuX3RyYXNoY2FuQXBpID8/IG5ldyBUcmFzaGNhbkFwaSh0aGlzLmFwaVNlcnZpY2UuZ2V0SW5zdGFuY2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFzaGNhbkFwaTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZWFyY2hBcGk6IFNlYXJjaEFwaTtcbiAgICBnZXQgc2VhcmNoQXBpKCk6IFNlYXJjaEFwaSB7XG4gICAgICAgIHRoaXMuX3NlYXJjaEFwaSA9IHRoaXMuX3NlYXJjaEFwaSA/PyBuZXcgU2VhcmNoQXBpKHRoaXMuYXBpU2VydmljZS5nZXRJbnN0YW5jZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlYXJjaEFwaTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9zaGFyZWRMaW5rc0FwaTogU2hhcmVkbGlua3NBcGk7XG4gICAgZ2V0IHNoYXJlZExpbmtzQXBpKCk6IFNoYXJlZGxpbmtzQXBpIHtcbiAgICAgICAgdGhpcy5fc2hhcmVkTGlua3NBcGkgPSB0aGlzLl9zaGFyZWRMaW5rc0FwaSA/PyBuZXcgU2hhcmVkbGlua3NBcGkodGhpcy5hcGlTZXJ2aWNlLmdldEluc3RhbmNlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcmVkTGlua3NBcGk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZmF2b3JpdGVzQXBpOiBGYXZvcml0ZXNBcGk7XG4gICAgZ2V0IGZhdm9yaXRlc0FwaSgpOiBGYXZvcml0ZXNBcGkge1xuICAgICAgICB0aGlzLl9mYXZvcml0ZXNBcGkgPSB0aGlzLl9mYXZvcml0ZXNBcGkgPz8gbmV3IEZhdm9yaXRlc0FwaSh0aGlzLmFwaVNlcnZpY2UuZ2V0SW5zdGFuY2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYXZvcml0ZXNBcGk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfbm9kZXNBcGk6IE5vZGVzQXBpO1xuICAgIGdldCBub2Rlc0FwaSgpOiBOb2Rlc0FwaSB7XG4gICAgICAgIHRoaXMuX25vZGVzQXBpID0gdGhpcy5fbm9kZXNBcGkgPz8gbmV3IE5vZGVzQXBpKHRoaXMuYXBpU2VydmljZS5nZXRJbnN0YW5jZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGVzQXBpO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBpU2VydmljZTogQWxmcmVzY29BcGlTZXJ2aWNlKSB7fVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBmaWxlcyByZWNlbnRseSBhY2Nlc3NlZCBieSBhIHVzZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGVyc29uSWQgSUQgb2YgdGhlIHVzZXJcbiAgICAgKiBAcGFyYW0gcGFnaW5hdGlvbiBTcGVjaWZpZXMgaG93IHRvIHBhZ2luYXRlIHRoZSByZXN1bHRzXG4gICAgICogQHBhcmFtIGZpbHRlcnMgU3BlY2lmaWVzIGFkZGl0aW9uYWwgZmlsdGVycyB0byBhcHBseSAoam9pbmVkIHdpdGggKipBTkQqKilcbiAgICAgKiBAcmV0dXJucyBMaXN0IG9mIG5vZGVzIGZvciB0aGUgcmVjZW50bHkgdXNlZCBmaWxlc1xuICAgICAqL1xuICAgIGdldFJlY2VudEZpbGVzKHBlcnNvbklkOiBzdHJpbmcsIHBhZ2luYXRpb246IFBhZ2luYXRpb25Nb2RlbCwgZmlsdGVycz86IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxSZXN1bHRTZXRQYWdpbmc+IHtcbiAgICAgICAgY29uc3QgZGVmYXVsdEZpbHRlciA9IFtcbiAgICAgICAgICAgICdUWVBFOlwiY29udGVudFwiJyxcbiAgICAgICAgICAgICctUEFUSDpcIi8vY206d2lraS8qXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiYXBwOmZpbGVsaW5rXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiY206dGh1bWJuYWlsXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiY206ZmFpbGVkVGh1bWJuYWlsXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiY206cmF0aW5nXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiZGw6ZGF0YUxpc3RcIicsXG4gICAgICAgICAgICAnLVRZUEU6XCJkbDp0b2RvTGlzdFwiJyxcbiAgICAgICAgICAgICctVFlQRTpcImRsOmlzc3VlXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiZGw6Y29udGFjdFwiJyxcbiAgICAgICAgICAgICctVFlQRTpcImRsOmV2ZW50QWdlbmRhXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiZGw6ZXZlbnRcIicsXG4gICAgICAgICAgICAnLVRZUEU6XCJkbDp0YXNrXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiZGw6c2ltcGxldGFza1wiJyxcbiAgICAgICAgICAgICctVFlQRTpcImRsOm1lZXRpbmdBZ2VuZGFcIicsXG4gICAgICAgICAgICAnLVRZUEU6XCJkbDpsb2NhdGlvblwiJyxcbiAgICAgICAgICAgICctVFlQRTpcImZtOnRvcGljXCInLFxuICAgICAgICAgICAgJy1UWVBFOlwiZm06cG9zdFwiJyxcbiAgICAgICAgICAgICctVFlQRTpcImlhOmNhbGVuZGFyRXZlbnRcIicsXG4gICAgICAgICAgICAnLVRZUEU6XCJsbms6bGlua1wiJ1xuICAgICAgICBdO1xuXG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGVvcGxlQXBpLmdldFBlcnNvbihwZXJzb25JZCkudGhlbihcbiAgICAgICAgICAgICAgICAocGVyc29uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJuYW1lID0gcGVyc29uLmVudHJ5LmlkO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJRdWVyaWVzID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgeyBxdWVyeTogYGNtOm1vZGlmaWVkOltOT1cvREFZLTMwREFZUyBUTyBOT1cvREFZKzFEQVldYCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBxdWVyeTogYGNtOm1vZGlmaWVyOicke3VzZXJuYW1lfScgT1IgY206Y3JlYXRvcjonJHt1c2VybmFtZX0nYCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBxdWVyeTogZGVmYXVsdEZpbHRlci5qb2luKCcgQU5EICcpIH1cbiAgICAgICAgICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVycyAmJiBmaWx0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlclF1ZXJpZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnk6IGZpbHRlcnMuam9pbigpXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1ZXJ5OiBTZWFyY2hSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeTogJyonLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlOiBTRUFSQ0hfTEFOR1VBR0UuQUZUU1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlclF1ZXJpZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlOiBbJ3BhdGgnLCAncHJvcGVydGllcycsICdhbGxvd2FibGVPcGVyYXRpb25zJywgJ2FzcGVjdE5hbWVzJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3J0OiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnRklFTEQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZDogJ2NtOm1vZGlmaWVkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNjZW5kaW5nOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWdpbmc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhJdGVtczogcGFnaW5hdGlvbi5tYXhJdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwQ291bnQ6IHBhZ2luYXRpb24uc2tpcENvdW50XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VhcmNoQXBpLnNlYXJjaChxdWVyeSkudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgIChzZWFyY2hSZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHNlYXJjaFJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgZmF2b3JpdGUgZmlsZXMgZm9yIHRoZSBjdXJyZW50IHVzZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFnaW5hdGlvbiBTcGVjaWZpZXMgaG93IHRvIHBhZ2luYXRlIHRoZSByZXN1bHRzXG4gICAgICogQHBhcmFtIGluY2x1ZGVGaWVsZHMgTGlzdCBvZiBkYXRhIGZpZWxkIG5hbWVzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdHNcbiAgICAgKiBAcGFyYW0gd2hlcmUgQSBzdHJpbmcgdG8gcmVzdHJpY3QgdGhlIHJldHVybmVkIG9iamVjdHMgYnkgdXNpbmcgYSBwcmVkaWNhdGVcbiAgICAgKiBAcmV0dXJucyBMaXN0IG9mIGZhdm9yaXRlIGZpbGVzXG4gICAgICovXG4gICAgbG9hZEZhdm9yaXRlcyhwYWdpbmF0aW9uOiBQYWdpbmF0aW9uTW9kZWwsIGluY2x1ZGVGaWVsZHM6IHN0cmluZ1tdID0gW10sIHdoZXJlPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxGYXZvcml0ZVBhZ2luZz4ge1xuICAgICAgICBjb25zdCBpbmNsdWRlRmllbGRzUmVxdWVzdCA9IHRoaXMuZ2V0SW5jbHVkZXNGaWVsZHMoaW5jbHVkZUZpZWxkcyk7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRQcmVkaWNhdGUgPSAnKEVYSVNUUyh0YXJnZXQvZmlsZSkgT1IgRVhJU1RTKHRhcmdldC9mb2xkZXIpKSc7XG5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIG1heEl0ZW1zOiBwYWdpbmF0aW9uLm1heEl0ZW1zLFxuICAgICAgICAgICAgc2tpcENvdW50OiBwYWdpbmF0aW9uLnNraXBDb3VudCxcbiAgICAgICAgICAgIHdoZXJlOiB3aGVyZSA/IGAke3doZXJlfSBBTkQgJHtkZWZhdWx0UHJlZGljYXRlfWAgOiBkZWZhdWx0UHJlZGljYXRlLFxuICAgICAgICAgICAgaW5jbHVkZTogaW5jbHVkZUZpZWxkc1JlcXVlc3RcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZhdm9yaXRlc0FwaS5saXN0RmF2b3JpdGVzKCctbWUtJywgb3B0aW9ucykudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhZ2U6IEZhdm9yaXRlUGFnaW5nID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJpZXM6IHJlc3VsdC5saXN0LmVudHJpZXMubWFwKCh7IGVudHJ5IH06IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlbnRyeS50YXJnZXQuZmlsZSB8fCBlbnRyeS50YXJnZXQuZm9sZGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQucHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLih0YXJnZXQucHJvcGVydGllcyB8fCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NtOnRpdGxlJzogZW50cnkudGl0bGUgfHwgdGFyZ2V0LnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjbTpkZXNjcmlwdGlvbic6IGVudHJ5LmRlc2NyaXB0aW9uIHx8IHRhcmdldC5kZXNjcmlwdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4oZW50cnkucHJvcGVydGllcyB8fCB7fSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmFzcGVjdE5hbWVzID0gZW50cnk/LmFzcGVjdE5hbWVzID8/IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuYWxsb3dhYmxlT3BlcmF0aW9ucyA9IGVudHJ5Py5hbGxvd2FibGVPcGVyYXRpb25zID8/IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeTogdGFyZ2V0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnaW5hdGlvbjogcmVzdWx0Lmxpc3QucGFnaW5hdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQocGFnZSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBzaXRlcyB0aGF0IHRoZSBjdXJyZW50IHVzZXIgaXMgYSBtZW1iZXIgb2YuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFnaW5hdGlvbiBTcGVjaWZpZXMgaG93IHRvIHBhZ2luYXRlIHRoZSByZXN1bHRzXG4gICAgICogQHBhcmFtIHdoZXJlIEEgc3RyaW5nIHRvIHJlc3RyaWN0IHRoZSByZXR1cm5lZCBvYmplY3RzIGJ5IHVzaW5nIGEgcHJlZGljYXRlXG4gICAgICogQHJldHVybnMgTGlzdCBvZiBzaXRlc1xuICAgICAqL1xuICAgIGxvYWRNZW1iZXJTaXRlcyhwYWdpbmF0aW9uOiBQYWdpbmF0aW9uTW9kZWwsIHdoZXJlPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxTaXRlTWVtYmVyUGFnaW5nPiB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbmNsdWRlOiBbJ3Byb3BlcnRpZXMnXSxcbiAgICAgICAgICAgIG1heEl0ZW1zOiBwYWdpbmF0aW9uLm1heEl0ZW1zLFxuICAgICAgICAgICAgc2tpcENvdW50OiBwYWdpbmF0aW9uLnNraXBDb3VudCxcbiAgICAgICAgICAgIHdoZXJlXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5zaXRlc0FwaS5saXN0U2l0ZU1lbWJlcnNoaXBzRm9yUGVyc29uKCctbWUtJywgb3B0aW9ucykudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0OiBTaXRlUm9sZVBhZ2luZykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWdlOiBTaXRlTWVtYmVyUGFnaW5nID0gbmV3IFNpdGVNZW1iZXJQYWdpbmcoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJpZXM6IHJlc3VsdC5saXN0LmVudHJpZXMubWFwKCh7IGVudHJ5OiB7IHNpdGUgfSB9OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZS5hbGxvd2FibGVPcGVyYXRpb25zID0gc2l0ZS5hbGxvd2FibGVPcGVyYXRpb25zID8gc2l0ZS5hbGxvd2FibGVPcGVyYXRpb25zIDogW0NSRUFURV9QRVJNSVNTSU9OXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZS5uYW1lID0gc2l0ZS5uYW1lIHx8IHNpdGUudGl0bGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeTogc2l0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luYXRpb246IHJlc3VsdC5saXN0LnBhZ2luYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChwYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBzaXRlcyBpbiB0aGUgcmVwb3NpdG9yeS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwYWdpbmF0aW9uIFNwZWNpZmllcyBob3cgdG8gcGFnaW5hdGUgdGhlIHJlc3VsdHNcbiAgICAgKiBAcGFyYW0gd2hlcmUgQSBzdHJpbmcgdG8gcmVzdHJpY3QgdGhlIHJldHVybmVkIG9iamVjdHMgYnkgdXNpbmcgYSBwcmVkaWNhdGVcbiAgICAgKiBAcmV0dXJucyBMaXN0IG9mIHNpdGVzXG4gICAgICovXG4gICAgbG9hZFNpdGVzKHBhZ2luYXRpb246IFBhZ2luYXRpb25Nb2RlbCwgd2hlcmU/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFNpdGVQYWdpbmc+IHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGluY2x1ZGU6IFsncHJvcGVydGllcycsICdhc3BlY3ROYW1lcyddLFxuICAgICAgICAgICAgbWF4SXRlbXM6IHBhZ2luYXRpb24ubWF4SXRlbXMsXG4gICAgICAgICAgICBza2lwQ291bnQ6IHBhZ2luYXRpb24uc2tpcENvdW50LFxuICAgICAgICAgICAgd2hlcmVcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNpdGVzQXBpLmxpc3RTaXRlcyhvcHRpb25zKS50aGVuKFxuICAgICAgICAgICAgICAgIChwYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHBhZ2UubGlzdC5lbnRyaWVzLm1hcCgoeyBlbnRyeSB9OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5Lm5hbWUgPSBlbnRyeS5uYW1lIHx8IGVudHJ5LnRpdGxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZW50cnkgfTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQocGFnZSk7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgaXRlbXMgY3VycmVudGx5IGluIHRoZSB0cmFzaC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwYWdpbmF0aW9uIFNwZWNpZmllcyBob3cgdG8gcGFnaW5hdGUgdGhlIHJlc3VsdHNcbiAgICAgKiBAcGFyYW0gaW5jbHVkZUZpZWxkcyBMaXN0IG9mIGRhdGEgZmllbGQgbmFtZXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0c1xuICAgICAqIEByZXR1cm5zIExpc3Qgb2YgZGVsZXRlZCBpdGVtc1xuICAgICAqL1xuICAgIGxvYWRUcmFzaGNhbihwYWdpbmF0aW9uOiBQYWdpbmF0aW9uTW9kZWwsIGluY2x1ZGVGaWVsZHM6IHN0cmluZ1tdID0gW10pOiBPYnNlcnZhYmxlPERlbGV0ZWROb2Rlc1BhZ2luZz4ge1xuICAgICAgICBjb25zdCBpbmNsdWRlRmllbGRzUmVxdWVzdCA9IHRoaXMuZ2V0SW5jbHVkZXNGaWVsZHMoaW5jbHVkZUZpZWxkcyk7XG5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGluY2x1ZGU6IGluY2x1ZGVGaWVsZHNSZXF1ZXN0LFxuICAgICAgICAgICAgbWF4SXRlbXM6IHBhZ2luYXRpb24ubWF4SXRlbXMsXG4gICAgICAgICAgICBza2lwQ291bnQ6IHBhZ2luYXRpb24uc2tpcENvdW50XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIGZyb20odGhpcy50cmFzaGNhbkFwaS5saXN0RGVsZXRlZE5vZGVzKG9wdGlvbnMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHNoYXJlZCBsaW5rcyBmb3IgdGhlIGN1cnJlbnQgdXNlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwYWdpbmF0aW9uIFNwZWNpZmllcyBob3cgdG8gcGFnaW5hdGUgdGhlIHJlc3VsdHNcbiAgICAgKiBAcGFyYW0gaW5jbHVkZUZpZWxkcyBMaXN0IG9mIGRhdGEgZmllbGQgbmFtZXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0c1xuICAgICAqIEBwYXJhbSB3aGVyZSBBIHN0cmluZyB0byByZXN0cmljdCB0aGUgcmV0dXJuZWQgb2JqZWN0cyBieSB1c2luZyBhIHByZWRpY2F0ZVxuICAgICAqIEByZXR1cm5zIExpc3Qgb2Ygc2hhcmVkIGxpbmtzXG4gICAgICovXG4gICAgbG9hZFNoYXJlZExpbmtzKHBhZ2luYXRpb246IFBhZ2luYXRpb25Nb2RlbCwgaW5jbHVkZUZpZWxkczogc3RyaW5nW10gPSBbXSwgd2hlcmU/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFNoYXJlZExpbmtQYWdpbmc+IHtcbiAgICAgICAgY29uc3QgaW5jbHVkZUZpZWxkc1JlcXVlc3QgPSB0aGlzLmdldEluY2x1ZGVzRmllbGRzKGluY2x1ZGVGaWVsZHMpO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbmNsdWRlOiBpbmNsdWRlRmllbGRzUmVxdWVzdCxcbiAgICAgICAgICAgIG1heEl0ZW1zOiBwYWdpbmF0aW9uLm1heEl0ZW1zLFxuICAgICAgICAgICAgc2tpcENvdW50OiBwYWdpbmF0aW9uLnNraXBDb3VudCxcbiAgICAgICAgICAgIHdoZXJlXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIGZyb20odGhpcy5zaGFyZWRMaW5rc0FwaS5saXN0U2hhcmVkTGlua3Mob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElzIHRoZSBmb2xkZXIgSUQgb25lIG9mIHRoZSB3ZWxsLWtub3duIGFsaWFzZXM/XG4gICAgICpcbiAgICAgKiBAcGFyYW0gZm9sZGVySWQgRm9sZGVyIElEIG5hbWUgdG8gY2hlY2tcbiAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBJRCBpcyBhIHdlbGwta25vd24gbmFtZSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAgICovXG4gICAgaXNDdXN0b21Tb3VyY2UoZm9sZGVySWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgaXNDdXN0b21Tb3VyY2VzID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHNvdXJjZXMgPSBbJy10cmFzaGNhbi0nLCAnLXNoYXJlZGxpbmtzLScsICctc2l0ZXMtJywgJy1teXNpdGVzLScsICctZmF2b3JpdGVzLScsICctcmVjZW50LSddO1xuXG4gICAgICAgIGlmIChzb3VyY2VzLmluZGV4T2YoZm9sZGVySWQpID4gLTEpIHtcbiAgICAgICAgICAgIGlzQ3VzdG9tU291cmNlcyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaXNDdXN0b21Tb3VyY2VzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElzIHRoZSBmb2xkZXIgSUQgYSBcIi1teVwiLCBcIi1yb290LVwiLCBvciBcIi1zaGFyZWQtXCIgYWxpYXM/XG4gICAgICpcbiAgICAgKiBAcGFyYW0gZm9sZGVySWQgRm9sZGVyIElEIG5hbWUgdG8gY2hlY2tcbiAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBJRCBpcyBvbmUgb2YgdGhlIHN1cHBvcnRlZCBzb3VyY2VzLCBmYWxzZSBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBpc1N1cHBvcnRlZFNvdXJjZShmb2xkZXJJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBpc1N1cHBvcnRlZFNvdXJjZXMgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IFsnLW15LScsICctcm9vdC0nLCAnLXNoYXJlZC0nXTtcblxuICAgICAgICBpZiAoc291cmNlcy5pbmRleE9mKGZvbGRlcklkKSA+IC0xKSB7XG4gICAgICAgICAgICBpc1N1cHBvcnRlZFNvdXJjZXMgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlzU3VwcG9ydGVkU291cmNlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgZm9sZGVyJ3MgY29udGVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbm9kZUlkIElEIG9mIHRoZSB0YXJnZXQgZm9sZGVyIG5vZGVcbiAgICAgKiBAcGFyYW0gcGFnaW5hdGlvbiBTcGVjaWZpZXMgaG93IHRvIHBhZ2luYXRlIHRoZSByZXN1bHRzXG4gICAgICogQHBhcmFtIGluY2x1ZGVGaWVsZHMgTGlzdCBvZiBkYXRhIGZpZWxkIG5hbWVzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdHNcbiAgICAgKiBAcGFyYW0gd2hlcmUgIEZpbHRlcnMgdGhlIE5vZGUgbGlzdCB1c2luZyB0aGUgKndoZXJlKiBjb25kaXRpb24gb2YgdGhlIFJFU1QgQVBJIChmb3IgZXhhbXBsZSwgaXNGb2xkZXI9dHJ1ZSkuIFNlZSB0aGUgUkVTVCBBUEkgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAgKiBAcmV0dXJucyBMaXN0IG9mIGl0ZW1zIGNvbnRhaW5lZCBpbiB0aGUgZm9sZGVyXG4gICAgICovXG4gICAgbG9hZEZvbGRlckJ5Tm9kZUlkKG5vZGVJZDogc3RyaW5nLCBwYWdpbmF0aW9uOiBQYWdpbmF0aW9uTW9kZWwsIGluY2x1ZGVGaWVsZHM6IHN0cmluZ1tdID0gW10sIHdoZXJlPzogc3RyaW5nKTogYW55IHtcbiAgICAgICAgaWYgKG5vZGVJZCA9PT0gJy10cmFzaGNhbi0nKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2FkVHJhc2hjYW4ocGFnaW5hdGlvbiwgaW5jbHVkZUZpZWxkcyk7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZUlkID09PSAnLXNoYXJlZGxpbmtzLScpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRTaGFyZWRMaW5rcyhwYWdpbmF0aW9uLCBpbmNsdWRlRmllbGRzLCB3aGVyZSk7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZUlkID09PSAnLXNpdGVzLScpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRTaXRlcyhwYWdpbmF0aW9uLCB3aGVyZSk7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZUlkID09PSAnLW15c2l0ZXMtJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9hZE1lbWJlclNpdGVzKHBhZ2luYXRpb24sIHdoZXJlKTtcbiAgICAgICAgfSBlbHNlIGlmIChub2RlSWQgPT09ICctZmF2b3JpdGVzLScpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRGYXZvcml0ZXMocGFnaW5hdGlvbiwgaW5jbHVkZUZpZWxkcywgd2hlcmUpO1xuICAgICAgICB9IGVsc2UgaWYgKG5vZGVJZCA9PT0gJy1yZWNlbnQtJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVjZW50RmlsZXMoJy1tZS0nLCBwYWdpbmF0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRPRE86IHJlbW92ZSBpdCBmcm9tIGhlcmVcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNvbnRlbnRzIG9mIG9uZSBvZiB0aGUgd2VsbC1rbm93biBhbGlhc2VzIGluIHRoZSBmb3JtIG9mIG5vZGUgSUQgc3RyaW5ncy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBub2RlSWQgSUQgb2YgdGhlIHRhcmdldCBmb2xkZXIgbm9kZVxuICAgICAqIEBwYXJhbSBwYWdpbmF0aW9uIFNwZWNpZmllcyBob3cgdG8gcGFnaW5hdGUgdGhlIHJlc3VsdHNcbiAgICAgKiBAcmV0dXJucyBMaXN0IG9mIG5vZGUgSURzXG4gICAgICovXG4gICAgZ2V0Q29ycmVzcG9uZGluZ05vZGVJZHMobm9kZUlkOiBzdHJpbmcsIHBhZ2luYXRpb246IFBhZ2luYXRpb25Nb2RlbCA9IHt9KTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbVNvdXJjZShub2RlSWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2FkRm9sZGVyQnlOb2RlSWQobm9kZUlkLCBw