@tangential/admin-console
Version:
A basic administration console
119 lines • 24.3 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { AuthUser } from '@tangential/authorization-service';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/form-field";
import * as i6 from "@angular/material/input";
export class UserComponent {
constructor() {
this.userRoles = [];
this.userGrantedPermissions = [];
this.userRolePermissions = [];
this.showSelector = true;
this.selected = false;
this.expanded = false;
this.selectionChange = new EventEmitter(false);
this.removeUser = new EventEmitter(false);
this.addUserRole = new EventEmitter(false);
this.removeUserRole = new EventEmitter(false);
this.addUserPermission = new EventEmitter(false);
this.removeUserPermission = new EventEmitter(false);
this._focusDebouncer = new EventEmitter(false);
this.submitted = false;
let distinct = this._focusDebouncer.asObservable();
distinct = distinct.pipe(debounceTime(10), distinctUntilChanged());
this.focus = distinct.pipe(filter((focused) => focused === true), map(() => {
this.expanded = true;
return new Event('focus');
}));
this.change = distinct.pipe(filter((focused) => focused === false && this._changed), map(() => this.user));
this.blur = distinct.pipe(filter((focused) => focused === false), map(() => new Event('blur')));
}
ngOnChanges(change) {
if (change.user_roles) {
// console.log('UserListItemComponent', 'ngOnChanges', this.roles)
// debugger
}
}
fireRemoveUser() {
this.removeUser.emit(this.user);
}
doToggleRole(role, enabled) {
if (enabled) {
this.addUserRole.emit({ user: this.user, role: role });
}
else {
this.removeUserRole.emit({ user: this.user, role: role });
}
}
doTogglePermission(permission) {
const event = { user: this.user, permission: permission };
if (this.userGrantedPermissions.some((item) => item.$key === permission.$key)) {
this.removeUserPermission.emit(event);
}
else {
this.addUserPermission.emit(event);
}
}
doToggleSelected() {
this.selected = !this.selected;
this.selectionChange.emit(this.selected);
}
onChange() {
this._changed = true;
}
onBlur() {
this._focusDebouncer.emit(false);
}
onFocus() {
this._focusDebouncer.emit(true);
}
onSubmit() {
console.log('UserComponent', 'onSubmit');
this.submitted = true;
}
}
UserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: UserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
UserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: UserComponent, selector: "tanj-user", inputs: { user: "user", userRoles: "userRoles", userGrantedPermissions: "userGrantedPermissions", userRolePermissions: "userRolePermissions", showSelector: "showSelector", selected: "selected", expanded: "expanded" }, outputs: { change: "change", selectionChange: "selectionChange", removeUser: "removeUser", addUserRole: "addUserRole", removeUserRole: "removeUserRole", addUserPermission: "addUserPermission", removeUserPermission: "removeUserPermission", focus: "focus", blur: "blur" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"tanj-user-form-wrapper\" flex layout=\"column\" layout-align=\"start\">\n <form *ngIf=\"user != null\" (ngSubmit)=\"onSubmit($event)\" #theForm=\"ngForm\" flex layout=\"row\"\n layout-align=\"space-between\">\n\n <div class=\"tanj-user-inputs-wrapper\" layout=\"row\" flex=\"80\" layout-align=\"space-between start\">\n <mat-form-field flex=\"40\">\n <input matInput [(ngModel)]=\"user.email\" name=\"email\" #fName=\"ngModel\"\n class=\"tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'email'\"\n required minlength=\"2\"\n value=\"{{user.email}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"email\"\n /></mat-form-field>\n <mat-form-field flex=\"60\">\n <input matInput [(ngModel)]=\"user.displayName\" name=\"displayName\" #fDescription=\"ngModel\"\n class=\"tanj-description tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n value=\"{{user.displayName}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"Display Name\"/>\n </mat-form-field>\n </div>\n <div class=\"tanj-delete-button\" flex layout=\"row\" layout-align=\"end center\">\n <button mat-mini-fab\n type=\"button\"\n aria-label=\"Delete User\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n (click)=\"fireRemoveUser()\"\n [disabled]=\"false\">\n <mat-icon class=\"mat-24\">delete</mat-icon>\n </button>\n </div>\n </form>\n</div>\n\n\n\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: UserComponent, decorators: [{
type: Component,
args: [{ selector: 'tanj-user', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"tanj-user-form-wrapper\" flex layout=\"column\" layout-align=\"start\">\n <form *ngIf=\"user != null\" (ngSubmit)=\"onSubmit($event)\" #theForm=\"ngForm\" flex layout=\"row\"\n layout-align=\"space-between\">\n\n <div class=\"tanj-user-inputs-wrapper\" layout=\"row\" flex=\"80\" layout-align=\"space-between start\">\n <mat-form-field flex=\"40\">\n <input matInput [(ngModel)]=\"user.email\" name=\"email\" #fName=\"ngModel\"\n class=\"tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'email'\"\n required minlength=\"2\"\n value=\"{{user.email}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"email\"\n /></mat-form-field>\n <mat-form-field flex=\"60\">\n <input matInput [(ngModel)]=\"user.displayName\" name=\"displayName\" #fDescription=\"ngModel\"\n class=\"tanj-description tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n value=\"{{user.displayName}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"Display Name\"/>\n </mat-form-field>\n </div>\n <div class=\"tanj-delete-button\" flex layout=\"row\" layout-align=\"end center\">\n <button mat-mini-fab\n type=\"button\"\n aria-label=\"Delete User\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n (click)=\"fireRemoveUser()\"\n [disabled]=\"false\">\n <mat-icon class=\"mat-24\">delete</mat-icon>\n </button>\n </div>\n </form>\n</div>\n\n\n\n" }]
}], ctorParameters: function () { return []; }, propDecorators: { user: [{
type: Input
}], userRoles: [{
type: Input
}], userGrantedPermissions: [{
type: Input
}], userRolePermissions: [{
type: Input
}], showSelector: [{
type: Input
}], selected: [{
type: Input
}], expanded: [{
type: Input
}], change: [{
type: Output
}], selectionChange: [{
type: Output
}], removeUser: [{
type: Output
}], addUserRole: [{
type: Output
}], removeUserRole: [{
type: Output
}], addUserPermission: [{
type: Output
}], removeUserPermission: [{
type: Output
}], focus: [{
type: Output
}], blur: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nZW50aWFsL2FkbWluLWNvbnNvbGUvc3JjL2xpYi9wYWdlcy91c2Vycy91c2VyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdlbnRpYWwvYWRtaW4tY29uc29sZS9zcmMvbGliL3BhZ2VzL3VzZXJzL3VzZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUMzSCxPQUFPLEVBQTJCLFFBQVEsRUFBQyxNQUFNLG1DQUFtQyxDQUFBO0FBQ3BGLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxNQUFNLENBQUE7QUFDL0IsT0FBTyxFQUFDLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUE7Ozs7Ozs7O0FBUTlFLE1BQU0sT0FBTyxhQUFhO0lBOEJ4QjtRQTNCUyxjQUFTLEdBQWUsRUFBRSxDQUFBO1FBQzFCLDJCQUFzQixHQUFxQixFQUFFLENBQUE7UUFDN0Msd0JBQW1CLEdBQXFCLEVBQUUsQ0FBQTtRQUUxQyxpQkFBWSxHQUFZLElBQUksQ0FBQTtRQUM1QixhQUFRLEdBQVksS0FBSyxDQUFBO1FBQ3pCLGFBQVEsR0FBWSxLQUFLLENBQUE7UUFHeEIsb0JBQWUsR0FBMEIsSUFBSSxZQUFZLENBQVUsS0FBSyxDQUFDLENBQUE7UUFDekUsZUFBVSxHQUEyQixJQUFJLFlBQVksQ0FBVyxLQUFLLENBQUMsQ0FBQTtRQUN0RSxnQkFBVyxHQUFxRCxJQUFJLFlBQVksQ0FBcUMsS0FBSyxDQUFDLENBQUE7UUFDM0gsbUJBQWMsR0FBcUQsSUFB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aGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb259IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQge0F1dGhQZXJtaXNzaW9uLCBBdXRoUm9sZSwgQXV0aFVzZXJ9IGZyb20gJ0B0YW5nZW50aWFsL2F1dGhvcml6YXRpb24tc2VydmljZSdcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcydcbmltcG9ydCB7ZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyLCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJ1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICAgICAgICAndGFuai11c2VyJyxcbiAgdGVtcGxhdGVVcmw6ICAgICAnLi91c2VyLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246ICAgVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBVc2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSB1c2VyOiBBdXRoVXNlclxuICBASW5wdXQoKSB1c2VyUm9sZXM6IEF1dGhSb2xlW10gPSBbXVxuICBASW5wdXQoKSB1c2VyR3JhbnRlZFBlcm1pc3Npb25zOiBBdXRoUGVybWlzc2lvbltdID0gW11cbiAgQElucHV0KCkgdXNlclJvbGVQZXJtaXNzaW9uczogQXV0aFBlcm1pc3Npb25bXSA9IFtdXG5cbiAgQElucHV0KCkgc2hvd1NlbGVjdG9yOiBib29sZWFuID0gdHJ1ZVxuICBASW5wdXQoKSBzZWxlY3RlZDogYm9vbGVhbiA9IGZhbHNlXG4gIEBJbnB1dCgpIGV4cGFuZGVkOiBib29sZWFuID0gZmFsc2VcblxuICBAT3V0cHV0KCkgY2hhbmdlOiBPYnNlcnZhYmxlPEF1dGhVc2VyPjtcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPihmYWxzZSlcbiAgQE91dHB1dCgpIHJlbW92ZVVzZXI6IEV2ZW50RW1pdHRlcjxBdXRoVXNlcj4gPSBuZXcgRXZlbnRFbWl0dGVyPEF1dGhVc2VyPihmYWxzZSlcbiAgQE91dHB1dCgpIGFkZFVzZXJSb2xlOiBFdmVudEVtaXR0ZXI8eyB1c2VyOiBBdXRoVXNlciwgcm9sZTogQXV0aFJvbGUgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgdXNlcjogQXV0aFVzZXIsIHJvbGU6IEF1dGhSb2xlIH0+KGZhbHNlKVxuICBAT3V0cHV0KCkgcmVtb3ZlVXNlclJvbGU6IEV2ZW50RW1pdHRlcjx7IHVzZXI6IEF1dGhVc2VyLCByb2xlOiBBdXRoUm9sZSB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyB1c2VyOiBBdXRoVXNlciwgcm9sZTogQXV0aFJvbGUgfT4oZmFsc2UpXG4gIEBPdXRwdXQoKSBhZGRVc2VyUGVybWlzc2lvbjogRXZlbnRFbWl0dGVyPHsgdXNlcjogQXV0aFVzZXIsIHBlcm1pc3Npb246IEF1dGhQZXJtaXNzaW9uIH0+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPHsgdXNlcjogQXV0aFVzZXIsIHBlcm1pc3Npb246IEF1dGhQZXJtaXNzaW9uIH0+KGZhbHNlKVxuICBAT3V0cHV0KCkgcmVtb3ZlVXNlclBlcm1pc3Npb246IEV2ZW50RW1pdHRlcjx7IHVzZXI6IEF1dGhVc2VyLCBwZXJtaXNzaW9uOiBBdXRoUGVybWlzc2lvbiB9PiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjx7IHVzZXI6IEF1dGhVc2VyLCBwZXJtaXNzaW9uOiBBdXRoUGVybWlzc2lvbiB9PihmYWxzZSlcblxuXG4gIHByaXZhdGUgX2ZvY3VzRGVib3VuY2VyOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KGZhbHNlKTtcblxuICBAT3V0cHV0KCkgZm9jdXM6IE9ic2VydmFibGU8RXZlbnQ+XG4gIEBPdXRwdXQoKSBibHVyOiBPYnNlcnZhYmxlPEV2ZW50PlxuXG4gIHN1Ym1pdHRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF9jaGFuZ2VkOiBib29sZWFuXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgbGV0IGRpc3RpbmN0OiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5fZm9jdXNEZWJvdW5jZXIuYXNPYnNlcnZhYmxlKClcbiAgICBkaXN0aW5jdCA9IGRpc3RpbmN0LnBpcGUoZGVib3VuY2VUaW1lKDEwKSxkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKVxuXG4gICAgdGhpcy5mb2N1cyA9IGRpc3RpbmN0LnBpcGUoXG4gICAgICBmaWx0ZXIoKGZvY3VzZWQpID0+IGZvY3VzZWQgPT09IHRydWUpLFxuICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgdGhpcy5leHBhbmRlZCA9IHRydWVcbiAgICAgICAgcmV0dXJuIG5ldyBFdmVudCgnZm9jdXMnKVxuICAgICAgfSkpXG5cbiAgICB0aGlzLmNoYW5nZSA9IGRpc3RpbmN0LnBpcGUoXG4gICAgICBmaWx0ZXIoKGZvY3VzZWQpID0+IGZvY3VzZWQgPT09IGZhbHNlICYmIHRoaXMuX2NoYW5nZWQpLFxuICAgICAgbWFwKCgpID0+IHRoaXMudXNlcikpXG5cbiAgICB0aGlzLmJsdXIgPSBkaXN0aW5jdC5waXBlKFxuICAgICAgZmlsdGVyKChmb2N1c2VkKSA9PiBmb2N1c2VkID09PSBmYWxzZSksXG4gICAgICBtYXAoKCkgPT4gbmV3IEV2ZW50KCdibHVyJykpKVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlOiBhbnkpIHtcbiAgICBpZiAoY2hhbmdlLnVzZXJfcm9sZXMpIHtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdVc2VyTGlzdEl0ZW1Db21wb25lbnQnLCAnbmdPbkNoYW5nZXMnLCB0aGlzLnJvbGVzKVxuICAgICAgLy8gZGVidWdnZXJcbiAgICB9XG4gIH1cblxuICBmaXJlUmVtb3ZlVXNlcigpIHtcbiAgICB0aGlzLnJlbW92ZVVzZXIuZW1pdCh0aGlzLnVzZXIpXG4gIH1cblxuICBkb1RvZ2dsZVJvbGUocm9sZTogQXV0aFJvbGUsIGVuYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICBpZiAoZW5hYmxlZCkge1xuICAgICAgdGhpcy5hZGRVc2VyUm9sZS5lbWl0KHt1c2VyOiB0aGlzLnVzZXIsIHJvbGU6IHJvbGV9KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbW92ZVVzZXJSb2xlLmVtaXQoe3VzZXI6IHRoaXMudXNlciwgcm9sZTogcm9sZX0pXG4gICAgfVxuICB9XG5cbiAgZG9Ub2dnbGVQZXJtaXNzaW9uKHBlcm1pc3Npb246IEF1dGhQZXJtaXNzaW9uKSB7XG4gICAgY29uc3QgZXZlbnQgPSB7dXNlcjogdGhpcy51c2VyLCBwZXJtaXNzaW9uOiBwZXJtaXNzaW9ufTtcbiAgICBpZiAodGhpcy51c2VyR3JhbnRlZFBlcm1pc3Npb25zLnNvbWUoKGl0ZW0pID0+IGl0ZW0uJGtleSA9PT0gcGVybWlzc2lvbi4ka2V5KSkge1xuICAgICAgdGhpcy5yZW1vdmVVc2VyUGVybWlzc2lvbi5lbWl0KGV2ZW50KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFkZFVzZXJQZXJtaXNzaW9uLmVtaXQoZXZlbnQpXG4gICAgfVxuICB9XG5cbiAgZG9Ub2dnbGVTZWxlY3RlZCgpIHtcbiAgICB0aGlzLnNlbGVjdGVkID0gIXRoaXMuc2VsZWN0ZWRcbiAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWQpXG4gIH1cblxuXG4gIG9uQ2hhbmdlKCkge1xuICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlXG4gIH1cblxuICBvbkJsdXIoKSB7XG4gICAgdGhpcy5fZm9jdXNEZWJvdW5jZXIuZW1pdChmYWxzZSlcbiAgfVxuXG4gIG9uRm9jdXMoKSB7XG4gICAgdGhpcy5fZm9jdXNEZWJvdW5jZXIuZW1pdCh0cnVlKVxuXG4gIH1cblxuICBvblN1Ym1pdCgpIHtcbiAgICBjb25zb2xlLmxvZygnVXNlckNvbXBvbmVudCcsICdvblN1Ym1pdCcpXG4gICAgdGhpcy5zdWJtaXR0ZWQgPSB0cnVlO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidGFuai11c2VyLWZvcm0td3JhcHBlclwiIGZsZXggbGF5b3V0PVwiY29sdW1uXCIgbGF5b3V0LWFsaWduPVwic3RhcnRcIj5cbiAgPGZvcm0gKm5nSWY9XCJ1c2VyICE9IG51bGxcIiAobmdTdWJtaXQpPVwib25TdWJtaXQoJGV2ZW50KVwiICN0aGVGb3JtPVwibmdGb3JtXCIgZmxleCBsYXlvdXQ9XCJyb3dcIlxuICAgICAgICBsYXlvdXQtYWxpZ249XCJzcGFjZS1iZXR3ZWVuXCI+XG5cbiAgICA8ZGl2IGNsYXNzPVwidGFuai11c2VyLWlucHV0cy13cmFwcGVyXCIgbGF5b3V0PVwicm93XCIgZmxleD1cIjgwXCIgbGF5b3V0LWFsaWduPVwic3BhY2UtYmV0d2VlbiBzdGFydFwiPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkIGZsZXg9XCI0MFwiPlxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJ1c2VyLmVtYWlsXCIgbmFtZT1cImVtYWlsXCIgI2ZOYW1lPVwibmdNb2RlbFwiXG4gICAgICAgICAgICAgICBjbGFzcz1cInRhbmotaW5wdXRcIlxuICAgICAgICAgICAgICAgZGl2aWRlckNvbG9yPVwiYWNjZW50XCJcbiAgICAgICAgICAgICAgIFt0eXBlXT1cIidlbWFpbCdcIlxuICAgICAgICAgICAgICAgcmVxdWlyZWQgbWlubGVuZ3RoPVwiMlwiXG4gICAgICAgICAgICAgICB2YWx1ZT1cInt7dXNlci5lbWFpbH19XCJcbiAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkNoYW5nZSgpXCJcbiAgICAgICAgICAgICAgIChmb2N1cyk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IG9uRm9jdXMoKVwiXG4gICAgICAgICAgICAgICAoYmx1cik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IG9uQmx1cigpXCJcbiAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZW1haWxcIlxuICAgICAgICAvPjwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICA8bWF0LWZvcm0tZmllbGQgZmxleD1cIjYwXCI+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cInVzZXIuZGlzcGxheU5hbWVcIiBuYW1lPVwiZGlzcGxheU5hbWVcIiAjZkRlc2NyaXB0aW9uPVwibmdNb2RlbFwiXG4gICAgICAgICAgICAgICBjbGFzcz1cInRhbmotZGVzY3JpcHRpb24gdGFuai1pbnB1dFwiXG4gICAgICAgICAgICAgICBkaXZpZGVyQ29sb3I9XCJhY2NlbnRcIlxuICAgICAgICAgICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgICAgICAgICAgIHZhbHVlPVwie3t1c2VyLmRpc3BsYXlOYW1lfX1cIlxuICAgICAgICAgICAgICAgKGNoYW5nZSk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IG9uQ2hhbmdlKClcIlxuICAgICAgICAgICAgICAgKGZvY3VzKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb25Gb2N1cygpXCJcbiAgICAgICAgICAgICAgIChibHVyKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb25CbHVyKClcIlxuICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJEaXNwbGF5IE5hbWVcIi8+XG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ0YW5qLWRlbGV0ZS1idXR0b25cIiBmbGV4IGxheW91dD1cInJvd1wiIGxheW91dC1hbGlnbj1cImVuZCBjZW50ZXJcIj5cbiAgICAgIDxidXR0b24gbWF0LW1pbmktZmFiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiRGVsZXRlIFVzZXJcIlxuICAgICAgICAgICAgICAoZm9jdXMpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkZvY3VzKClcIlxuICAgICAgICAgICAgICAoYmx1cik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IG9uQmx1cigpXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImZpcmVSZW1vdmVVc2VyKClcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmFsc2VcIj5cbiAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LTI0XCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG48L2Rpdj5cblxuXG5cbiJdfQ==