UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

39 lines 19.4 kB
import { Component, Input, TemplateRef } from '@angular/core'; import { OperationRealtimeService } from '@c8y/ngx-components'; import { OperationsService, OPERATION_STATUS_OPTIONS_MAP } from '@c8y/ngx-components/operations/shared'; import { pipe } from 'rxjs'; import { tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; import * as i2 from "@c8y/ngx-components/operations/shared"; import * as i3 from "@angular/common"; import * as i4 from "ngx-bootstrap/tooltip"; export class OperationsTimelineComponent { constructor(realtime, operationsService) { this.realtime = realtime; this.operationsService = operationsService; this.filterPipe = pipe(tap()); this.footerTemplates = []; this.propertiesToHide = []; this.OPERATION_STATUS_OPTIONS_MAP = OPERATION_STATUS_OPTIONS_MAP; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OperationsTimelineComponent, deps: [{ token: i1.OperationRealtimeService }, { token: i2.OperationsService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: OperationsTimelineComponent, selector: "c8y-operations-timeline", inputs: { operations: "operations", sourceId: "sourceId", filterPipe: "filterPipe", bodyTemplate: "bodyTemplate", footerTemplates: "footerTemplates", propertiesToHide: "propertiesToHide" }, ngImport: i0, template: "<c8y-ui-empty-state\n [icon]=\"'c8y-energy'\"\n [title]=\"'No recent operations found.' | translate\"\n ng-if=\"!operations?.data || !operations?.data?.length\"\n [horizontal]=\"true\"\n></c8y-ui-empty-state>\n<c8y-list-group>\n <c8y-li-timeline\n *c8yFor=\"\n let op of operations;\n pipe: filterPipe;\n realtime: realtime;\n realtimeOptions: { entityOrId: sourceId }\n \"\n >\n {{ op.creationTime | date: 'medium' }}\n <c8y-li\n #li\n (click)=\"li.toggleCollapsed()\"\n >\n <c8y-li-icon>\n <i\n [c8yIcon]=\"OPERATION_STATUS_OPTIONS_MAP[op.status].icon\"\n [tooltip]=\"op.status | translate\"\n container=\"body\"\n [ngClass]=\"OPERATION_STATUS_OPTIONS_MAP[op.status].styleClass\"\n [delay]=\"500\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex text-break-word\">\n <div>\n {{ op.status | translate }}\n <br class=\"visible-xs visible-sm\" />\n <ng-container\n *ngIf=\"bodyTemplate; else defaultBody\"\n [ngTemplateOutlet]=\"bodyTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: op }\"\n ></ng-container>\n <ng-template #defaultBody>\n <small>{{ op.description }}</small>\n </ng-template>\n </div>\n <div\n class=\"m-l-auto showOnHover\"\n *ngIf=\"op.status === 'PENDING'\"\n >\n <button\n class=\"btn btn-dot btn-dot--danger\"\n [attr.aria-label]=\"'Cancel operation' | translate\"\n tooltip=\"{{ 'Cancel operation' | translate }}\"\n placement=\"left\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"$event.stopPropagation(); operationsService.cancel(op)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </div>\n </c8y-li-body>\n\n <c8y-li-collapse>\n <div\n class=\"legend form-block\"\n translate\n >\n Details\n </div>\n <ul class=\"list-unstyled small\">\n <li\n class=\"p-t-4 p-b-4 d-flex separator-bottom\"\n *ngFor=\"let prop of operationsService.getStandardKeys(op) | keyvalue\"\n >\n <label class=\"small m-b-0 m-r-8 a-s-start\">\n {{ prop.value | translate }}\n </label>\n <span class=\"m-l-auto text-break-word\">\n {{ op[prop.key] | translate }}\n </span>\n </li>\n <li\n class=\"p-t-4 p-b-4 d-flex separator-bottom\"\n *ngFor=\"let key of operationsService.getNonStandardKeys(op, propertiesToHide)\"\n >\n <label class=\"small m-b-0 m-r-8 a-s-start\">\n {{ key | humanize | translate }}\n </label>\n <span class=\"m-l-auto text-code\">\n {{ op[key] | json }}\n </span>\n </li>\n </ul>\n <ng-container\n *ngFor=\"let footer of footerTemplates\"\n [ngTemplateOutlet]=\"footer\"\n [ngTemplateOutletContext]=\"{ $implicit: op }\"\n ></ng-container>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-li-timeline>\n</c8y-list-group>\n", dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: i1.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { 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.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i1.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: i1.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: i4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: i3.JsonPipe, name: "json" }, { kind: "pipe", type: i3.DatePipe, name: "date" }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.HumanizePipe, name: "humanize" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OperationsTimelineComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-operations-timeline', template: "<c8y-ui-empty-state\n [icon]=\"'c8y-energy'\"\n [title]=\"'No recent operations found.' | translate\"\n ng-if=\"!operations?.data || !operations?.data?.length\"\n [horizontal]=\"true\"\n></c8y-ui-empty-state>\n<c8y-list-group>\n <c8y-li-timeline\n *c8yFor=\"\n let op of operations;\n pipe: filterPipe;\n realtime: realtime;\n realtimeOptions: { entityOrId: sourceId }\n \"\n >\n {{ op.creationTime | date: 'medium' }}\n <c8y-li\n #li\n (click)=\"li.toggleCollapsed()\"\n >\n <c8y-li-icon>\n <i\n [c8yIcon]=\"OPERATION_STATUS_OPTIONS_MAP[op.status].icon\"\n [tooltip]=\"op.status | translate\"\n container=\"body\"\n [ngClass]=\"OPERATION_STATUS_OPTIONS_MAP[op.status].styleClass\"\n [delay]=\"500\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex text-break-word\">\n <div>\n {{ op.status | translate }}\n <br class=\"visible-xs visible-sm\" />\n <ng-container\n *ngIf=\"bodyTemplate; else defaultBody\"\n [ngTemplateOutlet]=\"bodyTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: op }\"\n ></ng-container>\n <ng-template #defaultBody>\n <small>{{ op.description }}</small>\n </ng-template>\n </div>\n <div\n class=\"m-l-auto showOnHover\"\n *ngIf=\"op.status === 'PENDING'\"\n >\n <button\n class=\"btn btn-dot btn-dot--danger\"\n [attr.aria-label]=\"'Cancel operation' | translate\"\n tooltip=\"{{ 'Cancel operation' | translate }}\"\n placement=\"left\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"$event.stopPropagation(); operationsService.cancel(op)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </div>\n </c8y-li-body>\n\n <c8y-li-collapse>\n <div\n class=\"legend form-block\"\n translate\n >\n Details\n </div>\n <ul class=\"list-unstyled small\">\n <li\n class=\"p-t-4 p-b-4 d-flex separator-bottom\"\n *ngFor=\"let prop of operationsService.getStandardKeys(op) | keyvalue\"\n >\n <label class=\"small m-b-0 m-r-8 a-s-start\">\n {{ prop.value | translate }}\n </label>\n <span class=\"m-l-auto text-break-word\">\n {{ op[prop.key] | translate }}\n </span>\n </li>\n <li\n class=\"p-t-4 p-b-4 d-flex separator-bottom\"\n *ngFor=\"let key of operationsService.getNonStandardKeys(op, propertiesToHide)\"\n >\n <label class=\"small m-b-0 m-r-8 a-s-start\">\n {{ key | humanize | translate }}\n </label>\n <span class=\"m-l-auto text-code\">\n {{ op[key] | json }}\n </span>\n </li>\n </ul>\n <ng-container\n *ngFor=\"let footer of footerTemplates\"\n [ngTemplateOutlet]=\"footer\"\n [ngTemplateOutletContext]=\"{ $implicit: op }\"\n ></ng-container>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-li-timeline>\n</c8y-list-group>\n" }] }], ctorParameters: () => [{ type: i1.OperationRealtimeService }, { type: i2.OperationsService }], propDecorators: { operations: [{ type: Input }], sourceId: [{ type: Input }], filterPipe: [{ type: Input }], bodyTemplate: [{ type: Input }], footerTemplates: [{ type: Input }], propertiesToHide: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9ucy10aW1lbGluZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9vcGVyYXRpb25zL29wZXJhdGlvbnMtdGltZWxpbmUvb3BlcmF0aW9ucy10aW1lbGluZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9vcGVyYXRpb25zL29wZXJhdGlvbnMtdGltZWxpbmUvb3BlcmF0aW9ucy10aW1lbGluZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFOUQsT0FBTyxFQUFtQix3QkFBd0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hGLE9BQU8sRUFDTCxpQkFBaUIsRUFFakIsNEJBQTRCLEVBQzdCLE1BQU0sdUNBQXVDLENBQUM7QUFDL0MsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1QixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQU1yQyxNQUFNLE9BQU8sMkJBQTJCO0lBcUJ0QyxZQUNTLFFBQWtDLEVBQ2xDLGlCQUFvQztRQURwQyxhQUFRLEdBQVIsUUFBUSxDQUEwQjtRQUNsQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBZjdDLGVBQVUsR0FBZ0MsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFNdEQsb0JBQWUsR0FBNEIsRUFBRSxDQUFDO1FBRzlDLHFCQUFnQixHQUFhLEVBQUUsQ0FBQztRQUVoQyxpQ0FBNEIsR0FBb0MsNEJBQTRCLENBQUM7SUFLMUYsQ0FBQzsrR0F4Qk8sMkJBQTJCO21HQUEzQiwyQkFBMkIsNlBDZnhDLG0wR0FzR0E7OzRGRHZGYSwyQkFBMkI7a0JBSnZDLFNBQVM7K0JBQ0UseUJBQXlCOzZIQUtuQyxVQUFVO3NCQURULEtBQUs7Z0JBSU4sUUFBUTtzQkFEUCxLQUFLO2dCQUlOLFVBQVU7c0JBRFQsS0FBSztnQkFJTixZQUFZO3NCQURYLEtBQUs7Z0JBSU4sZUFBZTtzQkFEZCxLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgVGVtcGxhdGVSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElPcGVyYXRpb24sIElSZXN1bHRMaXN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgRm9yT2ZGaWx0ZXJQaXBlLCBPcGVyYXRpb25SZWFsdGltZVNlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7XG4gIE9wZXJhdGlvbnNTZXJ2aWNlLFxuICBPcGVyYXRpb25TdGF0dXNPcHRpb25zTWFwU2hhcmVkLFxuICBPUEVSQVRJT05fU1RBVFVTX09QVElPTlNfTUFQXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvb3BlcmF0aW9ucy9zaGFyZWQnO1xuaW1wb3J0IHsgcGlwZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktb3BlcmF0aW9ucy10aW1lbGluZScsXG4gIHRlbXBsYXRlVXJsOiAnb3BlcmF0aW9ucy10aW1lbGluZS5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9uc1RpbWVsaW5lQ29tcG9uZW50IHtcbiAgQElucHV0KClcbiAgb3BlcmF0aW9uczogSVJlc3VsdExpc3Q8SU9wZXJhdGlvbj47XG5cbiAgQElucHV0KClcbiAgc291cmNlSWQ6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBmaWx0ZXJQaXBlOiBGb3JPZkZpbHRlclBpcGU8SU9wZXJhdGlvbj4gPSBwaXBlKHRhcCgpKTtcblxuICBASW5wdXQoKVxuICBib2R5VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgQElucHV0KClcbiAgZm9vdGVyVGVtcGxhdGVzOiBBcnJheTxUZW1wbGF0ZVJlZjxhbnk+PiA9IFtdO1xuXG4gIEBJbnB1dCgpXG4gIHByb3BlcnRpZXNUb0hpZGU6IHN0cmluZ1tdID0gW107XG5cbiAgT1BFUkFUSU9OX1NUQVRVU19PUFRJT05TX01BUDogT3BlcmF0aW9uU3RhdHVzT3B0aW9uc01hcFNoYXJlZCA9IE9QRVJBVElPTl9TVEFUVVNfT1BUSU9OU19NQVA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWx0aW1lOiBPcGVyYXRpb25SZWFsdGltZVNlcnZpY2UsXG4gICAgcHVibGljIG9wZXJhdGlvbnNTZXJ2aWNlOiBPcGVyYXRpb25zU2VydmljZVxuICApIHt9XG59XG4iLCI8Yzh5LXVpLWVtcHR5LXN0YXRlXG4gIFtpY29uXT1cIidjOHktZW5lcmd5J1wiXG4gIFt0aXRsZV09XCInTm8gcmVjZW50IG9wZXJhdGlvbnMgZm91bmQuJyB8IHRyYW5zbGF0ZVwiXG4gIG5nLWlmPVwiIW9wZXJhdGlvbnM/LmRhdGEgfHwgIW9wZXJhdGlvbnM/LmRhdGE/Lmxlbmd0aFwiXG4gIFtob3Jpem9udGFsXT1cInRydWVcIlxuPjwvYzh5LXVpLWVtcHR5LXN0YXRlPlxuPGM4eS1saXN0LWdyb3VwPlxuICA8Yzh5LWxpLXRpbWVsaW5lXG4gICAgKmM4eUZvcj1cIlxuICAgICAgbGV0IG9wIG9mIG9wZXJhdGlvbnM7XG4gICAgICBwaXBlOiBmaWx0ZXJQaXBlO1xuICAgICAgcmVhbHRpbWU6IHJlYWx0aW1lO1xuICAgICAgcmVhbHRpbWVPcHRpb25zOiB7IGVudGl0eU9ySWQ6IHNvdXJjZUlkIH1cbiAgICBcIlxuICA+XG4gICAge3sgb3AuY3JlYXRpb25UaW1lIHwgZGF0ZTogJ21lZGl1bScgfX1cbiAgICA8Yzh5LWxpXG4gICAgICAjbGlcbiAgICAgIChjbGljayk9XCJsaS50b2dnbGVDb2xsYXBzZWQoKVwiXG4gICAgPlxuICAgICAgPGM4eS1saS1pY29uPlxuICAgICAgICA8aVxuICAgICAgICAgIFtjOHlJY29uXT1cIk9QRVJBVElPTl9TVEFUVVNfT1BUSU9OU19NQVBbb3Auc3RhdHVzXS5pY29uXCJcbiAgICAgICAgICBbdG9vbHRpcF09XCJvcC5zdGF0dXMgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgIGNvbnRhaW5lcj1cImJvZHlcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cIk9QRVJBVElPTl9TVEFUVVNfT1BUSU9OU19NQVBbb3Auc3RhdHVzXS5zdHlsZUNsYXNzXCJcbiAgICAgICAgICBbZGVsYXldPVwiNTAwXCJcbiAgICAgICAgPjwvaT5cbiAgICAgIDwvYzh5LWxpLWljb24+XG4gICAgICA8Yzh5LWxpLWJvZHk+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdGV4dC1icmVhay13b3JkXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIHt7IG9wLnN0YXR1cyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPGJyIGNsYXNzPVwidmlzaWJsZS14cyB2aXNpYmxlLXNtXCIgLz5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCJib2R5VGVtcGxhdGU7IGVsc2UgZGVmYXVsdEJvZHlcIlxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJib2R5VGVtcGxhdGVcIlxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IG9wIH1cIlxuICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0Qm9keT5cbiAgICAgICAgICAgICAgPHNtYWxsPnt7IG9wLmRlc2NyaXB0aW9uIH19PC9zbWFsbD5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJtLWwtYXV0byBzaG93T25Ib3ZlclwiXG4gICAgICAgICAgICAqbmdJZj1cIm9wLnN0YXR1cyA9PT0gJ1BFTkRJTkcnXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kb3QgYnRuLWRvdC0tZGFuZ2VyXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInQ2FuY2VsIG9wZXJhdGlvbicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICB0b29sdGlwPVwie3sgJ0NhbmNlbCBvcGVyYXRpb24nIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgcGxhY2VtZW50PVwibGVmdFwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBbZGVsYXldPVwiNTAwXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb3BlcmF0aW9uc1NlcnZpY2UuY2FuY2VsKG9wKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGM4eUljb249XCJtaW51cy1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2M4eS1saS1ib2R5PlxuXG4gICAgICA8Yzh5LWxpLWNvbGxhcHNlPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJsZWdlbmQgZm9ybS1ibG9ja1wiXG4gICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgID5cbiAgICAgICAgICBEZXRhaWxzXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LXVuc3R5bGVkIHNtYWxsXCI+XG4gICAgICAgICAgPGxpXG4gICAgICAgICAgICBjbGFzcz1cInAtdC00IHAtYi00IGQtZmxleCBzZXBhcmF0b3ItYm90dG9tXCJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwcm9wIG9mIG9wZXJhdGlvbnNTZXJ2aWNlLmdldFN0YW5kYXJkS2V5cyhvcCkgfCBrZXl2YWx1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwic21hbGwgbS1iLTAgbS1yLTggYS1zLXN0YXJ0XCI+XG4gICAgICAgICAgICAgIHt7IHByb3AudmFsdWUgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm0tbC1hdXRvIHRleHQtYnJlYWstd29yZFwiPlxuICAgICAgICAgICAgICB7eyBvcFtwcm9wLmtleV0gfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDxsaVxuICAgICAgICAgICAgY2xhc3M9XCJwLXQtNCBwLWItNCBkLWZsZXggc2VwYXJhdG9yLWJvdHRvbVwiXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIG9wZXJhdGlvbnNTZXJ2aWNlLmdldE5vblN0YW5kYXJkS2V5cyhvcCwgcHJvcGVydGllc1RvSGlkZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInNtYWxsIG0tYi0wIG0tci04IGEtcy1zdGFydFwiPlxuICAgICAgICAgICAgICB7eyBrZXkgfCBodW1hbml6ZSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibS1sLWF1dG8gdGV4dC1jb2RlXCI+XG4gICAgICAgICAgICAgIHt7IG9wW2tleV0gfCBqc29uIH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgPC91bD5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ0Zvcj1cImxldCBmb290ZXIgb2YgZm9vdGVyVGVtcGxhdGVzXCJcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJmb290ZXJcIlxuICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogb3AgfVwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvYzh5LWxpLWNvbGxhcHNlPlxuICAgIDwvYzh5LWxpPlxuICA8L2M4eS1saS10aW1lbGluZT5cbjwvYzh5LWxpc3QtZ3JvdXA+XG4iXX0=