You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
abp/npm/ng-packs/dist/permission-management/esm2015/lib/components/permission-management.compo...

425 lines
37 KiB

/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, EventEmitter, Input, Output, Renderer2 } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { map, pluck, take } from 'rxjs/operators';
import { GetPermissions, UpdatePermissions } from '../actions/permission-management.actions';
import { PermissionManagementState } from '../states/permission-management.state';
export class PermissionManagementComponent {
/**
* @param {?} store
* @param {?} renderer
*/
constructor(store, renderer) {
this.store = store;
this.renderer = renderer;
this.visibleChange = new EventEmitter();
this.permissions = [];
this.selectThisTab = false;
this.selectAllTab = false;
this.modalBusy = false;
this.trackByFn = (/**
* @param {?} _
* @param {?} item
* @return {?}
*/
(_, item) => item.name);
}
/**
* @return {?}
*/
get visible() {
return this._visible;
}
/**
* @param {?} value
* @return {?}
*/
set visible(value) {
if (!this.selectedGroup)
return;
this._visible = value;
this.visibleChange.emit(value);
if (!value) {
this.selectedGroup = null;
}
}
/**
* @return {?}
*/
get selectedGroupPermissions$() {
return this.groups$.pipe(map((/**
* @param {?} groups
* @return {?}
*/
groups => this.selectedGroup ? groups.find((/**
* @param {?} group
* @return {?}
*/
group => group.name === this.selectedGroup.name)).permissions : [])), map((/**
* @param {?} permissions
* @return {?}
*/
permissions => permissions.map((/**
* @param {?} permission
* @return {?}
*/
permission => ((/** @type {?} */ (((/** @type {?} */ (Object.assign({}, permission, { margin: findMargin(permissions, permission), isGranted: this.permissions.find((/**
* @param {?} per
* @return {?}
*/
per => per.name === permission.name)).isGranted }))))))))))));
}
/**
* @return {?}
*/
ngOnInit() { }
/**
* @param {?} name
* @return {?}
*/
getChecked(name) {
return (this.permissions.find((/**
* @param {?} per
* @return {?}
*/
per => per.name === name)) || { isGranted: false }).isGranted;
}
/**
* @param {?} grantedProviders
* @return {?}
*/
isGrantedByRole(grantedProviders) {
if (grantedProviders.length) {
return grantedProviders.findIndex((/**
* @param {?} p
* @return {?}
*/
p => p.providerName === 'Role')) > -1;
}
return false;
}
/**
* @param {?} clickedPermission
* @param {?} value
* @return {?}
*/
onClickCheckbox(clickedPermission, value) {
if (clickedPermission.isGranted && this.isGrantedByRole(clickedPermission.grantedProviders))
return;
setTimeout((/**
* @return {?}
*/
() => {
this.permissions = this.permissions.map((/**
* @param {?} per
* @return {?}
*/
per => {
if (clickedPermission.name === per.name) {
return Object.assign({}, per, { isGranted: !per.isGranted });
}
else if (clickedPermission.name === per.parentName && clickedPermission.isGranted) {
return Object.assign({}, per, { isGranted: false });
}
else if (clickedPermission.parentName === per.name && !clickedPermission.isGranted) {
return Object.assign({}, per, { isGranted: true });
}
return per;
}));
this.setTabCheckboxState();
this.setGrantCheckboxState();
}), 0);
}
/**
* @return {?}
*/
setTabCheckboxState() {
this.selectedGroupPermissions$.pipe(take(1)).subscribe((/**
* @param {?} permissions
* @return {?}
*/
permissions => {
/** @type {?} */
const selectedPermissions = permissions.filter((/**
* @param {?} per
* @return {?}
*/
per => per.isGranted));
/** @type {?} */
const element = (/** @type {?} */ (document.querySelector('#select-all-in-this-tabs')));
if (selectedPermissions.length === permissions.length) {
element.indeterminate = false;
this.selectThisTab = true;
}
else if (selectedPermissions.length === 0) {
element.indeterminate = false;
this.selectThisTab = false;
}
else {
element.indeterminate = true;
}
}));
}
/**
* @return {?}
*/
setGrantCheckboxState() {
/** @type {?} */
const selectedAllPermissions = this.permissions.filter((/**
* @param {?} per
* @return {?}
*/
per => per.isGranted));
/** @type {?} */
const checkboxElement = (/** @type {?} */ (document.querySelector('#select-all-in-all-tabs')));
if (selectedAllPermissions.length === this.permissions.length) {
checkboxElement.indeterminate = false;
this.selectAllTab = true;
}
else if (selectedAllPermissions.length === 0) {
checkboxElement.indeterminate = false;
this.selectAllTab = false;
}
else {
checkboxElement.indeterminate = true;
}
}
/**
* @return {?}
*/
onClickSelectThisTab() {
this.selectedGroupPermissions$.pipe(take(1)).subscribe((/**
* @param {?} permissions
* @return {?}
*/
permissions => {
permissions.forEach((/**
* @param {?} permission
* @return {?}
*/
permission => {
if (permission.isGranted && this.isGrantedByRole(permission.grantedProviders))
return;
/** @type {?} */
const index = this.permissions.findIndex((/**
* @param {?} per
* @return {?}
*/
per => per.name === permission.name));
this.permissions = [
...this.permissions.slice(0, index),
Object.assign({}, this.permissions[index], { isGranted: !this.selectThisTab }),
...this.permissions.slice(index + 1)
];
}));
}));
this.setGrantCheckboxState();
}
/**
* @return {?}
*/
onClickSelectAll() {
this.permissions = this.permissions.map((/**
* @param {?} permission
* @return {?}
*/
permission => (Object.assign({}, permission, { isGranted: !this.selectAllTab }))));
this.selectThisTab = !this.selectAllTab;
}
/**
* @param {?} group
* @return {?}
*/
onChangeGroup(group) {
this.selectedGroup = group;
this.setTabCheckboxState();
}
/**
* @return {?}
*/
submit() {
this.modalBusy = true;
/** @type {?} */
const unchangedPermissions = getPermissions(this.store.selectSnapshot(PermissionManagementState.getPermissionGroups));
/** @type {?} */
const changedPermissions = this.permissions
.filter((/**
* @param {?} per
* @return {?}
*/
per => unchangedPermissions.find((/**
* @param {?} unchanged
* @return {?}
*/
unchanged => unchanged.name === per.name)).isGranted === per.isGranted ? false : true))
.map((/**
* @param {?} __0
* @return {?}
*/
({ name, isGranted }) => ({ name, isGranted })));
if (changedPermissions.length) {
this.store
.dispatch(new UpdatePermissions({
providerKey: this.providerKey,
providerName: this.providerName,
permissions: changedPermissions
}))
.subscribe((/**
* @return {?}
*/
() => {
this.modalBusy = false;
this.visible = false;
}));
}
else {
this.modalBusy = false;
this.visible = false;
}
}
/**
* @return {?}
*/
openModal() {
if (!this.providerKey || !this.providerName) {
throw new Error('Provider Key and Provider Name are required.');
}
this.store
.dispatch(new GetPermissions({
providerKey: this.providerKey,
providerName: this.providerName
}))
.pipe(pluck('PermissionManagementState', 'permissionRes'))
.subscribe((/**
* @param {?} permissionRes
* @return {?}
*/
(permissionRes) => {
this.selectedGroup = permissionRes.groups[0];
this.permissions = getPermissions(permissionRes.groups);
this.visible = true;
}));
}
/**
* @return {?}
*/
initModal() {
this.setTabCheckboxState();
this.setGrantCheckboxState();
}
/**
* @param {?} __0
* @return {?}
*/
ngOnChanges({ visible }) {
if (!visible)
return;
if (visible.currentValue) {
this.openModal();
}
else if (visible.currentValue === false && this.visible) {
this.visible = false;
}
}
}
PermissionManagementComponent.decorators = [
{ type: Component, args: [{
selector: 'abp-permission-management',
template: "<abp-modal [(visible)]=\"visible\" (init)=\"initModal()\" [busy]=\"modalBusy\">\n <ng-container *ngIf=\"{ entityName: entityName$ | async } as data\">\n <ng-template #abpHeader>\n <h4>{{ 'AbpPermissionManagement::Permissions' | abpLocalization }} - {{ data.entityName }}</h4>\n </ng-template>\n <ng-template #abpBody>\n <div class=\"custom-checkbox custom-control mb-2\">\n <input\n type=\"checkbox\"\n id=\"select-all-in-all-tabs\"\n name=\"select-all-in-all-tabs\"\n class=\"custom-control-input\"\n [(ngModel)]=\"selectAllTab\"\n (click)=\"onClickSelectAll()\"\n />\n <label class=\"custom-control-label\" for=\"select-all-in-all-tabs\">{{\n 'AbpPermissionManagement::SelectAllInAllTabs' | abpLocalization\n }}</label>\n </div>\n\n <hr class=\"mt-2 mb-2\" />\n <div class=\"row\">\n <div class=\"col-4\">\n <ul class=\"nav nav-pills flex-column\">\n <li *ngFor=\"let group of groups$ | async; trackBy: trackByFn\" class=\"nav-item\">\n <a\n class=\"nav-link pointer\"\n [class.active]=\"selectedGroup?.name === group?.name\"\n (click)=\"onChangeGroup(group)\"\n >{{ group?.displayName }}</a\n >\n </li>\n </ul>\n </div>\n <div class=\"col-8\">\n <h4>{{ selectedGroup?.displayName }}</h4>\n <hr class=\"mt-2 mb-3\" />\n <div class=\"pl-1 pt-1\">\n <div class=\"custom-checkbox custom-control mb-2\">\n <input\n type=\"checkbox\"\n id=\"select-all-in-this-tabs\"\n name=\"select-all-in-this-tabs\"\n class=\"custom-control-input\"\n [(ngModel)]=\"selectThisTab\"\n (click)=\"onClickSelectThisTab()\"\n />\n <label class=\"custom-control-label\" for=\"select-all-in-this-tabs\">{{\n 'AbpPermissionManagement::SelectAllInThisTab' | abpLocalization\n }}</label>\n </div>\n <hr class=\"mb-3\" />\n <div\n *ngFor=\"let permission of selectedGroupPermissions$ | async; let i = index; trackBy: trackByFn\"\n [style.margin-left]=\"permission.margin + 'px'\"\n class=\"custom-checkbox custom-control mb-2\"\n >\n <input\n #permissionCheckbox\n type=\"checkbox\"\n [checked]=\"getChecked(permission.name)\"\n [value]=\"getChecked(permission.name)\"\n [attr.id]=\"permission.name\"\n class=\"custom-control-input\"\n [disabled]=\"isGrantedByRole(permission.grantedProviders)\"\n />\n <label\n class=\"custom-control-label\"\n [attr.for]=\"permission.name\"\n (click)=\"onClickCheckbox(permission, permissionCheckbox.value)\"\n >{{ permission.displayName }}\n <span *ngFor=\"let provider of permission.grantedProviders\" class=\"badge badge-light\"\n >{{ provider.providerName }}: {{ provider.providerKey }}</span\n ></label\n >\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n <ng-template #abpFooter>\n <button type=\"button\" class=\"btn btn-secondary\" #abpClose>\n {{ 'AbpIdentity::Cancel' | abpLocalization }}\n </button>\n <abp-button iconClass=\"fa fa-check\" (click)=\"submit()\">{{ 'AbpIdentity::Save' | abpLocalization }}</abp-button>\n </ng-template>\n </ng-container>\n</abp-modal>\n"
}] }
];
/** @nocollapse */
PermissionManagementComponent.ctorParameters = () => [
{ type: Store },
{ type: Renderer2 }
];
PermissionManagementComponent.propDecorators = {
providerName: [{ type: Input }],
providerKey: [{ type: Input }],
visible: [{ type: Input }],
visibleChange: [{ type: Output }]
};
tslib_1.__decorate([
Select(PermissionManagementState.getPermissionGroups),
tslib_1.__metadata("design:type", Observable)
], PermissionManagementComponent.prototype, "groups$", void 0);
tslib_1.__decorate([
Select(PermissionManagementState.getEntitiyDisplayName),
tslib_1.__metadata("design:type", Observable)
], PermissionManagementComponent.prototype, "entityName$", void 0);
if (false) {
/** @type {?} */
PermissionManagementComponent.prototype.providerName;
/** @type {?} */
PermissionManagementComponent.prototype.providerKey;
/**
* @type {?}
* @protected
*/
PermissionManagementComponent.prototype._visible;
/** @type {?} */
PermissionManagementComponent.prototype.visibleChange;
/** @type {?} */
PermissionManagementComponent.prototype.groups$;
/** @type {?} */
PermissionManagementComponent.prototype.entityName$;
/** @type {?} */
PermissionManagementComponent.prototype.selectedGroup;
/** @type {?} */
PermissionManagementComponent.prototype.permissions;
/** @type {?} */
PermissionManagementComponent.prototype.selectThisTab;
/** @type {?} */
PermissionManagementComponent.prototype.selectAllTab;
/** @type {?} */
PermissionManagementComponent.prototype.modalBusy;
/** @type {?} */
PermissionManagementComponent.prototype.trackByFn;
/**
* @type {?}
* @private
*/
PermissionManagementComponent.prototype.store;
/**
* @type {?}
* @private
*/
PermissionManagementComponent.prototype.renderer;
}
/**
* @param {?} permissions
* @param {?} permission
* @return {?}
*/
function findMargin(permissions, permission) {
/** @type {?} */
const parentPermission = permissions.find((/**
* @param {?} per
* @return {?}
*/
per => per.name === permission.parentName));
if (parentPermission && parentPermission.parentName) {
/** @type {?} */
let margin = 20;
return (margin += findMargin(permissions, parentPermission));
}
return parentPermission ? 20 : 0;
}
/**
* @param {?} groups
* @return {?}
*/
function getPermissions(groups) {
return groups.reduce((/**
* @param {?} acc
* @param {?} val
* @return {?}
*/
(acc, val) => [...acc, ...val.permissions]), []);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1tYW5hZ2VtZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhYnAvbmcucGVybWlzc2lvbi1tYW5hZ2VtZW50LyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvcGVybWlzc2lvbi1tYW5hZ2VtZW50LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBQ04sU0FBUyxFQUdWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBUSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRTdGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBVWxGLE1BQU0sT0FBTyw2QkFBNkI7Ozs7O0lBK0R4QyxZQUFvQixLQUFZLEVBQVUsUUFBbUI7UUFBekMsVUFBSyxHQUFMLEtBQUssQ0FBTztRQUFVLGFBQVEsR0FBUixRQUFRLENBQVc7UUF0QzFDLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQVUvRCxnQkFBVyxHQUFzQyxFQUFFLENBQUM7UUFFcEQsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFFdEIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUVsQixjQUFTOzs7OztRQUFnRCxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUM7SUFvQmhCLENBQUM7Ozs7SUF0RGpFLElBQ0ksT0FBTztRQUNU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QXdLL0QsU0FBUyxVQUFVLENBQUMsV0FBOEMsRUFBRSxVQUEyQzs7VUFDdkcsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLElBQUk7Ozs7SUFBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFDLFVBQVUsRUFBQztJQUVwRixJQUFJLGdCQUFnQixJQUFJLGdCQUFnQixDQUFDLFVBQVUsRUFBRTs7WUFDL0MsTUFBTSxHQUFHLEVBQUU7UUFDZixPQUFPLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0tBQzlEO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQzs7Ozs7QUFFRCxTQUFTLGNBQWMsQ0FBQyxNQUFvQztJQUMxRCxPQUFPLE1BQU0sQ0FBQyxNQUFNOzs7OztJQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRSxFQUFFLENBQUMsQ0FBQztBQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRyYWNrQnlGdW5jdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNlbGVjdCwgU3RvcmUgfSBmcm9tICdAbmd4cy9zdG9yZSc7XG5pbXBvcnQgeyBmcm9tLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIHBsdWNrLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgR2V0UGVybWlzc2lvbnMsIFVwZGF0ZVBlcm1pc3Npb25zIH0gZnJvbSAnLi4vYWN0aW9ucy9wZXJtaXNzaW9uLW1hbmFnZW1lbnQuYWN0aW9ucyc7XG5pbXBvcnQgeyBQZXJtaXNzaW9uTWFuYWdlbWVudCB9IGZyb20gJy4uL21vZGVscy9wZXJtaXNzaW9uLW1hbmFnZW1lbnQnO1xuaW1wb3J0IHsgUGVybWlzc2lvbk1hbmFnZW1lbnRTdGF0ZSB9IGZyb20gJy4uL3N0YXRlcy9wZXJtaXNzaW9uLW1hbmFnZW1lbnQuc3RhdGUnO1xuXG50eXBlIFBlcm1pc3Npb25XaXRoTWFyZ2luID0gUGVybWlzc2lvbk1hbmFnZW1lbnQuUGVybWlzc2lvbiAmIHtcbiAgbWFyZ2luOiBudW1iZXI7XG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhYnAtcGVybWlzc2lvbi1tYW5hZ2VtZW50JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Blcm1pc3Npb24tbWFuYWdlbWVudC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgUGVybWlzc2lvbk1hbmFnZW1lbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpXG4gIHByb3ZpZGVyTmFtZTogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIHByb3ZpZGVyS2V5OiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIF92aXNpYmxlO1xuXG4gIEBJbnB1dCgpXG4gIGdldCB2aXNpYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl92aXNpYmxlO1xuICB9XG5cbiAgc2V0IHZpc2libGUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRHcm91cCkgcmV0dXJuO1xuXG4gICAgdGhpcy5fdmlzaWJsZSA9IHZhbHVlO1xuICAgIHRoaXMudmlzaWJsZUNoYW5nZS5lbWl0KHZhbHVlKTtcblxuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRHcm91cCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgQE91dHB1dCgpIHJlYWRvbmx5IHZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgQFNlbGVjdChQZXJtaXNzaW9uTWFuYWdlbWVudFN0YXRlLmdldFBlcm1pc3Npb25Hcm91cHMpXG4gIGdyb3VwcyQ6IE9ic2VydmFibGU8UGVybWlzc2lvbk1hbmFnZW1lbnQuR3JvdXBbXT47XG5cbiAgQFNlbGVjdChQZXJtaXNzaW9uTWFuYWdlbWVudFN0YXRlLmdldEVudGl0aXlEaXNwbGF5TmFtZSlcbiAgZW50aXR5TmFtZSQ6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICBzZWxlY3RlZEdyb3VwOiBQZXJtaXNzaW9uTWFuYWdlbWVudC5Hcm91cDtcblxuICBwZXJtaXNzaW9uczogUGVybWlzc2lvbk1hbmFnZW1lbnQuUGVybWlzc2lvbltdID0gW107XG5cbiAgc2VsZWN0VGhpc1RhYiA9IGZhbHNlO1xuXG4gIHNlbGVjdEFsbFRhYiA9IGZhbHNlO1xuXG4gIG1vZGFsQnVzeSA9IGZhbHNlO1xuXG4gIHRyYWNrQnlGbjogVHJhY2tCeUZ1bmN0aW9uPFBlcm1pc3Npb25NYW5hZ2VtZW50Lkdyb3VwPiA9IChfLCBpdGVtKSA9PiBpdGVtLm5hbWU7XG5cbiAgZ2V0IHNlbGVjdGVkR3JvdXBQZXJtaXNzaW9ucyQoKTogT2JzZXJ2YWJsZTxQZXJtaXNzaW9uV2l0aE1hcmdpbltdPiB7XG4gICAgcmV0dXJuIHRoaXMuZ3JvdXBzJC5waXBlKFxuICAgICAgbWFwKGdyb3VwcyA9PlxuICAgICAgICB0aGlzLnNlbGVjdGVkR3JvdXAgPyBncm91cHMuZmluZChncm91cCA9PiBncm91cC5uYW1lID09PSB0aGlzLnNlbGVjdGVkR3JvdXAubmFtZSkucGVybWlzc2lvbnMgOiBbXVxuICAgICAgKSxcbiAgICAgIG1hcDxQZXJtaXNzaW9uTWFuYWdlbWVudC5QZXJtaXNzaW9uW10sIFBlcm1pc3Npb25XaXRoTWFyZ2luW10+KHBlcm1pc3Npb25zID0+XG4gICAgICAgIHBlcm1pc3Npb25zLm1hcChcbiAgICAgICAgICBwZXJtaXNzaW9uID0+XG4gICAgICAgICAgICAoKHtcbiAgICAgICAgICAgICAgLi4ucGVybWlzc2lvbixcbiAgICAgICAgICAgICAgbWFyZ2luOiBmaW5kTWFyZ2luKHBlcm1pc3Npb25zLCBwZXJtaXNzaW9uKSxcbiAgICAgICAgICAgICAgaXNHcmFudGVkOiB0aGlzLnBlcm1pc3Npb25zLmZpbmQocGVyID0+IHBlci5uYW1lID09PSBwZXJtaXNzaW9uLm5hbWUpLmlzR3JhbnRlZFxuICAgICAgICAgICAgfSBhcyBhbnkpIGFzIFBlcm1pc3Npb25XaXRoTWFyZ2luKVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3RvcmU6IFN0b3JlLCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7fVxuXG4gIGdldENoZWNrZWQobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuICh0aGlzLnBlcm1pc3Npb25zLmZpbmQocGVyID0+IHBlci5uYW1lID09PSBuYW1lKSB8fCB7IGlzR3JhbnRlZDogZmFsc2UgfSkuaXNHcmFudGVkO1xuICB9XG5cbiAgaXNHcmFudGVkQnlSb2xlKGdyYW50ZWRQcm92aWRlcnM6IFBlcm1pc3Npb25NYW5hZ2VtZW50LkdyYW50ZWRQcm92aWRlcltdKTogYm9vbGVhbiB7XG4gICAgaWYgKGdyYW50ZWRQcm92aWRlcnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZ3JhbnRlZFByb3ZpZGVycy5maW5kSW5kZXgocCA9PiBwLnByb3ZpZGVyTmFtZSA9PT0gJ1JvbGUnKSA+IC0xO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBvbkNsaWNrQ2hlY2tib3goY2xpY2tlZFBlcm1pc3Npb246IFBlcm1pc3Npb25NYW5hZ2VtZW50LlBlcm1pc3Npb24sIHZhbHVlKSB7XG4gICAgaWYgKGNsaWNrZWRQZXJtaXNzaW9uLmlzR3JhbnRlZCAmJiB0aGlzLmlzR3JhbnRlZEJ5Um9sZShjbGlja2VkUGVybWlzc2lvbi5ncmFudGVkUHJvdmlkZXJzKSkgcmV0dXJuO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnBlcm1pc3Npb25zID0gdGhpcy5wZXJtaXNzaW9ucy5tYXAocGVyID0+IHtcbiAgICAgICAgaWYgKGNsaWNrZWRQZXJtaXNzaW9uLm5hbWUgPT09IHBlci5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHsgLi4ucGVyLCBpc0dyYW50ZWQ6ICFwZXIuaXNHcmFudGVkIH07XG4gICAgICAgIH0gZWxzZSBpZiAoY2xpY2tlZFBlcm1pc3Npb24ubmFtZSA9PT0gcGVyLnBhcmVudE5hbWUgJiYgY2xpY2tlZFBlcm1pc3Npb24uaXNHcmFudGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHsgLi4ucGVyLCBpc0dyYW50ZWQ6IGZhbHNlIH07XG4gICAgICAgIH0gZWxzZSBpZiAoY2xpY2tlZFBlcm1pc3Npb24ucGFyZW50TmFtZSA9PT0gcGVyLm5hbWUgJiYgIWNsaWNrZWRQZXJtaXNzaW9uLmlzR3JhbnRlZCkge1xuICAgICAgICAgIHJldHVybiB7IC4uLnBlciwgaXNHcmFudGVkOiB0cnVlIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGVyO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc2V0VGFiQ2hlY2tib3hTdGF0ZSgpO1xuICAgICAgdGhpcy5zZXRHcmFudENoZWNrYm94U3RhdGUoKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHNldFRhYkNoZWNrYm94U3RhdGUoKSB7XG4gICAgdGhpcy5zZWxlY3RlZEdyb3VwUGVybWlzc2lvbnMkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKHBlcm1pc3Npb25zID0+IHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkUGVybWlzc2lvbnMgPSBwZXJtaXNzaW9ucy5maWx0ZXIocGVyID0+IHBlci5pc0dyYW50ZWQpO1xuICAgICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWxlY3QtYWxsLWluLXRoaXMtdGFicycpIGFzIGFueTtcblxuICAgICAgaWYgKHNlbGVjdGVkUGVybWlzc2lvbnMubGVuZ3RoID09PSBwZXJtaXNzaW9ucy5sZW5ndGgpIHtcbiAgICAgICAgZWxlbWVudC5pbmRldGVybWluYXRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VsZWN0VGhpc1RhYiA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkUGVybWlzc2lvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGVsZW1lbnQuaW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNlbGVjdFRoaXNUYWIgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuaW5kZXRlcm1pbmF0ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzZXRHcmFudENoZWNrYm94U3RhdGUoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRBbGxQZXJtaXNzaW9ucyA9IHRoaXMucGVybWlzc2lvbnMuZmlsdGVyKHBlciA9PiBwZXIuaXNHcmFudGVkKTtcbiAgICBjb25zdCBjaGVja2JveEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VsZWN0LWFsbC1pbi1hbGwtdGFicycpIGFzIGFueTtcblxuICAgIGlmIChzZWxlY3RlZEFsbFBlcm1pc3Npb25zLmxlbmd0aCA9PT0gdGhpcy5wZXJtaXNzaW9ucy5sZW5ndGgpIHtcbiAgICAgIGNoZWNrYm94RWxlbWVudC5pbmRldGVybWluYXRlID0gZmFsc2U7XG4gICAgICB0aGlzLnNlbGVjdEFsbFRhYiA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZEFsbFBlcm1pc3Npb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY2hlY2tib3hFbGVtZW50LmluZGV0ZXJtaW5hdGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2VsZWN0QWxsVGFiID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoZWNrYm94RWxlbWVudC5pbmRldGVybWluYXRlID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBvbkNsaWNrU2VsZWN0VGhpc1RhYigpIHtcbiAgICB0aGlzLnNlbGVjdGVkR3JvdXBQZXJtaXNzaW9ucyQucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUocGVybWlzc2lvbnMgPT4ge1xuICAgICAgcGVybWlzc2lvbnMuZm9yRWFjaChwZXJtaXNzaW9uID0+IHtcbiAgICAgICAgaWYgKHBlcm1pc3Npb24uaXNHcmFudGVkICYmIHRoaXMuaXNHcmFudGVkQnlSb2xlKHBlcm1pc3Npb24uZ3JhbnRlZFByb3ZpZGVycykpIHJldHVybjtcblxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMucGVybWlzc2lvbnMuZmluZEluZGV4KHBlciA9PiBwZXIubmFtZSA9PT0gcGVybWlzc2lvbi5uYW1lKTtcblxuICAgICAgICB0aGlzLnBlcm1pc3Npb25zID0gW1xuICAgICAgICAgIC4uLnRoaXMucGVybWlzc2lvbnMuc2xpY2UoMCwgaW5kZXgpLFxuICAgICAgICAgIHsgLi4udGhpcy5wZXJtaXNzaW9uc1tpbmRleF0sIGlzR3JhbnRlZDogIXRoaXMuc2VsZWN0VGhpc1RhYiB9LFxuICAgICAgICAgIC4uLnRoaXMucGVybWlzc2lvbnMuc2xpY2UoaW5kZXggKyAxKVxuICAgICAgICBdO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldEdyYW50Q2hlY2tib3hTdGF0ZSgpO1xuICB9XG5cbiAgb25DbGlja1NlbGVjdEFsbCgpIHtcbiAgICB0aGlzLnBlcm1pc3Npb25zID0gdGhpcy5wZXJtaXNzaW9ucy5tYXAocGVybWlzc2lvbiA9PiAoe1xuICAgICAgLi4ucGVybWlzc2lvbixcbiAgICAgIGlzR3JhbnRlZDogIXRoaXMuc2VsZWN0QWxsVGFiXG4gICAgfSkpO1xuXG4gICAgdGhpcy5zZWxlY3RUaGlzVGFiID0gIXRoaXMuc2VsZWN0QWxsVGFiO1xuICB9XG5cbiAgb25DaGFuZ2VHcm91cChncm91cDogUGVybWlzc2lvbk1hbmFnZW1lbnQuR3JvdXApIHtcbiAgICB0aGlzLnNlbGVjdGVkR3JvdXAgPSBncm91cDtcbiAgICB0aGlzLnNldFRhYkNoZWNrYm94U3RhdGUoKTtcbiAgfVxuXG4gIHN1Ym1pdCgpIHtcbiAgICB0aGlzLm1vZGFsQnVzeSA9IHRydWU7XG4gICAgY29uc3QgdW5jaGFuZ2VkUGVybWlzc2lvbnMgPSBnZXRQZXJtaXNzaW9ucyhcbiAgICAgIHRoaXMuc3RvcmUuc2VsZWN0U25hcHNob3QoUGVybWlzc2lvbk1hbmFnZW1lbnRTdGF0ZS5nZXRQZXJtaXNzaW9uR3JvdXBzKVxuICAgICk7XG5cbiAgICBjb25zdCBjaGFuZ2VkUGVybWlzc2lvbnM6IFBlcm1pc3Npb25NYW5hZ2VtZW50Lk1pbmltdW1QZXJtaXNzaW9uW10gPSB0aGlzLnBlcm1pc3Npb25zXG4gICAgICAuZmlsdGVyKHBlciA9PlxuICAgICAgICB1bmNoYW5nZWRQZXJtaXNzaW9ucy5maW5kKHVuY2hhbmdlZCA9PiB1bmNoYW5nZWQubmFtZSA9PT0gcGVyLm5hbWUpLmlzR3JhbnRlZCA9PT0gcGVyLmlzR3JhbnRlZCA/IGZhbHNlIDogdHJ1ZVxuICAgICAgKVxuICAgICAgLm1hcCgoeyBuYW1lLCBpc0dyYW50ZWQgfSkgPT4gKHsgbmFtZSwgaXNHcmFudGVkIH0pKTtcblxuICAgIGlmIChjaGFuZ2VkUGVybWlzc2lvbnMubGVuZ3RoKSB7XG4gICAgICB0aGlzLnN0b3JlXG4gICAgICAgIC5kaXNwYXRjaChcbiAgICAgICAgICBuZXcgVXBkYXRlUGVybWlzc2lvbnMoe1xuICAgICAgICAgICAgcHJvdmlkZXJLZXk6IHRoaXMucHJvdmlkZXJLZXksXG4gICAgICAgICAgICBwcm92aWRlck5hbWU6IHRoaXMucHJvdmlkZXJOYW1lLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IGNoYW5nZWRQZXJtaXNzaW9uc1xuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5tb2RhbEJ1c3kgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kYWxCdXN5ID0gZmFsc2U7XG4gICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBvcGVuTW9kYWwoKSB7XG4gICAgaWYgKCF0aGlzLnByb3ZpZGVyS2V5IHx8ICF0aGlzLnByb3ZpZGVyTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm92aWRlciBLZXkgYW5kIFByb3ZpZGVyIE5hbWUgYXJlIHJlcXVpcmVkLicpO1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmVcbiAgICAgIC5kaXNwYXRjaChcbiAgICAgICAgbmV3IEdldFBlcm1pc3Npb25zKHtcbiAgICAgICAgICBwcm92aWRlcktleTogdGhpcy5wcm92aWRlcktleSxcbiAgICAgICAgICBwcm92aWRlck5hbWU6IHRoaXMucHJvdmlkZXJOYW1lXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAucGlwZShwbHVjaygnUGVybWlzc2lvbk1hbmFnZW1lbnRTdGF0ZScsICdwZXJtaXNzaW9uUmVzJykpXG4gICAgICAuc3Vic2NyaWJlKChwZXJtaXNzaW9uUmVzOiBQZXJtaXNzaW9uTWFuYWdlbWVudC5SZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkR3JvdXAgPSBwZXJtaXNzaW9uUmVzLmdyb3Vwc1swXTtcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9ucyA9IGdldFBlcm1pc3Npb25zKHBlcm1pc3Npb25SZXMuZ3JvdXBzKTtcblxuICAgICAgICB0aGlzLnZpc2libGUgPSB0cnVlO1xuICAgICAgfSk7XG4gIH1cblxuICBpbml0TW9kYWwoKSB7XG4gICAgdGhpcy5zZXRUYWJDaGVja2JveFN0YXRlKCk7XG4gICAgdGhpcy5zZXRHcmFudENoZWNrYm94U3RhdGUoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKHsgdmlzaWJsZSB9OiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKCF2aXNpYmxlKSByZXR1cm47XG5cbiAgICBpZiAodmlzaWJsZS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMub3Blbk1vZGFsKCk7XG4gICAgfSBlbHNlIGlmICh2aXNpYmxlLmN1cnJlbnRWYWx1ZSA9PT0gZmFsc2UgJiYgdGhpcy52aXNpYmxlKSB7XG4gICAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZE1hcmdpbihwZXJtaXNzaW9uczogUGVybWlzc2lvbk1hbmFnZW1lbnQuUGVybWlzc2lvbltdLCBwZXJtaXNzaW9uOiBQZXJtaXNzaW9uTWFuYWdlbWVudC5QZXJtaXNzaW9uKSB7XG4gIGNvbnN0IHBhcmVudFBlcm1pc3Npb24gPSBwZXJtaXNzaW9ucy5maW5kKHBlciA9PiBwZXIubmFtZSA9PT0gcGVybWlzc2lvbi5wYXJlbnROYW1lKTtcblxuICBpZiAocGFyZW50UGVybWlzc2lvbiAmJiBwYXJlbnRQZXJtaXNzaW9uLnBhcmVudE5hbWUpIHtcbiAgICBsZXQgbWFyZ2luID0gMjA7XG4gICAgcmV0dXJuIChtYXJnaW4gKz0gZmluZE1hcmdpbihwZXJtaXNzaW9ucywgcGFyZW50UGVybWlzc2lvbikpO1xuICB9XG5cbiAgcmV0dXJuIHBhcmVudFBlcm1pc3Npb24gPyAyMCA6IDA7XG59XG5cbmZ1bmN0aW9uIGdldFBlcm1pc3Npb25zKGdyb3VwczogUGVybWlzc2lvbk1hbmFnZW1lbnQuR3JvdXBbXSk6IFBlcm1pc3Npb25NYW5hZ2VtZW50LlBlcm1pc3Npb25bXSB7XG4gIHJldHVybiBncm91cHMucmVkdWNlKChhY2MsIHZhbCkgPT4gWy4uLmFjYywgLi4udmFsLnBlcm1pc3Npb25zXSwgW10pO1xufVxuIl19