UNPKG

dynamic-display-shared

Version:

A library for dynamic view

392 lines 56.7 kB
import { Injectable, Inject } from '@angular/core'; import { Observable } from 'rxjs'; // import { searchCategoriesMock } from '../models/entity-mock'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { Logger } from '../../infrastructure/logger'; import { applyDownloadLink } from '../documents/documents.helper'; import { downloadFileFinished, downloadFileStarted } from '../store/filter.actions'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "@ngrx/store"; import * as i3 from "../../infrastructure/logger"; export class EntityService { constructor(httpClient, store, logger, env) { this.httpClient = httpClient; this.store = store; this.logger = logger; this.env = env; // public pageSize = 5; // private _entities: Entity[] = []; // private _entitiesSubject: Subject<Entity[]> = new BehaviorSubject<Entity[]>(this._entities); this.innerEntitiesProcessHeight = []; this.cardProcessHeight = []; } getEntities(filterCategories, filtersParametersRange, filterTerm, skip, take, presentationTypeId, administrativeCode, entrepreneurCode, sortId) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities`; const filtersParameters = filterCategories.map(f => { return { parameterId: f.parameterId, values: f.data.map((d) => { return { value: d.dataItem }; }) }; }); const requestBody = { filterTerm, skip, take, presentationTypeId, filtersParameters, filtersParametersRange, sortId }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, requestBody, options).subscribe(response => { observer.next(response); observer.complete(); this.logger.debug(`${response.length} Entities have been fetched successfully`); }, error => { self.logger.error('An error occurred while fetching entities', error); observer.error(error); }); }); } downloadResultFile(filterCategories, filterParametersRange, filterTerm) { // : Observable<{ disposition: string; blobFile: Blob }> { const self = this; this.store.dispatch(downloadFileStarted()); return new Observable(observer => { const url = `${this.getBaseUrl()}/ExcelExport`; const filtersParameters = filterCategories.map(f => { return { parameterId: f.parameterId, values: f.data.map((d) => { return { value: d.dataItem }; }) }; }); const filtersParametersRange = filterParametersRange.map(f => { return { parameterMetadataId: f.parameterMetadataId, valueFrom: f.valueFrom, valueTo: f.valueTo }; }); const requestBody = { filterTerm, skip: 0, take: 1000000, presentationTypeId: 7, filtersParameters, filtersParametersRange }; const options = { responseType: 'blob', observe: 'response', // withCredentials: true, headers: new HttpHeaders({ 'content-type': 'application/json', 'response-type': 'blob', 'Access-Control-Expose-Headers': 'Content-Disposition' // authorization: 'Bearer my JWT', // accept: 'text/plain, */*', // 'Cache-Control': 'no-cache', }) }; this.httpClient.post(url, requestBody, options).subscribe( // @ts-ignore (response) => { const result = { // @ts-ignore blobFile: new Blob([response.body], { type: response.headers.get('Content-Type') }), disposition: response.headers.get('Content-Disposition') }; const dataType = result.blobFile.type; const binaryData = []; binaryData.push(result.blobFile); const href = window.URL.createObjectURL(new Blob(binaryData, { type: dataType })); let filename = null; if (result.disposition) { const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; const matches = filenameRegex.exec(result.disposition); if (matches != null && matches[1]) { filename = matches[1].replace(/['"]/g, ''); } } applyDownloadLink(href, filename); this.store.dispatch(downloadFileFinished()); // observer.next(result); observer.complete(); this.logger.debug(`File have been fetched successfully`); }, error => { self.logger.error('An error occurred while fetching file', error); observer.error(error); this.store.dispatch(downloadFileFinished()); }); }); } getEntity(fixedId, entityType, presentationTypeId) { const url = `${this.getBaseUrl()}/entities/${fixedId}/${Number(entityType)}/${presentationTypeId}`; // todo: return native observble return this.httpClient.get(url); // } } getEntityByBlockParcel(block, parcel, entityType, presentationTypeId) { // let ntt = this.entities.find((e => e.id === entityCode)); // if (ntt) { // return of(ntt); // } else { const url = `${this.getBaseUrl()}/entities/${block}/${parcel}/${Number(entityType)}/${presentationTypeId}`; // todo: return native observble return this.httpClient.get(url); // } } getEntityBySpecificPresentation(presentationId, relatedEntityId) { const url = `${this.getBaseUrl()}/entities/GetEntityBySpecificPresentation/${presentationId}/${relatedEntityId}`; // todo: return native observble return this.httpClient.get(url); // } } getBaseUrl() { return this.env.apiUrl; } getSearchCategories(filterCategories, filterRangeParameters, filterTerm, sortId) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/GetFilterCategories`; const filtersParameters = filterCategories.map(f => { return { parameterId: f.parameterId, values: f.data.map((d) => { return { value: d.dataItem }; }) }; }); const requestBody = { filtersParameters, filterRangeParameters, filterTerm, sortId }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, requestBody, options).subscribe(response => { observer.next(response); self.logger.info('Fetch search categories completed'); observer.complete(); }, error => { self.logger.error('An error occurred while fetching search categories', error); observer.error(error); }); }); } getHousingUnitsCharts(filterCategories, filtersCategoryRange, filterTerm) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/GetHousingUnitsCharts`; const filtersParameters = filterCategories.map(f => { return { parameterId: f.parameterId, values: f.data.map((d) => { return { value: d.dataItem }; }) }; }); const filtersParametersRange = filtersCategoryRange.map(f => { return { parameterMetadataId: f.parameterMetadataId, valueFrom: f.valueFrom, valueTo: f.valueTo }; }); const requestBody = { filtersParameters, filtersParametersRange, filterTerm }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, requestBody, options).subscribe(response => { observer.next(response); self.logger.info('Fetch housing units charts completed'); observer.complete(); }, error => { self.logger.error('An error occurred while fetching housing units charts', error); observer.error(error); }); }); } getHousingUnitsChartsHeaders(filterCategories, filtersCategoryRange, filterTerm) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/GetHousingUnitsChartsHeaders`; const filtersParameters = filterCategories.map(f => { return { parameterId: f.parameterId, values: f.data.map((d) => { return { value: d.dataItem }; }) }; }); const filtersParametersRange = filtersCategoryRange.map(f => { return { parameterMetadataId: f.parameterMetadataId, valueFrom: f.valueFrom, valueTo: f.valueTo }; }); const requestBody = { filtersParameters, filtersParametersRange, filterTerm }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, requestBody, options).subscribe(response => { observer.next(response); self.logger.info('Fetch housing units charts headers completed'); observer.complete(); }, error => { self.logger.error('An error occurred while fetching housing units charts headers.', error); observer.error(error); }); }); } getTargetCharts() { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/GetTargetCharts`; // const filtersParameters = filterCategories.map(f => { // return { // parameterId: f.parameterId, // values: f.data.map(d => { // return { value: d.dataItem }; // }) // }; // } // ); const requestBody = { //filtersParameters, filterTerm }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.get(url, options).subscribe(response => { observer.next(response); self.logger.info('Fetch target charts completed'); observer.complete(); }, error => { self.logger.error('An error occurred while fetching target charts', error); observer.error(error); }); }); } getStatusEntities(processId) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/GetStatusEntities`; const requestBody = { processId }; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, requestBody, options).subscribe(response => { observer.next(response); self.logger.info(`Get entitiesStatus completed`); observer.complete(); }, error => { self.logger.error(`An error occurred while get entitiesStatus`, error); observer.error(error); }); }); } getEntityTemplate(entityTypeId, presentationTypeId, parentRangeId) { const self = this; return new Observable(observer => { let url; if (parentRangeId) { url = `${this.getBaseUrl()}/entities/GetEntityTemplate/${entityTypeId}/${presentationTypeId}/${parentRangeId}`; } else { url = `${this.getBaseUrl()}/entities/GetEntityTemplate/${entityTypeId}/${presentationTypeId}/0`; } // const requestBody = { entityTypeId: entityTypeId }; // const options = { // headers: new HttpHeaders({ // 'Content-Type': 'application/json', // }) // }; this.httpClient.get(url).subscribe(response => { observer.next(response); self.logger.info(`Add&Get entitiy completed`); observer.complete(); }, error => { self.logger.error(`An error occurred while add&get entity`, error); observer.error(error); }); }); } markSuperRange(entityId, isSuperRange) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/MarkSuperRange/${entityId}`; const options = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; this.httpClient.post(url, isSuperRange, options).subscribe(response => { observer.next(response); self.logger.info(`Mark entity ${entityId} as super range completed`); observer.complete(); }, error => { self.logger.error(`An error occurred while mark entity ${entityId} as super range`, error); observer.error(error); }); }); } deleteEntity(entityId) { const self = this; return new Observable(observer => { const url = `${this.getBaseUrl()}/entities/Delete/${entityId}`; this.httpClient.delete(url).subscribe(response => { observer.next(response); self.logger.info(`Delete entitiy completed`); observer.complete(); }, error => { self.logger.error(`An error occurred while delete entity`, error); observer.error(error); }); }); } getSortOptions(entityMetadataId) { const url = `${this.getBaseUrl()}/entities/GetSortOptions/${entityMetadataId}`; // todo: return native observble return this.httpClient.get(url); // } } } EntityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: EntityService, deps: [{ token: i1.HttpClient }, { token: i2.Store }, { token: i3.Logger }, { token: 'env' }], target: i0.ɵɵFactoryTarget.Injectable }); EntityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: EntityService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: EntityService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.Store }, { type: i3.Logger }, { type: undefined, decorators: [{ type: Inject, args: ['env'] }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9keW5hbWljLWRpc3BsYXktc2hhcmVkL3NyYy9saWIvc2hhcmVkL3NlcnZpY2VzL2VudGl0eS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbEMsZ0VBQWdFO0FBQ2hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFnQixNQUFNLHNCQUFzQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDcEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBUWxFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7OztBQUtwRixNQUFNLE9BQU8sYUFBYTtJQVF4QixZQUNVLFVBQXNCLEVBQ3RCLEtBQXlCLEVBQVUsTUFBYyxFQUNoQyxHQUFRO1FBRnpCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsVUFBSyxHQUFMLEtBQUssQ0FBb0I7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2hDLFFBQUcsR0FBSCxHQUFHLENBQUs7UUFWbkMsdUJBQXVCO1FBQ3ZCLG9DQUFvQztRQUNwQywrRkFBK0Y7UUFFeEYsK0JBQTBCLEdBQWEsRUFBRSxDQUFDO1FBQzFDLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztJQUtELENBQUM7SUFJakMsV0FBVyxDQUFDLGdCQUFrQyxFQUFDLHNCQUE4QyxFQUFFLFVBQWtCLEVBQUUsSUFBWSxFQUFFLElBQVksRUFBRSxrQkFBMEIsRUFDOUssa0JB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IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEVudGl0eSB9IGZyb20gJy4uLy4uL3NoYXJlZC9tb2RlbC9lbnRpdHknO1xyXG4vLyBpbXBvcnQgeyBzZWFyY2hDYXRlZ29yaWVzTW9jayB9IGZyb20gJy4uL21vZGVscy9lbnRpdHktbW9jayc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBIZWFkZXJzLCBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IFN0b3JlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xyXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbmZyYXN0cnVjdHVyZS9sb2dnZXInO1xyXG5pbXBvcnQgeyBhcHBseURvd25sb2FkTGluayB9IGZyb20gJy4uL2RvY3VtZW50cy9kb2N1bWVudHMuaGVscGVyJztcclxuaW1wb3J0IHsgRW50aXR5VHlwZUluc3RhbmNlIH0gZnJvbSAnLi4vbW9kZWwvZW50aXR5LXR5cGUtaW5zdGFuY2UnO1xyXG5pbXBvcnQgeyBTb3J0T3B0aW9uIH0gZnJvbSAnLi4vbW9kZWwvc29ydC1vcHRpb24nO1xyXG5pbXBvcnQgeyBGaWx0ZXJDYXRlZ29yeSB9IGZyb20gJy4uL21vZGVsL2ZpbHRlci1jYXRlZ29yeSc7XHJcbmltcG9ydCB7IEZpbHRlclJhbmdlUGFyYW1ldGVyIH0gZnJvbSAnLi4vbW9kZWwvZmlsdGVyLXJhbmdlLXBhcmFtZXRlcic7XHJcbmltcG9ydCB7IEhvdXNpbmdVbml0c0NoYXJ0SGVhZGVyIH0gZnJvbSAnLi4vbW9kZWwvaG91c2luZy11bml0cy1jaGFydC1oZWFkZXInO1xyXG5pbXBvcnQgeyBIb3VzaW5nVW5pdHNDaGFydCB9IGZyb20gJy4uL21vZGVsL2hvdXNpbmctdW5pdHMtY2hhcnQnO1xyXG5pbXBvcnQgeyBUYXJnZXRDaGFydCB9IGZyb20gJy4uL21vZGVsL3RhcmdldC1jaGFydCc7XHJcbmltcG9ydCB7IGRvd25sb2FkRmlsZUZpbmlzaGVkLCBkb3dubG9hZEZpbGVTdGFydGVkIH0gZnJvbSAnLi4vc3RvcmUvZmlsdGVyLmFjdGlvbnMnO1xyXG5pbXBvcnQgeyBGaWx0ZXJTdGF0ZSB9IGZyb20gJy4uL3N0b3JlL2ZpbHRlci5yZWR1Y2VyJztcclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRW50aXR5U2VydmljZSB7XHJcbiAgLy8gcHVibGljIHBhZ2VTaXplID0gNTtcclxuICAvLyBwcml2YXRlIF9lbnRpdGllczogRW50aXR5W10gPSBbXTtcclxuICAvLyBwcml2YXRlIF9lbnRpdGllc1N1YmplY3Q6IFN1YmplY3Q8RW50aXR5W10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxFbnRpdHlbXT4odGhpcy5fZW50aXRpZXMpO1xyXG5cclxuICBwdWJsaWMgaW5uZXJFbnRpdGllc1Byb2Nlc3NIZWlnaHQ6IG51bWJlcltdID0gW107XHJcbiAgcHVibGljIGNhcmRQcm9jZXNzSGVpZ2h0OiBudW1iZXJbXSA9IFtdO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgaHR0cENsaWVudDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgc3RvcmU6IFN0b3JlPEZpbHRlclN0YXRlPiwgcHJpdmF0ZSBsb2dnZXI6IExvZ2dlcixcclxuICAgIEBJbmplY3QoJ2VudicpIHByb3RlY3RlZCBlbnY6IGFueSkgeyB9XHJcblxyXG5cclxuXHJcbiAgcHVibGljIGdldEVudGl0aWVzKGZpbHRlckNhdGVnb3JpZXM6IEZpbHRlckNhdGVnb3J5W10sZmlsdGVyc1BhcmFtZXRlcnNSYW5nZTogRmlsdGVyUmFuZ2VQYXJhbWV0ZXJbXSwgZmlsdGVyVGVybTogc3RyaW5nLCBza2lwOiBudW1iZXIsIHRha2U6IG51bWJlciwgcHJlc2VudGF0aW9uVHlwZUlkOiBudW1iZXIsXHJcbiAgICBhZG1pbmlzdHJhdGl2ZUNvZGU6IG51bWJlciwgZW50cmVwcmVuZXVyQ29kZTogbnVtYmVyLCBzb3J0SWQ6IG51bWJlcilcclxuICAgIDogT2JzZXJ2YWJsZTxFbnRpdHlbXT4ge1xyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xyXG5cclxuICAgICAgY29uc3QgdXJsID0gYCR7dGhpcy5nZXRCYXNlVXJsKCl9L2VudGl0aWVzYDtcclxuICAgICAgY29uc3QgZmlsdGVyc1BhcmFtZXRlcnMgPSBmaWx0ZXJDYXRlZ29yaWVzLm1hcChmID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgcGFyYW1ldGVySWQ6IGYucGFyYW1ldGVySWQsXHJcbiAgICAgICAgICB2YWx1ZXM6IGYuZGF0YS5tYXAoKGQ6IHsgZGF0YUl0ZW06IGFueTsgfSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogZC5kYXRhSXRlbSB9O1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3RCb2R5ID0ge1xyXG4gICAgICAgIGZpbHRlclRlcm0sXHJcbiAgICAgICAgc2tpcCxcclxuICAgICAgICB0YWtlLFxyXG4gICAgICAgIHByZXNlbnRhdGlvblR5cGVJZCxcclxuICAgICAgICBmaWx0ZXJzUGFyYW1ldGVycyxcclxuICAgICAgICBmaWx0ZXJzUGFyYW1ldGVyc1JhbmdlLFxyXG4gICAgICAgIHNvcnRJZFxyXG4gICAgICB9O1xyXG4gICAgICBjb25zdCBvcHRpb25zID0ge1xyXG4gICAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyh7XHJcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxyXG4gICAgICAgIH0pXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aGlzLmh0dHBDbGllbnQucG9zdDxFbnRpdHlbXT4odXJsLCByZXF1ZXN0Qm9keSwgb3B0aW9ucykuc3Vic2NyaWJlKFxyXG4gICAgICAgIHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgIG9ic2VydmVyLm5leHQocmVzcG9uc2UpO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3Jlc3BvbnNlLmxlbmd0aH0gRW50aXRpZXMgaGF2ZSBiZWVuIGZldGNoZWQgc3VjY2Vzc2Z1bGx5YCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvciA9PiB7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgZmV0Y2hpbmcgZW50aXRpZXMnLCBlcnJvcik7XHJcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZG93bmxvYWRSZXN1bHRGaWxlKGZpbHRlckNhdGVnb3JpZXM6IEZpbHRlckNhdGVnb3J5W10sIGZpbHRlclBhcmFtZXRlcnNSYW5nZTogRmlsdGVyUmFuZ2VQYXJhbWV0ZXJbXSwgZmlsdGVyVGVybTogc3RyaW5nKVxyXG4gICAgOiBPYnNlcnZhYmxlPHt9PiB7XHJcbiAgICAvLyA6IE9ic2VydmFibGU8eyBkaXNwb3NpdGlvbjogc3RyaW5nOyBibG9iRmlsZTogQmxvYiB9PiB7XHJcbiAgICBjb25zdCBzZWxmID0gdGhpcztcclxuICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2goZG93bmxvYWRGaWxlU3RhcnRlZCgpKTtcclxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XHJcblxyXG4gICAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmdldEJhc2VVcmwoKX0vRXhjZWxFeHBvcnRgO1xyXG4gICAgICBjb25zdCBmaWx0ZXJzUGFyYW1ldGVycyA9IGZpbHRlckNhdGVnb3JpZXMubWFwKGYgPT4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBwYXJhbWV0ZXJJZDogZi5wYXJhbWV0ZXJJZCxcclxuICAgICAgICAgIHZhbHVlczogZi5kYXRhLm1hcCgoZDogeyBkYXRhSXRlbTogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBkLmRhdGFJdGVtIH07XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgICAgKTtcclxuICAgICAgY29uc3QgZmlsdGVyc1BhcmFtZXRlcnNSYW5nZSA9IGZpbHRlclBhcmFtZXRlcnNSYW5nZS5tYXAoZiA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIHBhcmFtZXRlck1ldGFkYXRhSWQ6IGYucGFyYW1ldGVyTWV0YWRhdGFJZCxcclxuICAgICAgICAgIHZhbHVlRnJvbTogZi52YWx1ZUZyb20sXHJcbiAgICAgICAgICB2YWx1ZVRvOiBmLnZhbHVlVG9cclxuICAgICAgICB9O1xyXG4gICAgICB9KTtcclxuICAgICAgY29uc3QgcmVxdWVzdEJvZHkgPSB7XHJcbiAgICAgICAgZmlsdGVyVGVybSxcclxuICAgICAgICBza2lwOiAwLFxyXG4gICAgICAgIHRha2U6IDEwMDAwMDAsXHJcbiAgICAgICAgcHJlc2VudGF0aW9uVHlwZUlkOiA3LFxyXG4gICAgICAgIGZpbHRlcnNQYXJhbWV0ZXJzLFxyXG4gICAgICAgIGZpbHRlcnNQYXJhbWV0ZXJzUmFuZ2UgXHJcbiAgICAgIH07XHJcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgcmVzcG9uc2VUeXBlOiAnYmxvYicgYXMgJ2pzb24nLFxyXG4gICAgICAgIG9ic2VydmU6ICdyZXNwb25zZScgYXMgJ2JvZHknLFxyXG4gICAgICAgIC8vIHdpdGhDcmVkZW50aWFsczogdHJ1ZSxcclxuICAgICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMoe1xyXG4gICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcclxuICAgICAgICAgICdyZXNwb25zZS10eXBlJzogJ2Jsb2InIGFzICdqc29uJyxcclxuICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1FeHBvc2UtSGVhZGVycyc6ICdDb250ZW50LURpc3Bvc2l0aW9uJ1xyXG4gICAgICAgICAgLy8gYXV0aG9yaXphdGlvbjogJ0JlYXJlciBteSBKV1QnLFxyXG4gICAgICAgICAgLy8gYWNjZXB0OiAndGV4dC9wbGFpbiwgKi8qJyxcclxuICAgICAgICAgIC8vICdDYWNoZS1Db250cm9sJzogJ25vLWNhY2hlJyxcclxuICAgICAgICB9KVxyXG4gICAgICB9O1xyXG4gICAgICB0aGlzLmh0dHBDbGllbnQucG9zdCh1cmwsIHJlcXVlc3RCb2R5LCBvcHRpb25zKS5zdWJzY3JpYmUoXHJcbi8vIEB0cy1pZ25vcmVcclxuICAgICAgICAocmVzcG9uc2U6IEh0dHBSZXNwb25zZTxCbG9iPikgPT4ge1xyXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0ge1xyXG4vLyBAdHMtaWdub3JlXHJcbiAgICAgICAgICAgIGJsb2JGaWxlOiBuZXcgQmxvYihbcmVzcG9uc2UuYm9keV0sIHsgdHlwZTogcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIH0pLFxyXG4gICAgICAgICAgICBkaXNwb3NpdGlvbjogcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtRGlzcG9zaXRpb24nKVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIGNvbnN0IGRhdGFUeXBlID0gcmVzdWx0LmJsb2JGaWxlLnR5cGU7XHJcbiAgICAgICAgICBjb25zdCBiaW5hcnlEYXRhID0gW107XHJcbiAgICAgICAgICBiaW5hcnlEYXRhLnB1c2gocmVzdWx0LmJsb2JGaWxlKTtcclxuICAgICAgICAgIGNvbnN0IGhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihiaW5hcnlEYXRhLCB7IHR5cGU6IGRhdGFUeXBlIH0pKTtcclxuICAgICAgICAgIGxldCBmaWxlbmFtZSA9IG51bGw7XHJcbiAgICAgICAgICBpZiAocmVzdWx0LmRpc3Bvc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGVuYW1lUmVnZXggPSAvZmlsZW5hbWVbXjs9XFxuXSo9KChbJ1wiXSkuKj9cXDJ8W147XFxuXSopLztcclxuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGZpbGVuYW1lUmVnZXguZXhlYyhyZXN1bHQuZGlzcG9zaXRpb24pO1xyXG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAhPSBudWxsICYmIG1hdGNoZXNbMV0pIHtcclxuICAgICAgICAgICAgICBmaWxlbmFtZSA9IG1hdGNoZXNbMV0ucmVwbGFjZSgvWydcIl0vZywgJycpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBhcHBseURvd25sb2FkTGluayhocmVmLCBmaWxlbmFtZSk7XHJcbiAgICAgICAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKGRvd25sb2FkRmlsZUZpbmlzaGVkKCkpO1xyXG5cclxuICAgICAgICAgIC8vIG9ic2VydmVyLm5leHQocmVzdWx0KTtcclxuICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgRmlsZSBoYXZlIGJlZW4gZmV0Y2hlZCBzdWNjZXNzZnVsbHlgKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVycm9yID0+IHtcclxuICAgICAgICAgIHNlbGYubG9nZ2VyLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBmZXRjaGluZyBmaWxlJywgZXJyb3IpO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgICAgdGhpcy5zdG9yZS5kaXNwYXRjaChkb3dubG9hZEZpbGVGaW5pc2hlZCgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgZ2V0RW50aXR5KGZpeGVkSWQ6IHN0cmluZywgZW50aXR5VHlwZTogRW50aXR5VHlwZUluc3RhbmNlLCBwcmVzZW50YXRpb25UeXBlSWQ6IG51bWJlcilcclxuICAgIDogT2JzZXJ2YWJsZTxFbnRpdHk+IHtcclxuXHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmdldEJhc2VVcmwoKX0vZW50aXRpZXMvJHtmaXhlZElkfS8ke051bWJlcihlbnRpdHlUeXBlKX0vJHtwcmVzZW50YXRpb25UeXBlSWR9YDtcclxuICAgIC8vIHRvZG86IHJldHVybiBuYXRpdmUgb2JzZXJ2YmxlXHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxFbnRpdHk+KHVybCk7XHJcblxyXG4gICAgLy8gfVxyXG4gIH1cclxuXHJcbiAgZ2V0RW50aXR5QnlCbG9ja1BhcmNlbChibG9jazogbnVtYmVyLCBwYXJjZWw6IG51bWJlciwgZW50aXR5VHlwZTogRW50aXR5VHlwZUluc3RhbmNlLCBwcmVzZW50YXRpb25UeXBlSWQ6IG51bWJlcilcclxuICAgIDogT2JzZXJ2YWJsZTxFbnRpdHk+IHtcclxuICAgIC8vIGxldCBudHQgPSB0aGlzLmVudGl0aWVzLmZpbmQoKGUgPT4gZS5pZCA9PT0gZW50aXR5Q29kZSkpO1xyXG4gICAgLy8gaWYgKG50dCkge1xyXG4gICAgLy8gICByZXR1cm4gb2YobnR0KTtcclxuICAgIC8vIH0gZWxzZSB7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmdldEJhc2VVcmwoKX0vZW50aXRpZXMvJHtibG9ja30vJHtwYXJjZWx9LyR7TnVtYmVyKGVudGl0eVR5cGUpfS8ke3ByZXNlbnRhdGlvblR5cGVJZH1gO1xyXG4gICAgLy8gdG9kbzogcmV0dXJuIG5hdGl2ZSBvYnNlcnZibGVcclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0PEVudGl0eT4odXJsKTtcclxuXHJcbiAgICAvLyB9XHJcbiAgfVxyXG5cclxuICBnZXRFbnRpdHlCeVNwZWNpZmljUHJlc2VudGF0aW9uKHByZXNlbnRhdGlvbklkOiBudW1iZXIsIHJlbGF0ZWRFbnRpdHlJZDogbnVtYmVyKVxyXG4gICAgOiBPYnNlcnZhYmxlPEVudGl0eT4ge1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5nZXRCYXNlVXJsKCl9L2VudGl0aWVzL0dldEVudGl0eUJ5U3BlY2lmaWNQcmVzZW50YXRpb24vJHtwcmVzZW50YXRpb25JZH0vJHtyZWxhdGVkRW50aXR5SWR9YDtcclxuICAgIC8vIHRvZG86IHJldHVybiBuYXRpdmUgb2JzZXJ2YmxlXHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxFbnRpdHk+KHVybCk7XHJcblxyXG4gICAgLy8gfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRCYXNlVXJsKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5lbnYuYXBpVXJsO1xyXG4gIH1cclxuICBwdWJsaWMgZ2V0U2VhcmNoQ2F0ZWdvcmllcyhmaWx0ZXJDYXRlZ29yaWVzOiBGaWx0ZXJDYXRlZ29yeVtdLCBmaWx0ZXJSYW5nZVBhcmFtZXRlcnM6IEZpbHRlclJhbmdlUGFyYW1ldGVyW10sIGZpbHRlclRlcm06IHN0cmluZywgc29ydElkOiBudW1iZXIpXHJcbiAgICA6IE9ic2VydmFibGU8RmlsdGVyQ2F0ZWdvcnlbXT4ge1xyXG5cclxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xyXG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcclxuICAgICAgY29uc3QgdXJsID0gYCR7dGhpcy5nZXRCYXNlVXJsKCl9L2VudGl0aWVzL0dldEZpbHRlckNhdGVnb3JpZXNgO1xyXG4gICAgICBjb25zdCBmaWx0ZXJzUGFyYW1ldGVycyA9IGZpbHRlckNhdGVnb3JpZXMubWFwKGYgPT4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBwYXJhbWV0ZXJJZDogZi5wYXJhbWV0ZXJJZCxcclxuICAgICAgICAgIHZhbHVlczogZi5kYXRhLm1hcCgoZDogeyBkYXRhSXRlbTogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBkLmRhdGFJdGVtIH07XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgICAgKTtcclxuICAgICAgY29uc3QgcmVxdWVzdEJvZHkgPSB7XHJcbiAgICAgICAgZmlsdGVyc1BhcmFtZXRlcnMsIGZpbHRlclJhbmdlUGFyYW1ldGVycywgZmlsdGVyVGVybSwgc29ydElkXHJcbiAgICAgIH07XHJcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHtcclxuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICAgICAgfSlcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHRoaXMuaHR0cENsaWVudC5wb3N0PEZpbHRlckNhdGVnb3J5W10+KHVybCwgcmVxdWVzdEJvZHksIG9wdGlvbnMpLnN1YnNjcmliZShcclxuICAgICAgICByZXNwb25zZSA9PiB7XHJcblxyXG4gICAgICAgICAgb2JzZXJ2ZXIubmV4dChyZXNwb25zZSk7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5pbmZvKCdGZXRjaCBzZWFyY2ggY2F0ZWdvcmllcyBjb21wbGV0ZWQnKTtcclxuICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvciA9PiB7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgZmV0Y2hpbmcgc2VhcmNoIGNhdGVnb3JpZXMnLCBlcnJvcik7XHJcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0SG91c2luZ1VuaXRzQ2hhcnRzKGZpbHRlckNhdGVnb3JpZXM6IEZpbHRlckNhdGVnb3J5W10sZmlsdGVyc0NhdGVnb3J5UmFuZ2U6IEZpbHRlclJhbmdlUGFyYW1ldGVyW10sIGZpbHRlclRlcm06IHN0cmluZylcclxuICAgIDogT2JzZXJ2YWJsZTxIb3VzaW5nVW5pdHNDaGFydFtdPiB7XHJcblxyXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xyXG4gICAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmdldEJhc2VVcmwoKX0vZW50aXRpZXMvR2V0SG91c2luZ1VuaXRzQ2hhcnRzYDtcclxuICAgICAgY29uc3QgZmlsdGVyc1BhcmFtZXRlcnMgPSBmaWx0ZXJDYXRlZ29yaWVzLm1hcChmID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgcGFyYW1ldGVySWQ6IGYucGFyYW1ldGVySWQsXHJcbiAgICAgICAgICB2YWx1ZXM6IGYuZGF0YS5tYXAoKGQ6IHsgZGF0YUl0ZW06IGFueTsgfSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogZC5kYXRhSXRlbSB9O1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IGZpbHRlcnNQYXJhbWV0ZXJzUmFuZ2UgPSBmaWx0ZXJzQ2F0ZWdvcnlSYW5nZS5tYXAoZiA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIHBhcmFtZXRlck1ldGFkYXRhSWQ6IGYucGFyYW1ldGVyTWV0YWRhdGFJZCxcclxuICAgICAgICAgIHZhbHVlRnJvbTogZi52YWx1ZUZyb20sXHJcbiAgICAgICAgICB2YWx1ZVRvOiBmLnZhbHVlVG9cclxuICAgICAgICB9O1xyXG4gICAgICB9KTtcclxuICAgICAgY29uc3QgcmVxdWVzdEJvZHkgPSB7XHJcbiAgICAgICAgZmlsdGVyc1BhcmFtZXRlcnMsIGZpbHRlcnNQYXJhbWV0ZXJzUmFuZ2UsIGZpbHRlclRlcm0gXHJcbiAgICAgIH07XHJcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHtcclxuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICAgICAgfSlcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHRoaXMuaHR0cENsaWVudC5wb3N0PEhvdXNpbmdVbml0c0NoYXJ0W10+KHVybCwgcmVxdWVzdEJvZHksIG9wdGlvbnMpLnN1YnNjcmliZShcclxuICAgICAgICByZXNwb25zZSA9PiB7XHJcblxyXG4gICAgICAgICAgb2JzZXJ2ZXIubmV4dChyZXNwb25zZSk7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5pbmZvKCdGZXRjaCBob3VzaW5nIHVuaXRzIGNoYXJ0cyBjb21wbGV0ZWQnKTtcclxuICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvciA9PiB7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgZmV0Y2hpbmcgaG91c2luZyB1bml0cyBjaGFydHMnLCBlcnJvcik7XHJcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0SG91c2luZ1VuaXRzQ2hhcnRzSGVhZGVycyhmaWx0ZXJDYXRlZ29yaWVzOiBGaWx0ZXJDYXRlZ29yeVtdLGZpbHRlcnNDYXRlZ29yeVJhbmdlOiBGaWx0ZXJSYW5nZVBhcmFtZXRlcltdLCBmaWx0ZXJUZXJtOiBzdHJpbmcpXHJcbiAgICA6IE9ic2VydmFibGU8SG91c2luZ1VuaXRzQ2hhcnRIZWFkZXJbXT4ge1xyXG5cclxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xyXG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcclxuICAgICAgY29uc3QgdXJsID0gYCR7dGhpcy5nZXRCYXNlVXJsKCl9L2VudGl0aWVzL0dldEhvdXNpbmdVbml0c0NoYXJ0c0hlYWRlcnNgO1xyXG4gICAgICBjb25zdCBmaWx0ZXJzUGFyYW1ldGVycyA9IGZpbHRlckNhdGVnb3JpZXMubWFwKGYgPT4ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBwYXJhbWV0ZXJJZDogZi5wYXJhbWV0ZXJJZCxcclxuICAgICAgICAgIHZhbHVlczogZi5kYXRhLm1hcCgoZDogeyBkYXRhSXRlbTogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBkLmRhdGFJdGVtIH07XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgICAgKTtcclxuICAgICAgY29uc3QgZmlsdGVyc1BhcmFtZXRlcnNSYW5nZSA9IGZpbHRlcnNDYXRlZ29yeVJhbmdlLm1hcChmID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgcGFyYW1ldGVyTWV0YWRhdGFJZDogZi5wYXJhbWV0ZXJNZXRhZGF0YUlkLFxyXG4gICAgICAgICAgdmFsdWVGcm9tOiBmLnZhbHVlRnJvbSxcclxuICAgICAgICAgIHZhbHVlVG86IGYudmFsdWVUb1xyXG4gICAgICAgIH07XHJcbiAgICAgIH0pO1xyXG4gICAgICBjb25zdCByZXF1ZXN0Qm9keSA9IHtcclxuICAgICAgICBmaWx0ZXJzUGFyYW1ldGVycyxmaWx0ZXJzUGFyYW1ldGVyc1JhbmdlLCBmaWx0ZXJUZXJtIFxyXG4gICAgICB9O1xyXG4gICAgICBjb25zdCBvcHRpb25zID0ge1xyXG4gICAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyh7XHJcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxyXG4gICAgICAgIH0pXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aGlzLmh0dHBDbGllbnQucG9zdDxIb3VzaW5nVW5pdHNDaGFydEhlYWRlcltdPih1cmwsIHJlcXVlc3RCb2R5LCBvcHRpb25zKS5zdWJzY3JpYmUoXHJcbiAgICAgICAgcmVzcG9uc2UgPT4ge1xyXG5cclxuICAgICAgICAgIG9ic2VydmVyLm5leHQocmVzcG9uc2UpO1xyXG4gICAgICAgICAgc2VsZi5sb2dnZXIuaW5mbygnRmV0Y2ggaG91c2luZyB1bml0cyBjaGFydHMgaGVhZGVycyBjb21wbGV0ZWQnKTtcclxuICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvciA9PiB7XHJcbiAgICAgICAgICBzZWxmLmxvZ2dlci5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgZmV0Y2hpbmcgaG9