UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

64 lines 17.1 kB
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { AddressSpaceService } from './address-space.service'; import { omit } from 'lodash-es'; import * as i0 from "@angular/core"; import * as i1 from "./address-space.service"; import * as i2 from "@angular/common"; import * as i3 from "@c8y/ngx-components"; export class OpcuaAddressSpaceDetailComponent { set node(n) { this._node = n; if (n) { this.setNodeData(n); } else { // remove details from current view this.showDetails = false; } } constructor(addressSpaceService) { this.addressSpaceService = addressSpaceService; this.selected = false; this.showDetails = false; this.toggleAttrDetail = new EventEmitter(); } setNodeData(nodeData) { this.showDetails = true; const { attributes, references } = nodeData; this.nodeDataRef = references; const omitList = [ 'attributes', 'references', 'children', 'currentlyLoadingChildren', 'expanded', 'browsePath', 'relativePath', 'parentNode' ]; this.nodeDataAttr = Object.assign({}, attributes, omit(nodeData, omitList)); } toggleDetail(node) { this.showDetails = !this.showDetails; this.toggleAttrDetail.emit(node); } navigateTo(ancestors) { const nodeNavData = { node: this._node, selectedAncestorIds: ancestors }; this.toggleDetail(this._node); this.addressSpaceService.triggerNodeToOpen(nodeNavData); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OpcuaAddressSpaceDetailComponent, deps: [{ token: i1.AddressSpaceService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: OpcuaAddressSpaceDetailComponent, selector: "opcua-address-space-detail", inputs: { node: "node" }, outputs: { toggleAttrDetail: "toggleAttrDetail" }, ngImport: i0, template: "<div\n class=\"card m-b-4 split-row-2 animated fast pointer-all\"\n [ngClass]=\"{ fadeInRightBig: showDetails, fadeOutRightBig: !showDetails }\"\n>\n <div class=\"card-header separator\">\n <h4>{{ 'Attributes' | translate }}</h4>\n <button\n class=\"close m-l-auto visible-sm visible-xs\"\n title=\"{{ 'Close' | translate }}\"\n (click)=\"toggleDetail(nodeDataAttr)\"\n >\n &times;\n </button>\n </div>\n <div\n class=\"card-inner-scroll\"\n tabindex=\"0\"\n >\n <div\n class=\"card-block\"\n tabindex=\"-1\"\n >\n <table class=\"table table-striped table-condensed\">\n <colgroup>\n <col width=\"50%\" />\n <col width=\"50%\" />\n </colgroup>\n <thead>\n <tr>\n <th>{{ 'Attribute' | translate }}</th>\n <th>{{ 'Value' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of nodeDataAttr | keyvalue\">\n <td>{{ item.key }}</td>\n <td\n class=\"text-break-word\"\n *ngIf=\"item.key === 'absolutePaths'\"\n >\n {{ item.value | json }}\n </td>\n <td\n class=\"text-break-word\"\n *ngIf=\"item.key === 'ancestorNodeIds'\"\n >\n <a\n *ngFor=\"let value of item.value\"\n (click)=\"navigateTo(value)\"\n >\n {{ value | json }}\n </a>\n </td>\n <td *ngIf=\"item.key !== 'absolutePaths' && item.key !== 'ancestorNodeIds'\">\n {{ item.value }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n<div\n class=\"card split-row-2 animated fast pointer-all\"\n style=\"height: calc(50% - 4px)\"\n [ngClass]=\"{ fadeInRightBig: showDetails, fadeOutRightBig: !showDetails }\"\n>\n <div class=\"card-header separator\">\n <h4>{{ 'References' | translate }}</h4>\n </div>\n <div\n class=\"card-inner-scroll\"\n tabindex=\"0\"\n >\n <div\n class=\"card-block\"\n tabindex=\"-1\"\n >\n <table class=\"table table-striped table-condensed\">\n <colgroup>\n <col width=\"50%\" />\n <col width=\"50%\" />\n </colgroup>\n <thead>\n <tr>\n <th>{{ 'Attribute' | translate }}</th>\n <th>{{ 'Value' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of nodeDataRef\">\n <td>{{ item.referenceLabel }}</td>\n <td class=\"text-break-word\">{{ item.targetLabel }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2.JsonPipe, name: "json" }, { kind: "pipe", type: i2.KeyValuePipe, name: "keyvalue" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OpcuaAddressSpaceDetailComponent, decorators: [{ type: Component, args: [{ selector: 'opcua-address-space-detail', template: "<div\n class=\"card m-b-4 split-row-2 animated fast pointer-all\"\n [ngClass]=\"{ fadeInRightBig: showDetails, fadeOutRightBig: !showDetails }\"\n>\n <div class=\"card-header separator\">\n <h4>{{ 'Attributes' | translate }}</h4>\n <button\n class=\"close m-l-auto visible-sm visible-xs\"\n title=\"{{ 'Close' | translate }}\"\n (click)=\"toggleDetail(nodeDataAttr)\"\n >\n &times;\n </button>\n </div>\n <div\n class=\"card-inner-scroll\"\n tabindex=\"0\"\n >\n <div\n class=\"card-block\"\n tabindex=\"-1\"\n >\n <table class=\"table table-striped table-condensed\">\n <colgroup>\n <col width=\"50%\" />\n <col width=\"50%\" />\n </colgroup>\n <thead>\n <tr>\n <th>{{ 'Attribute' | translate }}</th>\n <th>{{ 'Value' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of nodeDataAttr | keyvalue\">\n <td>{{ item.key }}</td>\n <td\n class=\"text-break-word\"\n *ngIf=\"item.key === 'absolutePaths'\"\n >\n {{ item.value | json }}\n </td>\n <td\n class=\"text-break-word\"\n *ngIf=\"item.key === 'ancestorNodeIds'\"\n >\n <a\n *ngFor=\"let value of item.value\"\n (click)=\"navigateTo(value)\"\n >\n {{ value | json }}\n </a>\n </td>\n <td *ngIf=\"item.key !== 'absolutePaths' && item.key !== 'ancestorNodeIds'\">\n {{ item.value }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n<div\n class=\"card split-row-2 animated fast pointer-all\"\n style=\"height: calc(50% - 4px)\"\n [ngClass]=\"{ fadeInRightBig: showDetails, fadeOutRightBig: !showDetails }\"\n>\n <div class=\"card-header separator\">\n <h4>{{ 'References' | translate }}</h4>\n </div>\n <div\n class=\"card-inner-scroll\"\n tabindex=\"0\"\n >\n <div\n class=\"card-block\"\n tabindex=\"-1\"\n >\n <table class=\"table table-striped table-condensed\">\n <colgroup>\n <col width=\"50%\" />\n <col width=\"50%\" />\n </colgroup>\n <thead>\n <tr>\n <th>{{ 'Attribute' | translate }}</th>\n <th>{{ 'Value' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of nodeDataRef\">\n <td>{{ item.referenceLabel }}</td>\n <td class=\"text-break-word\">{{ item.targetLabel }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.AddressSpaceService }], propDecorators: { node: [{ type: Input }], toggleAttrDetail: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BjdWEtYWRkcmVzcy1zcGFjZS1kZXRhaWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvdG9jb2wtb3BjdWEvb3BjdWEtYWRkcmVzcy1zcGFjZS1kZXRhaWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vcHJvdG9jb2wtb3BjdWEvb3BjdWEtYWRkcmVzcy1zcGFjZS1kZXRhaWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQW9CLG1CQUFtQixFQUFzQixNQUFNLHlCQUF5QixDQUFDO0FBQ3BHLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7Ozs7O0FBTWpDLE1BQU0sT0FBTyxnQ0FBZ0M7SUFDM0MsSUFBYSxJQUFJLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDTixJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7YUFBTSxDQUFDO1lBQ04sbUNBQW1DO1lBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBVUQsWUFBb0IsbUJBQXdDO1FBQXhDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFQNUQsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUVWLHFCQUFnQixHQUFtQyxJQUFJLFlBQVksRUFBb0IsQ0FBQztJQUluQyxDQUFDO0lBQ2hFLFdBQVcsQ0FBQyxRQUFRO1FBQ2xCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLE1BQU0sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsUUFBUSxDQUFDO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO1FBQzlCLE1BQU0sUUFBUSxHQUFHO1lBQ2YsWUFBWTtZQUNaLFlBQVk7WUFDWixVQUFVO1lBQ1YsMEJBQTBCO1lBQzFCLFVBQVU7WUFDVixZQUFZO1lBQ1osY0FBYztZQUNkLFlBQVk7U0FDYixDQUFDO1FBQ0YsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELFVBQVUsQ0FBQyxTQUFtQjtRQUM1QixNQUFNLFdBQVcsR0FBdUI7WUFDdEMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLO1lBQ2hCLG1CQUFtQixFQUFFLFNBQVM7U0FDL0IsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUMxRCxDQUFDOytHQWxEVSxnQ0FBZ0M7bUdBQWhDLGdDQUFnQywrSUNSN0MsdXVGQW1HQTs7NEZEM0ZhLGdDQUFnQztrQkFKNUMsU0FBUzsrQkFDRSw0QkFBNEI7d0ZBSXpCLElBQUk7c0JBQWhCLEtBQUs7Z0JBY0ksZ0JBQWdCO3NCQUF6QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFkZHJlc3NTcGFjZU5vZGUsIEFkZHJlc3NTcGFjZVNlcnZpY2UsIE5vZGVOYXZpZ2F0aW9uRGF0YSB9IGZyb20gJy4vYWRkcmVzcy1zcGFjZS5zZXJ2aWNlJztcbmltcG9ydCB7IG9taXQgfSBmcm9tICdsb2Rhc2gtZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvcGN1YS1hZGRyZXNzLXNwYWNlLWRldGFpbCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9vcGN1YS1hZGRyZXNzLXNwYWNlLWRldGFpbC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgT3BjdWFBZGRyZXNzU3BhY2VEZXRhaWxDb21wb25lbnQge1xuICBASW5wdXQoKSBzZXQgbm9kZShuKSB7XG4gICAgdGhpcy5fbm9kZSA9IG47XG4gICAgaWYgKG4pIHtcbiAgICAgIHRoaXMuc2V0Tm9kZURhdGEobik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHJlbW92ZSBkZXRhaWxzIGZyb20gY3VycmVudCB2aWV3XG4gICAgICB0aGlzLnNob3dEZXRhaWxzID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIG5vZGVEYXRhQXR0cjogTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgbm9kZURhdGFSZWY6IG9iamVjdFtdO1xuICBzZWxlY3RlZCA9IGZhbHNlO1xuICBzaG93RGV0YWlscyA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSB0b2dnbGVBdHRyRGV0YWlsOiBFdmVudEVtaXR0ZXI8QWRkcmVzc1NwYWNlTm9kZT4gPSBuZXcgRXZlbnRFbWl0dGVyPEFkZHJlc3NTcGFjZU5vZGU+KCk7XG5cbiAgcHJpdmF0ZSBfbm9kZTogQWRkcmVzc1NwYWNlTm9kZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFkZHJlc3NTcGFjZVNlcnZpY2U6IEFkZHJlc3NTcGFjZVNlcnZpY2UpIHt9XG4gIHNldE5vZGVEYXRhKG5vZGVEYXRhKSB7XG4gICAgdGhpcy5zaG93RGV0YWlscyA9IHRydWU7XG4gICAgY29uc3QgeyBhdHRyaWJ1dGVzLCByZWZlcmVuY2VzIH0gPSBub2RlRGF0YTtcbiAgICB0aGlzLm5vZGVEYXRhUmVmID0gcmVmZXJlbmNlcztcbiAgICBjb25zdCBvbWl0TGlzdCA9IFtcbiAgICAgICdhdHRyaWJ1dGVzJyxcbiAgICAgICdyZWZlcmVuY2VzJyxcbiAgICAgICdjaGlsZHJlbicsXG4gICAgICAnY3VycmVudGx5TG9hZGluZ0NoaWxkcmVuJyxcbiAgICAgICdleHBhbmRlZCcsXG4gICAgICAnYnJvd3NlUGF0aCcsXG4gICAgICAncmVsYXRpdmVQYXRoJyxcbiAgICAgICdwYXJlbnROb2RlJ1xuICAgIF07XG4gICAgdGhpcy5ub2RlRGF0YUF0dHIgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzLCBvbWl0KG5vZGVEYXRhLCBvbWl0TGlzdCkpO1xuICB9XG5cbiAgdG9nZ2xlRGV0YWlsKG5vZGUpIHtcbiAgICB0aGlzLnNob3dEZXRhaWxzID0gIXRoaXMuc2hvd0RldGFpbHM7XG4gICAgdGhpcy50b2dnbGVBdHRyRGV0YWlsLmVtaXQobm9kZSk7XG4gIH1cblxuICBuYXZpZ2F0ZVRvKGFuY2VzdG9yczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBub2RlTmF2RGF0YTogTm9kZU5hdmlnYXRpb25EYXRhID0ge1xuICAgICAgbm9kZTogdGhpcy5fbm9kZSxcbiAgICAgIHNlbGVjdGVkQW5jZXN0b3JJZHM6IGFuY2VzdG9yc1xuICAgIH07XG5cbiAgICB0aGlzLnRvZ2dsZURldGFpbCh0aGlzLl9ub2RlKTtcbiAgICB0aGlzLmFkZHJlc3NTcGFjZVNlcnZpY2UudHJpZ2dlck5vZGVUb09wZW4obm9kZU5hdkRhdGEpO1xuICB9XG59XG4iLCI8ZGl2XG4gIGNsYXNzPVwiY2FyZCBtLWItNCBzcGxpdC1yb3ctMiBhbmltYXRlZCBmYXN0IHBvaW50ZXItYWxsXCJcbiAgW25nQ2xhc3NdPVwieyBmYWRlSW5SaWdodEJpZzogc2hvd0RldGFpbHMsIGZhZGVPdXRSaWdodEJpZzogIXNob3dEZXRhaWxzIH1cIlxuPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgc2VwYXJhdG9yXCI+XG4gICAgPGg0Pnt7ICdBdHRyaWJ1dGVzJyB8IHRyYW5zbGF0ZSB9fTwvaDQ+XG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJjbG9zZSBtLWwtYXV0byB2aXNpYmxlLXNtIHZpc2libGUteHNcIlxuICAgICAgdGl0bGU9XCJ7eyAnQ2xvc2UnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGVEZXRhaWwobm9kZURhdGFBdHRyKVwiXG4gICAgPlxuICAgICAgJnRpbWVzO1xuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY2FyZC1pbm5lci1zY3JvbGxcIlxuICAgIHRhYmluZGV4PVwiMFwiXG4gID5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImNhcmQtYmxvY2tcIlxuICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgPlxuICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc3RyaXBlZCB0YWJsZS1jb25kZW5zZWRcIj5cbiAgICAgICAgPGNvbGdyb3VwPlxuICAgICAgICAgIDxjb2wgd2lkdGg9XCI1MCVcIiAvPlxuICAgICAgICAgIDxjb2wgd2lkdGg9XCI1MCVcIiAvPlxuICAgICAgICA8L2NvbGdyb3VwPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoPnt7ICdBdHRyaWJ1dGUnIHwgdHJhbnNsYXRlIH19PC90aD5cbiAgICAgICAgICAgIDx0aD57eyAnVmFsdWUnIHwgdHJhbnNsYXRlIH19PC90aD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3RoZWFkPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBpdGVtIG9mIG5vZGVEYXRhQXR0ciB8IGtleXZhbHVlXCI+XG4gICAgICAgICAgICA8dGQ+e3sgaXRlbS5rZXkgfX08L3RkPlxuICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1icmVhay13b3JkXCJcbiAgICAgICAgICAgICAgKm5nSWY9XCJpdGVtLmtleSA9PT0gJ2Fic29sdXRlUGF0aHMnXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgaXRlbS52YWx1ZSB8IGpzb24gfX1cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LWJyZWFrLXdvcmRcIlxuICAgICAgICAgICAgICAqbmdJZj1cIml0ZW0ua2V5ID09PSAnYW5jZXN0b3JOb2RlSWRzJ1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHZhbHVlIG9mIGl0ZW0udmFsdWVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJuYXZpZ2F0ZVRvKHZhbHVlKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyB2YWx1ZSB8IGpzb24gfX1cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZCAqbmdJZj1cIml0ZW0ua2V5ICE9PSAnYWJzb2x1dGVQYXRocycgJiYgaXRlbS5rZXkgIT09ICdhbmNlc3Rvck5vZGVJZHMnXCI+XG4gICAgICAgICAgICAgIHt7IGl0ZW0udmFsdWUgfX1cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG48ZGl2XG4gIGNsYXNzPVwiY2FyZCBzcGxpdC1yb3ctMiBhbmltYXRlZCBmYXN0IHBvaW50ZXItYWxsXCJcbiAgc3R5bGU9XCJoZWlnaHQ6IGNhbGMoNTAlIC0gNHB4KVwiXG4gIFtuZ0NsYXNzXT1cInsgZmFkZUluUmlnaHRCaWc6IHNob3dEZXRhaWxzLCBmYWRlT3V0UmlnaHRCaWc6ICFzaG93RGV0YWlscyB9XCJcbj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIHNlcGFyYXRvclwiPlxuICAgIDxoND57eyAnUmVmZXJlbmNlcycgfCB0cmFuc2xhdGUgfX08L2g0PlxuICA8L2Rpdj5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY2FyZC1pbm5lci1zY3JvbGxcIlxuICAgIHRhYmluZGV4PVwiMFwiXG4gID5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImNhcmQtYmxvY2tcIlxuICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgPlxuICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc3RyaXBlZCB0YWJsZS1jb25kZW5zZWRcIj5cbiAgICAgICAgPGNvbGdyb3VwPlxuICAgICAgICAgIDxjb2wgd2lkdGg9XCI1MCVcIiAvPlxuICAgICAgICAgIDxjb2wgd2lkdGg9XCI1MCVcIiAvPlxuICAgICAgICA8L2NvbGdyb3VwPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoPnt7ICdBdHRyaWJ1dGUnIHwgdHJhbnNsYXRlIH19PC90aD5cbiAgICAgICAgICAgIDx0aD57eyAnVmFsdWUnIHwgdHJhbnNsYXRlIH19PC90aD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3RoZWFkPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBpdGVtIG9mIG5vZGVEYXRhUmVmXCI+XG4gICAgICAgICAgICA8dGQ+e3sgaXRlbS5yZWZlcmVuY2VMYWJlbCB9fTwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWJyZWFrLXdvcmRcIj57eyBpdGVtLnRhcmdldExhYmVsIH19PC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==