UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

331 lines 53.8 kB
import { Inject, Injectable, Optional } from '@angular/core'; import { BehaviorSubject, of, ReplaySubject, Subject, timer } from 'rxjs'; import { catchError, concatMap, filter, map, mergeMap, scan, switchMap, take, tap } from 'rxjs/operators'; import { HttpParams } from '@angular/common/http'; import { TaskEndpoint } from '../models/task-endpoint'; import { NAE_PREFERRED_TASK_ENDPOINT } from '../models/injection-token-task-endpoint'; import { PageLoadRequestContext } from '../../abstract/page-load-request-context'; import { LoadingWithFilterEmitter } from '../../../utility/loading-with-filter-emitter'; import { arrayToObservable } from '../../../utility/array-to-observable'; import { AbstractSortableViewComponent } from '../../abstract/sortable-view'; import { NAE_TASK_VIEW_CONFIGURATION } from '../models/task-view-configuration-injection-token'; import { PaginationParams } from '../../../utility/pagination/pagination-params'; import { createSortParam, PaginationSort } from '../../../utility/pagination/pagination-sort'; import * as i0 from "@angular/core"; import * as i1 from "../../../resources/engine-endpoint/task-resource.service"; import * as i2 from "../../../user/services/user.service"; import * as i3 from "../../../snack-bar/services/snack-bar.service"; import * as i4 from "@ngx-translate/core"; import * as i5 from "../../../search/search-service/search.service"; import * as i6 from "../../../logger/services/logger.service"; import * as i7 from "../../../user/services/user-comparator.service"; import * as i8 from "../../../search/search-keyword-resolver-service/search-index-resolver.service"; import * as i9 from "../models/task-endpoint"; export class TaskViewService extends AbstractSortableViewComponent { _taskService; _userService; _snackBarService; _translate; _searchService; _log; _userComparator; _preferredEndpoint; _tasks$; _changedFields$; _requestedPage$; _loading$; _endOfData; _pagination; _initiallyOpenOneTask; _closeTaskTabOnNoTasks; _panelUpdate$; _closeTab$; _subInitiallyOpen; _subCloseTask; _subSearch; // Serializing assign after cancel _allowMultiOpen; _initializing = true; _paginationView = false; constructor(_taskService, _userService, _snackBarService, _translate, _searchService, _log, _userComparator, resolver, _preferredEndpoint = null, taskViewConfig = null) { super(resolver); this._taskService = _taskService; this._userService = _userService; this._snackBarService = _snackBarService; this._translate = _translate; this._searchService = _searchService; this._log = _log; this._userComparator = _userComparator; this._preferredEndpoint = _preferredEndpoint; this._tasks$ = new Subject(); this._loading$ = new LoadingWithFilterEmitter(); this._changedFields$ = new Subject(); this._allowMultiOpen = true; this._endOfData = false; this._pagination = { size: 50, totalElements: undefined, totalPages: undefined, number: -1 }; this._requestedPage$ = new BehaviorSubject(new PageLoadRequestContext(this.activeFilter, Object.assign({}, this._pagination, { number: 0 }))); this._panelUpdate$ = new BehaviorSubject([]); this._closeTab$ = new ReplaySubject(1); this._preferredEndpoint = taskViewConfig?.preferredEndpoint ?? (this._preferredEndpoint ?? TaskEndpoint.MONGO); this._initializing = false; this._subSearch = this._searchService.activeFilter$.subscribe(() => { this.reload(); }); const tasksMap$ = this._requestedPage$.pipe(mergeMap(p => this.loadPage(p)), map(pageLoadResult => { if (pageLoadResult.requestContext && pageLoadResult.requestContext.clearLoaded) { // we set an empty value to the virtual scroll and then replace it by the real value forcing it to redraw its content const results = [{ tasks: {}, requestContext: null }, pageLoadResult]; return arrayToObservable(results); } else { return of(pageLoadResult); } }), concatMap(o => o), scan((acc, pageLoadResult) => { let result; if (pageLoadResult.requestContext === null) { return pageLoadResult.tasks; } if (pageLoadResult.requestContext.reloadCurrentTaskPage) { Object.keys(acc).forEach(taskId => { if (!pageLoadResult.tasks[taskId]) { delete acc[taskId]; } else { pageLoadResult.tasks[taskId].task.dataGroups = acc[taskId].task.dataGroups; pageLoadResult.tasks[taskId].initiallyExpanded = acc[taskId].initiallyExpanded; this.updateTask(acc[taskId].task, pageLoadResult.tasks[taskId].task); this.blockTaskFields(acc[taskId].task, !(acc[taskId].task.userId && this._userComparator.compareUsers(acc[taskId].task.userId))); if (!this._paginationView) { delete pageLoadResult.tasks[taskId]; } } }); result = Object.assign(acc, pageLoadResult.tasks); } else { result = { ...acc, ...pageLoadResult.tasks }; } Object.assign(this._pagination, pageLoadResult.requestContext.pagination); if (pageLoadResult.requestContext !== null) { this._loading$.off(pageLoadResult.requestContext.filter); } if (this._paginationView) { return pageLoadResult.tasks; } return result; }, {})); this._tasks$ = tasksMap$.pipe(map(v => Object.values(v)), map(taskArray => { if (taskArray.length === 1 && this._initiallyOpenOneTask) { taskArray[0].task.finishDate === undefined ? taskArray[0].initiallyExpanded = true : taskArray[0].initiallyExpanded = false; } return taskArray; }), tap(v => this._panelUpdate$.next(v))); this._subInitiallyOpen = (taskViewConfig?.initiallyOpenOneTask ?? of(true)).subscribe(bool => { this._initiallyOpenOneTask = bool; }); this._subCloseTask = (taskViewConfig?.closeTaskTabOnNoTasks ?? of(true)).subscribe(bool => { this._closeTaskTabOnNoTasks = bool; }); } ngOnDestroy() { super.ngOnDestroy(); this._changedFields$.complete(); this._requestedPage$.complete(); this._panelUpdate$.complete(); this._closeTab$.complete(); this._subInitiallyOpen.unsubscribe(); this._subCloseTask.unsubscribe(); this._subSearch.unsubscribe(); } get tasks$() { return this._tasks$; } get changedFields$() { return this._changedFields$; } get loading$() { return this._loading$.asObservable(); } get loading() { return this._loading$.isActive; } get panelUpdate() { return this._panelUpdate$.asObservable(); } get closeTab() { return this._closeTab$.asObservable(); } get pagination() { return this._pagination; } get activeFilter() { return this._searchService.activeFilter; } set allowMultiOpen(bool) { this._allowMultiOpen = bool; } get allowMultiOpen() { return this._allowMultiOpen; } set paginationView(value) { this._paginationView = value; } loadPage(requestContext) { if (requestContext === null || requestContext.pageNumber < 0) { return of({ tasks: {}, requestContext }); } let params = new HttpParams(); params = this.addSortParams(params); params = this.addPageParams(params, requestContext.pagination); this._loading$.on(requestContext.filter); let request; if (requestContext.filter.bodyContainsQuery() || this._preferredEndpoint === TaskEndpoint.ELASTIC) { request = timer(200).pipe(switchMap(() => this._taskService.searchTask(requestContext.filter, params).pipe(take(1)))); } else { request = this._taskService.getTasks(requestContext.filter, params).pipe(take(1)); } return request.pipe(catchError(err => { this._log.error('Loading tasks has failed!', err); this._loading$.off(requestContext.filter); return of({ content: [], pagination: { ...this._pagination } }); }), filter(() => { const r = requestContext.filter === this._searchService.activeFilter; if (!r) { this._loading$.off(requestContext.filter); this._log.debug('Received tasks page is no longer relevant since the active filter has changed before it could arrive.' + ' Discarding...'); } return r; }), tap(t => { Object.assign(requestContext.pagination, t.pagination); }), tap(t => { if (this._pagination.totalElements && this._pagination.totalElements > 0 && t.pagination.totalElements === 0 && !Array.isArray(t.content) && this._closeTaskTabOnNoTasks) { this._closeTab$.next(); } }), tap(t => { this._endOfData = !Array.isArray(t.content) || t.content.length === 0 || t.pagination.number === t.pagination.totalPages; }), map(tasks => Array.isArray(tasks.content) ? tasks : { ...tasks, content: [] }), map(tasks => { return tasks.content.reduce((acc, curr) => { this.blockTaskFields(curr, !(curr.userId && this._userComparator.compareUsers(curr.userId))); return { ...acc, [curr.stringId]: { task: curr, changedFields: this._changedFields$, initiallyExpanded: false } }; }, {}); }), map(tasks => ({ tasks, requestContext }))); } updateTask(old, neww) { Object.keys(old).forEach(key => { if (!neww.hasOwnProperty(key)) { delete old[key]; } }); Object.keys(neww).forEach(key => { if (neww[key] !== undefined && neww[key] !== null) { old[key] = neww[key]; } }); this.blockTaskFields(old, !(old.userId && this._userComparator.compareUsers(old.userId))); } blockTaskFields(task, block) { if (!task.dataGroups) { return; } task.dataGroups.forEach(g => g.fields.forEach(f => f.block = block)); } nextPage(renderedRange, totalLoaded, requestContext) { if (requestContext === undefined) { requestContext = new PageLoadRequestContext(this.activeFilter, this._pagination); requestContext.pagination.number += 1; } if (this.isLoadingRelevantFilter(requestContext) || this._endOfData) { return; } if (renderedRange.end === totalLoaded) { this._requestedPage$.next(requestContext); } } nextPagePagination(length, pageIndex, requestContext) { if (requestContext === undefined) { requestContext = new PageLoadRequestContext(this.activeFilter, this._pagination); requestContext.pagination.size = length; requestContext.pagination.number = pageIndex; } if (this.isLoadingRelevantFilter(requestContext) || this._endOfData) { return; } this._requestedPage$.next(requestContext); } isLoadingRelevantFilter(requestContext) { return requestContext === undefined || (this._loading$.isActiveWithFilter(requestContext.filter) && !requestContext.force); } reload() { if (!this._tasks$ || !this._pagination) { return; } this._endOfData = false; const requestContext = new PageLoadRequestContext(this.activeFilter, this._pagination, true); requestContext.pagination.number = 0; const range = { start: -1, end: 0 }; this.nextPage(range, 0, requestContext); } reloadCurrentPage(force) { if (!this._tasks$ || !this._pagination) { return; } this._endOfData = false; const requestContext = new PageLoadRequestContext(this.activeFilter, this._pagination, false, true, force); requestContext.pagination.number = 0; // TODO [BUG] - Reloading only first page const range = { start: -1, end: 0 }; this.nextPage(range, 0, requestContext); } getMetaFieldSortId() { // TODO Tasks were not sortable on old frontend sorting might require elastic mapping changes on backend return this._lastHeaderSearchState.fieldIdentifier; } getDefaultSortParam() { return createSortParam('priority', PaginationSort.DESCENDING); } addPageParams(params, pagination) { params = params.set(PaginationParams.PAGE_SIZE, `${pagination.size}`); params = params.set(PaginationParams.PAGE_NUMBER, `${pagination.number}`); return params; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskViewService, deps: [{ token: i1.TaskResourceService }, { token: i2.UserService }, { token: i3.SnackBarService }, { token: i4.TranslateService }, { token: i5.SearchService }, { token: i6.LoggerService }, { token: i7.UserComparatorService }, { token: i8.SearchIndexResolverService }, { token: NAE_PREFERRED_TASK_ENDPOINT, optional: true }, { token: NAE_TASK_VIEW_CONFIGURATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskViewService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TaskViewService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.TaskResourceService }, { type: i2.UserService }, { type: i3.SnackBarService }, { type: i4.TranslateService }, { type: i5.SearchService }, { type: i6.LoggerService }, { type: i7.UserComparatorService }, { type: i8.SearchIndexResolverService }, { type: i9.TaskEndpoint, decorators: [{ type: Optional }, { type: Inject, args: [NAE_PREFERRED_TASK_ENDPOINT] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NAE_TASK_VIEW_CONFIGURATION] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay12aWV3LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL3ZpZXcvdGFzay12aWV3L3NlcnZpY2UvdGFzay12aWV3LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQWEsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxlQUFlLEVBQWMsRUFBRSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQWdCLEtBQUssRUFBQyxNQUFNLE1BQU0sQ0FBQztBQU1sRyxPQUFPLEVBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFPaEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXJELE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLHlDQUF5QyxDQUFDO0FBQ3BGLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBR2hGLE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLDhDQUE4QyxDQUFDO0FBQ3RGLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBRXZFLE9BQU8sRUFBQyw2QkFBNkIsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQzNFLE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLG1EQUFtRCxDQUFDO0FBRzlGLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBQy9FLE9BQU8sRUFBQyxlQUFlLEVBQUUsY0FBYyxFQUFDLE1BQU0sNkNBQTZDLENBQUM7Ozs7Ozs7Ozs7O0FBSTVGLE1BQU0sT0FBTyxlQUFnQixTQUFRLDZCQUE2QjtJQXNCeEM7SUFDRjtJQUNBO0lBQ0E7SUFDRTtJQUNGO0lBQ0E7SUFFNEQ7SUE1QnRFLE9BQU8sQ0FBbUM7SUFDMUMsZUFBZSxDQUE0QjtJQUMzQyxlQUFlLENBQTBDO0lBQ3pELFNBQVMsQ0FBMkI7SUFDcEMsVUFBVSxDQUFVO0lBQ3BCLFdBQVcsQ0FBYTtJQUN4QixxQkFBcUIsQ0FBVTtJQUMvQixzQkFBc0IsQ0FBVTtJQUNoQyxhQUFhLENBQXdDO0lBQ3JELFVBQVUsQ0FBc0I7SUFDaEMsaUJBQWlCLENBQWU7SUFDaEMsYUFBYSxDQUFlO0lBQzVCLFVBQVUsQ0FBZTtJQUVuQyxrQ0FBa0M7SUFDeEIsZUFBZSxDQUFVO0lBRWxCLGFBQWEsR0FBWSxJQUFJLENBQUM7SUFDckMsZUFBZSxHQUFZLEtBQUssQ0FBQztJQUUzQyxZQUFzQixZQUFpQyxFQUNuQyxZQUF5QixFQUN6QixnQkFBaUMsRUFDakMsVUFBNEIsRUFDMUIsY0FBNkIsRUFDL0IsSUFBbUIsRUFDbkIsZUFBc0MsRUFDOUMsUUFBb0MsRUFDZ0MscUJBQW1DLElBQUksRUFDMUQsaUJBQXdDLElBQUk7UUFDckcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBVkUsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBQ25DLGlCQUFZLEdBQVosWUFBWSxDQUFhO1FBQ3pCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBaUI7UUFDakMsZUFBVSxHQUFWLFVBQVUsQ0FBa0I7UUFDMUIsbUJBQWMsR0FBZCxjQUFjLENBQWU7UUFDL0IsU0FBSSxHQUFKLElBQUksQ0FBZTtRQUNuQixvQkFBZSxHQUFmLGVBQWUsQ0FBdUI7UUFFc0IsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFxQjtRQUduSCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUF3QixDQUFDO1FBQ25ELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO1FBQ2hELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQW9CLENBQUM7UUFDdkQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLFdBQVcsR0FBRztZQUNmLElBQUksRUFBRSxFQUFFO1lBQ1IsYUFBYSxFQUFFLFNBQVM7WUFDeEIsVUFBVSxFQUFFLFNBQVM7WUFDckIsTUFBTSxFQUFFLENBQUMsQ0FBQztTQUNiLENBQUM7UUFDRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksZUFBZSxDQUN0QyxJQUFJLHNCQUFzQixDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQ2xHLENBQUM7UUFDRixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksZUFBZSxDQUF1QixFQUFFLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksYUFBYSxDQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxjQUFjLEVBQUUsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9HLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBRTNCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUMvRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FDdkMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUMvQixHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUU7WUFDakIsSUFBSSxjQUFjLENBQUMsY0FBYyxJQUFJLGNBQWMsQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFO2dCQUM1RSxxSEFBcUg7Z0JBQ3JILE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztnQkFDcEUsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNyQztpQkFBTTtnQkFDSCxPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQzthQUM3QjtRQUNMLENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUNqQixJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsY0FBYyxFQUFFLEVBQUU7WUFDekIsSUFBSSxNQUFzQyxDQUFDO1lBQzNDLElBQUksY0FBYyxDQUFDLGNBQWMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3hDLE9BQU8sY0FBYyxDQUFDLEtBQUssQ0FBQzthQUMvQjtZQUVELElBQUksY0FBYyxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsRUFBRTtnQkFDckQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7b0JBQzlCLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO3dCQUMvQixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztxQkFDdEI7eUJBQU07d0JBQ0gsY0FBYyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO3dCQUMzRSxjQUFjLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLGlCQUFpQixHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQzt3QkFDL0UsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3JFLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNOytCQUN6RCxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDcEUsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7NEJBQ3ZCLE9BQU8sY0FBYyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDdkM7cUJBQ0o7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNyRDtpQkFBTTtnQkFDSCxNQUFNLEdBQUcsRUFBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUMsQ0FBQzthQUM5QztZQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFFLElBQUksY0FBYyxDQUFDLGNBQWMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3hDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDNUQ7WUFDRCxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQ3RCLE9BQU8sY0FBYyxDQUFDLEtBQUssQ0FBQzthQUMvQjtZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2xCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDVCxDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsSUFBSSxDQUN6QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBeUIsQ0FBQyxFQUNsRCxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDWixJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtnQkFDdEQsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxDQUFDLENBQUM7b0JBQ3hDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsQ0FBQztvQkFDdkMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQzthQUM5QztZQUNELE9BQU8sU0FBUyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUxQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxjQUFjLEVBQUUsb0JBQW9CLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3pGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsY0FBYyxFQUFFLHFCQUFxQixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN0RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFdBQVc7UUFDUCxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxJQUFXLE1BQU07UUFDYixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQVcsY0FBYztRQUNyQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7SUFDaEMsQ0FBQztJQUVELElBQVcsUUFBUTtRQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQsSUFBVyxPQUFPO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQztJQUNuQyxDQUFDO0lBRUQsSUFBVyxXQUFXO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBVyxRQUFRO1FBQ2YsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFXLFVBQVU7UUFDakIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFjLFlBQVk7UUFDdEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQztJQUM1QyxDQUFDO0lBRUQsSUFBVyxjQUFjLENBQUMsSUFBYTtRQUNuQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBVyxjQUFjLENBQUMsS0FBYztRQUNwQyxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUNqQyxDQUFDO0lBRU0sUUFBUSxDQUFDLGNBQXNDO1FBQ2xELElBQUksY0FBYyxLQUFLLElBQUksSUFBSSxjQUFjLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRTtZQUMxRCxPQUFPLEVBQUUsQ0FBQyxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFDLENBQUMsQ0FBQztTQUMxQztRQUNELElBQUksTUFBTSxHQUFlLElBQUksVUFBVSxFQUFFLENBQUM7UUFDMUMsTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFekMsSUFBSSxPQUErQixDQUFDO1FBQ3BDLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsS0FBSyxZQUFZLENBQUMsT0FBTyxFQUFFO1lBQy9GLE9BQU8sR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUNyQixTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDN0YsQ0FBQztTQUNMO2FBQU07WUFDSCxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDckY7UUFDRCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQ2YsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2IsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzFDLE9BQU8sRUFBRSxDQUFDLEVBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUMsRUFBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLEVBQ0YsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNSLE1BQU0sQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUM7WUFDckUsSUFBSSxDQUFDLENBQUMsRUFBRTtnQkFDSixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHVHQUF1RztzQkFDakgsZ0JBQWdCLENBQUMsQ0FBQzthQUMzQjtZQUNELE9BQU8sQ0FBQyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ0osTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDSixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxHQUFHLENBQUM7bUJBQ2pFLENBQUMsQ0FBQyxVQUFVLENBQUMsYUFBYSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtnQkFDakcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUMxQjtRQUNMLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNKLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7bUJBQ3BDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUM7bUJBQ3RCLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1FBQzNELENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUMsR0FBRyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBQyxDQUFDLEVBQzVFLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNSLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUU7Z0JBQ3RDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdGLE9BQU87b0JBQ0gsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUU7d0JBQ3JCLElBQUksRUFBRSxJQUFJO3dCQUNWLGFBQWEsRUFBRSxJQUFJLENBQUMsZUFBZTt3QkFDbkMsaUJBQWlCLEVBQUUsS0FBSztxQkFDM0I7aUJBQ0osQ0FBQztZQUNOLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxLQUFLLEVBQUUsY0FBYyxFQUFDLENBQUMsQ0FBQyxDQUMxQyxDQUFDO0lBQ04sQ0FBQztJQUVPLFVBQVUsQ0FBQyxHQUFTLEVBQUUsSUFBVTtRQUNwQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDM0IsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDbkI7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQzVCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO2dCQUMvQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3hCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFTyxlQUFlLENBQUMsSUFBVSxFQUFFLEtBQWM7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbEIsT0FBTztTQUNWO1FBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRU0sUUFBUSxDQUFDLGFBQXdCLEVBQUUsV0FBbUIsRUFBRSxjQUF1QztRQUNsRyxJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUU7WUFDOUIsY0FBYyxHQUFHLElBQUksc0JBQXNCLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDakYsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO1NBQ3pDO1FBRUQsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqRSxPQUFPO1NBQ1Y7UUFFRCxJQUFJLGFBQWEsQ0FBQyxHQUFHLEtBQUssV0FBVyxFQUFFO1lBQ25DLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQzdDO0lBQ0wsQ0FBQztJQUVNLGtCQUFrQixDQUFDLE1BQWMsRUFBRSxTQUFpQixFQUFFLGNBQXVDO1FBQ2hHLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRTtZQUM5QixjQUFjLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRixjQUFjLENBQUMsVUFBVSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7WUFDeEMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO1NBQ2hEO1FBRUQsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqRSxPQUFPO1NBQ1Y7UUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRU8sdUJBQXVCLENBQUMsY0FBdUM7UUFDbkUsT0FBTyxjQUFjLEtBQUssU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0gsQ0FBQztJQUVNLE1BQU07UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEMsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0YsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sS0FBSyxHQUFHO1lBQ1YsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNULEdBQUcsRUFBRSxDQUFDO1NBQ1QsQ0FBQztRQUVGLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRU0saUJBQWlCLENBQUMsS0FBZTtRQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEMsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzRyxjQUFjLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7UUFDL0UsTUFBTSxLQUFLLEdBQUc7WUFDVixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsR0FBRyxFQUFFLENBQUM7U0FDVCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFUyxrQkFBa0I7UUFDeEIsd0dBQXdHO1FBQ3hHLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQztJQUN2RCxDQUFDO0lBRVMsbUJBQW1CO1FBQ3pCLE9BQU8sZUFBZSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVTLGFBQWEsQ0FBQyxNQUFrQixFQUFFLFVBQXNCO1FBQzlELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7d0dBclZRLGVBQWUsd1JBOEJRLDJCQUEyQiw2QkFDM0IsMkJBQTJCOzRHQS9CbEQsZUFBZTs7NEZBQWYsZUFBZTtrQkFEM0IsVUFBVTs7MEJBK0JNLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsMkJBQTJCOzswQkFDOUMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQywyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBPcHRpb25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgb2YsIFJlcGxheVN1YmplY3QsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgdGltZXJ9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtUYXNrUGFuZWxEYXRhfSBmcm9tICcuLi8uLi8uLi9wYW5lbC90YXNrLXBhbmVsLWRhdGEvdGFzay1wYW5lbC1kYXRhJztcbmltcG9ydCB7VGFza1Jlc291cmNlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vcmVzb3VyY2VzL2VuZ2luZS1lbmRwb2ludC90YXNrLXJlc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtVc2VyU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtTbmFja0JhclNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NuYWNrLWJhci9zZXJ2aWNlcy9zbmFjay1iYXIuc2VydmljZSc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBjb25jYXRNYXAsIGZpbHRlciwgbWFwLCBtZXJnZU1hcCwgc2Nhbiwgc3dpdGNoTWFwLCB0YWtlLCB0YXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7SHR0cFBhcmFtc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtQYWdpbmF0aW9ufSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3BhZ2luYXRpb24nO1xuaW1wb3J0IHtUYXNrfSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3Rhc2snO1xuaW1wb3J0IHtTZWFyY2hTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZWFyY2gvc2VhcmNoLXNlcnZpY2Uvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHtMb2dnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9sb2dnZXIvc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtMaXN0UmFuZ2V9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1VzZXJDb21wYXJhdG9yU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLWNvbXBhcmF0b3Iuc2VydmljZSc7XG5pbXBvcnQge1Rhc2tFbmRwb2ludH0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stZW5kcG9pbnQnO1xuaW1wb3J0IHtQYWdlfSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3BhZ2UnO1xuaW1wb3J0IHtOQUVfUFJFRkVSUkVEX1RBU0tfRU5EUE9JTlR9IGZyb20gJy4uL21vZGVscy9pbmplY3Rpb24tdG9rZW4tdGFzay1lbmRwb2ludCc7XG5pbXBvcnQge1BhZ2VMb2FkUmVxdWVzdENvbnRleHR9IGZyb20gJy4uLy4uL2Fic3RyYWN0L3BhZ2UtbG9hZC1yZXF1ZXN0LWNvbnRleHQnO1xuaW1wb3J0IHtGaWx0ZXJ9IGZyb20gJy4uLy4uLy4uL2ZpbHRlci9tb2RlbHMvZmlsdGVyJztcbmltcG9ydCB7VGFza1BhZ2VMb2FkUmVxdWVzdFJlc3VsdH0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stcGFnZS1sb2FkLXJlcXVlc3QtcmVzdWx0JztcbmltcG9ydCB7TG9hZGluZ1dpdGhGaWx0ZXJFbWl0dGVyfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L2xvYWRpbmctd2l0aC1maWx0ZXItZW1pdHRlcic7XG5pbXBvcnQge2FycmF5VG9PYnNlcnZhYmxlfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L2FycmF5LXRvLW9ic2VydmFibGUnO1xuaW1wb3J0IHtTZWFyY2hJbmRleFJlc29sdmVyU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VhcmNoL3NlYXJjaC1rZXl3b3JkLXJlc29sdmVyLXNlcnZpY2Uvc2VhcmNoLWluZGV4LXJlc29sdmVyLnNlcnZpY2UnO1xuaW1wb3J0IHtBYnN0cmFjdFNvcnRhYmxlVmlld0NvbXBvbmVudH0gZnJvbSAnLi4vLi4vYWJzdHJhY3Qvc29ydGFibGUtdmlldyc7XG5pbXBvcnQge05BRV9UQVNLX1ZJRVdfQ09ORklHVVJBVElPTn0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stdmlldy1jb25maWd1cmF0aW9uLWluamVjdGlvbi10b2tlbic7XG5pbXBvcnQge1Rhc2tWaWV3Q29uZmlndXJhdGlvbn0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stdmlldy1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7Q2hhbmdlZEZpZWxkc01hcH0gZnJvbSAnLi4vLi4vLi4vZXZlbnQvc2VydmljZXMvaW50ZXJmYWNlcy9jaGFuZ2VkLWZpZWxkcy1tYXAnO1xuaW1wb3J0IHtQYWdpbmF0aW9uUGFyYW1zfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L3BhZ2luYXRpb24vcGFnaW5hdGlvbi1wYXJhbXMnO1xuaW1wb3J0IHtjcmVhdGVTb3J0UGFyYW0sIFBhZ2luYXRpb25Tb3J0fSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L3BhZ2luYXRpb24vcGFnaW5hdGlvbi1zb3J0JztcblxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVGFza1ZpZXdTZXJ2aWNlIGV4dGVuZHMgQWJzdHJhY3RTb3J0YWJsZVZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gICAgcHJvdGVjdGVkIF90YXNrcyQ6IE9ic2VydmFibGU8QXJyYXk8VGFza1BhbmVsRGF0YT4+O1xuICAgIHByb3RlY3RlZCBfY2hhbmdlZEZpZWxkcyQ6IFN1YmplY3Q8Q2hhbmdlZEZpZWxkc01hcD47XG4gICAgcHJvdGVjdGVkIF9yZXF1ZXN0ZWRQYWdlJDogQmVoYXZpb3JTdWJqZWN0PFBhZ2VMb2FkUmVxdWVzdENvbnRleHQ+O1xuICAgIHByb3RlY3RlZCBfbG9hZGluZyQ6IExvYWRpbmdXaXRoRmlsdGVyRW1pdHRlcjtcbiAgICBwcm90ZWN0ZWQgX2VuZE9mRGF0YTogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX3BhZ2luYXRpb246IFBhZ2luYXRpb247XG4gICAgcHJvdGVjdGVkIF9pbml0aWFsbHlPcGVuT25lVGFzazogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX2Nsb3NlVGFza1RhYk9uTm9UYXNrczogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX3BhbmVsVXBkYXRlJDogQmVoYXZpb3JTdWJqZWN0PEFycmF5PFRhc2tQYW5lbERhdGE+PjtcbiAgICBwcm90ZWN0ZWQgX2Nsb3NlVGFiJDogUmVwbGF5U3ViamVjdDx2b2lkPjtcbiAgICBwcm90ZWN0ZWQgX3N1YkluaXRpYWxseU9wZW46IFN1YnNjcmlwdGlvbjtcbiAgICBwcm90ZWN0ZWQgX3N1YkNsb3NlVGFzazogU3Vic2NyaXB0aW9uO1xuICAgIHByb3RlY3RlZCBfc3ViU2VhcmNoOiBTdWJzY3JpcHRpb247XG5cbiAgICAvLyBTZXJpYWxpemluZyBhc3NpZ24gYWZ0ZXIgY2FuY2VsXG4gICAgcHJvdGVjdGVkIF9hbGxvd011bHRpT3BlbjogYm9vbGVhbjtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2luaXRpYWxpemluZzogYm9vbGVhbiA9IHRydWU7XG4gICAgcHJvdGVjdGVkIF9wYWdpbmF0aW9uVmlldzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIF90YXNrU2VydmljZTogVGFza1Jlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIF91c2VyU2VydmljZTogVXNlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfc25hY2tCYXJTZXJ2aWNlOiBTbmFja0JhclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfc2VhcmNoU2VydmljZTogU2VhcmNoU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfdXNlckNvbXBhcmF0b3I6IFVzZXJDb21wYXJhdG9yU2VydmljZSxcbiAgICAgICAgICAgICAgICByZXNvbHZlcjogU2VhcmNoSW5kZXhSZXNvbHZlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChOQUVfUFJFRkVSUkVEX1RBU0tfRU5EUE9JTlQpIHByb3RlY3RlZCByZWFkb25seSBfcHJlZmVycmVkRW5kcG9pbnQ6IFRhc2tFbmRwb2ludCA9IG51bGwsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChOQUVfVEFTS19WSUVXX0NPTkZJR1VSQVRJT04pIHRhc2tWaWV3Q29uZmlnOiBUYXNrVmlld0NvbmZpZ3VyYXRpb24gPSBudWxsKSB7XG4gICAgICAgIHN1cGVyKHJlc29sdmVyKTtcbiAgICAgICAgdGhpcy5fdGFza3MkID0gbmV3IFN1YmplY3Q8QXJyYXk8VGFza1BhbmVsRGF0YT4+KCk7XG4gICAgICAgIHRoaXMuX2xvYWRpbmckID0gbmV3IExvYWRpbmdXaXRoRmlsdGVyRW1pdHRlcigpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkRmllbGRzJCA9IG5ldyBTdWJqZWN0PENoYW5nZWRGaWVsZHNNYXA+KCk7XG4gICAgICAgIHRoaXMuX2FsbG93TXVsdGlPcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZW5kT2ZEYXRhID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BhZ2luYXRpb24gPSB7XG4gICAgICAgICAgICBzaXplOiA1MCxcbiAgICAgICAgICAgIHRvdGFsRWxlbWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHRvdGFsUGFnZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG51bWJlcjogLTFcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fcmVxdWVzdGVkUGFnZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFBhZ2VMb2FkUmVxdWVzdENvbnRleHQ+KFxuICAgICAgICAgICAgbmV3IFBhZ2VMb2FkUmVxdWVzdENvbnRleHQodGhpcy5hY3RpdmVGaWx0ZXIsIE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3BhZ2luYXRpb24sIHtudW1iZXI6IDB9KSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fcGFuZWxVcGRhdGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxBcnJheTxUYXNrUGFuZWxEYXRhPj4oW10pO1xuICAgICAgICB0aGlzLl9jbG9zZVRhYiQgPSBuZXcgUmVwbGF5U3ViamVjdDx2b2lkPigxKTtcbiAgICAgICAgdGhpcy5fcHJlZmVycmVkRW5kcG9pbnQgPSB0YXNrVmlld0NvbmZpZz8ucHJlZmVycmVkRW5kcG9pbnQgPz8gKHRoaXMuX3ByZWZlcnJlZEVuZHBvaW50ID8/IFRhc2tFbmRwb2ludC5NT05HTyk7XG5cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6aW5nID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fc3ViU2VhcmNoID0gdGhpcy5fc2VhcmNoU2VydmljZS5hY3RpdmVGaWx0ZXIkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0YXNrc01hcCQgPSB0aGlzLl9yZXF1ZXN0ZWRQYWdlJC5waXBlKFxuICAgICAgICAgICAgbWVyZ2VNYXAocCA9PiB0aGlzLmxvYWRQYWdlKHApKSxcbiAgICAgICAgICAgIG1hcChwYWdlTG9hZFJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0ICYmIHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0LmNsZWFyTG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIHNldCBhbiBlbXB0eSB2YWx1ZSB0byB0aGUgdmlydHVhbCBzY3JvbGwgYW5kIHRoZW4gcmVwbGFjZSBpdCBieSB0aGUgcmVhbCB2YWx1ZSBmb3JjaW5nIGl0IHRvIHJlZHJhdyBpdHMgY29udGVudFxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW3t0YXNrczoge30sIHJlcXVlc3RDb250ZXh0OiBudWxsfSwgcGFnZUxvYWRSZXN1bHRdO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlUb09ic2VydmFibGUocmVzdWx0cyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKHBhZ2VMb2FkUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNvbmNhdE1hcChvID0+IG8pLFxuICAgICAgICAgICAgc2NhbigoYWNjLCBwYWdlTG9hZFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCByZXN1bHQ6IHsgW2s6IHN0cmluZ106IFRhc2tQYW5lbERhdGEgfTtcbiAgICAgICAgICAgICAgICBpZiAocGFnZUxvYWRSZXN1bHQucmVxdWVzdENvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhZ2VMb2FkUmVzdWx0LnRhc2tzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwYWdlTG9hZFJlc3VsdC5yZXF1ZXN0Q29udGV4dC5yZWxvYWRDdXJyZW50VGFza1BhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoYWNjKS5mb3JFYWNoKHRhc2tJZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWNjW3Rhc2tJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0udGFzay5kYXRhR3JvdXBzID0gYWNjW3Rhc2tJZF0udGFzay5kYXRhR3JvdXBzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0uaW5pdGlhbGx5RXhwYW5kZWQgPSBhY2NbdGFza0lkXS5pbml0aWFsbHlFeHBhbmRlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVRhc2soYWNjW3Rhc2tJZF0udGFzaywgcGFnZUxvYWRSZXN1bHQudGFza3NbdGFza0lkXS50YXNrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJsb2NrVGFza0ZpZWxkcyhhY2NbdGFza0lkXS50YXNrLCAhKGFjY1t0YXNrSWRdLnRhc2sudXNlcklkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHRoaXMuX3VzZXJDb21wYXJhdG9yLmNvbXBhcmVVc2VycyhhY2NbdGFza0lkXS50YXNrLnVzZXJJZCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3BhZ2luYXRpb25WaWV3KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwYWdlTG9hZFJlc3VsdC50YXNrc1t0YXNrSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oYWNjLCBwYWdlTG9hZFJlc3VsdC50YXNrcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gey4uLmFjYywgLi4ucGFnZUxvYWRSZXN1bHQudGFza3N9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5fcGFnaW5hdGlvbiwgcGFnZUxvYWRSZXN1bHQucmVxdWVzdENvbnRleHQucGFnaW5hdGlvbik7XG4gICAgICAgICAgICAgICAgaWYgKHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRpbmckLm9mZihwYWdlTG9hZFJlc3VsdC5yZXF1ZXN0Q29udGV4dC5maWx0ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fcGFnaW5hdGlvblZpZXcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhZ2VMb2FkUmVzdWx0LnRhc2tzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfSwge30pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX3Rhc2tzJCA9IHRhc2tzTWFwJC5waXBlKFxuICAgICAgICAgICAgbWFwKHYgPT4gT2JqZWN0LnZhbHVlcyh2KSBhcyBBcnJheTxUYXNrUGFuZWxEYXRhPiksXG4gICAgICAgICAgICBtYXAodGFza0FycmF5ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGFza0FycmF5Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLl9pbml0aWFsbHlPcGVuT25lVGFzaykge1xuICAgICAgICAgICAgICAgICAgICB0YXNrQXJyYXlbMF0udGFzay5maW5pc2hEYXRlID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFza0FycmF5WzBdLmluaXRpYWxseUV4cGFuZGVkID0gdHJ1ZSA6XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrQXJyYXlbMF0uaW5pdGlhbGx5RXhwYW5kZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhc2tBcnJheTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKHYgPT4gdGhpcy5fcGFuZWxVcGRhdGUkLm5leHQodikpKTtcblxuICAgICAgICB0aGlzLl9zdWJJbml0aWFsbHlPcGVuID0gKHRhc2tWaWV3Q29uZmlnPy5pbml0aWFsbHlPcGVuT25lVGFzayA/PyBvZih0cnVlKSkuc3Vic2NyaWJlKGJvb2wgPT4ge1xuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGx5T3Blbk9uZVRhc2sgPSBib29sO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9zdWJDbG9zZVRhc2sgPSAodGFza1ZpZXdDb25maWc/LmNsb3NlVGFza1RhYk9uTm9UYXNrcyA/PyBvZih0cnVlKSkuc3Vic2NyaWJlKGJvb2wgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY2xvc2VUYXNrVGFiT25Ob1Rhc2tzID0gYm9vbDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgICAgIHRoaXMuX2NoYW5nZWRGaWVsZHMkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX3JlcXVlc3RlZFBhZ2UkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX3BhbmVsVXBkYXRlJC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLl9jbG9zZVRhYiQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fc3ViSW5pdGlhbGx5T3Blbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9zdWJDbG9zZVRhc2sudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fc3ViU2VhcmNoLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB0YXNrcyQoKTogT2JzZXJ2YWJsZTxBcnJheTxUYXNrUGFuZWxEYXRhPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGFza3MkO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgY2hhbmdlZEZpZWxkcyQoKTogU3ViamVjdDxDaGFuZ2VkRmllbGRzTWFwPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jaGFuZ2VkRmllbGRzJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxvYWRpbmckKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGluZyQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsb2FkaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGluZyQuaXNBY3RpdmU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBwYW5lbFVwZGF0ZSgpOiBPYnNlcnZhYmxlPEFycmF5PFRhc2tQYW5lbERhdGE+PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5lbFVwZGF0ZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjbG9zZVRhYigpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlVGFiJC5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHBhZ2luYXRpb24oKTogUGFnaW5hdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYWdpbmF0aW9uO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgYWN0aXZlRmlsdGVyKCk6IEZpbHRlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWFyY2hTZXJ2aWNlLmFjdGl2ZUZpbHRlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IGFsbG93TXVsdGlPcGVuKGJvb2w6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fYWxsb3dNdWx0aU9wZW4gPSBib29sO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgYWxsb3dNdWx0aU9wZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbGxvd011bHRpT3BlbjtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHBhZ2luYXRpb25WaWV3KHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX3BhZ2luYXRpb25WaWV3ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGxvYWRQYWdlKHJlcXVlc3RDb250ZXh0OiBQYWdlTG9hZFJlcXVlc3RDb250ZXh0KTogT2JzZXJ2YWJsZTxUYXNrUGFnZUxvYWRSZXF1ZXN0UmVzdWx0PiB7XG4gICAgICAgIGlmIChyZXF1ZXN0Q29udGV4dCA9PT0gbnVsbCB8fCByZXF1ZXN0Q29udGV4dC5wYWdlTnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHt0YXNrczoge30sIHJlcXVlc3RDb250ZXh0fSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhcmFtczogSHR0cFBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XG4gICAgICAgIHBhcmFtcyA9IHRoaXMuYWRkU29ydFBhcmFtcyhwYXJhbXMpO1xuICAgICAgICBwYXJhbXMgPSB0aGlzLmFkZFBhZ2VQYXJhbXMocGFyYW1zLCByZXF1ZXN0Q29udGV4dC5wYWdpbmF0aW9uKTtcbiAgICAgICAgdGhpcy5fbG9hZGluZyQub24ocmVxdWVzdENvbnRleHQuZmlsdGVyKTtcblxuICAgICAgICBsZXQgcmVxdWVzdDogT2JzZXJ2YWJsZTxQYWdlPFRhc2s+PjtcbiAgICAgICAgaWYgKHJlcXVlc3RDb250ZXh0LmZpbHRlci5ib2R5Q29udGFpbnNRdWVyeSgpIHx8IHRoaXMuX3ByZWZlcnJlZEVuZHBvaW50ID09PSBUYXNrRW5kcG9pbnQuRUxBU1RJQykge1xuICAgICAgICAgICAgcmVxdWVzdCA9IHRpbWVyKDIwMCkucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fdGFza1NlcnZpY2Uuc2VhcmNoVGFzayhyZXF1ZXN0Q29udGV4dC5maWx0ZXIsIHBhcmFtcykucGlwZSh0YWtlKDEpKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXF1ZXN0ID0gdGhpcy5fdGFza1NlcnZpY2UuZ2V0VGFza3MocmVxdWVzdENvbnRleHQuZmlsdGVyLCBwYXJhbXMpLnBpcGUodGFrZSgxKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcXVlc3QucGlwZShcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2cuZXJyb3IoJ0xvYWRpbmcgdGFza3MgaGFzIGZhaWxlZCEnLCBlcnIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRpbmckLm9mZihyZXF1ZXN0Q29udGV4dC5maWx0ZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvZih7Y29udGVudDogW10sIHBhZ2luYXRpb246IHsuLi50aGlzLl9wYWdpbmF0aW9ufX0pO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHIgPSByZXF1ZXN0Q29udGV4dC5maWx0ZXIgPT09IHRoaXMuX3NlYXJjaFNlcnZpY2UuYWN0aXZlRmlsdGVyO1xuICAgICAgICAgICAgICAgIGlmICghcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkaW5nJC5vZmYocmVxdWVzdENvbnRleHQuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9nLmRlYnVnKCdSZWNlaXZlZCB0YXNrcyBwYWdlIGlzIG5vIGxvbmdlciByZWxldmFudCBzaW5jZSB0aGUgYWN0aXZlIGZpbHRlciBoYXMgY2hhbmdlZCBiZWZvcmUgaXQgY291bGQgYXJyaXZlLidcbiAgICAgICAgICAgICAgICAgICAgICAgICsgJyBEaXNjYXJkaW5nLi4uJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihyZXF1ZXN0Q29udGV4dC5wYWdpbmF0aW9uLCB0LnBhZ2luYXRpb24pO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhZ2luYXRpb24udG90YWxFbGVtZW50cyAmJiB0aGlzLl9wYWdpbmF0aW9uLnRvdGFsRWxlbWVudHMgPiAwXG4gICAgICAgICAgICAgICAgICAgICYmIHQucGFnaW5hdGlvbi50b3RhbEVsZW1lbnRzID09PSAwICYmICFBcnJheS5pc0FycmF5KHQuY29udGVudCkgJiYgdGhpcy5fY2xvc2VUYXNrVGFiT25Ob1Rhc2tzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2Nsb3NlVGFiJC5uZXh0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YXAodCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZW5kT2ZEYXRhID0gIUFycmF5LmlzQXJyYXkodC5jb250ZW50KVxuICAgICAgICAgICAgICAgICAgICB8fCB0LmNvbnRlbnQubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgICAgIHx8IHQucGFnaW5hdGlvbi5udW1iZXIgPT09IHQucGFnaW5hdGlvbi50b3RhbFBhZ2VzO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAodGFza3MgPT4gQXJyYXkuaXNBcnJheSh0YXNrcy5jb250ZW50KSA/IHRhc2tzIDogey4uLnRhc2tzLCBjb250ZW50OiBbXX0pLFxuICAgICAgICAgICAgbWFwKHRhc2tzID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFza3MuY29udGVudC5yZWR1Y2UoKGFjYywgY3VycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJsb2NrVGFza0ZpZWxkcyhjdXJyLCAhKGN1cnIudXNlcklkICYmIHRoaXMuX3VzZXJDb21wYXJhdG9yLmNvbXBhcmVVc2VycyhjdXJyLnVzZXJJZCkpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmFjYywgW2N1cnIuc3RyaW5nSWRdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFzazogY3VycixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkRmllbGRzOiB0aGlzLl9jaGFuZ2VkRmllbGRzJCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsbHlFeHBhbmRlZDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9LCB7fSk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1hcCh0YXNrcyA9PiAoe3Rhc2tzLCByZXF1ZXN0Q29udGV4dH0pKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlVGFzayhvbGQ6IFRhc2ssIG5ld3c6IFRhc2spIHtcbiAgICAgICAgT2JqZWN0LmtleXMob2xkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBpZiAoIW5ld3cuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvbGRba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5rZXlzKG5ld3cpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmIChuZXd3W2tleV0gIT09IHVuZGVmaW5lZCAmJiBuZXd3W2tleV0gIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBvbGRba2V5XSA9IG5ld3dba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYmxvY2tUYXNrRmllbGRzKG9sZCwgIShvbGQudXNlcklkICYmIHRoaXMuX3VzZXJDb21wYXJhdG9yLmNvbXBhcmVVc2VycyhvbGQudXNlcklkKSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYmxvY2tUYXNrRmllbGRzKHRhc2s6IFRhc2ssIGJsb2NrOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICghdGFzay5kYXRhR3JvdXBzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGFzay5kYXRhR3JvdXBzLmZvckVhY2goZyA9PiBnLmZpZWxkcy5mb3JFYWNoKGYgPT4gZi5ibG9jayA9IGJsb2NrKSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5leHRQYWdlKHJlbmRlcmVkUmFuZ2U6IExpc3RSYW5nZSwgdG90YWxMb2FkZWQ6IG51bWJlciwgcmVxdWVzdENvbnRleHQ/OiBQYWdlTG9hZFJlcX