UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

78 lines 29.4 kB
import { Component } from '@angular/core'; import { AlertService, gettext, ModalService, PX_ACTIONS, Status } from '@c8y/ngx-components'; import { DeviceProvisionedCertificatesService } from './device-provisioned-certificates.service'; import { ActivatedRoute } from '@angular/router'; import { CrlService } from '@c8y/client'; import { BehaviorSubject } from 'rxjs'; import { switchMap, map, tap, finalize, shareReplay } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; import * as i2 from "./device-provisioned-certificates.service"; import * as i3 from "@c8y/client"; import * as i4 from "@angular/router"; import * as i5 from "@ngx-translate/core"; import * as i6 from "@angular/common"; export class DeviceTabProvisionedCertificatesComponent { constructor(alertService, modalService, deviceSerialsService, crlService, route, translateService) { this.alertService = alertService; this.modalService = modalService; this.deviceSerialsService = deviceSerialsService; this.crlService = crlService; this.route = route; this.translateService = translateService; this.reloading = false; this.reload = new BehaviorSubject(null); this.provisionedCertificates = this.reload.pipe(tap(() => { this.reloading = true; }), map(() => this.route.snapshot.parent.data.contextData), switchMap(device => this.deviceSerialsService.getDeviceProvisionedCertificates(device)), tap(() => { this.reloading = false; }), shareReplay(1), finalize(() => { this.reloading = false; })); this.PX_ACTIONS = PX_ACTIONS; } ngOnInit() { this.reload.next(); } highlightDependingOnExpirationStatus(item) { const warningOffset = 24 * 60 * 60 * 1000 * 90; // 90 days const todayTimestamp = new Date().getTime(); const warningTimestamp = new Date().getTime() + warningOffset; const notAfterTimestamp = new Date(item.validTill).getTime(); const expired = notAfterTimestamp < todayTimestamp; const expiresInLessThan90Days = notAfterTimestamp < warningTimestamp; if (expired) { return 'text-danger'; } if (expiresInLessThan90Days) { return 'text-warning'; } return ''; } async revokeProvisionedCertificate(provisionedCertificate) { if (provisionedCertificate) { try { const serialNumberInHex = provisionedCertificate.serialNumber; await this.confirmRevocation(serialNumberInHex); await this.crlService.uploadCrls([{ serialNumberInHex }]); } catch (error) { this.alertService.addServerFailure(error); } finally { this.reload.next(); } } } async confirmRevocation(serialNumber) { return await this.modalService.confirm(gettext('Revoke provisioned certificate'), this.translateService.instant(gettext(`You are about to revoke provisioned certificate {{ serialNumber }}. Do you want to proceed?`), { serialNumber }), Status.DANGER, { ok: gettext('Revoke'), cancel: gettext('Cancel') }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeviceTabProvisionedCertificatesComponent, deps: [{ token: i1.AlertService }, { token: i1.ModalService }, { token: i2.DeviceProvisionedCertificatesService }, { token: i3.CrlService }, { token: i4.ActivatedRoute }, { token: i5.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DeviceTabProvisionedCertificatesComponent, selector: "device-tab-serials-component", ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n (click)=\"reload.next()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!-- TODO: Add link to the mentioned documentation when it's available -->\n<c8y-ui-empty-state\n [icon]=\"'certificate'\"\n [title]=\"'No provisioned certificates to display.' | translate\"\n *ngIf=\"(provisionedCertificates | async)?.length === 0\"\n></c8y-ui-empty-state>\n\n<div\n [ngStyle]=\"{ width: '50%' }\"\n *ngIf=\"(provisionedCertificates | async)?.length > 0\"\n>\n <div class=\"bg-level-0\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Provisioned certificates\n </div>\n </div>\n <div class=\"p-16\">\n <c8y-list-group class=\"m-b-24\">\n <div\n class=\"page-sticky-header hidden-xs c8y-list__item\"\n style=\"display: block !important\"\n >\n <div class=\"c8y-list__item__block\">\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-60\">\n <div class=\"col-5\">\n <span\n class=\"text-truncate\"\n title=\" {{ 'Serial No.' | translate }} \"\n >\n {{ 'Serial No.' | translate }}\n </span>\n </div>\n <div class=\"col-6\">\n <span\n class=\"text-truncate\"\n title=\"{{ 'Expiration date' | translate }}\"\n >\n {{ 'Expiration date' | translate }}\n </span>\n </div>\n <div class=\"col-1\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <c8y-li\n *ngFor=\"let provisionedCertificate of provisionedCertificates | async; let i = index\"\n >\n <c8y-li-body class=\"content-flex-60\">\n <div class=\"col-5\">\n <div\n class=\"text-truncate\"\n title=\"{{ 'Serial No.' | translate }}: {{ provisionedCertificate.serialNumber }}\"\n >\n <span\n class=\"text-label-small m-t-8 m-r-8 visible-xs-inline\"\n translate\n >\n Serial No.\n </span>\n {{ provisionedCertificate.serialNumber }}\n </div>\n </div>\n\n <div class=\"col-6\">\n <div\n class=\"text-truncate\"\n title=\"{{ 'Expiration date' | translate }}: {{\n provisionedCertificate.validTill | c8yDate\n }}\"\n >\n <span\n class=\"text-label-small m-t-8 m-r-8 visible-xs-inline\"\n translate\n >\n Expiration date\n </span>\n <small\n *ngIf=\"provisionedCertificate.validTill\"\n [ngClass]=\"highlightDependingOnExpirationStatus(provisionedCertificate)\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"calendar\"\n *ngIf=\"!highlightDependingOnExpirationStatus(provisionedCertificate)\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"warning\"\n *ngIf=\"highlightDependingOnExpirationStatus(provisionedCertificate)\"\n ></i>\n <span>{{ provisionedCertificate.validTill | c8yDate }}</span>\n </small>\n </div>\n </div>\n <div class=\"col-1\">\n <button\n class=\"btn btn-dot btn-dot--danger\"\n title=\"{{ 'Revoke' | translate }}\"\n type=\"button\"\n (click)=\"revokeProvisionedCertificate(provisionedCertificate)\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-list-group>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i1.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeviceTabProvisionedCertificatesComponent, decorators: [{ type: Component, args: [{ selector: 'device-tab-serials-component', template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n (click)=\"reload.next()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<!-- TODO: Add link to the mentioned documentation when it's available -->\n<c8y-ui-empty-state\n [icon]=\"'certificate'\"\n [title]=\"'No provisioned certificates to display.' | translate\"\n *ngIf=\"(provisionedCertificates | async)?.length === 0\"\n></c8y-ui-empty-state>\n\n<div\n [ngStyle]=\"{ width: '50%' }\"\n *ngIf=\"(provisionedCertificates | async)?.length > 0\"\n>\n <div class=\"bg-level-0\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Provisioned certificates\n </div>\n </div>\n <div class=\"p-16\">\n <c8y-list-group class=\"m-b-24\">\n <div\n class=\"page-sticky-header hidden-xs c8y-list__item\"\n style=\"display: block !important\"\n >\n <div class=\"c8y-list__item__block\">\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-60\">\n <div class=\"col-5\">\n <span\n class=\"text-truncate\"\n title=\" {{ 'Serial No.' | translate }} \"\n >\n {{ 'Serial No.' | translate }}\n </span>\n </div>\n <div class=\"col-6\">\n <span\n class=\"text-truncate\"\n title=\"{{ 'Expiration date' | translate }}\"\n >\n {{ 'Expiration date' | translate }}\n </span>\n </div>\n <div class=\"col-1\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <c8y-li\n *ngFor=\"let provisionedCertificate of provisionedCertificates | async; let i = index\"\n >\n <c8y-li-body class=\"content-flex-60\">\n <div class=\"col-5\">\n <div\n class=\"text-truncate\"\n title=\"{{ 'Serial No.' | translate }}: {{ provisionedCertificate.serialNumber }}\"\n >\n <span\n class=\"text-label-small m-t-8 m-r-8 visible-xs-inline\"\n translate\n >\n Serial No.\n </span>\n {{ provisionedCertificate.serialNumber }}\n </div>\n </div>\n\n <div class=\"col-6\">\n <div\n class=\"text-truncate\"\n title=\"{{ 'Expiration date' | translate }}: {{\n provisionedCertificate.validTill | c8yDate\n }}\"\n >\n <span\n class=\"text-label-small m-t-8 m-r-8 visible-xs-inline\"\n translate\n >\n Expiration date\n </span>\n <small\n *ngIf=\"provisionedCertificate.validTill\"\n [ngClass]=\"highlightDependingOnExpirationStatus(provisionedCertificate)\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"calendar\"\n *ngIf=\"!highlightDependingOnExpirationStatus(provisionedCertificate)\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"warning\"\n *ngIf=\"highlightDependingOnExpirationStatus(provisionedCertificate)\"\n ></i>\n <span>{{ provisionedCertificate.validTill | c8yDate }}</span>\n </small>\n </div>\n </div>\n <div class=\"col-1\">\n <button\n class=\"btn btn-dot btn-dot--danger\"\n title=\"{{ 'Revoke' | translate }}\"\n type=\"button\"\n (click)=\"revokeProvisionedCertificate(provisionedCertificate)\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-list-group>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.AlertService }, { type: i1.ModalService }, { type: i2.DeviceProvisionedCertificatesService }, { type: i3.CrlService }, { type: i4.ActivatedRoute }, { type: i5.TranslateService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2aWNlLXRhYi1wcm92aXNpb25lZC1jZXJ0aWZpY2F0ZXMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2aWNlLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy9kZXZpY2UtdGFiLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9kZXZpY2UtcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzL2RldmljZS10YWItcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5RixPQUFPLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNqRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBa0IsTUFBTSxhQUFhLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7OztBQVF2RCxNQUFNLE9BQU8seUNBQXlDO0lBb0JwRCxZQUNVLFlBQTBCLEVBQzFCLFlBQTBCLEVBQzFCLG9CQUEwRCxFQUMxRCxVQUFzQixFQUN0QixLQUFxQixFQUNyQixnQkFBa0M7UUFMbEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIs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Q0FBQyxZQUFZLENBQUMsT0FBTyxDQUNwQyxPQUFPLENBQUMsZ0NBQWdDLENBQUMsRUFDekMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FDM0IsT0FBTyxDQUNMLDZGQUE2RixDQUM5RixFQUNELEVBQUUsWUFBWSxFQUFFLENBQ2pCLEVBQ0QsTUFBTSxDQUFDLE1BQU0sRUFDYixFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUNyRCxDQUFDO0lBQ0osQ0FBQzsrR0EzRVUseUNBQXlDO21HQUF6Qyx5Q0FBeUMsb0VDZnRELG0ySUFvSUE7OzRGRHJIYSx5Q0FBeUM7a0JBSnJELFNBQVM7K0JBQ0UsOEJBQThCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSwgZ2V0dGV4dCwgTW9kYWxTZXJ2aWNlLCBQWF9BQ1RJT05TLCBTdGF0dXMgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IERldmljZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzU2VydmljZSB9IGZyb20gJy4vZGV2aWNlLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IENybFNlcnZpY2UsIElNYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCwgdGFwLCBmaW5hbGl6ZSwgc2hhcmVSZXBsYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5cbmV4cG9ydCB0eXBlIFByb3Zpc2lvbmVkQ2VydGlmaWNhdGUgPSB7IHNlcmlhbE51bWJlcjogc3RyaW5nOyB2YWxpZFRpbGw6IHN0cmluZyB9O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkZXZpY2UtdGFiLXNlcmlhbHMtY29tcG9uZW50JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2RldmljZS10YWItcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBEZXZpY2VUYWJQcm92aXNpb25lZENlcnRpZmljYXRlc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHJlbG9hZGluZyA9IGZhbHNlO1xuICByZWxvYWQ6IEJlaGF2aW9yU3ViamVjdDx2b2lkPiA9IG5ldyBCZWhhdmlvclN1YmplY3QobnVsbCk7XG4gIHByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzOiBPYnNlcnZhYmxlPFByb3Zpc2lvbmVkQ2VydGlmaWNhdGVbXT4gPSB0aGlzLnJlbG9hZC5waXBlKFxuICAgIHRhcCgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZGluZyA9IHRydWU7XG4gICAgfSksXG4gICAgbWFwKCgpID0+IHRoaXMucm91dGUuc25hcHNob3QucGFyZW50LmRhdGEuY29udGV4dERhdGEgYXMgSU1hbmFnZWRPYmplY3QpLFxuICAgIHN3aXRjaE1hcChkZXZpY2UgPT4gdGhpcy5kZXZpY2VTZXJpYWxzU2VydmljZS5nZXREZXZpY2VQcm92aXNpb25lZENlcnRpZmljYXRlcyhkZXZpY2UpKSxcbiAgICB0YXAoKCkgPT4ge1xuICAgICAgdGhpcy5yZWxvYWRpbmcgPSBmYWxzZTtcbiAgICB9KSxcbiAgICBzaGFyZVJlcGxheSgxKSxcbiAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZGluZyA9IGZhbHNlO1xuICAgIH0pXG4gICk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IFBYX0FDVElPTlMgPSBQWF9BQ1RJT05TO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE1vZGFsU2VydmljZSxcbiAgICBwcml2YXRlIGRldmljZVNlcmlhbHNTZXJ2aWNlOiBEZXZpY2VQcm92aXNpb25lZENlcnRpZmljYXRlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjcmxTZXJ2aWNlOiBDcmxTZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWxvYWQubmV4dCgpO1xuICB9XG5cbiAgaGlnaGxpZ2h0RGVwZW5kaW5nT25FeHBpcmF0aW9uU3RhdHVzKGl0ZW06IFByb3Zpc2lvbmVkQ2VydGlmaWNhdGUpIHtcbiAgICBjb25zdCB3YXJuaW5nT2Zmc2V0ID0gMjQgKiA2MCAqIDYwICogMTAwMCAqIDkwOyAvLyA5MCBkYXlzXG4gICAgY29uc3QgdG9kYXlUaW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCB3YXJuaW5nVGltZXN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgKyB3YXJuaW5nT2Zmc2V0O1xuICAgIGNvbnN0IG5vdEFmdGVyVGltZXN0YW1wID0gbmV3IERhdGUoaXRlbS52YWxpZFRpbGwpLmdldFRpbWUoKTtcbiAgICBjb25zdCBleHBpcmVkID0gbm90QWZ0ZXJUaW1lc3RhbXAgPCB0b2RheVRpbWVzdGFtcDtcbiAgICBjb25zdCBleHBpcmVzSW5MZXNzVGhhbjkwRGF5cyA9IG5vdEFmdGVyVGltZXN0YW1wIDwgd2FybmluZ1RpbWVzdGFtcDtcbiAgICBpZiAoZXhwaXJlZCkge1xuICAgICAgcmV0dXJuICd0ZXh0LWRhbmdlcic7XG4gICAgfVxuICAgIGlmIChleHBpcmVzSW5MZXNzVGhhbjkwRGF5cykge1xuICAgICAgcmV0dXJuICd0ZXh0LXdhcm5pbmcnO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBhc3luYyByZXZva2VQcm92aXNpb25lZENlcnRpZmljYXRlKHByb3Zpc2lvbmVkQ2VydGlmaWNhdGU6IFByb3Zpc2lvbmVkQ2VydGlmaWNhdGUpIHtcbiAgICBpZiAocHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2VyaWFsTnVtYmVySW5IZXggPSBwcm92aXNpb25lZENlcnRpZmljYXRlLnNlcmlhbE51bWJlcjtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25maXJtUmV2b2NhdGlvbihzZXJpYWxOdW1iZXJJbkhleCk7XG4gICAgICAgIGF3YWl0IHRoaXMuY3JsU2VydmljZS51cGxvYWRDcmxzKFt7IHNlcmlhbE51bWJlckluSGV4IH1dKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5yZWxvYWQubmV4dCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29uZmlybVJldm9jYXRpb24oc2VyaWFsTnVtYmVyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5tb2RhbFNlcnZpY2UuY29uZmlybShcbiAgICAgIGdldHRleHQoJ1Jldm9rZSBwcm92aXNpb25lZCBjZXJ0aWZpY2F0ZScpLFxuICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICAgIGdldHRleHQoXG4gICAgICAgICAgYFlvdSBhcmUgYWJvdXQgdG8gcmV2b2tlIHByb3Zpc2lvbmVkIGNlcnRpZmljYXRlIHt7IHNlcmlhbE51bWJlciB9fS4gRG8geW91IHdhbnQgdG8gcHJvY2VlZD9gXG4gICAgICAgICksXG4gICAgICAgIHsgc2VyaWFsTnVtYmVyIH1cbiAgICAgICksXG4gICAgICBTdGF0dXMuREFOR0VSLFxuICAgICAgeyBvazogZ2V0dGV4dCgnUmV2b2tlJyksIGNhbmNlbDogZ2V0dGV4dCgnQ2FuY2VsJykgfVxuICAgICk7XG4gIH1cbn1cbiIsIjxjOHktYWN0aW9uLWJhci1pdGVtIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiPlxuICA8YnV0dG9uXG4gICAgY2xhc3M9XCJidG4gYnRuLWxpbmtcIlxuICAgIHRpdGxlPVwie3sgJ1JlbG9hZCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIChjbGljayk9XCJyZWxvYWQubmV4dCgpXCJcbiAgPlxuICAgIDxpXG4gICAgICBjOHlJY29uPVwicmVmcmVzaFwiXG4gICAgICBbbmdDbGFzc109XCJ7ICdpY29uLXNwaW4nOiByZWxvYWRpbmcgfVwiXG4gICAgPjwvaT5cbiAgICB7eyAnUmVsb2FkJyB8IHRyYW5zbGF0ZSB9fVxuICA8L2J1dHRvbj5cbjwvYzh5LWFjdGlvbi1iYXItaXRlbT5cblxuPCEtLSBUT0RPOiBBZGQgbGluayB0byB0aGUgbWVudGlvbmVkIGRvY3VtZW50YXRpb24gd2hlbiBpdCdzIGF2YWlsYWJsZSAtLT5cbjxjOHktdWktZW1wdHktc3RhdGVcbiAgW2ljb25dPVwiJ2NlcnRpZmljYXRlJ1wiXG4gIFt0aXRsZV09XCInTm8gcHJvdmlzaW9uZWQgY2VydGlmaWNhdGVzIHRvIGRpc3BsYXkuJyB8IHRyYW5zbGF0ZVwiXG4gICpuZ0lmPVwiKHByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzIHwgYXN5bmMpPy5sZW5ndGggPT09IDBcIlxuPjwvYzh5LXVpLWVtcHR5LXN0YXRlPlxuXG48ZGl2XG4gIFtuZ1N0eWxlXT1cInsgd2lkdGg6ICc1MCUnIH1cIlxuICAqbmdJZj1cIihwcm92aXNpb25lZENlcnRpZmljYXRlcyB8IGFzeW5jKT8ubGVuZ3RoID4gMFwiXG4+XG4gIDxkaXYgY2xhc3M9XCJiZy1sZXZlbC0wXCI+XG4gICAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIHNlcGFyYXRvclwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImNhcmQtdGl0bGVcIlxuICAgICAgICB0cmFuc2xhdGVcbiAgICAgID5cbiAgICAgICAgUHJvdmlzaW9uZWQgY2VydGlmaWNhdGVzXG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwicC0xNlwiPlxuICAgICAgPGM4eS1saXN0LWdyb3VwIGNsYXNzPVwibS1iLTI0XCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cInBhZ2Utc3RpY2t5LWhlYWRlciBoaWRkZW4teHMgYzh5LWxpc3RfX2l0ZW1cIlxuICAgICAgICAgIHN0eWxlPVwiZGlzcGxheTogYmxvY2sgIWltcG9ydGFudFwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW1fX2Jsb2NrXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW1fX2JvZHlcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtZmxleC02MFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtNVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCIge3sgJ1NlcmlhbCBOby4nIHwgdHJhbnNsYXRlIH19IFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdTZXJpYWwgTm8uJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtNlwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyAnRXhwaXJhdGlvbiBkYXRlJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdFeHBpcmF0aW9uIGRhdGUnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC0xXCI+PC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxjOHktbGlcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgcHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZSBvZiBwcm92aXNpb25lZENlcnRpZmljYXRlcyB8IGFzeW5jOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxjOHktbGktYm9keSBjbGFzcz1cImNvbnRlbnQtZmxleC02MFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC01XCI+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgICAgICAgIHRpdGxlPVwie3sgJ1NlcmlhbCBOby4nIHwgdHJhbnNsYXRlIH19OiB7eyBwcm92aXNpb25lZENlcnRpZmljYXRlLnNlcmlhbE51bWJlciB9fVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsIG0tdC04IG0tci04IHZpc2libGUteHMtaW5saW5lXCJcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIFNlcmlhbCBOby5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAge3sgcHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZS5zZXJpYWxOdW1iZXIgfX1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC02XCI+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgICAgICAgIHRpdGxlPVwie3sgJ0V4cGlyYXRpb24gZGF0ZScgfCB0cmFuc2xhdGUgfX06IHt7XG4gICAgICAgICAgICAgICAgICBwcm92aXNpb25lZENlcnRpZmljYXRlLnZhbGlkVGlsbCB8IGM4eURhdGVcbiAgICAgICAgICAgICAgICB9fVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsIG0tdC04IG0tci04IHZpc2libGUteHMtaW5saW5lXCJcbiAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIEV4cGlyYXRpb24gZGF0ZVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c21hbGxcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZS52YWxpZFRpbGxcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiaGlnaGxpZ2h0RGVwZW5kaW5nT25FeHBpcmF0aW9uU3RhdHVzKHByb3Zpc2lvbmVkQ2VydGlmaWNhdGUpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm0tci00XCJcbiAgICAgICAgICAgICAgICAgICAgYzh5SWNvbj1cImNhbGVuZGFyXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhaGlnaGxpZ2h0RGVwZW5kaW5nT25FeHBpcmF0aW9uU3RhdHVzKHByb3Zpc2lvbmVkQ2VydGlmaWNhdGUpXCJcbiAgICAgICAgICAgICAgICAgID48L2k+XG4gICAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm0tci00XCJcbiAgICAgICAgICAgICAgICAgICAgYzh5SWNvbj1cIndhcm5pbmdcIlxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImhpZ2hsaWdodERlcGVuZGluZ09uRXhwaXJhdGlvblN0YXR1cyhwcm92aXNpb25lZENlcnRpZmljYXRlKVwiXG4gICAgICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgcHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZS52YWxpZFRpbGwgfCBjOHlEYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTFcIj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kb3QgYnRuLWRvdC0tZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICB0aXRsZT1cInt7ICdSZXZva2UnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwicmV2b2tlUHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZShwcm92aXNpb25lZENlcnRpZmljYXRlKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aSBjOHlJY29uPVwiZGVsZXRlXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvYzh5LWxpLWJvZHk+XG4gICAgICAgIDwvYzh5LWxpPlxuICAgICAgPC9jOHktbGlzdC1ncm91cD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==