@netgrif/components-core
Version:
Netgrif Application engine frontend core Angular library
561 lines • 84.5 kB
JavaScript
import { EventEmitter, Injectable } from '@angular/core';
import { BehaviorSubject, of } from 'rxjs';
import { LoadingEmitter } from "../../../utility/loading-emitter";
import { filter, map, take } from "rxjs/operators";
import { DoubleDrawerUtils } from "../util/double-drawer-utils";
import { HttpParams } from "@angular/common/http";
import { PaginationParams } from "../../../utility/pagination/pagination-params";
import { SimpleFilter } from "../../../filter/models/simple-filter";
import { MENU_IDENTIFIERS, MenuOrder, RIGHT_SIDE_INIT_PAGE_SIZE, RIGHT_SIDE_NEW_PAGE_SIZE, SETTINGS_TRANSITION_ID } from '../../model/navigation-configs';
import { GroupNavigationConstants } from "../../model/group-navigation-constants";
import { PathService } from "../../service/path.service";
import * as i0 from "@angular/core";
import * as i1 from "../../../logger/services/logger.service";
import * as i2 from "../../../configuration/configuration.service";
import * as i3 from "@angular/router";
import * as i4 from "../../../resources/engine-endpoint/case-resource.service";
import * as i5 from "../../../authorization/permission/access.service";
import * as i6 from "@ngx-translate/core";
import * as i7 from "../../../routing/dynamic-navigation-route-provider/dynamic-navigation-route-provider.service";
import * as i8 from "../../../routing/redirect-service/redirect.service";
import * as i9 from "../../service/path.service";
import * as i10 from "../../../user/services/user.service";
/**
* Service for managing navigation in double-drawer
* */
export class DoubleDrawerNavigationService {
_log;
_config;
_activatedRoute;
_caseResourceService;
_accessService;
_translateService;
_dynamicRoutingService;
_redirectService;
_pathService;
_userService;
/**
* List of displayed items on the left side
* */
_leftItems$;
/**
* List of displayed items on the right side
* */
_rightItems$;
/**
* List of hidden items
* */
_moreItems$;
/**
* List of custom items in more menu
* */
_hiddenCustomItems$;
/**
* List of custom items
* */
_childCustomViews;
itemsOrder;
_leftLoading$;
_rightLoading$;
_nodeLoading$;
_currentPathSubscription;
/**
* Currently display uri
* Siblings of the node are on the left, children are on the right
*/
_currentPath;
_fromResolver;
/**
* Currently selected navigation item
*/
_currentNavigationItem;
defaultViewIcon = 'filter_alt';
customItemsInitialized;
hiddenCustomItemsInitialized;
itemClicked;
itemLoaded;
constructor(_log, _config, _activatedRoute, _caseResourceService, _accessService, _translateService, _dynamicRoutingService, _redirectService, _pathService, _userService) {
this._log = _log;
this._config = _config;
this._activatedRoute = _activatedRoute;
this._caseResourceService = _caseResourceService;
this._accessService = _accessService;
this._translateService = _translateService;
this._dynamicRoutingService = _dynamicRoutingService;
this._redirectService = _redirectService;
this._pathService = _pathService;
this._userService = _userService;
this._leftItems$ = new BehaviorSubject([]);
this._rightItems$ = new BehaviorSubject([]);
this._moreItems$ = new BehaviorSubject([]);
this._hiddenCustomItems$ = new BehaviorSubject([]);
this._childCustomViews = {};
this._leftLoading$ = new LoadingEmitter();
this._rightLoading$ = new LoadingEmitter();
this._nodeLoading$ = new LoadingEmitter();
this._currentNavigationItem = undefined;
this.itemsOrder = MenuOrder.Ascending;
this.customItemsInitialized = false;
this.hiddenCustomItemsInitialized = false;
this.itemClicked = new EventEmitter();
this.itemLoaded = new EventEmitter();
}
ngOnDestroy() {
this._currentPathSubscription?.unsubscribe();
this._leftLoading$.complete();
this._rightLoading$.complete();
this._nodeLoading$.complete();
this.itemClicked.complete();
this.itemLoaded.complete();
}
get canGoBackLoading$() {
return this._nodeLoading$;
}
get currentPath() {
return this._currentPath;
}
set currentPath(path) {
if (path === this._currentPath || this.leftLoading$.isActive || this.rightLoading$.isActive) {
return;
}
this._currentPath = path;
if (!path) {
return;
}
if (this.nodeLoading$.isActive) {
this.nodeLoading$.subscribe(() => {
this.resolveMenuItems(path);
});
}
else {
this.resolveMenuItems(path);
}
}
set currentNavigationItem(item) {
this._currentNavigationItem = item;
}
resolveMenuItems(path) {
if (path === PathService.SEPARATOR) {
this._leftItems$.next([]);
this.loadRightSide();
}
else {
if (!this.leftItems.find(item => item.resource?.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH)?.value === path)) {
this.loadLeftSide();
}
this.loadRightSide();
}
}
get itemClicked$() {
return this.itemClicked;
}
get itemLoaded$() {
return this.itemLoaded;
}
get rightItems$() {
return this._rightItems$;
}
get leftItems$() {
return this._leftItems$;
}
get moreItems$() {
return this._moreItems$;
}
get hiddenCustomItems$() {
return this._hiddenCustomItems$;
}
get rightItems() {
return this._rightItems$.getValue();
}
get leftItems() {
return this._leftItems$.getValue();
}
get moreItems() {
return this._moreItems$.getValue();
}
get hiddenCustomItems() {
return this._hiddenCustomItems$.getValue();
}
get leftLoading$() {
return this._leftLoading$;
}
get rightLoading$() {
return this._rightLoading$;
}
get nodeLoading$() {
return this._nodeLoading$;
}
set fromResolver(value) {
this._fromResolver = value;
}
loadNavigationItems(node) {
if (this.currentPath === PathService.SEPARATOR) {
this._leftItems$.next([]);
this.loadRightSide();
}
else {
if (!this._leftItems$.getValue().find(item => DoubleDrawerUtils.isNodeCorrespondingToItem(node, item))) {
this.loadLeftSide();
}
this.loadRightSide();
}
}
/**
* On home click, the current level is set to 0, and current parent is
* set to root node.
* */
onHomeClick() {
if (this.leftLoading$.isActive || this.rightLoading$.isActive) {
return;
}
this._pathService.activePath = PathService.SEPARATOR;
}
/**
* On back click, the parent is set to parent of left nodes, that will solve
* the right side menu (elements that were in left side, after backward
* navigation will be on the right side).
* Current level is set to a lower number in order to set the left side menu.
* */
onBackClick() {
if (this.leftLoading$.isActive || this.rightLoading$.isActive || this.currentPath === PathService.SEPARATOR) {
return;
}
this._pathService.activePath = this.extractParentPath(this.currentPath);
this.itemClicked.emit({ path: this._pathService.activePath, isHome: false });
}
/**
* On item click, the selected item's view is rendered (by routerLink). If the selected item has children items, the menu is updated
* and view, that is rendered is selected by the defined rule. The rule is: On first check for default view in children.
* On second check if the clicked item has a view. On third, pick any other children's view, else show nothing.
* */
onItemClick(item) {
this._currentNavigationItem = item;
if (item.resource === undefined) {
// custom view represented only in nae.json
if (item.processUri === this.currentPath) {
this._pathService.activePath = this.currentPath;
}
else {
this._pathService.activePath = this.extractParentPath(this.currentPath);
}
this.itemClicked.emit({ path: this._pathService.activePath, isHome: false });
}
else {
const path = item.resource.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH)?.value;
if (DoubleDrawerUtils.hasItemChildren(item) && !this.leftLoading$.isActive && !this.rightLoading$.isActive) {
this._pathService.activePath = path;
this.itemClicked.emit({ path: this._pathService.activePath, isHome: false });
this._rightLoading$.pipe(filter(isRightLoading => isRightLoading === false), take(1)).subscribe(() => {
this.openAvailableView();
});
}
else if (!path.includes(this.currentPath)) {
this._pathService.activePath = this.extractParentPath(this.currentPath);
this.itemClicked.emit({ path: this._pathService.activePath, isHome: false });
}
else {
this._pathService.activePath = this.currentPath;
this.itemClicked.emit({ path: this._pathService.activePath, isHome: false });
}
}
}
/**
* Opens a view of the current right items in the menu by defined rule. The rule is: First, it checks whether a navigation
* item was clicked. Second, check for default view in children.
* Third check if the clicked item has a view. Fourth, pick any other children's view, else
* show nothing.
* */
openAvailableView() {
let allItems = this.rightItems.concat(this.moreItems);
if (this._currentNavigationItem) {
let alreadyClickedItem = allItems.find(item => item.id === this._currentNavigationItem.id);
if (!!alreadyClickedItem) {
// when the folder has not changed and a menu item is clicked.
return;
}
}
if (this._fromResolver) {
this._fromResolver = false;
return;
}
let autoOpenItems = allItems.filter(item => DoubleDrawerUtils.hasItemAutoOpenView(item));
if (autoOpenItems.length > 0) {
this._redirectService.redirect(autoOpenItems[0].routing.path);
return;
}
if (DoubleDrawerUtils.hasItemView(this._currentNavigationItem)) {
// is routed by routerLink on item click
return;
}
let itemsWithView = allItems.filter(item => DoubleDrawerUtils.hasItemView(item));
if (itemsWithView.length > 0) {
this._redirectService.redirect(autoOpenItems[0].routing.path);
}
}
loadMoreItems() {
if (this.moreItems.length > RIGHT_SIDE_NEW_PAGE_SIZE) {
let currentRightItems = this.rightItems;
let currentMoreItems = this.moreItems;
currentRightItems.push(...currentMoreItems.splice(0, RIGHT_SIDE_NEW_PAGE_SIZE));
this.rightItems$.next(currentRightItems);
this.moreItems$.next(currentMoreItems);
}
else {
let currentRightItems = this.rightItems;
currentRightItems.push(...this.moreItems);
this.rightItems$.next(currentRightItems);
this.moreItems$.next([]);
}
}
initializeCustomViewsOfView(view, viewConfigPath) {
if (!view || this.customItemsInitialized || this.hiddenCustomItemsInitialized)
return;
Object.entries(view.children).forEach(([key, childView]) => {
const childViewConfigPath = viewConfigPath + '/' + key;
this.resolveUriForChildViews(childViewConfigPath, childView);
this.resolveHiddenMenuItemFromChildViews(childViewConfigPath, childView);
});
this.resolveCustomViewsInRightSide();
this.resolveCustomViewsInLeftSide();
this.customItemsInitialized = true;
this.hiddenCustomItemsInitialized = true;
}
switchOrder() {
this.itemsOrder = (this.itemsOrder + 1) % 2;
let multiplier = 1;
if (this.itemsOrder === MenuOrder.Descending) {
multiplier = -1;
}
let currentRightItems = this.rightItems;
let currentLeftItems = this.leftItems;
currentRightItems.sort((a, b) => multiplier * a?.navigation?.title.localeCompare(b?.navigation?.title));
currentLeftItems.sort((a, b) => multiplier * a?.navigation?.title.localeCompare(b?.navigation?.title));
this.rightItems$.next(currentRightItems);
this.leftItems$.next(currentLeftItems);
}
isAscending() {
return this.itemsOrder === MenuOrder.Ascending;
}
loadLeftSide() {
if (this.currentPath === PathService.SEPARATOR) {
this._leftItems$.next([]);
return;
}
this.leftLoading$.on();
this.getItemCaseByPath(this.extractParentPath(this.currentPath)).subscribe(page => {
let childCases$;
let targetItem;
let orderedChildCaseIds;
if (page?.pagination?.totalElements === 0) {
childCases$ = of([]);
}
else {
targetItem = page.content[0];
orderedChildCaseIds = DoubleDrawerUtils.extractChildCaseIds(targetItem);
if (orderedChildCaseIds == undefined || orderedChildCaseIds.length === 0) {
childCases$ = of([]);
}
else {
childCases$ = this.getItemCasesByIdsInOnePage(orderedChildCaseIds).pipe(map(p => p.content));
}
}
childCases$.subscribe(result => {
result = result.map(folder => this.resolveItemCaseToNavigationItem(folder)).filter(i => !!i);
this._leftItems$.next(result.sort((a, b) => orderedChildCaseIds.indexOf(a.resource.stringId) - orderedChildCaseIds.indexOf(b.resource.stringId)));
this.resolveCustomViewsInLeftSide();
this._leftLoading$.off();
this.itemLoaded.emit({ menu: 'left', items: this.leftItems });
}, error => {
this._log.error(error);
this._leftItems$.next([]);
this.resolveCustomViewsInLeftSide();
this._leftLoading$.off();
});
}, error => {
this._log.error(error);
this._leftItems$.next([]);
this.resolveCustomViewsInLeftSide();
this._leftLoading$.off();
});
}
loadRightSide() {
this._rightLoading$.on();
this._moreItems$.next([]);
this.getItemCaseByPath(this.currentPath).subscribe(page => {
let childCases$;
let targetItem;
let orderedChildCaseIds;
if (page?.pagination?.totalElements === 0) {
childCases$ = of([]);
}
else {
targetItem = page?.content[0];
orderedChildCaseIds = DoubleDrawerUtils.extractChildCaseIds(targetItem);
if (orderedChildCaseIds === undefined || orderedChildCaseIds.length === 0) {
childCases$ = of([]);
}
else {
childCases$ = this.getItemCasesByIdsInOnePage(orderedChildCaseIds).pipe(map(p => p.content));
}
}
childCases$.subscribe(result => {
result = result.sort((a, b) => orderedChildCaseIds.indexOf(a.stringId) - orderedChildCaseIds.indexOf(b.stringId));
if (result.length > RIGHT_SIDE_INIT_PAGE_SIZE) {
const rawRightItems = result.splice(0, RIGHT_SIDE_INIT_PAGE_SIZE);
this._rightItems$.next(rawRightItems.map(folder => this.resolveItemCaseToNavigationItem(folder)).filter(i => !!i));
this._moreItems$.next(result.map(folder => this.resolveItemCaseToNavigationItem(folder)).filter(i => !!i));
}
else {
this._rightItems$.next(result.map(folder => this.resolveItemCaseToNavigationItem(folder)).filter(i => !!i));
}
this.resolveCustomViewsInRightSide();
this._rightLoading$.off();
this.itemLoaded.emit({ menu: 'right', items: this.rightItems });
this.openAvailableView();
}, error => {
this._log.error(error);
this._rightItems$.next([]);
this._moreItems$.next([]);
this.resolveCustomViewsInRightSide();
this._rightLoading$.off();
});
}, error => {
this._log.error(error);
this._rightItems$.next([]);
this._moreItems$.next([]);
this.resolveCustomViewsInRightSide();
this._rightLoading$.off();
});
}
getItemCasesByIdsInOnePage(caseIds) {
return this.getItemCasesByIds(caseIds, 0, caseIds.length);
}
getItemCasesByIds(caseIds, pageNumber, pageSize) {
const searchBody = {
id: caseIds,
process: MENU_IDENTIFIERS.map(id => ({ identifier: id })),
};
let httpParams = new HttpParams()
.set(PaginationParams.PAGE_SIZE, pageSize)
.set(PaginationParams.PAGE_NUMBER, pageNumber);
return this._caseResourceService.searchCases(SimpleFilter.fromCaseQuery(searchBody), httpParams);
}
resolveItemCaseToNavigationItem(itemCase) {
if (DoubleDrawerUtils.representsRootNode(itemCase)) {
return;
}
const item = {
access: {},
navigation: {
icon: itemCase.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_MENU_ICON)?.value || this.defaultViewIcon,
title: this.getTranslation(itemCase.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_MENU_NAME)?.value) || itemCase.title,
},
routing: {
path: this.getItemRoutingPath(itemCase),
},
id: itemCase.stringId,
resource: itemCase,
};
const resolvedRoles = DoubleDrawerUtils.resolveAccessRoles(itemCase, GroupNavigationConstants.ITEM_FIELD_ID_ALLOWED_ROLES);
const resolvedBannedRoles = DoubleDrawerUtils.resolveAccessRoles(itemCase, GroupNavigationConstants.ITEM_FIELD_ID_BANNED_ROLES);
if (!!resolvedRoles)
item.access['role'] = resolvedRoles;
if (!!resolvedBannedRoles)
item.access['bannedRole'] = resolvedBannedRoles;
if (!this._accessService.canAccessView(item, item.routing?.path))
return;
return item;
}
resolveCustomViewsInLeftSide() {
if (!!this.extractParentPath(this.currentPath) && !!this._childCustomViews[this.extractParentPath(this.currentPath)]) {
let currentLeftItems = this._leftItems$.getValue();
currentLeftItems.push(...Object.values(this._childCustomViews[this.extractParentPath(this.currentPath)]));
this._leftItems$.next(currentLeftItems);
}
}
resolveCustomViewsInRightSide() {
if (!!this._currentPath && !!this._childCustomViews[this._currentPath]) {
let currentRightItems = this._rightItems$.getValue();
currentRightItems.push(...Object.values(this._childCustomViews[this._currentPath]));
this._rightItems$.next(currentRightItems);
}
}
resolveUriForChildViews(configPath, childView) {
if (!childView.processUri)
return;
if (!this._accessService.canAccessView(childView, configPath))
return;
if (!this._childCustomViews[childView.processUri]) {
this._childCustomViews[childView.processUri] = {};
}
this._childCustomViews[childView.processUri][configPath] = {
id: configPath,
...childView,
};
}
resolveHiddenMenuItemFromChildViews(configPath, childView) {
if (!childView.navigation)
return;
if (!this._accessService.canAccessView(childView, configPath))
return;
if (!!(childView?.navigation?.hidden)) {
let currentHiddenCustomItems = this._hiddenCustomItems$.getValue();
currentHiddenCustomItems.push({
id: configPath,
...childView,
});
this._hiddenCustomItems$.next(currentHiddenCustomItems);
}
}
getTranslation(value) {
const locale = this._translateService.currentLang.split('-')[0];
return locale in value.translations ? value.translations[locale] : value.defaultValue;
}
getItemRoutingPath(itemCase) {
const taskId = DoubleDrawerUtils.findTaskIdInCase(itemCase, SETTINGS_TRANSITION_ID);
const url = this._dynamicRoutingService.route;
const prefix = url.startsWith('/') ? '' : '/';
return `${prefix}${url}/${taskId}`;
}
processLeftItems(cases, orderedChildCaseIds) {
const result = cases
.map(folder => this.resolveItemCaseToNavigationItem(folder))
.filter(i => !!i);
return result.sort((a, b) => orderedChildCaseIds.indexOf(a.resource.stringId) - orderedChildCaseIds.indexOf(b.resource.stringId));
}
/**
* Retrieves a case item based on the given path.
* @param {string} [path] - The identifier path to locate the specific case item. If undefined, it defaults to searching without a specific path.
* @return {Observable<Page<Case>>} An observable stream containing the page of case items which match the provided path.
*/
getItemCaseByPath(path) {
const searchBody = {
data: {
[GroupNavigationConstants.ITEM_FIELD_ID_NODE_PATH]: path
},
process: { identifier: "menu_item" }
};
let httpParams = new HttpParams()
.set(PaginationParams.PAGE_SIZE, 1)
.set(PaginationParams.PAGE_NUMBER, 0);
return this._caseResourceService.searchCases(SimpleFilter.fromCaseQuery(searchBody), httpParams);
}
extractParentPath(path) {
if (path === '/') {
return path;
}
if (path?.lastIndexOf('/') === 0) {
return '/';
}
return path?.substring(0, path?.lastIndexOf('/'));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DoubleDrawerNavigationService, deps: [{ token: i1.LoggerService }, { token: i2.ConfigurationService }, { token: i3.ActivatedRoute }, { token: i4.CaseResourceService }, { token: i5.AccessService }, { token: i6.TranslateService }, { token: i7.DynamicNavigationRouteProviderService }, { token: i8.RedirectService }, { token: i9.PathService }, { token: i10.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DoubleDrawerNavigationService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DoubleDrawerNavigationService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [{ type: i1.LoggerService }, { type: i2.ConfigurationService }, { type: i3.ActivatedRoute }, { type: i4.CaseResourceService }, { type: i5.AccessService }, { type: i6.TranslateService }, { type: i7.DynamicNavigationRouteProviderService }, { type: i8.RedirectService }, { type: i9.PathService }, { type: i10.UserService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG91YmxlLWRyYXdlci1uYXZpZ2F0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMtY29yZS9zcmMvbGliL25hdmlnYXRpb24vbmF2aWdhdGlvbi1kb3VibGUtZHJhd2VyL3NlcnZpY2UvZG91YmxlLWRyYXdlci1uYXZpZ2F0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFlBQVksRUFBRSxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFDLGVBQWUsRUFBYyxFQUFFLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFDbkUsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQ2hFLE9BQU8sRUFBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR2pELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBRzlELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwrQ0FBK0MsQ0FBQztBQUMvRSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFZbEUsT0FBTyxFQUNILGdCQUFnQixFQUNoQixTQUFTLEVBRVQseUJBQXlCLEVBQ3pCLHdCQUF3QixFQUN4QixzQkFBc0IsRUFDekIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUd4QyxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRixPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7Ozs7OztBQUd2RDs7S0FFSztBQUlMLE1BQU0sT0FBTyw2QkFBNkI7SUE0Q3hCO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNB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RyxDQUFDO1NBQ2Q7UUFDRCxPQUFPLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN0RCxDQUFDO3dHQTFqQlEsNkJBQTZCOzRHQUE3Qiw2QkFBNkIsY0FGMUIsTUFBTTs7NEZBRVQsNkJBQTZCO2tCQUh6QyxVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RXZlbnRFbWl0dGVyLCBJbmplY3RhYmxlLCBPbkRlc3Ryb3l9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIG9mLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtMb2FkaW5nRW1pdHRlcn0gZnJvbSBcIi4uLy4uLy4uL3V0aWxpdHkvbG9hZGluZy1lbWl0dGVyXCI7XG5pbXBvcnQge2ZpbHRlciwgbWFwLCB0YWtlfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7Q2FzZX0gZnJvbSBcIi4uLy4uLy4uL3Jlc291cmNlcy9pbnRlcmZhY2UvY2FzZVwiO1xuaW1wb3J0IHtMb2dnZXJTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vbG9nZ2VyL3NlcnZpY2VzL2xvZ2dlci5zZXJ2aWNlXCI7XG5pbXBvcnQge0RvdWJsZURyYXdlclV0aWxzfSBmcm9tIFwiLi4vdXRpbC9kb3VibGUtZHJhd2VyLXV0aWxzXCI7XG5pbXBvcnQge1BhZ2V9IGZyb20gXCIuLi8uLi8uLi9yZXNvdXJjZXMvaW50ZXJmYWNlL3BhZ2VcIjtcbmltcG9ydCB7Q2FzZVNlYXJjaFJlcXVlc3RCb2R5LCBQZXRyaU5ldFNlYXJjaFJlcXVlc3R9IGZyb20gXCIuLi8uLi8uLi9maWx0ZXIvbW9kZWxzL2Nhc2Utc2VhcmNoLXJlcXVlc3QtYm9keVwiO1xuaW1wb3J0IHtIdHRwUGFyYW1zfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7UGFnaW5hdGlvblBhcmFtc30gZnJvbSBcIi4uLy4uLy4uL3V0aWxpdHkvcGFnaW5hdGlvbi9wYWdpbmF0aW9uLXBhcmFtc1wiO1xuaW1wb3J0IHtTaW1wbGVGaWx0ZXJ9IGZyb20gXCIuLi8uLi8uLi9maWx0ZXIvbW9kZWxzL3NpbXBsZS1maWx0ZXJcIjtcbmltcG9ydCB7Q2FzZVJlc291cmNlU2VydmljZX0gZnJvbSBcIi4uLy4uLy4uL3Jlc291cmNlcy9lbmdpbmUtZW5kcG9pbnQvY2FzZS1yZXNvdXJjZS5zZXJ2aWNlXCI7XG5pbXBvcnQge0kxOG5GaWVsZFZhbHVlfSBmcm9tIFwiLi4vLi4vLi4vZGF0YS1maWVsZHMvaTE4bi1maWVsZC9tb2RlbHMvaTE4bi1maWVsZC12YWx1ZVwiO1xuaW1wb3J0IHtUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xuaW1wb3J0IHtcbiAgICBEeW5hbWljTmF2aWdhdGlvblJvdXRlUHJvdmlkZXJTZXJ2aWNlXG59IGZyb20gXCIuLi8uLi8uLi9yb3V0aW5nL2R5bmFtaWMtbmF2aWdhdGlvbi1yb3V0ZS1wcm92aWRlci9keW5hbWljLW5hdmlnYXRpb24tcm91dGUtcHJvdmlkZXIuc2VydmljZVwiO1xuaW1wb3J0IHtSZWRpcmVjdFNlcnZpY2V9IGZyb20gXCIuLi8uLi8uLi9yb3V0aW5nL3JlZGlyZWN0LXNlcnZpY2UvcmVkaXJlY3Quc2VydmljZVwiO1xuaW1wb3J0IHtBY2Nlc3NTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vYXV0aG9yaXphdGlvbi9wZXJtaXNzaW9uL2FjY2Vzcy5zZXJ2aWNlXCI7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XG5pbXBvcnQge0NvbmZpZ3VyYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7Vmlld30gZnJvbSBcIi4uLy4uLy4uLy4uL2NvbW1vbnMvc2NoZW1hXCI7XG5pbXBvcnQge1xuICAgIE1FTlVfSURFTlRJRklFUlMsXG4gICAgTWVudU9yZGVyLFxuICAgIE5hdmlnYXRpb25JdGVtLFxuICAgIFJJR0hUX1NJREVfSU5JVF9QQUdFX1NJWkUsXG4gICAgUklHSFRfU0lERV9ORVdfUEFHRV9TSVpFLFxuICAgIFNFVFRJTkdTX1RSQU5TSVRJT05fSURcbn0gZnJvbSAnLi4vLi4vbW9kZWwvbmF2aWdhdGlvbi1jb25maWdzJztcbmltcG9ydCB7VXJpTm9kZVJlc291cmNlfSBmcm9tICcuLi8uLi9tb2RlbC91cmktcmVzb3VyY2UnO1xuaW1wb3J0IHtNZW51SXRlbUNsaWNrRXZlbnQsIE1lbnVJdGVtTG9hZGVkRXZlbnR9IGZyb20gJy4uLy4uL21vZGVsL25hdmlnYXRpb24tbWVudS1ldmVudHMnO1xuaW1wb3J0IHtHcm91cE5hdmlnYXRpb25Db25zdGFudHN9IGZyb20gXCIuLi8uLi9tb2RlbC9ncm91cC1uYXZpZ2F0aW9uLWNvbnN0YW50c1wiO1xuaW1wb3J0IHtQYXRoU2VydmljZX0gZnJvbSBcIi4uLy4uL3NlcnZpY2UvcGF0aC5zZXJ2aWNlXCI7XG5pbXBvcnQge1VzZXJTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vdXNlci9zZXJ2aWNlcy91c2VyLnNlcnZpY2VcIjtcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBtYW5hZ2luZyBuYXZpZ2F0aW9uIGluIGRvdWJsZS1kcmF3ZXJcbiAqICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBEb3VibGVEcmF3ZXJOYXZpZ2F0aW9uU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGRpc3BsYXllZCBpdGVtcyBvbiB0aGUgbGVmdCBzaWRlXG4gICAgICogKi9cbiAgICBwcm90ZWN0ZWQgX2xlZnRJdGVtcyQ6IEJlaGF2aW9yU3ViamVjdDxBcnJheTxOYXZpZ2F0aW9uSXRlbT4+O1xuICAgIC8qKlxuICAgICAqIExpc3Qgb2YgZGlzcGxheWVkIGl0ZW1zIG9uIHRoZSByaWdodCBzaWRlXG4gICAgICogKi9cbiAgICBwcm90ZWN0ZWQgX3JpZ2h0SXRlbXMkOiBCZWhhdmlvclN1YmplY3Q8QXJyYXk8TmF2aWdhdGlvbkl0ZW0+PjtcbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGhpZGRlbiBpdGVtc1xuICAgICAqICovXG4gICAgcHJvdGVjdGVkIF9tb3JlSXRlbXMkOiBCZWhhdmlvclN1YmplY3Q8QXJyYXk8TmF2aWdhdGlvbkl0ZW0+PjtcbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGN1c3RvbSBpdGVtcyBpbiBtb3JlIG1lbnVcbiAgICAgKiAqL1xuICAgIHByb3RlY3RlZCBfaGlkZGVuQ3VzdG9tSXRlbXMkOiBCZWhhdmlvclN1YmplY3Q8QXJyYXk8TmF2aWdhdGlvbkl0ZW0+PjtcbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGN1c3RvbSBpdGVtc1xuICAgICAqICovXG4gICAgcHJvdGVjdGVkIF9jaGlsZEN1c3RvbVZpZXdzOiB7IFt1cmk6IHN0cmluZ106IHsgW2tleTogc3RyaW5nXTogTmF2aWdhdGlvbkl0ZW0gfSB9O1xuICAgIHByb3RlY3RlZCBpdGVtc09yZGVyOiBNZW51T3JkZXI7XG4gICAgcHJvdGVjdGVkIF9sZWZ0TG9hZGluZyQ6IExvYWRpbmdFbWl0dGVyO1xuICAgIHByb3RlY3RlZCBfcmlnaHRMb2FkaW5nJDogTG9hZGluZ0VtaXR0ZXI7XG4gICAgcHJvdGVjdGVkIF9ub2RlTG9hZGluZyQ6IExvYWRpbmdFbWl0dGVyO1xuICAgIHByb3RlY3RlZCBfY3VycmVudFBhdGhTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgZGlzcGxheSB1cmlcbiAgICAgKiBTaWJsaW5ncyBvZiB0aGUgbm9kZSBhcmUgb24gdGhlIGxlZnQsIGNoaWxkcmVuIGFyZSBvbiB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2N1cnJlbnRQYXRoOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBfZnJvbVJlc29sdmVyOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnRseSBzZWxlY3RlZCBuYXZpZ2F0aW9uIGl0ZW1cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgX2N1cnJlbnROYXZpZ2F0aW9uSXRlbTogTmF2aWdhdGlvbkl0ZW0gfCB1bmRlZmluZWQ7XG4gICAgcHJvdGVjdGVkIGRlZmF1bHRWaWV3SWNvbjogc3RyaW5nID0gJ2ZpbHRlcl9hbHQnO1xuICAgIHByb3RlY3RlZCBjdXN0b21JdGVtc0luaXRpYWxpemVkOiBib29sZWFuO1xuICAgIHByb3RlY3RlZCBoaWRkZW5DdXN0b21JdGVtc0luaXRpYWxpemVkOiBib29sZWFuO1xuICAgIHByb3RlY3RlZCBpdGVtQ2xpY2tlZDogRXZlbnRFbWl0dGVyPE1lbnVJdGVtQ2xpY2tFdmVudD47XG4gICAgcHJvdGVjdGVkIGl0ZW1Mb2FkZWQ6IEV2ZW50RW1pdHRlcjxNZW51SXRlbUxvYWRlZEV2ZW50PjtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgX2xvZzogTG9nZ2VyU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIF9jb25maWc6IENvbmZpZ3VyYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgX2FjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgcHJvdGVjdGVkIF9jYXNlUmVzb3VyY2VTZXJ2aWNlOiBDYXNlUmVzb3VyY2VTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgX2FjY2Vzc1NlcnZpY2U6IEFjY2Vzc1NlcnZpY2UsXG4gICAgICAgIHByb3RlY3RlZCBfdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIF9keW5hbWljUm91dGluZ1NlcnZpY2U6IER5bmFtaWNOYXZpZ2F0aW9uUm91dGVQcm92aWRlclNlcnZpY2UsXG4gICAgICAgIHByb3RlY3RlZCBfcmVkaXJlY3RTZXJ2aWNlOiBSZWRpcmVjdFNlcnZpY2UsXG4gICAgICAgIHByb3RlY3RlZCBfcGF0aFNlcnZpY2U6IFBhdGhTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgX3VzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcbiAgICApIHtcbiAgICAgICAgdGhpcy5fbGVmdEl0ZW1zJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoW10pO1xuICAgICAgICB0aGlzLl9yaWdodEl0ZW1zJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoW10pO1xuICAgICAgICB0aGlzLl9tb3JlSXRlbXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdChbXSk7XG4gICAgICAgIHRoaXMuX2hpZGRlbkN1c3RvbUl0ZW1zJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoW10pO1xuICAgICAgICB0aGlzLl9jaGlsZEN1c3RvbVZpZXdzID0ge307XG4gICAgICAgIHRoaXMuX2xlZnRMb2FkaW5nJCA9IG5ldyBMb2FkaW5nRW1pdHRlcigpO1xuICAgICAgICB0aGlzLl9yaWdodExvYWRpbmckID0gbmV3IExvYWRpbmdFbWl0dGVyKCk7XG4gICAgICAgIHRoaXMuX25vZGVMb2FkaW5nJCA9IG5ldyBMb2FkaW5nRW1pdHRlcigpO1xuICAgICAgICB0aGlzLl9jdXJyZW50TmF2aWdhdGlvbkl0ZW0gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuaXRlbXNPcmRlciA9IE1lbnVPcmRlci5Bc2NlbmRpbmc7XG4gICAgICAgIHRoaXMuY3VzdG9tSXRlbXNJbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmhpZGRlbkN1c3RvbUl0ZW1zSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8TWVudUl0ZW1DbGlja0V2ZW50PigpO1xuICAgICAgICB0aGlzLml0ZW1Mb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lbnVJdGVtTG9hZGVkRXZlbnQ+KCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9jdXJyZW50UGF0aFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fbGVmdExvYWRpbmckLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TG9hZGluZyQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5fbm9kZUxvYWRpbmckLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuaXRlbUNsaWNrZWQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5pdGVtTG9hZGVkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjYW5Hb0JhY2tMb2FkaW5nJCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGVMb2FkaW5nJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGN1cnJlbnRQYXRoKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50UGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IGN1cnJlbnRQYXRoKHBhdGg6IHN0cmluZykge1xuICAgICAgICBpZiAocGF0aCA9PT0gdGhpcy5fY3VycmVudFBhdGggfHwgdGhpcy5sZWZ0TG9hZGluZyQuaXNBY3RpdmUgfHwgdGhpcy5yaWdodExvYWRpbmckLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY3VycmVudFBhdGggPSBwYXRoO1xuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5ub2RlTG9hZGluZyQuaXNBY3RpdmUpIHtcbiAgICAgICAgICAgIHRoaXMubm9kZUxvYWRpbmckLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlTWVudUl0ZW1zKHBhdGgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZU1lbnVJdGVtcyhwYXRoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgY3VycmVudE5hdmlnYXRpb25JdGVtKGl0ZW06IE5hdmlnYXRpb25JdGVtIHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnROYXZpZ2F0aW9uSXRlbSA9IGl0ZW07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlc29sdmVNZW51SXRlbXMocGF0aDogc3RyaW5nKSB7XG4gICAgICAgIGlmIChwYXRoID09PSBQYXRoU2VydmljZS5TRVBBUkFUT1IpIHtcbiAgICAgICAgICAgIHRoaXMuX2xlZnRJdGVtcyQubmV4dChbXSlcbiAgICAgICAgICAgIHRoaXMubG9hZFJpZ2h0U2lkZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmxlZnRJdGVtcy5maW5kKGl0ZW0gPT4gaXRlbS5yZXNvdXJjZT8uaW1tZWRpYXRlRGF0YS5maW5kKGYgPT4gZi5zdHJpbmdJZCA9PT0gR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLklURU1fRklFTERfSURfTk9ERV9QQVRIKT8udmFsdWUgPT09IHBhdGgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkTGVmdFNpZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubG9hZFJpZ2h0U2lkZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpdGVtQ2xpY2tlZCQoKTogRXZlbnRFbWl0dGVyPE1lbnVJdGVtQ2xpY2tFdmVudD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtQ2xpY2tlZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGl0ZW1Mb2FkZWQkKCk6IEV2ZW50RW1pdHRlcjxNZW51SXRlbUxvYWRlZEV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1Mb2FkZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByaWdodEl0ZW1zJCgpOiBCZWhhdmlvclN1YmplY3Q8QXJyYXk8TmF2aWdhdGlvbkl0ZW0+PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yaWdodEl0ZW1zJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxlZnRJdGVtcyQoKTogQmVoYXZpb3JTdWJqZWN0PEFycmF5PE5hdmlnYXRpb25JdGVtPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVmdEl0ZW1zJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG1vcmVJdGVtcyQoKTogQmVoYXZpb3JTdWJqZWN0PEFycmF5PE5hdmlnYXRpb25JdGVtPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9yZUl0ZW1zJDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhpZGRlbkN1c3RvbUl0ZW1zJCgpOiBCZWhhdmlvclN1YmplY3Q8QXJyYXk8TmF2aWdhdGlvbkl0ZW0+PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oaWRkZW5DdXN0b21JdGVtcyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByaWdodEl0ZW1zKCk6IEFycmF5PE5hdmlnYXRpb25JdGVtPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yaWdodEl0ZW1zJC5nZXRWYWx1ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbGVmdEl0ZW1zKCk6IEFycmF5PE5hdmlnYXRpb25JdGVtPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZWZ0SXRlbXMkLmdldFZhbHVlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBtb3JlSXRlbXMoKTogQXJyYXk8TmF2aWdhdGlvbkl0ZW0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vcmVJdGVtcyQuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhpZGRlbkN1c3RvbUl0ZW1zKCk6IEFycmF5PE5hdmlnYXRpb25JdGVtPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oaWRkZW5DdXN0b21JdGVtcyQuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxlZnRMb2FkaW5nJCgpOiBMb2FkaW5nRW1pdHRlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZWZ0TG9hZGluZyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByaWdodExvYWRpbmckKCk6IExvYWRpbmdFbWl0dGVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JpZ2h0TG9hZGluZyQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBub2RlTG9hZGluZyQoKTogTG9hZGluZ0VtaXR0ZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZUxvYWRpbmckO1xuICAgIH1cblxuICAgIHNldCBmcm9tUmVzb2x2ZXIodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZnJvbVJlc29sdmVyID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGxvYWROYXZpZ2F0aW9uSXRlbXMobm9kZTogVXJpTm9kZVJlc291cmNlKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRQYXRoID09PSBQYXRoU2VydmljZS5TRVBBUkFUT1IpIHtcbiAgICAgICAgICAgIHRoaXMuX2xlZnRJdGVtcyQubmV4dChbXSk7XG4gICAgICAgICAgICB0aGlzLmxvYWRSaWdodFNpZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fbGVmdEl0ZW1zJC5nZXRWYWx1ZSgpLmZpbmQoaXRlbSA9PiBEb3VibGVEcmF3ZXJVdGlscy5pc05vZGVDb3JyZXNwb25kaW5nVG9JdGVtKG5vZGUsIGl0ZW0pKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZExlZnRTaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxvYWRSaWdodFNpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGhvbWUgY2xpY2ssIHRoZSBjdXJyZW50IGxldmVsIGlzIHNldCB0byAwLCBhbmQgY3VycmVudCBwYXJlbnQgaXNcbiAgICAgKiBzZXQgdG8gcm9vdCBub2RlLlxuICAgICAqICovXG4gICAgcHVibGljIG9uSG9tZUNsaWNrKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5sZWZ0TG9hZGluZyQuaXNBY3RpdmUgfHwgdGhpcy5yaWdodExvYWRpbmckLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9wYXRoU2VydmljZS5hY3RpdmVQYXRoID0gUGF0aFNlcnZpY2UuU0VQQVJBVE9SO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGJhY2sgY2xpY2ssIHRoZSBwYXJlbnQgaXMgc2V0IHRvIHBhcmVudCBvZiBsZWZ0IG5vZGVzLCB0aGF0IHdpbGwgc29sdmVcbiAgICAgKiB0aGUgcmlnaHQgc2lkZSBtZW51IChlbGVtZW50cyB0aGF0IHdlcmUgaW4gbGVmdCBzaWRlLCBhZnRlciBiYWNrd2FyZFxuICAgICAqIG5hdmlnYXRpb24gd2lsbCBiZSBvbiB0aGUgcmlnaHQgc2lkZSkuXG4gICAgICogQ3VycmVudCBsZXZlbCBpcyBzZXQgdG8gYSBsb3dlciBudW1iZXIgaW4gb3JkZXIgdG8gc2V0IHRoZSBsZWZ0IHNpZGUgbWVudS5cbiAgICAgKiAqL1xuICAgIHB1YmxpYyBvbkJhY2tDbGljaygpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubGVmdExvYWRpbmckLmlzQWN0aXZlIHx8IHRoaXMucmlnaHRMb2FkaW5nJC5pc0FjdGl2ZSB8fCB0aGlzLmN1cnJlbnRQYXRoID09PSBQYXRoU2VydmljZS5TRVBBUkFUT1IpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3BhdGhTZXJ2aWNlLmFjdGl2ZVBhdGggPSB0aGlzLmV4dHJhY3RQYXJlbnRQYXRoKHRoaXMuY3VycmVudFBhdGgpO1xuICAgICAgICB0aGlzLml0ZW1DbGlja2VkLmVtaXQoe3BhdGg6IHRoaXMuX3BhdGhTZXJ2aWNlLmFjdGl2ZVBhdGgsIGlzSG9tZTogZmFsc2V9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPbiBpdGVtIGNsaWNrLCB0aGUgc2VsZWN0ZWQgaXRlbSdzIHZpZXcgaXMgcmVuZGVyZWQgKGJ5IHJvdXRlckxpbmspLiBJZiB0aGUgc2VsZWN0ZWQgaXRlbSBoYXMgY2hpbGRyZW4gaXRlbXMsIHRoZSBtZW51IGlzIHVwZGF0ZWRcbiAgICAgKiBhbmQgdmlldywgdGhhdCBpcyByZW5kZXJlZCBpcyBzZWxlY3RlZCBieSB0aGUgZGVmaW5lZCBydWxlLiBUaGUgcnVsZSBpczogT24gZmlyc3QgY2hlY2sgZm9yIGRlZmF1bHQgdmlldyBpbiBjaGlsZHJlbi5cbiAgICAgKiBPbiBzZWNvbmQgY2hlY2sgaWYgdGhlIGNsaWNrZWQgaXRlbSBoYXMgYSB2aWV3LiBPbiB0aGlyZCwgcGljayBhbnkgb3RoZXIgY2hpbGRyZW4ncyB2aWV3LCBlbHNlIHNob3cgbm90aGluZy5cbiAgICAgKiAqL1xuICAgIHB1YmxpYyBvbkl0ZW1DbGljayhpdGVtOiBOYXZpZ2F0aW9uSXRlbSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9jdXJyZW50TmF2aWdhdGlvbkl0ZW0gPSBpdGVtO1xuICAgICAgICBpZiAoaXRlbS5yZXNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBjdXN0b20gdmlldyByZXByZXNlbnRlZCBvbmx5IGluIG5hZS5qc29uXG4gICAgICAgICAgICBpZiAoaXRlbS5wcm9jZXNzVXJpID09PSB0aGlzLmN1cnJlbnRQYXRoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGF0aFNlcnZpY2UuYWN0aXZlUGF0aCA9IHRoaXMuY3VycmVudFBhdGg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhdGhTZXJ2aWNlLmFjdGl2ZVBhdGggPSB0aGlzLmV4dHJhY3RQYXJlbnRQYXRoKHRoaXMuY3VycmVudFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5lbWl0KHtwYXRoOiB0aGlzLl9wYXRoU2VydmljZS5hY3RpdmVQYXRoLCBpc0hvbWU6IGZhbHNlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gaXRlbS5yZXNvdXJjZS5pbW1lZGlhdGVEYXRhLmZpbmQoZiA9PiBmLnN0cmluZ0lkID09PSBHcm91cE5hdmlnYXRpb25Db25zdGFudHMuSVRFTV9GSUVMRF9JRF9OT0RFX1BBVEgpPy52YWx1ZVxuXG4gICAgICAgICAgICBpZiAoRG91YmxlRHJhd2VyVXRpbHMuaGFzSXRlbUNoaWxkcmVuKGl0ZW0pICYmICF0aGlzLmxlZnRMb2FkaW5nJC5pc0FjdGl2ZSAmJiAhdGhpcy5yaWdodExvYWRpbmckLmlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGF0aFNlcnZpY2UuYWN0aXZlUGF0aCA9IHBhdGg7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5lbWl0KHtwYXRoOiB0aGlzLl9wYXRoU2VydmljZS5hY3RpdmVQYXRoLCBpc0hvbWU6IGZhbHNlfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmlnaHRMb2FkaW5nJC5waXBlKFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoaXNSaWdodExvYWRpbmcgPT4gaXNSaWdodExvYWRpbmcgPT09IGZhbHNlKSxcbiAgICAgICAgICAgICAgICAgICAgdGFrZSgxKVxuICAgICAgICAgICAgICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuQXZhaWxhYmxlVmlldygpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFwYXRoLmluY2x1ZGVzKHRoaXMuY3VycmVudFBhdGgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGF0aFNlcnZpY2UuYWN0aXZlUGF0aCA9IHRoaXMuZXh0cmFjdFBhcmVudFBhdGgodGhpcy5jdXJyZW50UGF0aCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5lbWl0KHtwYXRoOiB0aGlzLl9wYXRoU2VydmljZS5hY3RpdmVQYXRoLCBpc0hvbWU6IGZhbHNlfSk7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGF0aFNlcnZpY2UuYWN0aXZlUGF0aCA9IHRoaXMuY3VycmVudFBhdGg7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtQ2xpY2tlZC5lbWl0KHtwYXRoOiB0aGlzLl9wYXRoU2VydmljZS5hY3RpdmVQYXRoLCBpc0hvbWU6IGZhbHNlfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIGEgdmlldyBvZiB0aGUgY3VycmVudCByaWdodCBpdGVtcyBpbiB0aGUgbWVudSBieSBkZWZpbmVkIHJ1bGUuIFRoZSBydWxlIGlzOiBGaXJzdCwgaXQgY2hlY2tzIHdoZXRoZXIgYSBuYXZpZ2F0aW9uXG4gICAgICogaXRlbSB3YXMgY2xpY2tlZC4gU2Vjb25kLCBjaGVjayBmb3IgZGVmYXVsdCB2aWV3IGluIGNoaWxkcmVuLlxuICAgICAqIFRoaXJkIGNoZWNrIGlmIHRoZSBjbGlja2VkIGl0ZW0gaGFzIGEgdmlldy4gRm91cnRoLCBwaWNrIGFueSBvdGhlciBjaGlsZHJlbidzIHZpZXcsIGVsc2VcbiAgICAgKiBzaG93IG5vdGhpbmcuXG4gICAgICogKi9cbiAgICBwdWJsaWMgb3BlbkF2YWlsYWJsZVZpZXcoKSB7XG4gICAgICAgIGxldCBhbGxJdGVtczogQXJyYXk8TmF2aWdhdGlvbkl0ZW0+ID0gdGhpcy5yaWdodEl0ZW1zLmNvbmNhdCh0aGlzLm1vcmVJdGVtcyk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnROYXZpZ2F0aW9uSXRlbSkge1xuICAgICAgICAgICAgbGV0IGFscmVhZHlDbGlja2VkSXRlbTogTmF2aWdhdGlvbkl0ZW0gPSBhbGxJdGVtcy5maW5kKGl0ZW0gPT4gaXRlbS5pZCA9PT0gdGhpcy5fY3VycmVudE5hdmlnYXRpb25JdGVtLmlkKTtcbiAgICAgICAgICAgIGlmICghIWFscmVhZHlDbGlja2VkSXRlbSkge1xuICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhlIGZvbGRlciBoYXMgbm90IGNoYW5nZWQgYW5kIGEgbWVudSBpdGVtIGlzIGNsaWNrZWQuXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2Zyb21SZXNvbHZlcikge1xuICAgICAgICAgICAgdGhpcy5fZnJvbVJlc29sdmVyID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgYXV0b09wZW5JdGVtczogQXJyYXk8TmF2aWdhdGlvbkl0ZW0+ID0gYWxsSXRlbXMuZmlsdGVyKGl0ZW0gPT4gRG91YmxlRHJhd2VyVXRpbHMuaGFzSXRlbUF1dG9PcGVuVmlldyhpdGVtKSk7XG4gICAgICAgIGlmIChhdXRvT3Blbkl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3JlZGlyZWN0U2VydmljZS5yZWRpcmVjdChhdXRvT3Blbkl0ZW1zWzBdLnJvdXRpbmcucGF0aCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoRG91YmxlRHJhd2VyVXRpbHMuaGFzSXRlbVZpZXcodGhpcy5fY3VycmVudE5hdmlnYXRpb25JdGVtKSkge1xuICAgICAgICAgICAgLy8gaXMgcm91dGVkIGJ5IHJvdXRlckxpbmsgb24gaXRlbSBjbGlja1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGl0ZW1zV2l0aFZpZXc6IEFycmF5PE5hdmlnYXRpb25JdGVtPiA9IGFsbEl0ZW1zLmZpbHRlcihpdGVtID0+IERvdWJsZURyYXdlclV0aWxzLmhhc0l0ZW1WaWV3KGl0ZW0pKTtcbiAgICAgICAgaWYgKGl0ZW1zV2l0aFZpZXcubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5fcmVkaXJlY3RTZXJ2aWNlLnJlZGlyZWN0KGF1dG9PcGVuSXRlbXNbMF0ucm91dGluZy5wYXRoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkTW9yZUl0ZW1zKCkge1xuICAgICAgICBpZiAodGhpcy5tb3JlSXRlbXMubGVuZ3RoID4gUklHSFRfU0lERV9ORVdfUEFHRV9TSVpFKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudFJpZ2h0SXRlbXMgPSB0aGlzLnJpZ2h0SXRlbXM7XG4gICAgICAgICAgICBsZXQgY3VycmVudE1vcmVJdGVtcyA9IHRoaXMubW9yZUl0ZW1zO1xuICAgICAgICAgICAgY3VycmVudFJpZ2h0SXRlbXMucHVzaCguLi5jdXJyZW50TW9yZUl0ZW1zLnNwbGljZSgwLCBSSUdIVF9TSURFX05FV19QQUdFX1NJWkUpKTtcbiAgICAgICAgICAgIHRoaXMucmlnaHRJdGVtcyQubmV4dChjdXJyZW50UmlnaHRJdGVtcyk7XG4gICAgICAgICAgICB0aGlzLm1vcmVJdGVtcyQubmV4dChjdXJyZW50TW9yZUl0ZW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBjdXJyZW50UmlnaHRJdGVtcyA9IHRoaXMucmlnaHRJdGVtcztcbiAgICAgICAgICAgIGN1cnJlbnRSaWdodEl0ZW1zLnB1c2goLi4udGhpcy5tb3JlSXRlbXMpO1xuICAgICAgICAgICAgdGhpcy5yaWdodEl0ZW1zJC5uZXh0KGN1cnJlbnRSaWdodEl0ZW1zKTtcbiAgICAgICAgICAgIHRoaXMubW9yZUl0ZW1zJC5uZXh0KFtdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBpbml0aWFsaXplQ3VzdG9tVmlld3NPZlZpZXcodmlldzogVmlldywgdmlld0NvbmZpZ1BhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAoIXZpZXcgfHwgdGhpcy5jdXN0b21JdGVtc0luaXRpYWxpemVkIHx8IHRoaXMuaGlkZGVuQ3VzdG9tSXRlbXNJbml0aWFsaXplZCkgcmV0dXJuO1xuXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHZpZXcuY2hpbGRyZW4pLmZvckVhY2goKFtrZXksIGNoaWxkVmlld10pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkVmlld0NvbmZpZ1BhdGg6IHN0cmluZyA9IHZpZXdDb25maWdQYXRoICsgJy8nICsga2V5O1xuICAgICAgICAgICAgdGhpcy5yZXNvbHZlVXJpRm9yQ2hpbGRWaWV3cyhjaGlsZFZpZXdDb25maWdQYXRoLCBjaGlsZFZpZXcpO1xuICAgICAgICAgICAgdGhpcy5yZXNvbHZlSGlkZGVuTWVudUl0ZW1Gcm9tQ2hpbGRWaWV3cyhjaGlsZFZpZXdDb25maWdQYXRoLCBjaGlsZFZpZXcpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnJlc29sdmVDdXN0b21WaWV3c0luUmlnaHRTaWRlKCk7XG4gICAgICAgIHRoaXMucmVzb2x2ZUN1c3RvbVZpZXdzSW5MZWZ0U2lkZSgpO1xuXG4gICAgICAgIHRoaXMuY3VzdG9tSXRlbXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIHRoaXMuaGlkZGVuQ3VzdG9tSXRlbXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIHN3aXRjaE9yZGVyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLml0ZW1zT3JkZXIgPSAodGhpcy5pdGVtc09yZGVyICsgMSkgJSAyO1xuICAgICAgICBsZXQgbXVsdGlwbGllciA9IDE7XG4gICAgICAgIGlmICh0aGlzLml0ZW1zT3JkZXIgPT09IE1lbnVPcmRlci5EZXNjZW5kaW5nKSB7XG4gICAgICAgICAgICBtdWx0aXBsaWVyID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1cnJlbnRSaWdodEl0ZW1zID0gdGhpcy5yaWdodEl0ZW1zO1xuICAgICAgICBsZXQgY3VycmVudExlZnRJdGVtcyA9IHRoaXMubGVmdEl0ZW1zO1xuICAgICAgICBjdXJyZW50UmlnaHRJdGVtcy5zb3J0KChhLCBiKSA9PiBtdWx0aXBsaWVyICogKGE/Lm5hdmlnYXRpb24gYXMgTmF2aWdhdGlvbkl0ZW0pPy50aXRsZS5sb2NhbGVDb21wYXJlKChiPy5uYXZpZ2F0aW9uIGFzIE5hdmlnYXRpb25JdGVtKT8udGl0bGUpKTtcbiAgICAgICAgY3VycmVudExlZnRJdGVtcy5zb3J0KChhLCBiKSA9PiBtdWx0aXBsaWVyICogKGE/Lm5hdmlnYXRpb24gYXMgTmF2aWdhdGlvbkl0ZW0pPy50aXRsZS5sb2NhbGVDb21wYXJlKChiPy5uYXZpZ2F0aW9uIGFzIE5hdmlnYXRpb25JdGVtKT8udGl0bGUpKTtcbiAgICAgICAgdGhpcy5yaWdodEl0ZW1zJC5uZXh0KGN1cnJlbnRSaWdodEl0ZW1zKTtcbiAgICAgICAgdGhpcy5sZWZ0SXRlbXMkLm5leHQoY3VycmVudExlZnRJdGVtcyk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzQXNjZW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtc09yZGVyID09PSBNZW51T3JkZXIuQXNjZW5kaW5nO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBsb2FkTGVmdFNpZGUoKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRQYXRoID09PSBQYXRoU2VydmljZS5TRVBBUkFUT1IpIHtcbiAgICAgICAgICAgIHRoaXMuX2xlZnRJdGVtcyQubmV4dChbXSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxlZnRMb2FkaW5nJC5vbigpO1xuXG4gICAgICAgIHRoaXMuZ2V0SXRlbUNhc2VCeVBhdGgodGhpcy5leHRyYWN0UGFyZW50UGF0aCh0aGlzLmN1cnJlbnRQYXRoKSkuc3Vic2NyaWJlKHBhZ2UgPT4ge1xuICAgICAgICAgICAgbGV0IGNoaWxkQ2FzZXMkO1xuICAgICAgICAgICAgbGV0IHRhcmdldEl0ZW07XG4gICAgICAgICAgICBsZXQgb3JkZXJlZENoaWxkQ2FzZUlkcztcblxuICAgICAgICAgICAgaWYgKHBhZ2U/LnBhZ2luYXRpb24/LnRvdGFsRWxlbWVudHMgPT09IDApIHtcbiAgICAgICAgICAgICAgICBjaGlsZENhc2VzJCA9IG9mKFtdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0SXRlbSA9IHBhZ2UuY29udGVudFswXTtcbiAgICAgICAgICAgICAgICBvcmRlcmVkQ2hpbGRDYXNlSWRzID0gRG91YmxlRHJhd2VyVXRpbHMuZXh0cmFjdENoaWxkQ2FzZUlkcyh0YXJnZXRJdGVtKTtcbiAgICAgICAgICAgICAgICBpZiAob3JkZXJlZENoaWxkQ2FzZUlkcyA9PSB1bmRlZmluZWQgfHwgb3JkZXJlZENoaWxkQ2FzZUlkcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRDYXNlcyQgPSBvZihbXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRDYXNlcyQgPSB0aGlzLmdldEl0ZW1DYXNlc0J5SWRzSW5PbmVQYWdlKG9yZGVyZWRDaGlsZENhc2VJZHMpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXAocCA9PiBwLmNvbnRlbnQpLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2hpbGRDYXNlcyQuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm1hcChmb2xkZXIgPT4gdGhpcy5yZXNvbHZlSXRlbUNhc2VUb05hdmlnYXRpb25JdGVtKGZvbGRlcikpLmZpbHRlcihpID0+ICEhaSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbGVmdEl0ZW1zJC5uZXh0KHJlc3VsdC5zb3J0KChhLCBiKSA9PiBvcmRlcmVkQ2hpbGRDYXNlSWRzLmluZGV4T2YoYS5yZXNvdXJjZS5zdHJpbmdJZCkgLSBvcmRlcmVkQ2hpbGRDYXNlSWRzLmluZGV4T2YoYi5yZXNvdXJjZS5zdHJpbmdJZCkpKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVDdXN0b21WaWV3c0luTGVmdFNpZGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9sZWZ0TG9hZGluZyQub2ZmKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtTG9hZGVkLmVtaXQoe21lbnU6ICdsZWZ0JywgaXRlbXM6IHRoaXMubGVmdEl0ZW1zfSk7XG4gICAgICAgICAgICB9LCBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9nLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9sZWZ0SXRlbXMkLm5leHQoW10pXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlQ3VzdG9tVmlld3NJbkxlZnRTaWRlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbGVmdExvYWRpbmckLm9mZigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2xvZy5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB0aGlzLl9sZWZ0SXRlbXMkLm5leHQoW10pXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVDdXN0b21WaWV3c0luTGVmdFNpZGUoKTtcbiAgICAgICAgICAgIHRoaXMuX2xlZnRMb2FkaW5nJC5vZmYoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGxvYWRSaWdodFNpZGUoKSB7XG4gICAgICAgIHRoaXMuX3JpZ2h0TG9hZGluZyQub24oKTtcbiAgICAgICAgdGhpcy5fbW9yZUl0ZW1zJC5uZXh0KFtdKVxuXG4gICAgICAgIHRoaXMuZ2V0SXRlbUNhc2VCeVBhdGgodGhpcy5jdXJyZW50UGF0aCkuc3Vic2NyaWJlKHBhZ2UgPT4ge1xuICAgICAgICAgICAgbGV0IGNoaWxkQ2FzZXMkO1xuICAgICAgICAgICAgbGV0IHRhcmdldEl0ZW07XG4gICAgICAgICAgICBsZXQgb3JkZXJlZENoaWxkQ2FzZUlkcztcblxuICAgICAgICAgICAgaWYgKHBhZ2U/LnBhZ2luYXRpb24/LnRvdGFsRWxlbWVudHMgPT09IDApIHtcbiAgICAgICAgICAgICAgICBjaGlsZENhc2VzJCA9IG9mKFtdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0SXRlbSA9IHBhZ2U/LmNvbnRlbnRbMF07XG4gICAgICAgICAgICAgICAgb3JkZXJlZENoaWxkQ2FzZUlkcyA9IERvdWJsZURyYXdlclV0aWxzLmV4dHJhY3RDaGlsZENhc2VJZHModGFyZ2V0SXRlbSk7XG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyZWRDaGlsZENhc2VJZHMgPT09IHVuZGVmaW5lZCB8fCBvcmRlcmVkQ2hpbGRDYXNlSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZENhc2VzJCA9IG9mKFtdKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZENhc2VzJCA9IHRoaXMuZ2V0SXRlbUNhc2VzQnlJZHNJbk9uZVBhZ2Uob3JkZXJlZENoaWxkQ2FzZUlkcykucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcChwID0+IHAuY29udGVudCksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjaGlsZENhc2VzJC5zdWJzY3JpYmUocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAocmVzdWx0IGFzIENhc2VbXSkuc29ydCgoYSwgYikgPT4gb3JkZXJlZENoaWxkQ2FzZUlkcy5pbmRleE9mKGEuc3RyaW5nSWQpIC0gb3JkZXJlZENoaWxkQ2FzZUlkcy5pbmRleE9mKGIuc3RyaW5nSWQpKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA+IFJJR0hUX1NJREVfSU5JVF9QQUdFX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmF3UmlnaHRJdGVtczogQ2FzZVtdID0gcmVzdWx0LnNwbGljZSgwLCBSSUdIVF9TSURFX0lOSVRfUEFHRV9TSVpFKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmlnaHRJdGVtcyQubmV4dChyYXdSaWdodEl0ZW1zLm1hcChmb2xkZXIgPT4gdGhpcy5yZXNvbHZlSXRlbUNhc2VUb05hdmlnYXRpb25JdGVtKGZvbGRlcikpLmZpbHRlcihpID0+ICEhaSkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tb3JlSXRlbXMkLm5leHQocmVzdWx0Lm1hcChmb2xkZXIgPT4gdGhpcy5yZXNvbHZlSXRlbUNhc2VUb05hdmlnYXRpb25JdGVtKGZvbGRlcikpLmZpbHRlcihpID0+ICEhaSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JpZ2h0SXRlbXMkLm5leHQocmVzdWx0Lm1hcChmb2xkZXIgPT4gdGhpcy5yZXNvbHZlSXRlbUNhc2VUb05hdmlnYXRpb25JdGVtKGZvbGRlcikpLmZpbHRlcihpID0+ICEhaSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVDdXN0b21WaWV3c0luUmlnaHRTaWRlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmlnaHRMb2FkaW5nJC5vZmYoKTtcbiAgICAgICAgICAgICAgICB0aGlzLml0ZW1Mb2FkZWQuZW1pdCh7bWVudTogJ3JpZ2h0JywgaXRlbXM6IHRoaXMucmlnaHRJdGVtc30pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuQXZhaWxhYmxlVmlldygpO1xuICAgICAgICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvZy5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmlnaHRJdGVtcyQubmV4dChbXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9yZUl0ZW1zJC5uZXh0KFtdKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVDdXN0b21WaWV3c0luUmlnaHRTaWRlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmlnaHRMb2FkaW5nJC5vZmYoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBlcnJvciA9PiB7XG4gICAgICAgICAgICB0aGlzLl9sb2cuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5fcmlnaHRJdGVtcyQubmV4dChbXSk7XG4gICAgICAgICAgICB0aGlzLl9tb3JlSXRlbXMkLm5leHQoW10pO1xuICAgICAgICAgICAgdGhpcy5yZXNvbHZlQ3VzdG9tVmlld3NJblJpZ2h0U2lkZSgpO1xuICAgICAgICAgICAgdGhpcy5fcmlnaHRMb2FkaW5nJC5vZmYoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldEl0ZW1DYXNlc0J5SWRzSW5PbmVQYWdlKGNhc2VJZHM6IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxQYWdlPENhc2U+PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEl0ZW1DYXNlc0J5SWRzKGNhc2VJZHMsIDAsIGNhc2VJZHMubGVuZ3RoKTtcbiAgICB9XG5cblxuICAgIHByb3RlY3RlZCBnZXRJdGVtQ2FzZXNCeUlkcyhjYXNlSWRzOiBzdHJpbmdbXSwgcGFnZU51bWJlcjogbnVtYmVyLCBwYWdlU2l6ZTogc3RyaW5nIHwgbnVtYmVyKTogT2JzZXJ2YWJsZTxQYWdlPENhc2U+PiB7XG4gICAgICAgIGNvbnN0IHNlYXJjaEJvZHk6IENhc2VTZWFyY2hSZXF1ZXN0Qm9keSA9IHtcbiAgICAgICAgICAgIGlkOiBjYXNlSWRzLFxuICAgICAgICAgICAgcHJvY2VzczogTUVOVV9JREVOVElGSUVSUy5tYXAoaWQgPT4gKHtpZGVudGlmaWVyOiBpZH0gYXMgUGV0cmlOZXRTZWFyY2hSZXF1ZXN0KSksXG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IGh0dHBQYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpXG4gICAgICAgICAgICAuc2V0KFBhZ2luYXRpb25QYXJhbXMuUEFHRV9TSVpFLCBwYWdlU2l6ZSlcbiAgICAgICAgICAgIC5zZXQoUGFnaW5hdGlvblBhcmFtcy5QQUdFX05VTUJFUiwgcGFnZU51bWJlcik7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXNlUmVzb3VyY2VTZXJ2aWNlLnNlYXJjaENhc2VzKFNpbXBsZUZpbHRlci5mcm9tQ2FzZVF1ZXJ5KHNlYXJjaEJvZHkpLCBodHRwUGFyYW1zKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVzb2x2ZUl0ZW1DYXNlVG9OYXZpZ2F0aW9uSXRlbShpdGVtQ2FzZTogQ2FzZSk6IE5hdmlnYXRpb25JdGVtIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKERvdWJsZURyYXdlclV0aWxzLnJlcHJlc2VudHNSb290Tm9kZShpdGVtQ2FzZSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpdGVtOiBOYXZpZ2F0aW9uSXRlbSA9IHtcbiAgICAgICAgICAgIGFjY2Vzczoge30sXG4gICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgaWNvbjogaXRlbUNhc2UuaW1tZWRpYXRlRGF0YS5maW5kKGYgPT4gZi5zdHJpbmdJZCA9PT0gR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLklURU1fRklFTERfSURfTUVOVV9JQ09OKT8udmFsdWUgfHwgdGhpcy5kZWZhdWx0Vmlld0ljb24sXG4gICAgICAgICAgICAgICAgdGl0bGU6IHRoaXMuZ2V0VHJhbnNsYXRpb24oaXRlbUNhc2UuaW1tZWRpYXRlRGF0YS5maW5kKGYgPT4gZi5zdHJpbmdJZCA9PT0gR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLklURU1fRklFTERfSURfTUVOVV9OQU1FKT8udmFsdWUpIHx8IGl0ZW1DYXNlLnRpdGxlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJvdXRpbmc6IHtcbiAgICAgICAgICAgICAgICBwYXRoOiB0aGlzLmdldEl0ZW1Sb3V0aW5nUGF0aChpdGVtQ2FzZSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaWQ6IGl0ZW1DYXNlLnN0cmluZ0lkLFxuICAgICAgICAgICAgcmVzb3VyY2U6IGl0ZW1DYXNlLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXNvbHZlZFJvbGVzID0gRG91YmxlRHJhd2VyVXRpbHMucmVzb2x2ZUFjY2Vzc1JvbGVzKGl0ZW1DYXNlLCBHcm91cE5hdmlnYXRpb25Db25zdGFudHMuSVRFTV9GSUVMRF9JRF9BTExPV0VEX1JPTEVTKTtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRCYW5uZWRSb2xlcyA9IERvdWJsZURyYXdlclV0aWxzLnJlc29sdmVBY2Nlc3NSb2xlcyhpdGVtQ2FzZSwgR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLklURU1fRklFTERfSURfQkFOTkVEX1JPTEVTKTtcbiAgICAgICAgaWYgKCEhcmVzb2x2ZWRSb2xlcykgaXRlbS5hY2Nlc3NbJ3JvbGUnXSA9IHJlc29sdmVkUm9sZXM7XG4gICAgICAgIGlmICghIXJlc29sdmVkQmFubmVkUm9sZXMpIGl0ZW0uYWNjZXNzWydiYW5uZWRSb2xlJ10gPSByZXNvbHZlZEJhbm5lZFJvbGVzO1xuICAgICAgICBpZiAoIXRoaXMuX2FjY2Vzc1NlcnZpY2UuY2FuQWNjZXNzVmlldyhpdGVtLCBpdGVtLnJvdXRpbmc/LnBhdGgpKSByZXR1cm47XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZXNvbHZlQ3VzdG9tVmlld3NJbkxlZnRTaWRlKCkge1xuICAgICAgICBpZiAoISF0aGlzLmV4dHJhY3RQYXJlbnRQYXRoKHRoaXMuY3VycmVudFBhdGgpICYmICEhdGhpcy5fY2hpbGRDdXN0b21WaWV3c1t0aGlzLmV4dHJhY3RQYXJlbnRQYXRoKHRoaXMuY3VycmVudFBhdGgpXSkge1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRMZWZ0SXRlbXMgPSB0aGlzLl9sZWZ0SXRlbXMkLmdldFZhbHVlKCk7XG4gICAgICAgICAgICBjdXJyZW50TGVmdEl0ZW1zLnB1c2goLi4uT2JqZWN0LnZhbHVlcyh0aGlzLl9jaGlsZEN1c3RvbVZpZXdzW3RoaXMuZXh0cmFjdFBhcmVudFBhdGgodGhpcy5jdXJyZW50UGF0aCldKSk7XG4gICAgICAgICAgICB0aGlzLl9sZWZ0SXRlbXMkLm5leHQoY3VycmVudExlZnRJdGVtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVzb2x2ZUN1c3RvbVZpZXdzSW5SaWdodFNpZGUoKSB7XG4gICAgICAgIGlmICghIXRoaXMuX2N1cnJlbnRQYXRoICYmICEhdGhpcy5fY2hpbGRDdXN0b21WaWV3c1t0aGlzLl9jdXJyZW50UGF0aF0pIHtcbiAgICAgICAgICAgIGxldCBjdXJyZW50UmlnaHRJdGVtcyA9IHRoaXMuX3JpZ2h0SXRlbXMkLmdldFZhbHVlKCk7XG4gICAgICAgICAgICBjdXJyZW50UmlnaHRJdGVtcy5wdXNoKC4uLk9iamVjdC52YWx1ZXModGhpcy5fY2hpbGRDdXN0b21WaWV3c1t0aGlzLl9jdXJyZW50UGF0aF0pKTtcbiAgICAgICAgICAgIHRoaXMuX3JpZ2h0SXRlbXMkLm5leHQoY3VycmVudFJpZ2h0SXRlbXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlc29sdmVVcmlGb3JDaGlsZFZpZXdzKGNvbmZpZ1BhdGg6IHN0cmluZywgY2hpbGRWaWV3OiBWaWV3KTogdm9pZCB7XG4gICAgICAgIGlmICghY2hpbGRWaWV3LnByb2Nlc3NVcmkpIHJldHVybjtcbiAgICAgICAgaWYgKCF0aGlzLl9hY2Nlc3NTZXJ2aWNlLmNhbkFjY2Vzc1ZpZXcoY2hpbGRWaWV3LCBjb25maWdQYXRoKSkgcmV0dXJuO1xuICAgICAgICBpZiAoIXRoaXMuX2NoaWxkQ3VzdG9tVmlld3NbY2hpbGRWaWV3LnByb2Nlc3NVcmldKSB7XG4gICAgICAgICAgICB0aGlzLl9jaGlsZEN1c3RvbVZpZXdzW2NoaWxkVmlldy5wcm9jZXNzVXJpXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NoaWxkQ3VzdG9tVmlld3NbY2hpbGRWaWV3LnByb2Nlc3NVcmldW2NvbmZpZ1BhdGhdID0ge1xuICAgICAgICAgICAgaWQ6IGNvbmZpZ1BhdGgsXG4gICAgICAgICAgICAuLi5jaGlsZFZpZXcsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlc29sdmVIaWRkZW5NZW51SXRlbUZyb21DaGlsZFZpZXdzKGNvbmZpZ1BhdGg6IHN0cmluZywgY2hpbGRWaWV3OiBWaWV3KTogdm9pZCB7XG4gICAgICAgIGlmICghY2hpbGRWaWV3Lm5hdmlnYXRpb24pIHJldHVybjtcbiAgICAgICAgaWYgKCF0aGlzLl9hY2Nlc3NTZXJ2aWNlLmNhbkFjY2Vzc1ZpZXcoY2hpbGRWaWV3LCBjb25maWdQYXRoKSkgcmV0dXJuO1xuICAgICAgICBpZiAoISEoKGNoaWxkVmlldz8ubmF2aWdhdGlvbiBhcyBhbnkpPy5oaWRkZW4pKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudEhpZGRlbkN1c3RvbUl0ZW1zID0gdGhpcy5faGlkZGVuQ3VzdG9tSXRlbXMkLmdldFZhbHVlKCk7XG4gICAgICAgICAgICBjdXJyZW50SGlkZGVuQ3VzdG9tSXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgaWQ6IGNvbmZpZ1BhdGgsXG4gICAgICAgICAgICAgICAgLi4uY2hpbGRWaWV3LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9oaWRkZW5DdXN0b21JdGVtcyQubmV4dChjdXJyZW50SGlkZGVuQ3VzdG9tSXRlbXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldFRyYW5zbGF0aW9uKHZhbHVlOiBJMThuRmllbGRWYWx1ZSk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuX3RyYW5zbGF0ZVNlcnZpY2UuY3VycmVudExhbmcuc3BsaXQoJy0nKVswXTtcbiAgICAgICAgcmV0dXJuIGxvY2FsZSBpbiB2YWx1ZS50cmFuc2xhdGlvbnMgPyB2YWx1ZS50cmFuc2xhdGlvbnNbbG9jYWxlXSA6IHZhbHVlLmRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0SXRlbVJvdXRpbmdQYXRoKGl0ZW1DYXNlOiBDYXNlKSB7XG4gICAgICAgIGNvbnN0IHRhc2tJZCA9IERvdWJsZURyYXdlclV0aWxzLmZpbmRUYXNrSWRJbkNhc2UoaXRlbUNhc2UsIFNFVFRJTkdTX1RSQU5TSVRJT05fSUQpO1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLl9keW5hbWljUm91dGluZ1NlcnZpY2Uucm91dGU7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IHVybC5zdGFydHNXaXRoKCcvJykgPyAnJyA6ICcvJztcbiAgICAgICAgcmV0dXJuIGAke3ByZWZpeH0ke3VybH0vJHt0YXNrSWR9YDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NMZWZ0SXRlbXMoY2FzZXM6IENhc2VbXSwgb3JkZXJlZENoaWxkQ2FzZUlkczogc3RyaW5nW10pOiBOYXZpZ2F0aW9uSXRlbVtdIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FzZXNcbiAgICAgICAgICAgIC5tYXAoZm9sZGVyID0+IHRoaXMucmVzb2x2ZUl0ZW1DYXNlVG9OYXZpZ2F0aW9uSXRlbShmb2xkZXIpKVxuICAgICAgICAgICAgLmZpbHRlcihpID0+ICEhaSk7XG4gICAgICAgIHJldHVybiByZXN1bHQuc29ydCgoYSwgYikgPT5cbiAgICAgICAgICAgIG9yZGVyZWRDaGlsZENhc2VJZHMuaW5kZXhPZihhLnJlc291cmNlLnN0cmluZ0lkKSAtIG9yZGVyZWRDaGlsZENhc2VJZHMuaW5kZXhPZihiLnJlc291cmNlLnN0cmluZ0lkKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIGNhc2UgaXRlbSBiYXNlZCBvbiB0aGUgZ2l2ZW4gcGF0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhdGhdIC0gVGhlIGlkZW50aWZpZXIgcGF0aCB0byBsb2NhdGUgdGhlIHNwZWNpZmljIGNhc2UgaXRlbS4gSWYgdW5kZWZpbmVkLCBpdCBkZWZhdWx0cyB0byBzZWFyY2hpbmcgd2l0aG91dCBhIHNwZWNpZmljIHBhdGguXG4gICAgICogQHJldHVybiB7T2JzZXJ2YWJsZTxQYWdlPENhc2U+Pn0gQW4gb2JzZXJ2YWJsZSBzdHJlYW0gY29udGFpbmluZyB0aGUgcGFnZSBvZiBjYXNlIGl0ZW1zIHdoaWNoIG1hdGNoIHRoZSBwcm92aWRlZCBwYXRoLlxuICAgICAqL1xuICAgIGdldEl0ZW1DYXNlQnlQYXRoKHBhdGg/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFBhZ2U8Q2FzZT4+IHtcbiAgICAgICAgY29uc3Qgc2VhcmNoQm9keTogQ2FzZVNlYXJjaFJlcXVlc3RCb2R5ID0ge1xuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIFtHcm91cE5hdmlnYXRpb25Db25zdGFudHMuSVRFTV9GSUVMRF9JRF9OT0RFX1BBVEhdOiBwYXRoXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvY2Vzczoge2lkZW50aWZpZXI6IFwibWVudV9pdGVtXCJ9XG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IGh0dHBQYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpXG4gICAgICAgICAgICAuc2V0KFBhZ2luYXRpb25QYXJhbXMuUEFHRV9TSVpFLCAxKVxuICAgICAgICAgICAgLnNldChQYWdpbmF0aW9uUGFyYW1zLlBBR0VfTlVNQkVSLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nhc2VSZXNvdXJjZVNlcnZpY2Uuc2VhcmNoQ2FzZXMoU2ltcGxlRmlsdGVyLmZyb21DYXNlUXVlcnkoc2VhcmNoQm9keSksIGh0dHBQYXJhbXMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBleHRyYWN0UGFyZW50UGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAocGF0aCA9PT0gJy8nKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGF0aD8ubGFzdEluZGV4T2YoJy8nKSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuICcvJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGF0aD8uc3Vic3RyaW5nKDAsIHBhdGg/Lmxhc3RJbmRleE9mKCcvJykpO1xuICAgIH1cblxuXG59XG4iXX0=