@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
331 lines • 53.9 kB
JavaScript
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.assignee
&& this._userComparator.compareUsers(acc[taskId].task.assignee.id)));
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.assignee && this._userComparator.compareUsers(curr.assignee.id)));
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.assignee && this._userComparator.compareUsers(old.assignee.id)));
}
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay12aWV3LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL3ZpZXcvdGFzay12aWV3L3NlcnZpY2UvdGFzay12aWV3LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQWEsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxlQUFlLEVBQWMsRUFBRSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQWdCLEtBQUssRUFBQyxNQUFNLE1BQU0sQ0FBQztBQU1sRyxPQUFPLEVBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFPaEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXJELE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLHlDQUF5QyxDQUFDO0FBQ3BGLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBR2hGLE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLDhDQUE4QyxDQUFDO0FBQ3RGLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBRXZFLE9BQU8sRUFBQyw2QkFBNkIsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQzNFLE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLG1EQUFtRCxDQUFDO0FBRzlGLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBQy9FLE9BQU8sRUFBQyxlQUFlLEVBQUUsY0FBYyxF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WUFDVixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsR0FBRyxFQUFFLENBQUM7U0FDVCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFUyxrQkFBa0I7UUFDeEIsd0dBQXdHO1FBQ3hHLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQztJQUN2RCxDQUFDO0lBRVMsbUJBQW1CO1FBQ3pCLE9BQU8sZUFBZSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVTLGFBQWEsQ0FBQyxNQUFrQixFQUFFLFVBQXNCO1FBQzlELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7d0dBclZRLGVBQWUsd1JBOEJRLDJCQUEyQiw2QkFDM0IsMkJBQTJCOzRHQS9CbEQsZUFBZTs7NEZBQWYsZUFBZTtrQkFEM0IsVUFBVTs7MEJBK0JNLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsMkJBQTJCOzswQkFDOUMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQywyQkFBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBPcHRpb25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgb2YsIFJlcGxheVN1YmplY3QsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgdGltZXJ9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtUYXNrUGFuZWxEYXRhfSBmcm9tICcuLi8uLi8uLi9wYW5lbC90YXNrLXBhbmVsLWRhdGEvdGFzay1wYW5lbC1kYXRhJztcbmltcG9ydCB7VGFza1Jlc291cmNlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vcmVzb3VyY2VzL2VuZ2luZS1lbmRwb2ludC90YXNrLXJlc291cmNlLnNlcnZpY2UnO1xuaW1wb3J0IHtVc2VyU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtTbmFja0JhclNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL3NuYWNrLWJhci9zZXJ2aWNlcy9zbmFjay1iYXIuc2VydmljZSc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBjb25jYXRNYXAsIGZpbHRlciwgbWFwLCBtZXJnZU1hcCwgc2Nhbiwgc3dpdGNoTWFwLCB0YWtlLCB0YXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7SHR0cFBhcmFtc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtQYWdpbmF0aW9ufSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3BhZ2luYXRpb24nO1xuaW1wb3J0IHtUYXNrfSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3Rhc2snO1xuaW1wb3J0IHtTZWFyY2hTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9zZWFyY2gvc2VhcmNoLXNlcnZpY2Uvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHtMb2dnZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9sb2dnZXIvc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtMaXN0UmFuZ2V9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1VzZXJDb21wYXJhdG9yU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLWNvbXBhcmF0b3Iuc2VydmljZSc7XG5pbXBvcnQge1Rhc2tFbmRwb2ludH0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stZW5kcG9pbnQnO1xuaW1wb3J0IHtQYWdlfSBmcm9tICcuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3BhZ2UnO1xuaW1wb3J0IHtOQUVfUFJFRkVSUkVEX1RBU0tfRU5EUE9JTlR9IGZyb20gJy4uL21vZGVscy9pbmplY3Rpb24tdG9rZW4tdGFzay1lbmRwb2ludCc7XG5pbXBvcnQge1BhZ2VMb2FkUmVxdWVzdENvbnRleHR9IGZyb20gJy4uLy4uL2Fic3RyYWN0L3BhZ2UtbG9hZC1yZXF1ZXN0LWNvbnRleHQnO1xuaW1wb3J0IHtGaWx0ZXJ9IGZyb20gJy4uLy4uLy4uL2ZpbHRlci9tb2RlbHMvZmlsdGVyJztcbmltcG9ydCB7VGFza1BhZ2VMb2FkUmVxdWVzdFJlc3VsdH0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stcGFnZS1sb2FkLXJlcXVlc3QtcmVzdWx0JztcbmltcG9ydCB7TG9hZGluZ1dpdGhGaWx0ZXJFbWl0dGVyfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L2xvYWRpbmctd2l0aC1maWx0ZXItZW1pdHRlcic7XG5pbXBvcnQge2FycmF5VG9PYnNlcnZhYmxlfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L2FycmF5LXRvLW9ic2VydmFibGUnO1xuaW1wb3J0IHtTZWFyY2hJbmRleFJlc29sdmVyU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VhcmNoL3NlYXJjaC1rZXl3b3JkLXJlc29sdmVyLXNlcnZpY2Uvc2VhcmNoLWluZGV4LXJlc29sdmVyLnNlcnZpY2UnO1xuaW1wb3J0IHtBYnN0cmFjdFNvcnRhYmxlVmlld0NvbXBvbmVudH0gZnJvbSAnLi4vLi4vYWJzdHJhY3Qvc29ydGFibGUtdmlldyc7XG5pbXBvcnQge05BRV9UQVNLX1ZJRVdfQ09ORklHVVJBVElPTn0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stdmlldy1jb25maWd1cmF0aW9uLWluamVjdGlvbi10b2tlbic7XG5pbXBvcnQge1Rhc2tWaWV3Q29uZmlndXJhdGlvbn0gZnJvbSAnLi4vbW9kZWxzL3Rhc2stdmlldy1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7Q2hhbmdlZEZpZWxkc01hcH0gZnJvbSAnLi4vLi4vLi4vZXZlbnQvc2VydmljZXMvaW50ZXJmYWNlcy9jaGFuZ2VkLWZpZWxkcy1tYXAnO1xuaW1wb3J0IHtQYWdpbmF0aW9uUGFyYW1zfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L3BhZ2luYXRpb24vcGFnaW5hdGlvbi1wYXJhbXMnO1xuaW1wb3J0IHtjcmVhdGVTb3J0UGFyYW0sIFBhZ2luYXRpb25Tb3J0fSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L3BhZ2luYXRpb24vcGFnaW5hdGlvbi1zb3J0JztcblxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVGFza1ZpZXdTZXJ2aWNlIGV4dGVuZHMgQWJzdHJhY3RTb3J0YWJsZVZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gICAgcHJvdGVjdGVkIF90YXNrcyQ6IE9ic2VydmFibGU8QXJyYXk8VGFza1BhbmVsRGF0YT4+O1xuICAgIHByb3RlY3RlZCBfY2hhbmdlZEZpZWxkcyQ6IFN1YmplY3Q8Q2hhbmdlZEZpZWxkc01hcD47XG4gICAgcHJvdGVjdGVkIF9yZXF1ZXN0ZWRQYWdlJDogQmVoYXZpb3JTdWJqZWN0PFBhZ2VMb2FkUmVxdWVzdENvbnRleHQ+O1xuICAgIHByb3RlY3RlZCBfbG9hZGluZyQ6IExvYWRpbmdXaXRoRmlsdGVyRW1pdHRlcjtcbiAgICBwcm90ZWN0ZWQgX2VuZE9mRGF0YTogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX3BhZ2luYXRpb246IFBhZ2luYXRpb247XG4gICAgcHJvdGVjdGVkIF9pbml0aWFsbHlPcGVuT25lVGFzazogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX2Nsb3NlVGFza1RhYk9uTm9UYXNrczogYm9vbGVhbjtcbiAgICBwcm90ZWN0ZWQgX3BhbmVsVXBkYXRlJDogQmVoYXZpb3JTdWJqZWN0PEFycmF5PFRhc2tQYW5lbERhdGE+PjtcbiAgICBwcm90ZWN0ZWQgX2Nsb3NlVGFiJDogUmVwbGF5U3ViamVjdDx2b2lkPjtcbiAgICBwcm90ZWN0ZWQgX3N1YkluaXRpYWxseU9wZW46IFN1YnNjcmlwdGlvbjtcbiAgICBwcm90ZWN0ZWQgX3N1YkNsb3NlVGFzazogU3Vic2NyaXB0aW9uO1xuICAgIHByb3RlY3RlZCBfc3ViU2VhcmNoOiBTdWJzY3JpcHRpb247XG5cbiAgICAvLyBTZXJpYWxpemluZyBhc3NpZ24gYWZ0ZXIgY2FuY2VsXG4gICAgcHJvdGVjdGVkIF9hbGxvd011bHRpT3BlbjogYm9vbGVhbjtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2luaXRpYWxpemluZzogYm9vbGVhbiA9IHRydWU7XG4gICAgcHJvdGVjdGVkIF9wYWdpbmF0aW9uVmlldzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIF90YXNrU2VydmljZTogVGFza1Jlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIF91c2VyU2VydmljZTogVXNlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfc25hY2tCYXJTZXJ2aWNlOiBTbmFja0JhclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfc2VhcmNoU2VydmljZTogU2VhcmNoU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIF9sb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBfdXNlckNvbXBhcmF0b3I6IFVzZXJDb21wYXJhdG9yU2VydmljZSxcbiAgICAgICAgICAgICAgICByZXNvbHZlcjogU2VhcmNoSW5kZXhSZXNvbHZlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChOQUVfUFJFRkVSUkVEX1RBU0tfRU5EUE9JTlQpIHByb3RlY3RlZCByZWFkb25seSBfcHJlZmVycmVkRW5kcG9pbnQ6IFRhc2tFbmRwb2ludCA9IG51bGwsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChOQUVfVEFTS19WSUVXX0NPTkZJR1VSQVRJT04pIHRhc2tWaWV3Q29uZmlnOiBUYXNrVmlld0NvbmZpZ3VyYXRpb24gPSBudWxsKSB7XG4gICAgICAgIHN1cGVyKHJlc29sdmVyKTtcbiAgICAgICAgdGhpcy5fdGFza3MkID0gbmV3IFN1YmplY3Q8QXJyYXk8VGFza1BhbmVsRGF0YT4+KCk7XG4gICAgICAgIHRoaXMuX2xvYWRpbmckID0gbmV3IExvYWRpbmdXaXRoRmlsdGVyRW1pdHRlcigpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkRmllbGRzJCA9IG5ldyBTdWJqZWN0PENoYW5nZWRGaWVsZHNNYXA+KCk7XG4gICAgICAgIHRoaXMuX2FsbG93TXVsdGlPcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZW5kT2ZEYXRhID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3BhZ2luYXRpb24gPSB7XG4gICAgICAgICAgICBzaXplOiA1MCxcbiAgICAgICAgICAgIHRvdGFsRWxlbWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHRvdGFsUGFnZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG51bWJlcjogLTFcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fcmVxdWVzdGVkUGFnZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFBhZ2VMb2FkUmVxdWVzdENvbnRleHQ+KFxuICAgICAgICAgICAgbmV3IFBhZ2VMb2FkUmVxdWVzdENvbnRleHQodGhpcy5hY3RpdmVGaWx0ZXIsIE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3BhZ2luYXRpb24sIHtudW1iZXI6IDB9KSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fcGFuZWxVcGRhdGUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxBcnJheTxUYXNrUGFuZWxEYXRhPj4oW10pO1xuICAgICAgICB0aGlzLl9jbG9zZVRhYiQgPSBuZXcgUmVwbGF5U3ViamVjdDx2b2lkPigxKTtcbiAgICAgICAgdGhpcy5fcHJlZmVycmVkRW5kcG9pbnQgPSB0YXNrVmlld0NvbmZpZz8ucHJlZmVycmVkRW5kcG9pbnQgPz8gKHRoaXMuX3ByZWZlcnJlZEVuZHBvaW50ID8/IFRhc2tFbmRwb2ludC5NT05HTyk7XG5cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6aW5nID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fc3ViU2VhcmNoID0gdGhpcy5fc2VhcmNoU2VydmljZS5hY3RpdmVGaWx0ZXIkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0YXNrc01hcCQgPSB0aGlzLl9yZXF1ZXN0ZWRQYWdlJC5waXBlKFxuICAgICAgICAgICAgbWVyZ2VNYXAocCA9PiB0aGlzLmxvYWRQYWdlKHApKSxcbiAgICAgICAgICAgIG1hcChwYWdlTG9hZFJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0ICYmIHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0LmNsZWFyTG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIHNldCBhbiBlbXB0eSB2YWx1ZSB0byB0aGUgdmlydHVhbCBzY3JvbGwgYW5kIHRoZW4gcmVwbGFjZSBpdCBieSB0aGUgcmVhbCB2YWx1ZSBmb3JjaW5nIGl0IHRvIHJlZHJhdyBpdHMgY29udGVudFxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW3t0YXNrczoge30sIHJlcXVlc3RDb250ZXh0OiBudWxsfSwgcGFnZUxvYWRSZXN1bHRdO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlUb09ic2VydmFibGUocmVzdWx0cyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKHBhZ2VMb2FkUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNvbmNhdE1hcChvID0+IG8pLFxuICAgICAgICAgICAgc2NhbigoYWNjLCBwYWdlTG9hZFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCByZXN1bHQ6IHsgW2s6IHN0cmluZ106IFRhc2tQYW5lbERhdGEgfTtcbiAgICAgICAgICAgICAgICBpZiAocGFnZUxvYWRSZXN1bHQucmVxdWVzdENvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhZ2VMb2FkUmVzdWx0LnRhc2tzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwYWdlTG9hZFJlc3VsdC5yZXF1ZXN0Q29udGV4dC5yZWxvYWRDdXJyZW50VGFza1BhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoYWNjKS5mb3JFYWNoKHRhc2tJZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWNjW3Rhc2tJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0udGFzay5kYXRhR3JvdXBzID0gYWNjW3Rhc2tJZF0udGFzay5kYXRhR3JvdXBzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMb2FkUmVzdWx0LnRhc2tzW3Rhc2tJZF0uaW5pdGlhbGx5RXhwYW5kZWQgPSBhY2NbdGFza0lkXS5pbml0aWFsbHlFeHBhbmRlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVRhc2soYWNjW3Rhc2tJZF0udGFzaywgcGFnZUxvYWRSZXN1bHQudGFza3NbdGFza0lkXS50YXNrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJsb2NrVGFza0ZpZWxkcyhhY2NbdGFza0lkXS50YXNrLCAhKGFjY1t0YXNrSWRdLnRhc2suYXNzaWduZWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5fdXNlckNvbXBhcmF0b3IuY29tcGFyZVVzZXJzKGFjY1t0YXNrSWRdLnRhc2suYXNzaWduZWUuaWQpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9wYWdpbmF0aW9uVmlldykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFnZUxvYWRSZXN1bHQudGFza3NbdGFza0lkXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBPYmplY3QuYXNzaWduKGFjYywgcGFnZUxvYWRSZXN1bHQudGFza3MpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHsuLi5hY2MsIC4uLnBhZ2VMb2FkUmVzdWx0LnRhc2tzfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMuX3BhZ2luYXRpb24sIHBhZ2VMb2FkUmVzdWx0LnJlcXVlc3RDb250ZXh0LnBhZ2luYXRpb24pO1xuICAgICAgICAgICAgICAgIGlmIChwYWdlTG9hZFJlc3VsdC5yZXF1ZXN0Q29udGV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkaW5nJC5vZmYocGFnZUxvYWRSZXN1bHQucmVxdWVzdENvbnRleHQuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhZ2luYXRpb25WaWV3KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYWdlTG9hZFJlc3VsdC50YXNrcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0sIHt9KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLl90YXNrcyQgPSB0YXNrc01hcCQucGlwZShcbiAgICAgICAgICAgIG1hcCh2ID0+IE9iamVjdC52YWx1ZXModikgYXMgQXJyYXk8VGFza1BhbmVsRGF0YT4pLFxuICAgICAgICAgICAgbWFwKHRhc2tBcnJheSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRhc2tBcnJheS5sZW5ndGggPT09IDEgJiYgdGhpcy5faW5pdGlhbGx5T3Blbk9uZVRhc2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGFza0FycmF5WzBdLnRhc2suZmluaXNoRGF0ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tBcnJheVswXS5pbml0aWFsbHlFeHBhbmRlZCA9IHRydWUgOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGFza0FycmF5WzBdLmluaXRpYWxseUV4cGFuZGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0YXNrQXJyYXk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHRhcCh2ID0+IHRoaXMuX3BhbmVsVXBkYXRlJC5uZXh0KHYpKSk7XG5cbiAgICAgICAgdGhpcy5fc3ViSW5pdGlhbGx5T3BlbiA9ICh0YXNrVmlld0NvbmZpZz8uaW5pdGlhbGx5T3Blbk9uZVRhc2sgPz8gb2YodHJ1ZSkpLnN1YnNjcmliZShib29sID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxseU9wZW5PbmVUYXNrID0gYm9vbDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fc3ViQ2xvc2VUYXNrID0gKHRhc2tWaWV3Q29uZmlnPy5jbG9zZVRhc2tUYWJPbk5vVGFza3MgPz8gb2YodHJ1ZSkpLnN1YnNjcmliZShib29sID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlVGFza1RhYk9uTm9UYXNrcyA9IGJvb2w7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgICAgICB0aGlzLl9jaGFuZ2VkRmllbGRzJC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLl9yZXF1ZXN0ZWRQYWdlJC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLl9wYW5lbFVwZGF0ZSQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fY2xvc2VUYWIkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX3N1YkluaXRpYWxseU9wZW4udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fc3ViQ2xvc2VUYXNrLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuX3N1YlNlYXJjaC51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdGFza3MkKCk6IE9ic2VydmFibGU8QXJyYXk8VGFza1BhbmVsRGF0YT4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rhc2tzJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGNoYW5nZWRGaWVsZHMkKCk6IFN1YmplY3Q8Q2hhbmdlZEZpZWxkc01hcD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2hhbmdlZEZpZWxkcyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsb2FkaW5nJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRpbmckLmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbG9hZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRpbmckLmlzQWN0aXZlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgcGFuZWxVcGRhdGUoKTogT2JzZXJ2YWJsZTxBcnJheTxUYXNrUGFuZWxEYXRhPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZWxVcGRhdGUkLmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgY2xvc2VUYWIoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZVRhYiQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBwYWdpbmF0aW9uKCk6IFBhZ2luYXRpb24ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFnaW5hdGlvbjtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGFjdGl2ZUZpbHRlcigpOiBGaWx0ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VhcmNoU2VydmljZS5hY3RpdmVGaWx0ZXI7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBhbGxvd011bHRpT3Blbihib29sOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2FsbG93TXVsdGlPcGVuID0gYm9vbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGFsbG93TXVsdGlPcGVuKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWxsb3dNdWx0aU9wZW47XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBwYWdpbmF0aW9uVmlldyh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9wYWdpbmF0aW9uVmlldyA9IHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkUGFnZShyZXF1ZXN0Q29udGV4dDogUGFnZUxvYWRSZXF1ZXN0Q29udGV4dCk6IE9ic2VydmFibGU8VGFza1BhZ2VMb2FkUmVxdWVzdFJlc3VsdD4ge1xuICAgICAgICBpZiAocmVxdWVzdENvbnRleHQgPT09IG51bGwgfHwgcmVxdWVzdENvbnRleHQucGFnZU51bWJlciA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBvZih7dGFza3M6IHt9LCByZXF1ZXN0Q29udGV4dH0pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJhbXM6IEh0dHBQYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpO1xuICAgICAgICBwYXJhbXMgPSB0aGlzLmFkZFNvcnRQYXJhbXMocGFyYW1zKTtcbiAgICAgICAgcGFyYW1zID0gdGhpcy5hZGRQYWdlUGFyYW1zKHBhcmFtcywgcmVxdWVzdENvbnRleHQucGFnaW5hdGlvbik7XG4gICAgICAgIHRoaXMuX2xvYWRpbmckLm9uKHJlcXVlc3RDb250ZXh0LmZpbHRlcik7XG5cbiAgICAgICAgbGV0IHJlcXVlc3Q6IE9ic2VydmFibGU8UGFnZTxUYXNrPj47XG4gICAgICAgIGlmIChyZXF1ZXN0Q29udGV4dC5maWx0ZXIuYm9keUNvbnRhaW5zUXVlcnkoKSB8fCB0aGlzLl9wcmVmZXJyZWRFbmRwb2ludCA9PT0gVGFza0VuZHBvaW50LkVMQVNUSUMpIHtcbiAgICAgICAgICAgIHJlcXVlc3QgPSB0aW1lcigyMDApLnBpcGUoXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3Rhc2tTZXJ2aWNlLnNlYXJjaFRhc2socmVxdWVzdENvbnRleHQuZmlsdGVyLCBwYXJhbXMpLnBpcGUodGFrZSgxKSkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVxdWVzdCA9IHRoaXMuX3Rhc2tTZXJ2aWNlLmdldFRhc2tzKHJlcXVlc3RDb250ZXh0LmZpbHRlciwgcGFyYW1zKS5waXBlKHRha2UoMSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXF1ZXN0LnBpcGUoXG4gICAgICAgICAgICBjYXRjaEVycm9yKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9nLmVycm9yKCdMb2FkaW5nIHRhc2tzIGhhcyBmYWlsZWQhJywgZXJyKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkaW5nJC5vZmYocmVxdWVzdENvbnRleHQuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2Yoe2NvbnRlbnQ6IFtdLCBwYWdpbmF0aW9uOiB7Li4udGhpcy5fcGFnaW5hdGlvbn19KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZmlsdGVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByID0gcmVxdWVzdENvbnRleHQuZmlsdGVyID09PSB0aGlzLl9zZWFyY2hTZXJ2aWNlLmFjdGl2ZUZpbHRlcjtcbiAgICAgICAgICAgICAgICBpZiAoIXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGluZyQub2ZmKHJlcXVlc3RDb250ZXh0LmZpbHRlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvZy5kZWJ1ZygnUmVjZWl2ZWQgdGFza3MgcGFnZSBpcyBubyBsb25nZXIgcmVsZXZhbnQgc2luY2UgdGhlIGFjdGl2ZSBmaWx0ZXIgaGFzIGNoYW5nZWQgYmVmb3JlIGl0IGNvdWxkIGFycml2ZS4nXG4gICAgICAgICAgICAgICAgICAgICAgICArICcgRGlzY2FyZGluZy4uLicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKHQgPT4ge1xuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocmVxdWVzdENvbnRleHQucGFnaW5hdGlvbiwgdC5wYWdpbmF0aW9uKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKHQgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9wYWdpbmF0aW9uLnRvdGFsRWxlbWVudHMgJiYgdGhpcy5fcGFnaW5hdGlvbi50b3RhbEVsZW1lbnRzID4gMFxuICAgICAgICAgICAgICAgICAgICAmJiB0LnBhZ2luYXRpb24udG90YWxFbGVtZW50cyA9PT0gMCAmJiAhQXJyYXkuaXNBcnJheSh0LmNvbnRlbnQpICYmIHRoaXMuX2Nsb3NlVGFza1RhYk9uTm9UYXNrcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jbG9zZVRhYiQubmV4dCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKHQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2VuZE9mRGF0YSA9ICFBcnJheS5pc0FycmF5KHQuY29udGVudClcbiAgICAgICAgICAgICAgICAgICAgfHwgdC5jb250ZW50Lmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICAgICAgICB8fCB0LnBhZ2luYXRpb24ubnVtYmVyID09PSB0LnBhZ2luYXRpb24udG90YWxQYWdlcztcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKHRhc2tzID0+IEFycmF5LmlzQXJyYXkodGFza3MuY29udGVudCkgPyB0YXNrcyA6IHsuLi50YXNrcywgY29udGVudDogW119KSxcbiAgICAgICAgICAgIG1hcCh0YXNrcyA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhc2tzLmNvbnRlbnQucmVkdWNlKChhY2MsIGN1cnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ibG9ja1Rhc2tGaWVsZHMoY3VyciwgIShjdXJyLmFzc2lnbmVlICYmIHRoaXMuX3VzZXJDb21wYXJhdG9yLmNvbXBhcmVVc2VycyhjdXJyLmFzc2lnbmVlLmlkKSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uYWNjLCBbY3Vyci5zdHJpbmdJZF06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiBjdXJyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRGaWVsZHM6IHRoaXMuX2NoYW5nZWRGaWVsZHMkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxseUV4cGFuZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKHRhc2tzID0+ICh7dGFza3MsIHJlcXVlc3RDb250ZXh0fSkpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVUYXNrKG9sZDogVGFzaywgbmV3dzogVGFzaykge1xuICAgICAgICBPYmplY3Qua2V5cyhvbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmICghbmV3dy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIG9sZFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmtleXMobmV3dykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgaWYgKG5ld3dba2V5XSAhPT0gdW5kZWZpbmVkICYmIG5ld3dba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG9sZFtrZXldID0gbmV3d1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ibG9ja1Rhc2tGaWVsZHMob2xkLCAhKG9sZC5hc3NpZ25lZSAmJiB0aGlzLl91c2VyQ29tcGFyYXRvci5jb21wYXJlVXNlcnMob2xkLmFzc2lnbmVlLmlkKSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYmxvY2tUYXNrRmllbGRzKHRhc2s6IFRhc2ssIGJsb2NrOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICghdGFzay5kYXRhR3JvdXBzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGFzay5kYXRhR3JvdXBzLmZvckVhY2goZyA9PiBnLmZpZWxkcy5mb3JFYWNoKGYgPT4gZi5ibG9jayA9IGJsb2NrKSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5leHRQYWdlKHJlbmRlcmVkUmFuZ2U6IExpc3RSYW5nZSwgdG90YWxMb2FkZWQ6IG51bWJlciwgcmVxdWVzdENvbnRleHQ/OiBQYWdlTG9hZFJlcXVlc3RDb250ZXh0KTogdm9pZCB7XG4gICAgICAgIGlmIChyZXF1ZXN0Q29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXF1ZXN0Q29udGV4dCA9IG5ldyBQYWdlTG9hZFJlcXVlc3RDb250ZXh0KHRoaXMuYWN0aXZlRmlsdGVyLCB0aGlzLl9wYWdpbmF0aW9uKTtcbiAgICAgICAgICAgIHJlcXVlc3RDb250ZXh0LnBhZ2luYXRpb24ubnVtYmVyICs9IDE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pc0xvYWRpbmdSZWxldmFudEZpbHRlcihyZXF1ZXN0Q29udGV4dCkgfHwgdGhpcy5fZW5kT2ZEYXRhKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVuZGVyZWRSYW5nZS5lbmQgPT09IHRvdGFsTG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXF1ZXN0ZWRQYWdlJC5uZXh0KHJlcXVlc3RDb250ZXh0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZXh0UGFnZVBhZ2luYXRpb24obGVuZ3RoOiBudW1iZXIsIHBhZ2VJbmRleDogbnVtYmVyLCByZXF1ZXN0Q29udGV4dD86IFBhZ2VMb2FkUmVxdWVzdENvbnRleHQpOiB2b2lkIHtcbiAgICAgICAgaWYgKHJlcXVlc3RDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJlcXVlc3RDb250ZXh0ID0gbmV3IFBhZ2VMb2FkUmVxdWVzdENvbnRleHQodGhpcy5hY3RpdmVGaWx0ZXIsIHRoaXMuX3BhZ2luYXRpb24pO1xuICAgICAgICAgICAgcmVxdWVzdENvbnRleHQucGFnaW5hdGlvbi5zaXplID0gbGVuZ3RoO1xuICAgICAgICAgICAgcmVxdWVzdENvbnRleHQucGFnaW5hdGlvbi5udW1iZXIgPSBwYWdlSW5kZXg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pc0xvYWRpbmdSZWxldmFudEZpbHRlcihyZXF1ZXN0Q29udGV4dCkgfHwgdGhpcy5fZW5kT2ZEYXRhKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcmVxdWVzdGVkUGFnZSQubmV4dChyZXF1ZXN0Q29udGV4dCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0xvYWRpbmdSZWxldmFudEZpbHRlcihyZXF1ZXN0Q29udGV4dD86IFBhZ2VMb2FkUmVxdWVzdENvbnRleHQpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3RDb250ZXh0ID09PSB1bmRlZmluZWQgfHwgKHRoaXMuX2xvYWRpbmckLmlzQWN0aXZlV2l0aEZpbHRlcihyZXF1ZXN0Q29udGV4dC5maWx0ZXIpICYmICFyZXF1ZXN0Q29udGV4dC5mb3JjZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbG9hZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLl90YXNrcyQgfHwgIXRoaXMuX3BhZ2luYXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2VuZE9mRGF0YSA9IGZhbHNlO1xuICAgICAgICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IG5ldyBQYWdlTG9hZFJlcXVlc3RDb250ZXh0KHRoaXMuYWN0aXZlRmlsdGVyLCB0aGlzLl9wYWdpbmF0aW9uLCB0cnVlKTtcbiAgICAgICAgcmVxdWVzdENvbnRleHQucGFnaW5hdGlvbi5udW1iZXIgPSAwO1xuICAgICAgICBjb25zdCByYW5nZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiAtMSxcbiAgICAgICAgICAgIGVuZDogMFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubmV4dFBhZ2UocmFuZ2UsIDAsIHJlcXVlc3RDb250ZXh0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVsb2FkQ3VycmVudFBhZ2UoZm9yY2U/OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5fdGFza3MkIHx8ICF0aGlzLl9wYWdpbmF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9lbmRPZkRhdGEgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgcmVxdWVzdENvbnRleHQgPSBuZXcgUGFnZUxvYWRSZXF1ZXN0Q29udGV4dCh0aGlzLmFjdGl2ZUZpbHRlciwgdGhpcy5fcGFnaW5hdGlvbiwgZmFsc2UsIHRydWUsIGZvcmNlKTtcbiAgICAgICAgcmVxdWVzdENvbnRleHQucGFnaW5hdGlvbi5udW1iZXIgPSAwOyAvLyBUT0RPIFtCVUddIC0gUmVsb2FkaW5nIG9ubHkgZmlyc3QgcGFnZVxuICAgICAgICBjb25zdCByYW5nZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiAtMSxcbiAgICAgICAgICAgIGVuZDogMFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm5leHRQYWdlKHJhbmdlLCAwLCByZXF1ZXN0Q29udGV4dCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldE1ldGFGaWVsZFNvcnRJZCgpOiBzdHJpbmcge1xuICAgICAgICAvLyBUT0RPIFRhc2tzIHdlcmUgbm90IHNvcnRhYmxlIG9uIG9sZCBmcm9udGVuZCBzb3J0aW5nIG1pZ2h0IHJlcXVpcmUgZWxhc3RpYyBtYXBwaW5nIGNoYW5nZXMgb24gYmFja2VuZFxuICAgICAgICByZXR1cm4gdGhpcy5fbGFzdEhlYWRlclNlYXJjaFN0YXRlLmZpZWxkSWRlbnRpZmllcjtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0RGVmYXVsdFNvcnRQYXJhbSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gY3JlYXRlU29ydFBhcmFtKCdwcmlvcml0eScsIFBhZ2luYXRpb25Tb3J0LkRFU0NFTkRJTkcpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBhZGRQYWdlUGFyYW1zKHBhcmFtczogSHR0cFBhcmFtcywgcGFnaW5hdGlvbjogUGFnaW5hdGlvbik6IEh0dHBQYXJhbXMge1xuICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KFBhZ2luYXRpb25QYXJhbXMuUEFHRV9TSVpFLCBgJHtwYWdpbmF0aW9uLnNpemV9YCk7XG4gICAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoUGFnaW5hdGlvblBhcmFtcy5QQUdFX05VTUJFUiwgYCR7cGFnaW5hdGlvbi5udW1iZXJ9YCk7XG4gICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgfVxufVxuIl19