UNPKG

@alfresco/adf-content-services

Version:
219 lines 39.6 kB
/*! * @license * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NotificationService } from '@alfresco/adf-core'; import { EventEmitter, Injectable } from '@angular/core'; import { BehaviorSubject, forkJoin, of, Subject } from 'rxjs'; import { finalize, map, switchMap } from 'rxjs/operators'; import { NodePermissionService } from '../../services/node-permission.service'; import { NodePermissionDialogService } from '../../services/node-permission-dialog.service'; import { NodesApiService } from '../../../common/services/nodes-api.service'; import { ContentService } from '../../../common/services/content.service'; import { AllowableOperationsEnum } from '../../../common/models/allowable-operations.enum'; import * as i0 from "@angular/core"; import * as i1 from "../../../common/services/nodes-api.service"; import * as i2 from "../../services/node-permission.service"; import * as i3 from "../../services/node-permission-dialog.service"; import * as i4 from "../../../common/services/content.service"; import * as i5 from "@alfresco/adf-core"; const SITE_MANAGER_ROLE = 'SiteManager'; export class PermissionListService { constructor(nodeService, nodePermissionService, nodePermissionDialogService, contentService, notificationService) { this.nodeService = nodeService; this.nodePermissionService = nodePermissionService; this.nodePermissionDialogService = nodePermissionDialogService; this.contentService = contentService; this.notificationService = notificationService; this.updated = new EventEmitter(); this.errored = new EventEmitter(); this.loading$ = new BehaviorSubject(true); this.error$ = new Subject(); this.nodeWithRoles$ = new Subject(); this.data$ = this.nodeWithRoles$.pipe(map(({ node, roles }) => { const nodeLocalPermissions = this.nodePermissionService.getLocalPermissions(node); const localPermissions = this.updateReadOnlyPermission(node, nodeLocalPermissions); return { node, roles, localPermissions, inheritedPermissions: this.nodePermissionService.getInheritedPermission(node) }; })); } fetchPermission(nodeId) { this.loading$.next(true); this.nodePermissionService .getNodeWithRoles(nodeId) .pipe(finalize(() => this.loading$.next(false))) .subscribe(({ node, roles }) => { this.node = node; this.roles = roles; this.nodeWithRoles$.next({ node, roles }); }, () => this.error$.next(true)); } toggleInherited(change) { if (this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.UPDATEPERMISSIONS)) { let updateLocalPermission$ = of(null); const nodeBody = { permissions: { isInheritanceEnabled: !this.node.permissions.isInheritanceEnabled } }; const authorityId = this.getManagerAuthority(this.node); if (authorityId) { const permissions = [...(this.node.permissions.locallySet || []), { authorityId, name: SITE_MANAGER_ROLE, accessStatus: 'ALLOWED' }]; updateLocalPermission$ = this.nodePermissionService.updatePermissions(this.node, permissions); } updateLocalPermission$.pipe(switchMap(() => this.nodeService.updateNode(this.node.id, nodeBody, { include: ['permissions'] }))).subscribe((nodeUpdated) => { const message = nodeUpdated.permissions.isInheritanceEnabled ? 'PERMISSION_MANAGER.MESSAGE.INHERIT-ENABLE-SUCCESS' : 'PERMISSION_MANAGER.MESSAGE.INHERIT-DISABLE-SUCCESS'; this.notificationService.showInfo(message); nodeUpdated.permissions.inherited = nodeUpdated.permissions?.inherited ?? []; this.reloadNode(nodeUpdated); }, () => { change.source.checked = this.node.permissions.isInheritanceEnabled; this.notificationService.showWarning('PERMISSION_MANAGER.MESSAGE.TOGGLE-PERMISSION-FAILED'); }); } else { change.source.checked = this.node.permissions.isInheritanceEnabled; this.notificationService.showError('PERMISSION_MANAGER.ERROR.NOT-ALLOWED'); } } updateNodePermissionByDialog() { this.nodePermissionDialogService .openAddPermissionDialog(this.node, this.roles, 'PERMISSION_MANAGER.ADD-PERMISSION.TITLE') .pipe(switchMap((selection) => { const total = selection.length; const group = selection.filter(({ authorityId }) => this.isGroup(authorityId)).length; return forkJoin({ user: of(total - group), group: of(group), node: this.nodePermissionService.updateNodePermissions(this.node.id, selection) }); })) .subscribe(({ user, group, node }) => { this.notificationService.showInfo('PERMISSION_MANAGER.MESSAGE.PERMISSION-ADD-SUCCESS', null, { user, group }); this.reloadNode(node); }, () => { this.notificationService.showError('PERMISSION_MANAGER.MESSAGE.PERMISSION-ADD-FAIL'); this.reloadNode(); }); } deletePermissions(permissions) { this.nodePermissionService.removePermissions(this.node, permissions).subscribe((node) => { const total = permissions.length; const group = permissions.filter(({ authorityId }) => this.isGroup(authorityId)).length; this.notificationService.showInfo('PERMISSION_MANAGER.MESSAGE.PERMISSION-BULK-DELETE-SUCCESS', null, { user: total - group, group }); this.reloadNode(node); }, () => { this.notificationService.showError('PERMISSION_MANAGER.MESSAGE.PERMISSION-DELETE-FAIL'); this.reloadNode(); }); } updateRole(role, permission) { const updatedPermissionRole = this.buildUpdatedPermission(role, permission); this.nodePermissionService.updatePermissionRole(this.node, updatedPermissionRole).subscribe((node) => { this.notificationService.showInfo('PERMISSION_MANAGER.MESSAGE.PERMISSION-UPDATE-SUCCESS'); this.reloadNode(node); this.updated.emit(permission); }, () => { this.notificationService.showError('PERMISSION_MANAGER.MESSAGE.PERMISSION-UPDATE-FAIL'); this.reloadNode(); this.errored.emit(permission); }); } bulkRoleUpdate(role) { const permissions = [...this.node.permissions.locallySet].map((permission) => this.buildUpdatedPermission(role, permission)); this.nodePermissionService.updatePermissions(this.node, permissions).subscribe((node) => { const total = permissions.length; const group = permissions.filter(({ authorityId }) => this.isGroup(authorityId)).length; this.notificationService.showInfo('PERMISSION_MANAGER.MESSAGE.PERMISSION-BULK-UPDATE-SUCCESS', null, { user: total - group, group }); this.reloadNode(node); }, () => { this.notificationService.showError('PERMISSION_MANAGER.MESSAGE.PERMISSION-UPDATE-FAIL'); this.reloadNode(); }); } deletePermission(permission) { const cloneNode = { ...this.node, permissions: { ...this.node.permissions, locallySet: [...this.node.permissions.locallySet] } }; this.nodePermissionService.removePermission(cloneNode, permission).subscribe((node) => { this.notificationService.showInfo('PERMISSION_MANAGER.MESSAGE.PERMISSION-DELETE-SUCCESS'); if (!node.permissions.locallySet) { node.permissions.locallySet = []; } this.reloadNode(node); }, () => { this.notificationService.showError('PERMISSION_MANAGER.MESSAGE.PERMISSION-DELETE-FAIL'); this.reloadNode(); }); } buildUpdatedPermission(role, permission) { return { accessStatus: permission.accessStatus, name: this.canUpdateThePermission(this.node, permission) ? role : permission.name, authorityId: permission.authorityId }; } reloadNode(node) { if (node != null) { Object.assign(this.node.permissions, node.permissions); } this.nodeWithRoles$.next({ node: this.node, roles: this.roles }); } getManagerAuthority(node) { const sitePath = node.path.elements.find((path) => path.nodeType === 'st:site'); let hasLocalManagerPermission = false; let authorityId; if (sitePath) { authorityId = `GROUP_site_${sitePath.name}_${SITE_MANAGER_ROLE}`; hasLocalManagerPermission = !!node.permissions.locallySet?.find((permission) => permission.authorityId === authorityId && permission.name === SITE_MANAGER_ROLE); } if (!hasLocalManagerPermission && authorityId) { return authorityId; } return null; } updateReadOnlyPermission(node, permissions) { permissions.forEach((permission) => { if (!this.canUpdateThePermission(node, permission)) { permission.readonly = true; } }); return permissions; } canUpdateThePermission(node, permission) { const sitePath = node.path.elements.find((path) => path.nodeType === 'st:site'); if (!node.permissions.isInheritanceEnabled && sitePath) { const authorityId = `GROUP_site_${sitePath.name}_${SITE_MANAGER_ROLE}`; return !(permission.authorityId === authorityId && permission.name === SITE_MANAGER_ROLE); } return true; } isGroup(authorityId) { return authorityId.startsWith('GROUP_') || authorityId.startsWith('ROLE_'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionListService, deps: [{ token: i1.NodesApiService }, { token: i2.NodePermissionService }, { token: i3.NodePermissionDialogService }, { token: i4.ContentService }, { token: i5.NotificationService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionListService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionListService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.NodesApiService }, { type: i2.NodePermissionService }, { type: i3.NodePermissionDialogService }, { type: i4.ContentService }, { type: i5.NotificationService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1saXN0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3Blcm1pc3Npb24tbWFuYWdlci9jb21wb25lbnRzL3Blcm1pc3Npb24tbGlzdC9wZXJtaXNzaW9uLWxpc3Quc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSTFELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQy9FLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0RBQWtELENBQUM7Ozs7Ozs7QUFFM0YsTUFBTSxpQkFBaUIsR0FBRyxhQUFhLENBQUM7QUFLeEMsTUFBTSxPQUFPLHFCQUFxQjtJQXVCOUIsWUFDWSxXQUE0QixFQUM1QixxQkFBNEMsRUFDNUMsMkJBQXdELEVBQ3hELGNBQThCLEVBQzlCLG1CQUF3QztRQUp4QyxnQkFBVyxHQUFYLFdBQVcsQ0FBaUI7UUFDNUIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQUM1Qyxn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TyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEVBQUUsQ0FBQztnQkFDakQsVUFBVSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDL0IsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVELHNCQUFzQixDQUFDLElBQVUsRUFBRSxVQUE2QjtRQUM1RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDaEYsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLElBQUksUUFBUSxFQUFFLENBQUM7WUFDckQsTUFBTSxXQUFXLEdBQUcsY0FBYyxRQUFRLENBQUMsSUFBSSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDdkUsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLFdBQVcsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRU8sT0FBTyxDQUFDLFdBQVc7UUFDdkIsT0FBTyxXQUFXLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0UsQ0FBQzs4R0EvTlEscUJBQXFCO2tIQUFyQixxQkFBcUIsY0FGbEIsTUFBTTs7MkZBRVQscUJBQXFCO2tCQUhqQyxVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCDCqSAyMDA1LTIwMjUgSHlsYW5kIFNvZnR3YXJlLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgTm90aWZpY2F0aW9uU2VydmljZSB9IGZyb20gJ0BhbGZyZXNjby9hZGYtY29yZSc7XG5pbXBvcnQgeyBOb2RlLCBQZXJtaXNzaW9uRWxlbWVudCB9IGZyb20gJ0BhbGZyZXNjby9qcy1hcGknO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRTbGlkZVRvZ2dsZUNoYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NsaWRlLXRvZ2dsZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGZvcmtKb2luLCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmluYWxpemUsIG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgUm9sZU1vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JvbGUubW9kZWwnO1xuaW1wb3J0IHsgUGVybWlzc2lvbkRpc3BsYXlNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9wZXJtaXNzaW9uLm1vZGVsJztcbmltcG9ydCB7IE5vZGVQZXJtaXNzaW9uc01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL21lbWJlci5tb2RlbCc7XG5pbXBvcnQgeyBOb2RlUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub2RlLXBlcm1pc3Npb24uc2VydmljZSc7XG5pbXBvcnQgeyBOb2RlUGVybWlzc2lvbkRpYWxvZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ub2RlLXBlcm1pc3Npb24tZGlhbG9nLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm9kZXNBcGlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uL3NlcnZpY2VzL25vZGVzLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IENvbnRlbnRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uL3NlcnZpY2VzL2NvbnRlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBBbGxvd2FibGVPcGVyYXRpb25zRW51bSB9IGZyb20gJy4uLy4uLy4uL2NvbW1vbi9tb2RlbHMvYWxsb3dhYmxlLW9wZXJhdGlvbnMuZW51bSc7XG5cbmNvbnN0IFNJVEVfTUFOQUdFUl9ST0xFID0gJ1NpdGVNYW5hZ2VyJztcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBQZXJtaXNzaW9uTGlzdFNlcnZpY2Uge1xuICAgIHVwZGF0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFBlcm1pc3Npb25EaXNwbGF5TW9kZWw+KCk7XG4gICAgZXJyb3JlZCA9IG5ldyBFdmVudEVtaXR0ZXI8UGVybWlzc2lvbkRpc3BsYXlNb2RlbD4oKTtcblxuICAgIGxvYWRpbmckOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHRydWUpO1xuICAgIGVycm9yJDogU3ViamVjdDxib29sZWFuPiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgbm9kZVdpdGhSb2xlcyQ6IFN1YmplY3Q8eyBub2RlOiBOb2RlOyByb2xlczogUm9sZU1vZGVsW10gfT4gPSBuZXcgU3ViamVjdCgpO1xuICAgIGRhdGEkOiBPYnNlcnZhYmxlPE5vZGVQZXJtaXNzaW9uc01vZGVsPiA9IHRoaXMubm9kZVdpdGhSb2xlcyQucGlwZShcbiAgICAgICAgbWFwKCh7IG5vZGUsIHJvbGVzIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVMb2NhbFBlcm1pc3Npb25zID0gdGhpcy5ub2RlUGVybWlzc2lvblNlcnZpY2UuZ2V0TG9jYWxQZXJtaXNzaW9ucyhub2RlKTtcbiAgICAgICAgICAgIGNvbnN0IGxvY2FsUGVybWlzc2lvbnMgPSB0aGlzLnVwZGF0ZVJlYWRPbmx5UGVybWlzc2lvbihub2RlLCBub2RlTG9jYWxQZXJtaXNzaW9ucyk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgcm9sZXMsXG4gICAgICAgICAgICAgICAgbG9jYWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgICBpbmhlcml0ZWRQZXJtaXNzaW9uczogdGhpcy5ub2RlUGVybWlzc2lvblNlcnZpY2UuZ2V0SW5oZXJpdGVkUGVybWlzc2lvbihub2RlKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlcbiAgICApO1xuXG4gICAgcHJpdmF0ZSBub2RlOiBOb2RlO1xuICAgIHByaXZhdGUgcm9sZXM6IFJvbGVNb2RlbFtdO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVzQXBpU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBub2RlUGVybWlzc2lvblNlcnZpY2U6IE5vZGVQZXJtaXNzaW9uU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBub2RlUGVybWlzc2lvbkRpYWxvZ1NlcnZpY2U6IE5vZGVQZXJtaXNzaW9uRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb250ZW50U2VydmljZTogQ29udGVudFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm90aWZpY2F0aW9uU2VydmljZTogTm90aWZpY2F0aW9uU2VydmljZVxuICAgICkge31cblxuICAgIGZldGNoUGVybWlzc2lvbihub2RlSWQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmxvYWRpbmckLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMubm9kZVBlcm1pc3Npb25TZXJ2aWNlXG4gICAgICAgICAgICAuZ2V0Tm9kZVdpdGhSb2xlcyhub2RlSWQpXG4gICAgICAgICAgICAucGlwZShmaW5hbGl6ZSgoKSA9PiB0aGlzLmxvYWRpbmckLm5leHQoZmFsc2UpKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgKHsgbm9kZSwgcm9sZXMgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvbGVzID0gcm9sZXM7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9kZVdpdGhSb2xlcyQubmV4dCh7IG5vZGUsIHJvbGVzIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKCkgPT4gdGhpcy5lcnJvciQubmV4dCh0cnVlKVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICB0b2dnbGVJbmhlcml0ZWQoY2hhbmdlOiBNYXRTbGlkZVRvZ2dsZUNoYW5nZSkge1xuICAgICAgICBpZiAodGhpcy5jb250ZW50U2VydmljZS5oYXNBbGxvd2FibGVPcGVyYXRpb25zKHRoaXMubm9kZSwgQWxsb3dhYmxlT3BlcmF0aW9uc0VudW0uVVBEQVRFUEVSTUlTU0lPTlMpKSB7XG4gICAgICAgICAgICBsZXQgdXBkYXRlTG9jYWxQZXJtaXNzaW9uJDogT2JzZXJ2YWJsZTxOb2RlPiA9IG9mKG51bGwpO1xuICAgICAgICAgICAgY29uc3Qgbm9kZUJvZHkgPSB7XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgaXNJbmhlcml0YW5jZUVuYWJsZWQ6ICF0aGlzLm5vZGUucGVybWlzc2lvbnMuaXNJbmhlcml0YW5jZUVuYWJsZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBhdXRob3JpdHlJZCA9IHRoaXMuZ2V0TWFuYWdlckF1dGhvcml0eSh0aGlzLm5vZGUpO1xuICAgICAgICAgICAgaWYgKGF1dGhvcml0eUlkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVybWlzc2lvbnMgPSBbLi4uKHRoaXMubm9kZS5wZXJtaXNzaW9ucy5sb2NhbGx5U2V0IHx8IFtdKSwgeyBhdXRob3JpdHlJZCwgbmFtZTogU0lURV9NQU5BR0VSX1JPTEUsIGFjY2Vzc1N0YXR1czogJ0FMTE9XRUQnIH1dO1xuICAgICAgICAgICAgICAgIHVwZGF0ZUxvY2FsUGVybWlzc2lvbiQgPSB0aGlzLm5vZGVQZXJtaXNzaW9uU2VydmljZS51cGRhdGVQZXJtaXNzaW9ucyh0aGlzLm5vZGUsIHBlcm1pc3Npb25zKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdXBkYXRlTG9jYWxQZXJtaXNzaW9uJC5waXBlKHN3aXRjaE1hcCgoKSA9PiB0aGlzLm5vZGVTZXJ2aWNlLnVwZGF0ZU5vZGUodGhpcy5ub2RlLmlkLCBub2RlQm9keSwgeyBpbmNsdWRlOiBbJ3Blcm1pc3Npb25zJ10gfSkpKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgKG5vZGVVcGRhdGVkOiBOb2RlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBub2RlVXBkYXRlZC5wZXJtaXNzaW9ucy5pc0luaGVyaXRhbmNlRW5hYmxlZFxuICAgICAgICAgICAgICAgICAgICAgICAgPyAnUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuSU5IRVJJVC1FTkFCTEUtU1VDQ0VTUydcbiAgICAgICAgICAgICAgICAgICAgICAgIDogJ1BFUk1JU1NJT05fTUFOQUdFUi5NRVNTQUdFLklOSEVSSVQtRElTQUJMRS1TVUNDRVNTJztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLnNob3dJbmZvKG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBub2RlVXBkYXRlZC5wZXJtaXNzaW9ucy5pbmhlcml0ZWQgPSBub2RlVXBkYXRlZC5wZXJtaXNzaW9ucz8uaW5oZXJpdGVkID8/IFtdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZE5vZGUobm9kZVVwZGF0ZWQpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjaGFuZ2Uuc291cmNlLmNoZWNrZWQgPSB0aGlzLm5vZGUucGVybWlzc2lvbnMuaXNJbmhlcml0YW5jZUVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93V2FybmluZygnUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuVE9HR0xFLVBFUk1JU1NJT04tRkFJTEVEJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNoYW5nZS5zb3VyY2UuY2hlY2tlZCA9IHRoaXMubm9kZS5wZXJtaXNzaW9ucy5pc0luaGVyaXRhbmNlRW5hYmxlZDtcbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93RXJyb3IoJ1BFUk1JU1NJT05fTUFOQUdFUi5FUlJPUi5OT1QtQUxMT1dFRCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlTm9kZVBlcm1pc3Npb25CeURpYWxvZygpIHtcbiAgICAgICAgdGhpcy5ub2RlUGVybWlzc2lvbkRpYWxvZ1NlcnZpY2VcbiAgICAgICAgICAgIC5vcGVuQWRkUGVybWlzc2lvbkRpYWxvZyh0aGlzLm5vZGUsIHRoaXMucm9sZXMsICdQRVJNSVNTSU9OX01BTkFHRVIuQURELVBFUk1JU1NJT04uVElUTEUnKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKChzZWxlY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdG90YWwgPSBzZWxlY3Rpb24ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBncm91cCA9IHNlbGVjdGlvbi5maWx0ZXIoKHsgYXV0aG9yaXR5SWQgfSkgPT4gdGhpcy5pc0dyb3VwKGF1dGhvcml0eUlkKSkubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9ya0pvaW4oe1xuICAgICAgICAgICAgICAgICAgICAgICAgdXNlcjogb2YodG90YWwgLSBncm91cCksXG4gICAgICAgICAgICAgICAgICAgICAgICBncm91cDogb2YoZ3JvdXApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogdGhpcy5ub2RlUGVybWlzc2lvblNlcnZpY2UudXBkYXRlTm9kZVBlcm1pc3Npb25zKHRoaXMubm9kZS5pZCwgc2VsZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAoeyB1c2VyLCBncm91cCwgbm9kZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93SW5mbygnUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuUEVSTUlTU0lPTi1BREQtU1VDQ0VTUycsIG51bGwsIHsgdXNlciwgZ3JvdXAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkTm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLnNob3dFcnJvcignUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuUEVSTUlTU0lPTi1BREQtRkFJTCcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZE5vZGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIGRlbGV0ZVBlcm1pc3Npb25zKHBlcm1pc3Npb25zOiBQZXJtaXNzaW9uRWxlbWVudFtdKSB7XG4gICAgICAgIHRoaXMubm9kZVBlcm1pc3Npb25TZXJ2aWNlLnJlbW92ZVBlcm1pc3Npb25zKHRoaXMubm9kZSwgcGVybWlzc2lvbnMpLnN1YnNjcmliZShcbiAgICAgICAgICAgIChub2RlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG90YWwgPSBwZXJtaXNzaW9ucy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgY29uc3QgZ3JvdXAgPSBwZXJtaXNzaW9ucy5maWx0ZXIoKHsgYXV0aG9yaXR5SWQgfSkgPT4gdGhpcy5pc0dyb3VwKGF1dGhvcml0eUlkKSkubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93SW5mbygnUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuUEVSTUlTU0lPTi1CVUxLLURFTEVURS1TVUNDRVNTJywgbnVsbCwgeyB1c2VyOiB0b3RhbCAtIGdyb3VwLCBncm91cCB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZE5vZGUobm9kZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93RXJyb3IoJ1BFUk1JU1NJT05fTUFOQUdFUi5NRVNTQUdFLlBFUk1JU1NJT04tREVMRVRFLUZBSUwnKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZE5vZGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICB1cGRhdGVSb2xlKHJvbGU6IHN0cmluZywgcGVybWlzc2lvbjogUGVybWlzc2lvbkRpc3BsYXlNb2RlbCkge1xuICAgICAgICBjb25zdCB1cGRhdGVkUGVybWlzc2lvblJvbGUgPSB0aGlzLmJ1aWxkVXBkYXRlZFBlcm1pc3Npb24ocm9sZSwgcGVybWlzc2lvbik7XG4gICAgICAgIHRoaXMubm9kZVBlcm1pc3Npb25TZXJ2aWNlLnVwZGF0ZVBlcm1pc3Npb25Sb2xlKHRoaXMubm9kZSwgdXBkYXRlZFBlcm1pc3Npb25Sb2xlKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAobm9kZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uU2VydmljZS5zaG93SW5mbygnUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuUEVSTUlTU0lPTi1VUERBVEUtU1VDQ0VTUycpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkTm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZWQuZW1pdChwZXJtaXNzaW9uKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLnNob3dFcnJvcignUEVSTUlTU0lPTl9NQU5BR0VSLk1FU1NBR0UuUEVSTUlTU0lPTi1VUERBVEUtRkFJTCcpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkTm9kZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JlZC5lbWl0KHBlcm1pc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGJ1bGtSb2xlVXBkYXRlKHJvbGU6IHN0cmluZykge1xuICAgICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsuLi50aGlzLm5vZGUucGVybWlzc2lvbnMubG9jYWxseVNldF0ubWFwKChwZXJtaXNzaW9uKSA9PiB0aGlzLmJ1aWxkVXBkYXRlZFBlcm1pc3Npb24ocm9sZSwgcGVybWlzc2lvbikpO1xuICAgICAgICB0aGlzLm5vZGVQZXJtaXNzaW9uU2VydmljZS51cGRhdGVQZXJtaXNzaW9ucyh0aGlzLm5vZGUsIHBlcm1pc3Npb25zKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAobm9kZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvdGFsID0gcGVybWlzc2lvbnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IGdyb3VwID0gcGVybWlzc2lvbnMuZmlsdGVyKCh7IGF1dGhvcml0eUlkIH0pID0+IHRoaXMuaXNHcm91cChhdXRob3JpdHlJZCkpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2hvd0luZm8oJ1BFUk1JU1NJT05fTUFOQUdFUi5NRVNTQUdFLlBFUk1JU1NJT04tQlVMSy1VUERBVEUtU1VDQ0VTUycsIG51bGwsIHsgdXNlcjogdG90YWwgLSBncm91cCwgZ3JvdXAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWxvYWROb2RlKG5vZGUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2hvd0Vycm9yKCdQRVJNSVNTSU9OX01BTkFHRVIuTUVTU0FHRS5QRVJNSVNTSU9OLVVQREFURS1GQUlMJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWxvYWROb2RlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZGVsZXRlUGVybWlzc2lvbihwZXJtaXNzaW9uOiBQZXJtaXNzaW9uRGlzcGxheU1vZGVsKSB7XG4gICAgICAgIGNvbnN0IGNsb25lTm9kZSA9IHsgLi4udGhpcy5ub2RlLCBwZXJtaXNzaW9uczogeyAuLi50aGlzLm5vZGUucGVybWlzc2lvbnMsIGxvY2FsbHlTZXQ6IFsuLi50aGlzLm5vZGUucGVybWlzc2lvbnMubG9jYWxseVNldF0gfSB9O1xuICAgICAgICB0aGlzLm5vZGVQZXJtaXNzaW9uU2VydmljZS5yZW1vdmVQZXJtaXNzaW9uKGNsb25lTm9kZSwgcGVybWlzc2lvbikuc3Vic2NyaWJlKFxuICAgICAgICAgICAgKG5vZGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2hvd0luZm8oJ1BFUk1JU1NJT05fTUFOQUdFUi5NRVNTQUdFLlBFUk1JU1NJT04tREVMRVRFLVNVQ0NFU1MnKTtcbiAgICAgICAgICAgICAgICBpZiAoIW5vZGUucGVybWlzc2lvbnMubG9jYWxseVNldCkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBlcm1pc3Npb25zLmxvY2FsbHlTZXQgPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5yZWxvYWROb2RlKG5vZGUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2hvd0Vycm9yKCdQRVJNSVNTSU9OX01BTkFHRVIuTUVTU0FHRS5QRVJNSVNTSU9OLURFTEVURS1GQUlMJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWxvYWROb2RlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFVwZGF0ZWRQZXJtaXNzaW9uKHJvbGU6IHN0cmluZywgcGVybWlzc2lvbjogUGVybWlzc2lvbkVsZW1lbnQpOiBQZXJtaXNzaW9uRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhY2Nlc3NTdGF0dXM6IHBlcm1pc3Npb24uYWNjZXNzU3RhdHVzLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5jYW5VcGRhdGVUaGVQZXJtaXNzaW9uKHRoaXMubm9kZSwgcGVybWlzc2lvbikgPyByb2xlIDogcGVybWlzc2lvbi5uYW1lLFxuICAgICAgICAgICAgYXV0aG9yaXR5SWQ6IHBlcm1pc3Npb24uYXV0aG9yaXR5SWRcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbG9hZE5vZGUobm9kZT86IE5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLm5vZGUucGVybWlzc2lvbnMsIG5vZGUucGVybWlzc2lvbnMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZVdpdGhSb2xlcyQubmV4dCh7IG5vZGU6IHRoaXMubm9kZSwgcm9sZXM6IHRoaXMucm9sZXMgfSk7XG4gICAgfVxuXG4gICAgZ2V0TWFuYWdlckF1dGhvcml0eShub2RlOiBOb2RlKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qgc2l0ZVBhdGggPSBub2RlLnBhdGguZWxlbWVudHMuZmluZCgocGF0aCkgPT4gcGF0aC5ub2RlVHlwZSA9PT0gJ3N0OnNpdGUnKTtcbiAgICAgICAgbGV0IGhhc0xvY2FsTWFuYWdlclBlcm1pc3Npb24gPSBmYWxzZTtcbiAgICAgICAgbGV0IGF1dGhvcml0eUlkOiBzdHJpbmc7XG4gICAgICAgIGlmIChzaXRlUGF0aCkge1xuICAgICAgICAgICAgYXV0aG9yaXR5SWQgPSBgR1JPVVBfc2l0ZV8ke3NpdGVQYXRoLm5hbWV9XyR7U0lURV9NQU5BR0VSX1JPTEV9YDtcbiAgICAgICAgICAgIGhhc0xvY2FsTWFuYWdlclBlcm1pc3Npb24gPSAhIW5vZGUucGVybWlzc2lvbnMubG9jYWxseVNldD8uZmluZChcbiAgICAgICAgICAgICAgICAocGVybWlzc2lvbikgPT4gcGVybWlzc2lvbi5hdXRob3JpdHlJZCA9PT0gYXV0aG9yaXR5SWQgJiYgcGVybWlzc2lvbi5uYW1lID09PSBTSVRFX01BTkFHRVJfUk9MRVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaGFzTG9jYWxNYW5hZ2VyUGVybWlzc2lvbiAmJiBhdXRob3JpdHlJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGF1dGhvcml0eUlkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHVwZGF0ZVJlYWRPbmx5UGVybWlzc2lvbihub2RlOiBOb2RlLCBwZXJtaXNzaW9uczogUGVybWlzc2lvbkRpc3BsYXlNb2RlbFtdKTogUGVybWlzc2lvbkRpc3BsYXlNb2RlbFtdIHtcbiAgICAgICAgcGVybWlzc2lvbnMuZm9yRWFjaCgocGVybWlzc2lvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNhblVwZGF0ZVRoZVBlcm1pc3Npb24obm9kZSwgcGVybWlzc2lvbikpIHtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9uLnJlYWRvbmx5ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwZXJtaXNzaW9ucztcbiAgICB9XG5cbiAgICBjYW5VcGRhdGVUaGVQZXJtaXNzaW9uKG5vZGU6IE5vZGUsIHBlcm1pc3Npb246IFBlcm1pc3Npb25FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHNpdGVQYXRoID0gbm9kZS5wYXRoLmVsZW1lbnRzLmZpbmQoKHBhdGgpID0+IHBhdGgubm9kZVR5cGUgPT09ICdzdDpzaXRlJyk7XG4gICAgICAgIGlmICghbm9kZS5wZXJtaXNzaW9ucy5pc0luaGVyaXRhbmNlRW5hYmxlZCAmJiBzaXRlUGF0aCkge1xuICAgICAgICAgICAgY29uc3QgYXV0aG9yaXR5SWQgPSBgR1JPVVBfc2l0ZV8ke3NpdGVQYXRoLm5hbWV9XyR7U0lURV9NQU5BR0VSX1JPTEV9YDtcbiAgICAgICAgICAgIHJldHVybiAhKHBlcm1pc3Npb24uYXV0aG9yaXR5SWQgPT09IGF1dGhvcml0eUlkICYmIHBlcm1pc3Npb24ubmFtZSA9PT0gU0lURV9NQU5BR0VSX1JPTEUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNHcm91cChhdXRob3JpdHlJZCkge1xuICAgICAgICByZXR1cm4gYXV0aG9yaXR5SWQuc3RhcnRzV2l0aCgnR1JPVVBfJykgfHwgYXV0aG9yaXR5SWQuc3RhcnRzV2l0aCgnUk9MRV8nKTtcbiAgICB9XG59XG4iXX0=