@tangential/admin-console
Version:
A basic administration console
124 lines • 27.6 kB
JavaScript
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { AdminService, AuthPermission } from '@tangential/authorization-service';
import { NameGenerator } from '@tangential/core';
import { MatSort } from '@angular/material/sort';
import { SelectionModel } from '@angular/cdk/collections';
import { MatTableDataSource } from '@angular/material/table';
import { AdminConsoleParentPage } from '../_parent/admin-console-parent.page';
import * as i0 from "@angular/core";
import * as i1 from "@tangential/authorization-service";
import * as i2 from "../_parent/admin-console-parent.page";
import * as i3 from "@angular/cdk/a11y";
import * as i4 from "@angular/material/checkbox";
import * as i5 from "@tangential/components";
import * as i6 from "@angular/material/table";
import * as i7 from "@angular/material/sort";
import * as i8 from "@angular/common";
export class PermissionManagerPage {
constructor(adminService, parent, _liveAnnouncer, changeDetectorRef) {
this.adminService = adminService;
this.parent = parent;
this._liveAnnouncer = _liveAnnouncer;
this.changeDetectorRef = changeDetectorRef;
this.displayedColumns = ['select', '$key', 'description', 'createdMils', 'editedMils'];
this.dataSource = new MatTableDataSource();
this.selection = new SelectionModel(true, []);
this.rows = [];
this.selected = [];
}
ngOnInit() {
this.parent.auth$.subscribe({
next: (v) => {
this.rows = v.settings.permissions;
this.dataSource = new MatTableDataSource(v.settings.permissions);
this.dataSource.sort = this.sort;
this.changeDetectorRef.markForCheck();
}
});
}
get nextItemIndex() {
let idx = 1;
if (this.rows && this.rows.length) {
idx = (this.rows[this.rows.length - 1].orderIndex + 1);
}
return idx;
}
onAddItemAction() {
const permission = AuthPermission.from({
$key: NameGenerator.generate(),
orderIndex: this.nextItemIndex
});
this.adminService.addPermission(permission).catch((reason) => {
console.error('PermissionManagerPage', 'error adding permission', reason);
throw new Error(reason);
});
}
onRemove(key) {
this.adminService.removePermission(key).catch((reason) => {
console.error('PermissionManagerPage', 'error removing permission', reason);
throw new Error(reason);
});
}
onRemoveSelectedAction(keys) {
keys.forEach((key) => {
this.adminService.removePermission(key).catch((reason) => {
console.error('PermissionManagerPage', 'error removing permission', reason);
throw new Error(reason);
});
});
}
onItemChange(permission) {
this.adminService.updatePermission(permission).catch((reason) => {
console.error('PermissionManagerPage', 'error updating permission', reason);
throw new Error(reason);
});
}
/**
* Borrowed directly from Angular Material examples: https://material.angular.io/components/table/overview
*/
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
toggleAllRows() {
if (this.isAllSelected()) {
this.selection.clear();
return;
}
this.selection.select(...this.dataSource.data);
}
/** The label for the checkbox on the passed row */
checkboxLabel(row) {
if (!row) {
return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} ${row.description}`;
}
/** Announce the change in sort state for assistive technology. */
announceSortChange(sortState) {
// This example uses English messages. If your application supports
// multiple language, you would internationalize these strings.
// Furthermore, you can customize the message to add additional
// details about the values being sorted.
if (sortState.direction) {
this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
}
else {
this._liveAnnouncer.announce('Sorting cleared');
}
}
}
PermissionManagerPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PermissionManagerPage, deps: [{ token: i1.AdminService }, { token: i2.AdminConsoleParentPage }, { token: i3.LiveAnnouncer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
PermissionManagerPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: PermissionManagerPage, selector: "tanj-permission-manager", viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n", dependencies: [{ kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5.PageBodyComponent, selector: "tanj-page-body", inputs: ["suppressHeaderShim", "flex", "layout", "layoutAlign"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: i8.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: PermissionManagerPage, decorators: [{
type: Component,
args: [{ selector: 'tanj-permission-manager', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<tanj-page-body>\n <table mat-table matSort (matSortChange)=\"announceSortChange($event)\" [dataSource]=\"dataSource\" class=\"mat-elevation-z8 tng-user-mgr-table\">\n\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" >\n <mat-checkbox (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- UID Column -->\n <ng-container matColumnDef=\"$key\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Permission ID\"> Permission ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.$key}} </td>\n </ng-container>\n\n <!-- User name Column -->\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Description\"> Description </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.description}} </td>\n </ng-container>\n\n <!-- User Email Column -->\n <ng-container matColumnDef=\"createdMils\" >\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Created Date\"> Created </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.createdMils | date:'yyyy-MM~dd, HH:mm:ss'}} </td>\n </ng-container>\n\n <!-- Last Sign in Column -->\n <ng-container matColumnDef=\"editedMils\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription=\"Sort by Last Modified\"> Last Modified </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.editedMils | date:'yyyy-MM~dd, HH:mm:ss' }} </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"selection.toggle(row)\"></tr>\n </table>\n\n</tanj-page-body>\n" }]
}], ctorParameters: function () { return [{ type: i1.AdminService }, { type: i2.AdminConsoleParentPage }, { type: i3.LiveAnnouncer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sort: [{
type: ViewChild,
args: [MatSort]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1tYW5hZ2VyLnBhZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nZW50aWFsL2FkbWluLWNvbnNvbGUvc3JjL2xpYi9wYWdlcy9wZXJtaXNzaW9uLW1hbmFnZXIvcGVybWlzc2lvbi1tYW5hZ2VyLnBhZ2UudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nZW50aWFsL2FkbWluLWNvbnNvbGUvc3JjL2xpYi9wYWdlcy9wZXJtaXNzaW9uLW1hbmFnZXIvcGVybWlzc2lvbi1tYW5hZ2VyLnBhZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFDL0MsT0FBTyxFQUFDLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDMUgsT0FBTyxFQUFDLFlBQVksRUFBRSxjQUFjLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUMvRSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFDLE9BQU8sRUFBTyxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RCxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQTs7Ozs7Ozs7OztBQVEzRSxNQUFNLE9BQU8scUJBQXFCO0lBUWhDLFlBQW9CLFlBQTBCLEVBQzFCLE1BQThCLEVBQzlCLGNBQTZCLEVBQzdCLGlCQUFvQztRQUhwQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixXQUFNLEdBQU4sTUFBTSxDQUF3QjtRQUM5QixtQkFBYyxHQUFkLGNBQWMs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LENBQUM7SUFDeEYsQ0FBQztJQUVELGtFQUFrRTtJQUNsRSxrQkFBa0IsQ0FBQyxTQUFlO1FBQ2hDLG1FQUFtRTtRQUNuRSwrREFBK0Q7UUFDL0QsK0RBQStEO1FBQy9ELHlDQUF5QztRQUN6QyxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUU7WUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxTQUFTLENBQUMsU0FBUyxRQUFRLENBQUMsQ0FBQztTQUNyRTthQUFNO1lBQ0wsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztTQUNqRDtJQUNILENBQUM7O21IQTdHVSxxQkFBcUI7dUdBQXJCLHFCQUFxQixxR0FjckIsT0FBTyxnREM3QnBCLHk2RUFrREE7NEZEbkNhLHFCQUFxQjtrQkFOakMsU0FBUzsrQkFDUyx5QkFBeUIsbUJBRXpCLHVCQUF1QixDQUFDLE1BQU0saUJBQzlCLGlCQUFpQixDQUFDLElBQUk7b01BZ0JuQixJQUFJO3NCQUF2QixTQUFTO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0xpdmVBbm5vdW5jZXJ9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5J1xuaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QWRtaW5TZXJ2aWNlLCBBdXRoUGVybWlzc2lvbn0gZnJvbSAnQHRhbmdlbnRpYWwvYXV0aG9yaXphdGlvbi1zZXJ2aWNlJztcbmltcG9ydCB7TmFtZUdlbmVyYXRvcn0gZnJvbSAnQHRhbmdlbnRpYWwvY29yZSc7XG5pbXBvcnQge01hdFNvcnQsIFNvcnR9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xuaW1wb3J0IHtTZWxlY3Rpb25Nb2RlbH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcbmltcG9ydCB7TWF0VGFibGVEYXRhU291cmNlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJsZSc7XG5pbXBvcnQge0FkbWluQ29uc29sZVBhcmVudFBhZ2V9IGZyb20gJy4uL19wYXJlbnQvYWRtaW4tY29uc29sZS1wYXJlbnQucGFnZSdcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAgICAgICAgJ3RhbmotcGVybWlzc2lvbi1tYW5hZ2VyJyxcbiAgdGVtcGxhdGVVcmw6ICAgICAnLi9wZXJtaXNzaW9uLW1hbmFnZXIucGFnZS5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246ICAgVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBQZXJtaXNzaW9uTWFuYWdlclBhZ2UgaW1wbGVtZW50cyBPbkluaXQge1xuICBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFsnc2VsZWN0JywgJyRrZXknLCAnZGVzY3JpcHRpb24nLCAnY3JlYXRlZE1pbHMnLCAnZWRpdGVkTWlscyddO1xuICBkYXRhU291cmNlID0gbmV3IE1hdFRhYmxlRGF0YVNvdXJjZTxBdXRoUGVybWlzc2lvbj4oKTtcbiAgc2VsZWN0aW9uID0gbmV3IFNlbGVjdGlvbk1vZGVsPEF1dGhQZXJtaXNzaW9uPih0cnVlLCBbXSk7XG5cbiAgcm93czogQXV0aFBlcm1pc3Npb25bXSA9IFtdO1xuICBzZWxlY3RlZDogYW55W10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFkbWluU2VydmljZTogQWRtaW5TZXJ2aWNlLFxuICAgICAgICAgICAgICBwcml2YXRlIHBhcmVudDogQWRtaW5Db25zb2xlUGFyZW50UGFnZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfbGl2ZUFubm91bmNlcjogTGl2ZUFubm91bmNlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgfVxuXG4gIEBWaWV3Q2hpbGQoTWF0U29ydCkgc29ydDogTWF0U29ydDtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnBhcmVudC5hdXRoJC5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHYpID0+IHtcbiAgICAgICAgdGhpcy5yb3dzID0gdi5zZXR0aW5ncy5wZXJtaXNzaW9uc1xuICAgICAgICB0aGlzLmRhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlPEF1dGhQZXJtaXNzaW9uPih2LnNldHRpbmdzLnBlcm1pc3Npb25zKTtcbiAgICAgICAgdGhpcy5kYXRhU291cmNlLnNvcnQgPSB0aGlzLnNvcnQ7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgZ2V0IG5leHRJdGVtSW5kZXgoKTogbnVtYmVyIHtcbiAgICBsZXQgaWR4ID0gMVxuICAgIGlmICh0aGlzLnJvd3MgJiYgdGhpcy5yb3dzLmxlbmd0aCkge1xuICAgICAgaWR4ID0gKHRoaXMucm93c1t0aGlzLnJvd3MubGVuZ3RoIC0gMV0ub3JkZXJJbmRleCArIDEpXG4gICAgfVxuICAgIHJldHVybiBpZHhcbiAgfVxuXG4gIG9uQWRkSXRlbUFjdGlvbigpIHtcbiAgICBjb25zdCBwZXJtaXNzaW9uID0gQXV0aFBlcm1pc3Npb24uZnJvbSh7XG4gICAgICAka2V5OiAgICAgICBOYW1lR2VuZXJhdG9yLmdlbmVyYXRlKCksXG4gICAgICBvcmRlckluZGV4OiB0aGlzLm5leHRJdGVtSW5kZXhcbiAgICB9KVxuICAgIHRoaXMuYWRtaW5TZXJ2aWNlLmFkZFBlcm1pc3Npb24ocGVybWlzc2lvbikuY2F0Y2goKHJlYXNvbikgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcignUGVybWlzc2lvbk1hbmFnZXJQYWdlJywgJ2Vycm9yIGFkZGluZyBwZXJtaXNzaW9uJywgcmVhc29uKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKHJlYXNvbilcbiAgICB9KVxuICB9XG5cbiAgb25SZW1vdmUoa2V5OiBzdHJpbmcpIHtcbiAgICB0aGlzLmFkbWluU2VydmljZS5yZW1vdmVQZXJtaXNzaW9uKGtleSkuY2F0Y2goKHJlYXNvbikgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcignUGVybWlzc2lvbk1hbmFnZXJQYWdlJywgJ2Vycm9yIHJlbW92aW5nIHBlcm1pc3Npb24nLCByZWFzb24pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IocmVhc29uKVxuICAgIH0pXG4gIH1cblxuICBvblJlbW92ZVNlbGVjdGVkQWN0aW9uKGtleXM6IHN0cmluZ1tdKSB7XG4gICAga2V5cy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIHRoaXMuYWRtaW5TZXJ2aWNlLnJlbW92ZVBlcm1pc3Npb24oa2V5KS5jYXRjaCgocmVhc29uKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Blcm1pc3Npb25NYW5hZ2VyUGFnZScsICdlcnJvciByZW1vdmluZyBwZXJtaXNzaW9uJywgcmVhc29uKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVhc29uKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cblxuICBvbkl0ZW1DaGFuZ2UocGVybWlzc2lvbjogQXV0aFBlcm1pc3Npb24pIHtcbiAgICB0aGlzLmFkbWluU2VydmljZS51cGRhdGVQZXJtaXNzaW9uKHBlcm1pc3Npb24pLmNhdGNoKChyZWFzb24pID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Blcm1pc3Npb25NYW5hZ2VyUGFnZScsICdlcnJvciB1cGRhdGluZyBwZXJtaXNzaW9uJywgcmVhc29uKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKHJlYXNvbilcbiAgICB9KVxuXG4gIH1cblxuICAvKipcbiAgICogQm9ycm93ZWQgZGlyZWN0bHkgZnJvbSBBbmd1bGFyIE1hdGVyaWFsIGV4YW1wbGVzOiBodHRwczovL21hdGVyaWFsLmFuZ3VsYXIuaW8vY29tcG9uZW50cy90YWJsZS9vdmVydmlld1xuICAgKi9cbiAgLyoqIFdoZXRoZXIgdGhlIG51bWJlciBvZiBzZWxlY3RlZCBlbGVtZW50cyBtYXRjaGVzIHRoZSB0b3RhbCBudW1iZXIgb2Ygcm93cy4gKi9cbiAgaXNBbGxTZWxlY3RlZCgpIHtcbiAgICBjb25zdCBudW1TZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uLnNlbGVjdGVkLmxlbmd0aDtcbiAgICBjb25zdCBudW1Sb3dzID0gdGhpcy5kYXRhU291cmNlLmRhdGEubGVuZ3RoO1xuICAgIHJldHVybiBudW1TZWxlY3RlZCA9PT0gbnVtUm93cztcbiAgfVxuXG4gIC8qKiBTZWxlY3RzIGFsbCByb3dzIGlmIHRoZXkgYXJlIG5vdCBhbGwgc2VsZWN0ZWQ7IG90aGVyd2lzZSBjbGVhciBzZWxlY3Rpb24uICovXG4gIHRvZ2dsZUFsbFJvd3MoKSB7XG4gICAgaWYgKHRoaXMuaXNBbGxTZWxlY3RlZCgpKSB7XG4gICAgICB0aGlzLnNlbGVjdGlvbi5jbGVhcigpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGlvbi5zZWxlY3QoLi4udGhpcy5kYXRhU291cmNlLmRhdGEpO1xuICB9XG5cbiAgLyoqIFRoZSBsYWJlbCBmb3IgdGhlIGNoZWNrYm94IG9uIHRoZSBwYXNzZWQgcm93ICovXG4gIGNoZWNrYm94TGFiZWwocm93PzogQXV0aFBlcm1pc3Npb24pOiBzdHJpbmcge1xuICAgIGlmICghcm93KSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy5pc0FsbFNlbGVjdGVkKCkgPyAnZGVzZWxlY3QnIDogJ3NlbGVjdCd9IGFsbGA7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLnNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdykgPyAnZGVzZWxlY3QnIDogJ3NlbGVjdCd9ICR7cm93LmRlc2NyaXB0aW9ufWA7XG4gIH1cblxuICAvKiogQW5ub3VuY2UgdGhlIGNoYW5nZSBpbiBzb3J0IHN0YXRlIGZvciBhc3Npc3RpdmUgdGVjaG5vbG9neS4gKi9cbiAgYW5ub3VuY2VTb3J0Q2hhbmdlKHNvcnRTdGF0ZTogU29ydCkge1xuICAgIC8vIFRoaXMgZXhhbXBsZSB1c2VzIEVuZ2xpc2ggbWVzc2FnZXMuIElmIHlvdXIgYXBwbGljYXRpb24gc3VwcG9ydHNcbiAgICAvLyBtdWx0aXBsZSBsYW5ndWFnZSwgeW91IHdvdWxkIGludGVybmF0aW9uYWxpemUgdGhlc2Ugc3RyaW5ncy5cbiAgICAvLyBGdXJ0aGVybW9yZSwgeW91IGNhbiBjdXN0b21pemUgdGhlIG1lc3NhZ2UgdG8gYWRkIGFkZGl0aW9uYWxcbiAgICAvLyBkZXRhaWxzIGFib3V0IHRoZSB2YWx1ZXMgYmVpbmcgc29ydGVkLlxuICAgIGlmIChzb3J0U3RhdGUuZGlyZWN0aW9uKSB7XG4gICAgICB0aGlzLl9saXZlQW5ub3VuY2VyLmFubm91bmNlKGBTb3J0ZWQgJHtzb3J0U3RhdGUuZGlyZWN0aW9ufWVuZGluZ2ApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9saXZlQW5ub3VuY2VyLmFubm91bmNlKCdTb3J0aW5nIGNsZWFyZWQnKTtcbiAgICB9XG4gIH1cblxufVxuIiwiPHRhbmotcGFnZS1ib2R5PlxuICA8dGFibGUgbWF0LXRhYmxlIG1hdFNvcnQgKG1hdFNvcnRDaGFuZ2UpPVwiYW5ub3VuY2VTb3J0Q2hhbmdlKCRldmVudClcIiAgW2RhdGFTb3VyY2VdPVwiZGF0YVNvdXJjZVwiIGNsYXNzPVwibWF0LWVsZXZhdGlvbi16OCB0bmctdXNlci1tZ3ItdGFibGVcIj5cblxuICAgIDwhLS0gQ2hlY2tib3ggQ29sdW1uIC0tPlxuICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2VsZWN0XCI+XG4gICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICA8bWF0LWNoZWNrYm94IChjaGFuZ2UpPVwiJGV2ZW50ID8gdG9nZ2xlQWxsUm93cygpIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgaXNBbGxTZWxlY3RlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJzZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiAhaXNBbGxTZWxlY3RlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXJpYS1sYWJlbF09XCJjaGVja2JveExhYmVsKClcIj5cbiAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICA8L3RoPlxuICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiID5cbiAgICAgICAgPG1hdC1jaGVja2JveCAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIiRldmVudCA/IHNlbGVjdGlvbi50b2dnbGUocm93KSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdylcIlxuICAgICAgICAgICAgICAgICAgICAgIFthcmlhLWxhYmVsXT1cImNoZWNrYm94TGFiZWwocm93KVwiPlxuICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgIDwvdGQ+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIFVJRCBDb2x1bW4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCIka2V5XCI+XG4gICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlciBzb3J0QWN0aW9uRGVzY3JpcHRpb249XCJTb3J0IGJ5IFBlcm1pc3Npb24gSURcIj4gUGVybWlzc2lvbiBJRCA8L3RoPlxuICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj4ge3tlbGVtZW50LiRrZXl9fSA8L3RkPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBVc2VyIG5hbWUgQ29sdW1uIC0tPlxuICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGVzY3JpcHRpb25cIj5cbiAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyIHNvcnRBY3Rpb25EZXNjcmlwdGlvbj1cIlNvcnQgYnkgRGVzY3JpcHRpb25cIj4gIERlc2NyaXB0aW9uIDwvdGg+XG4gICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPiB7e2VsZW1lbnQuZGVzY3JpcHRpb259fSA8L3RkPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBVc2VyIEVtYWlsIENvbHVtbiAtLT5cbiAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNyZWF0ZWRNaWxzXCIgPlxuICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXIgc29ydEFjdGlvbkRlc2NyaXB0aW9uPVwiU29ydCBieSBDcmVhdGVkIERhdGVcIj4gQ3JlYXRlZCA8L3RoPlxuICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj4ge3tlbGVtZW50LmNyZWF0ZWRNaWxzICB8IGRhdGU6J3l5eXktTU1+ZGQsIEhIOm1tOnNzJ319IDwvdGQ+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIExhc3QgU2lnbiBpbiBDb2x1bW4gLS0+XG4gICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJlZGl0ZWRNaWxzXCI+XG4gICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlciBzb3J0QWN0aW9uRGVzY3JpcHRpb249XCJTb3J0IGJ5IExhc3QgTW9kaWZpZWRcIj4gTGFzdCBNb2RpZmllZCA8L3RoPlxuICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj4ge3tlbGVtZW50LmVkaXRlZE1pbHMgfCBkYXRlOid5eXl5LU1NfmRkLCBISDptbTpzcycgfX0gPC90ZD5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnM7XCIgKGNsaWNrKT1cInNlbGVjdGlvbi50b2dnbGUocm93KVwiPjwvdHI+XG4gIDwvdGFibGU+XG5cbjwvdGFuai1wYWdlLWJvZHk+XG4iXX0=