UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

120 lines 29.5 kB
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { gettext } from '@c8y/ngx-components'; import { TranslateService } from '@ngx-translate/core'; import { cloneDeep } from 'lodash-es'; import { ContextDashboardService } from '../context-dashboard.service'; import * as i0 from "@angular/core"; import * as i1 from "@ngx-translate/core"; import * as i2 from "../context-dashboard.service"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/common"; export class DashboardVersionHistoryComponent { constructor(translateService, contextDashboardService) { this.translateService = translateService; this.contextDashboardService = contextDashboardService; this.dashboardHistory = []; this.onRevert = new EventEmitter(); this.dashboardHistoryExtended = []; this.restoredDashboardMessage = gettext('Restored dashboard state from {{ restoredStateCreationDate }}'); this.versionHistoryLimitMessage = gettext('Store up to {{ versionHistoryLimit }} dashboard versions. Any additional versions will replace/delete older ones'); } ngOnInit() { this.generateDashboardHistoryDescription(); } generateDashboardHistoryDescription() { for (const dashboard of this.dashboardHistory) { const copiedDashboard = { ...dashboard }; let settingChangesMessage = ''; let assetModelMessage = ''; let widgetChanges = ''; if (dashboard.historyDescription.changeType === 'create') { copiedDashboard.descriptionText = this.translateService.instant(this.isReport ? gettext('Report created.') : gettext('Dashboard created.')); this.dashboardHistoryExtended.push(copiedDashboard); continue; } if (dashboard.historyDescription.changeType === 'reset') { copiedDashboard.descriptionText = this.translateService.instant(gettext('Reset widgets')); this.dashboardHistoryExtended.push(copiedDashboard); continue; } const isDashboardUpdated = dashboard.historyDescription.dashboardSettingChanges?.length > 0; if (isDashboardUpdated) { const translatedValuesChanged = dashboard.historyDescription.dashboardSettingChanges .map(val => this.translateService.instant(val)) .join(', '); settingChangesMessage = this.translateService.instant(this.isReport ? gettext('Report updated: {{ values }}.') : gettext('Dashboard updated: {{ values }}.'), { values: translatedValuesChanged }); } const isDeviceDashboard = dashboard.historyDescription.deviceType != null && !this.isReport; if (isDeviceDashboard) { assetModelMessage = this.translateService.instant(dashboard.historyDescription.deviceType ? gettext('Dashboard asset model has been enabled.') : gettext('Dashboard asset model has been disabled.')); } if (dashboard.historyDescription.widgetChanges) { for (const change in dashboard.historyDescription.widgetChanges) { const widgetList = dashboard.historyDescription.widgetChanges[change]; if (!widgetList) { continue; } const translatedWidgetList = dashboard.translateWidgetTitle ? widgetList.map(widget => this.translateService.instant(widget)) : widgetList; switch (change) { case 'added': widgetChanges = widgetChanges + this.translateService.instant(gettext('Added widgets: {{ widgetList }}. '), { widgetList: `"${translatedWidgetList.join('", "')}"` }); break; case 'removed': widgetChanges = widgetChanges + this.translateService.instant(gettext('Removed widgets: {{ widgetList }}. '), { widgetList: `"${translatedWidgetList.join('", "')}"` }); break; case 'config': widgetChanges = widgetChanges + this.translateService.instant(gettext('Updated widgets: {{ widgetList }}. '), { widgetList: `"${translatedWidgetList.join('", "')}"` }); break; case 'arrangement': widgetChanges = widgetChanges + this.translateService.instant(gettext('Rearranged widgets: {{ widgetList }}. '), { widgetList: `"${translatedWidgetList.join('", "')}"` }); break; default: break; } } } copiedDashboard.descriptionText = `${settingChangesMessage} ${assetModelMessage} ${widgetChanges}`; this.dashboardHistoryExtended.push(copiedDashboard); } } revertDashboard(dashboard) { const newDashboard = cloneDeep(dashboard); newDashboard.historyDescription.restored = dashboard.created; this.onRevert.emit(newDashboard); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardVersionHistoryComponent, deps: [{ token: i1.TranslateService }, { token: i2.ContextDashboardService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DashboardVersionHistoryComponent, selector: "c8y-dashboard-version-history", inputs: { dashboardHistory: "dashboardHistory", isReport: "isReport" }, outputs: { onRevert: "onRevert" }, ngImport: i0, template: "<div class=\"bg-component p-t-8 p-b-8 separator-bottom text-center\">\n <i\n class=\"text-info m-r-4\"\n c8yIcon=\"info\"\n ></i>\n {{\n versionHistoryLimitMessage\n | translate: { versionHistoryLimit: contextDashboardService.VERSION_HISTORY_SIZE_LIMIT }\n }}\n</div>\n<c8y-list-group class=\"p-t-24 p-b-24\">\n <c8y-li-timeline\n *ngFor=\"let dashboard of dashboardHistoryExtended; index as i\"\n [ngClass]=\"{ active: i === 0 }\"\n >\n {{ dashboard.created | date: 'mediumDate' }}\n {{ dashboard.created | date: 'shortTime' }}\n <c8y-li data-cy=\"c8y-dashboard-version-history--history-row\">\n <c8y-li-body>\n <div class=\"d-flex a-i-start\">\n <div class=\"flex-grow\">\n <span\n class=\"text-truncate-wrap\"\n title=\"{{ dashboard.descriptionText }}\"\n data-cy=\"c8y-dashboard-version-history--history-title\"\n >\n {{ dashboard.descriptionText }}\n {{\n dashboard.historyDescription.restored\n ? (restoredDashboardMessage\n | translate\n : {\n restoredStateCreationDate: dashboard.historyDescription.restored | c8yDate\n })\n : ''\n }}\n </span>\n <small\n class=\"text-muted\"\n title=\"{{ 'by`user`' | translate }} {{ dashboard.author }}\"\n *ngIf=\"dashboard.author\"\n >\n <div class=\"icon-flex\">\n <i c8yIcon=\"c8y-user\"></i>\n {{ dashboard.author }}\n </div>\n </small>\n </div>\n\n <span\n class=\"label label-primary m-l-auto\"\n title=\"{{ 'The last saved status of the dashboard' | translate }}\"\n *ngIf=\"i === 0\"\n >\n {{ 'Current`dashboard status`' | translate }}\n </span>\n <span\n class=\"m-l-auto showOnHover\"\n *ngIf=\"dashboardHistoryExtended.length > 1 && i > 0\"\n >\n <button\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Restore the dashboard to this status' | translate }}\"\n type=\"button\"\n (click)=\"revertDashboard(dashboard)\"\n >\n {{ 'Restore' | translate }}\n </button>\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n</c8y-list-group>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i4.DatePipe, name: "date" }, { kind: "pipe", type: i3.DatePipe, name: "c8yDate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardVersionHistoryComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-dashboard-version-history', template: "<div class=\"bg-component p-t-8 p-b-8 separator-bottom text-center\">\n <i\n class=\"text-info m-r-4\"\n c8yIcon=\"info\"\n ></i>\n {{\n versionHistoryLimitMessage\n | translate: { versionHistoryLimit: contextDashboardService.VERSION_HISTORY_SIZE_LIMIT }\n }}\n</div>\n<c8y-list-group class=\"p-t-24 p-b-24\">\n <c8y-li-timeline\n *ngFor=\"let dashboard of dashboardHistoryExtended; index as i\"\n [ngClass]=\"{ active: i === 0 }\"\n >\n {{ dashboard.created | date: 'mediumDate' }}\n {{ dashboard.created | date: 'shortTime' }}\n <c8y-li data-cy=\"c8y-dashboard-version-history--history-row\">\n <c8y-li-body>\n <div class=\"d-flex a-i-start\">\n <div class=\"flex-grow\">\n <span\n class=\"text-truncate-wrap\"\n title=\"{{ dashboard.descriptionText }}\"\n data-cy=\"c8y-dashboard-version-history--history-title\"\n >\n {{ dashboard.descriptionText }}\n {{\n dashboard.historyDescription.restored\n ? (restoredDashboardMessage\n | translate\n : {\n restoredStateCreationDate: dashboard.historyDescription.restored | c8yDate\n })\n : ''\n }}\n </span>\n <small\n class=\"text-muted\"\n title=\"{{ 'by`user`' | translate }} {{ dashboard.author }}\"\n *ngIf=\"dashboard.author\"\n >\n <div class=\"icon-flex\">\n <i c8yIcon=\"c8y-user\"></i>\n {{ dashboard.author }}\n </div>\n </small>\n </div>\n\n <span\n class=\"label label-primary m-l-auto\"\n title=\"{{ 'The last saved status of the dashboard' | translate }}\"\n *ngIf=\"i === 0\"\n >\n {{ 'Current`dashboard status`' | translate }}\n </span>\n <span\n class=\"m-l-auto showOnHover\"\n *ngIf=\"dashboardHistoryExtended.length > 1 && i > 0\"\n >\n <button\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Restore the dashboard to this status' | translate }}\"\n type=\"button\"\n (click)=\"revertDashboard(dashboard)\"\n >\n {{ 'Restore' | translate }}\n </button>\n </span>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n</c8y-list-group>\n" }] }], ctorParameters: () => [{ type: i1.TranslateService }, { type: i2.ContextDashboardService }], propDecorators: { dashboardHistory: [{ type: Input }], isReport: [{ type: Input }], onRevert: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLXZlcnNpb24taGlzdG9yeS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb250ZXh0LWRhc2hib2FyZC9kYXNoYm9hcmQtc2V0dGluZ3MvZGFzaGJvYXJkLXZlcnNpb24taGlzdG9yeS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb250ZXh0LWRhc2hib2FyZC9kYXNoYm9hcmQtc2V0dGluZ3MvZGFzaGJvYXJkLXZlcnNpb24taGlzdG9yeS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUU5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7QUFNdkUsTUFBTSxPQUFPLGdDQUFnQztJQVkzQyxZQUNVLGdCQUFrQyxFQUNuQyx1QkFBZ0Q7UUFEL0MscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNuQyw0QkFBdUIsR0FBdkIsdUJBQXVCLENBQXlCO1FBYmhELHFCQUFnQixHQUF1QixFQUFFLENBQUM7UUFFekMsYUFBUSxHQUFtQyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3hFLDZCQUF3QixHQUF3RCxFQUFFLENBQUM7UUFDbkYsNkJBQXdCLEdBQUcsT0FBTyxDQUNoQywrREFBK0QsQ0FDaEUsQ0FBQztRQUNGLCtCQUEwQixHQUFHLE9BQU8sQ0FDbEMsa0hBQWtILENBQ25ILENBQUM7SUFLQyxDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRCxtQ0FBbUM7UUFDakMsS0FBSyxNQUFNLFNBQVMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUM5QyxNQUFNLGVBQWUsR0FBb0QsRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO1lBRTFGLElBQUkscUJBQXFCLEdBQUcsRUFBRSxDQUFDO1lBQy9CLElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1lBQzNCLElBQUksYUFBYSxHQUFHLEVBQUUsQ0FBQztZQUV2QixJQUFJLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3pELGVBQWUsQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUMzRSxDQUFDO2dCQUNGLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ3BELFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxTQUFTLENBQUMsa0JBQWtCLENBQUMsVUFBVSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUN4RCxlQUFlLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBQzFGLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ3BELFNBQVM7WUFDWCxDQUFDO1lBRUQsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsdUJBQXVCLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUM1RixJQUFJLGtCQUFrQixFQUFFLENBQUM7Z0JBQ3ZCLE1BQU0sdUJBQXVCLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLHVCQUF1QjtxQkFDakYsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztxQkFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNkLHFCQUFxQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQ25ELElBQUksQ0FBQyxRQUFRO29CQUNYLENBQUMsQ0FBQyxPQUFPLENBQUMsK0JBQStCLENBQUM7b0JBQzFDLENBQUMsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLENBQUMsRUFDL0MsRUFBRSxNQUFNLEVBQUUsdUJBQXVCLEVBQUUsQ0FDcEMsQ0FBQztZQUNKLENBQUM7WUFFRCxNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUM1RixJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3RCLGlCQUFpQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQy9DLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVO29CQUNyQyxDQUFDLENBQUMsT0FBTyxDQUFDLHlDQUF5QyxDQUFDO29CQUNwRCxDQUFDLENBQUMsT0FBTyxDQUFDLDBDQUEwQyxDQUFDLENBQ3hELENBQUM7WUFDSixDQUFDO1lBRUQsSUFBSSxTQUFTLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQy9DLEtBQUssTUFBTSxNQUFNLElBQUksU0FBUyxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUNoRSxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN0RSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQ2hCLFNBQVM7b0JBQ1gsQ0FBQztvQkFDRCxNQUFNLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxvQkFBb0I7d0JBQ3pELENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDakUsQ0FBQyxDQUFDLFVBQVUsQ0FBQztvQkFDZixRQUFRLE1BQU0sRUFBRSxDQUFDO3dCQUNmLEtBQUssT0FBTzs0QkFDVixhQUFhO2dDQUNYLGFBQWE7b0NBQ2IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUNBQW1DLENBQUMsRUFBRTt3Q0FDMUUsVUFBVSxFQUFFLElBQUksb0JBQW9CLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHO3FDQUNyRCxDQUFDLENBQUM7NEJBQ0wsTUFBTTt3QkFDUixLQUFLLFNBQVM7NEJBQ1osYUFBYTtnQ0FDWCxhQUFhO29DQUNiLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHFDQUFxQyxDQUFDLEVBQUU7d0NBQzVFLFVBQVUsRUFBRSxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRztxQ0FDckQsQ0FBQyxDQUFDOzRCQUNMLE1BQU07d0JBQ1IsS0FBSyxRQUFROzRCQUNYLGFBQWE7Z0NBQ1gsYUFBYTtvQ0FDYixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxxQ0FBcUMsQ0FBQyxFQUFFO3dDQUM1RSxVQUFVLEVBQUUsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUc7cUNBQ3JELENBQUMsQ0FBQzs0QkFDTCxNQUFNO3dCQUNSLEtBQUssYUFBYTs0QkFDaEIsYUFBYTtnQ0FDWCxhQUFhO29DQUNiLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHdDQUF3QyxDQUFDLEVBQUU7d0NBQy9FLFVBQVUsRUFBRSxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRztxQ0FDckQsQ0FBQyxDQUFDOzRCQUNMLE1BQU07d0JBQ1I7NEJBQ0UsTUFBTTtvQkFDVixDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBRUQsZUFBZSxDQUFDLGVBQWUsR0FBRyxHQUFHLHFCQUFxQixJQUFJLGlCQUFpQixJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ25HLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsU0FBMkI7UUFDekMsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFDLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUM3RCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQXJIVSxnQ0FBZ0M7bUdBQWhDLGdDQUFnQyxnTENYN0MsMGhGQTBFQTs7NEZEL0RhLGdDQUFnQztrQkFKNUMsU0FBUzsrQkFDRSwrQkFBK0I7MkhBSWhDLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNJLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQ29udGV4dERhc2hib2FyZCB9IGZyb20gJy4uL2NvbnRleHQtZGFzaGJvYXJkLm1vZGVsJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBDb250ZXh0RGFzaGJvYXJkU2VydmljZSB9IGZyb20gJy4uL2NvbnRleHQtZGFzaGJvYXJkLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktZGFzaGJvYXJkLXZlcnNpb24taGlzdG9yeScsXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXNoYm9hcmQtdmVyc2lvbi1oaXN0b3J5LmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBEYXNoYm9hcmRWZXJzaW9uSGlzdG9yeUNvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGRhc2hib2FyZEhpc3Rvcnk6IENvbnRleHREYXNoYm9hcmRbXSA9IFtdO1xuICBASW5wdXQoKSBpc1JlcG9ydDogYm9vbGVhbjtcbiAgQE91dHB1dCgpIG9uUmV2ZXJ0OiBFdmVudEVtaXR0ZXI8Q29udGV4dERhc2hib2FyZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIGRhc2hib2FyZEhpc3RvcnlFeHRlbmRlZDogKENvbnRleHREYXNoYm9hcmQgJiB7IGRlc2NyaXB0aW9uVGV4dD86IHN0cmluZyB9KVtdID0gW107XG4gIHJlc3RvcmVkRGFzaGJvYXJkTWVzc2FnZSA9IGdldHRleHQoXG4gICAgJ1Jlc3RvcmVkIGRhc2hib2FyZCBzdGF0ZSBmcm9tIHt7IHJlc3RvcmVkU3RhdGVDcmVhdGlvbkRhdGUgfX0nXG4gICk7XG4gIHZlcnNpb25IaXN0b3J5TGltaXRNZXNzYWdlID0gZ2V0dGV4dChcbiAgICAnU3RvcmUgdXAgdG8ge3sgdmVyc2lvbkhpc3RvcnlMaW1pdCB9fSBkYXNoYm9hcmQgdmVyc2lvbnMuIEFueSBhZGRpdGlvbmFsIHZlcnNpb25zIHdpbGwgcmVwbGFjZS9kZWxldGUgb2xkZXIgb25lcydcbiAgKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHVibGljIGNvbnRleHREYXNoYm9hcmRTZXJ2aWNlOiBDb250ZXh0RGFzaGJvYXJkU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5nZW5lcmF0ZURhc2hib2FyZEhpc3RvcnlEZXNjcmlwdGlvbigpO1xuICB9XG5cbiAgZ2VuZXJhdGVEYXNoYm9hcmRIaXN0b3J5RGVzY3JpcHRpb24oKSB7XG4gICAgZm9yIChjb25zdCBkYXNoYm9hcmQgb2YgdGhpcy5kYXNoYm9hcmRIaXN0b3J5KSB7XG4gICAgICBjb25zdCBjb3BpZWREYXNoYm9hcmQ6IENvbnRleHREYXNoYm9hcmQgJiB7IGRlc2NyaXB0aW9uVGV4dD86IHN0cmluZyB9ID0geyAuLi5kYXNoYm9hcmQgfTtcblxuICAgICAgbGV0IHNldHRpbmdDaGFuZ2VzTWVzc2FnZSA9ICcnO1xuICAgICAgbGV0IGFzc2V0TW9kZWxNZXNzYWdlID0gJyc7XG4gICAgICBsZXQgd2lkZ2V0Q2hhbmdlcyA9ICcnO1xuXG4gICAgICBpZiAoZGFzaGJvYXJkLmhpc3RvcnlEZXNjcmlwdGlvbi5jaGFuZ2VUeXBlID09PSAnY3JlYXRlJykge1xuICAgICAgICBjb3BpZWREYXNoYm9hcmQuZGVzY3JpcHRpb25UZXh0ID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICAgICAgdGhpcy5pc1JlcG9ydCA/IGdldHRleHQoJ1JlcG9ydCBjcmVhdGVkLicpIDogZ2V0dGV4dCgnRGFzaGJvYXJkIGNyZWF0ZWQuJylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmRIaXN0b3J5RXh0ZW5kZWQucHVzaChjb3BpZWREYXNoYm9hcmQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXNoYm9hcmQuaGlzdG9yeURlc2NyaXB0aW9uLmNoYW5nZVR5cGUgPT09ICdyZXNldCcpIHtcbiAgICAgICAgY29waWVkRGFzaGJvYXJkLmRlc2NyaXB0aW9uVGV4dCA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGdldHRleHQoJ1Jlc2V0IHdpZGdldHMnKSk7XG4gICAgICAgIHRoaXMuZGFzaGJvYXJkSGlzdG9yeUV4dGVuZGVkLnB1c2goY29waWVkRGFzaGJvYXJkKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlzRGFzaGJvYXJkVXBkYXRlZCA9IGRhc2hib2FyZC5oaXN0b3J5RGVzY3JpcHRpb24uZGFzaGJvYXJkU2V0dGluZ0NoYW5nZXM/Lmxlbmd0aCA+IDA7XG4gICAgICBpZiAoaXNEYXNoYm9hcmRVcGRhdGVkKSB7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0ZWRWYWx1ZXNDaGFuZ2VkID0gZGFzaGJvYXJkLmhpc3RvcnlEZXNjcmlwdGlvbi5kYXNoYm9hcmRTZXR0aW5nQ2hhbmdlc1xuICAgICAgICAgIC5tYXAodmFsID0+IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KHZhbCkpXG4gICAgICAgICAgLmpvaW4oJywgJyk7XG4gICAgICAgIHNldHRpbmdDaGFuZ2VzTWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICAgIHRoaXMuaXNSZXBvcnRcbiAgICAgICAgICAgID8gZ2V0dGV4dCgnUmVwb3J0IHVwZGF0ZWQ6IHt7IHZhbHVlcyB9fS4nKVxuICAgICAgICAgICAgOiBnZXR0ZXh0KCdEYXNoYm9hcmQgdXBkYXRlZDoge3sgdmFsdWVzIH19LicpLFxuICAgICAgICAgIHsgdmFsdWVzOiB0cmFuc2xhdGVkVmFsdWVzQ2hhbmdlZCB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlzRGV2aWNlRGFzaGJvYXJkID0gZGFzaGJvYXJkLmhpc3RvcnlEZXNjcmlwdGlvbi5kZXZpY2VUeXBlICE9IG51bGwgJiYgIXRoaXMuaXNSZXBvcnQ7XG4gICAgICBpZiAoaXNEZXZpY2VEYXNoYm9hcmQpIHtcbiAgICAgICAgYXNzZXRNb2RlbE1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgICBkYXNoYm9hcmQuaGlzdG9yeURlc2NyaXB0aW9uLmRldmljZVR5cGVcbiAgICAgICAgICAgID8gZ2V0dGV4dCgnRGFzaGJvYXJkIGFzc2V0IG1vZGVsIGhhcyBiZWVuIGVuYWJsZWQuJylcbiAgICAgICAgICAgIDogZ2V0dGV4dCgnRGFzaGJvYXJkIGFzc2V0IG1vZGVsIGhhcyBiZWVuIGRpc2FibGVkLicpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXNoYm9hcmQuaGlzdG9yeURlc2NyaXB0aW9uLndpZGdldENoYW5nZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBjaGFuZ2UgaW4gZGFzaGJvYXJkLmhpc3RvcnlEZXNjcmlwdGlvbi53aWRnZXRDaGFuZ2VzKSB7XG4gICAgICAgICAgY29uc3Qgd2lkZ2V0TGlzdCA9IGRhc2hib2FyZC5oaXN0b3J5RGVzY3JpcHRpb24ud2lkZ2V0Q2hhbmdlc1tjaGFuZ2VdO1xuICAgICAgICAgIGlmICghd2lkZ2V0TGlzdCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHRyYW5zbGF0ZWRXaWRnZXRMaXN0ID0gZGFzaGJvYXJkLnRyYW5zbGF0ZVdpZGdldFRpdGxlXG4gICAgICAgICAgICA/IHdpZGdldExpc3QubWFwKHdpZGdldCA9PiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCh3aWRnZXQpKVxuICAgICAgICAgICAgOiB3aWRnZXRMaXN0O1xuICAgICAgICAgIHN3aXRjaCAoY2hhbmdlKSB7XG4gICAgICAgICAgICBjYXNlICdhZGRlZCc6XG4gICAgICAgICAgICAgIHdpZGdldENoYW5nZXMgPVxuICAgICAgICAgICAgICAgIHdpZGdldENoYW5nZXMgK1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGdldHRleHQoJ0FkZGVkIHdpZGdldHM6IHt7IHdpZGdldExpc3QgfX0uICcpLCB7XG4gICAgICAgICAgICAgICAgICB3aWRnZXRMaXN0OiBgXCIke3RyYW5zbGF0ZWRXaWRnZXRMaXN0LmpvaW4oJ1wiLCBcIicpfVwiYFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3JlbW92ZWQnOlxuICAgICAgICAgICAgICB3aWRnZXRDaGFuZ2VzID1cbiAgICAgICAgICAgICAgICB3aWRnZXRDaGFuZ2VzICtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChnZXR0ZXh0KCdSZW1vdmVkIHdpZGdldHM6IHt7IHdpZGdldExpc3QgfX0uICcpLCB7XG4gICAgICAgICAgICAgICAgICB3aWRnZXRMaXN0OiBgXCIke3RyYW5zbGF0ZWRXaWRnZXRMaXN0LmpvaW4oJ1wiLCBcIicpfVwiYFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2NvbmZpZyc6XG4gICAgICAgICAgICAgIHdpZGdldENoYW5nZXMgPVxuICAgICAgICAgICAgICAgIHdpZGdldENoYW5nZXMgK1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGdldHRleHQoJ1VwZGF0ZWQgd2lkZ2V0czoge3sgd2lkZ2V0TGlzdCB9fS4gJyksIHtcbiAgICAgICAgICAgICAgICAgIHdpZGdldExpc3Q6IGBcIiR7dHJhbnNsYXRlZFdpZGdldExpc3Quam9pbignXCIsIFwiJyl9XCJgXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYXJyYW5nZW1lbnQnOlxuICAgICAgICAgICAgICB3aWRnZXRDaGFuZ2VzID1cbiAgICAgICAgICAgICAgICB3aWRnZXRDaGFuZ2VzICtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChnZXR0ZXh0KCdSZWFycmFuZ2VkIHdpZGdldHM6IHt7IHdpZGdldExpc3QgfX0uICcpLCB7XG4gICAgICAgICAgICAgICAgICB3aWRnZXRMaXN0OiBgXCIke3RyYW5zbGF0ZWRXaWRnZXRMaXN0LmpvaW4oJ1wiLCBcIicpfVwiYFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb3BpZWREYXNoYm9hcmQuZGVzY3JpcHRpb25UZXh0ID0gYCR7c2V0dGluZ0NoYW5nZXNNZXNzYWdlfSAke2Fzc2V0TW9kZWxNZXNzYWdlfSAke3dpZGdldENoYW5nZXN9YDtcbiAgICAgIHRoaXMuZGFzaGJvYXJkSGlzdG9yeUV4dGVuZGVkLnB1c2goY29waWVkRGFzaGJvYXJkKTtcbiAgICB9XG4gIH1cblxuICByZXZlcnREYXNoYm9hcmQoZGFzaGJvYXJkOiBDb250ZXh0RGFzaGJvYXJkKTogdm9pZCB7XG4gICAgY29uc3QgbmV3RGFzaGJvYXJkID0gY2xvbmVEZWVwKGRhc2hib2FyZCk7XG4gICAgbmV3RGFzaGJvYXJkLmhpc3RvcnlEZXNjcmlwdGlvbi5yZXN0b3JlZCA9IGRhc2hib2FyZC5jcmVhdGVkO1xuICAgIHRoaXMub25SZXZlcnQuZW1pdChuZXdEYXNoYm9hcmQpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiYmctY29tcG9uZW50IHAtdC04IHAtYi04IHNlcGFyYXRvci1ib3R0b20gdGV4dC1jZW50ZXJcIj5cbiAgPGlcbiAgICBjbGFzcz1cInRleHQtaW5mbyBtLXItNFwiXG4gICAgYzh5SWNvbj1cImluZm9cIlxuICA+PC9pPlxuICB7e1xuICAgIHZlcnNpb25IaXN0b3J5TGltaXRNZXNzYWdlXG4gICAgICB8IHRyYW5zbGF0ZTogeyB2ZXJzaW9uSGlzdG9yeUxpbWl0OiBjb250ZXh0RGFzaGJvYXJkU2VydmljZS5WRVJTSU9OX0hJU1RPUllfU0laRV9MSU1JVCB9XG4gIH19XG48L2Rpdj5cbjxjOHktbGlzdC1ncm91cCBjbGFzcz1cInAtdC0yNCBwLWItMjRcIj5cbiAgPGM4eS1saS10aW1lbGluZVxuICAgICpuZ0Zvcj1cImxldCBkYXNoYm9hcmQgb2YgZGFzaGJvYXJkSGlzdG9yeUV4dGVuZGVkOyBpbmRleCBhcyBpXCJcbiAgICBbbmdDbGFzc109XCJ7IGFjdGl2ZTogaSA9PT0gMCB9XCJcbiAgPlxuICAgIHt7IGRhc2hib2FyZC5jcmVhdGVkIHwgZGF0ZTogJ21lZGl1bURhdGUnIH19XG4gICAge3sgZGFzaGJvYXJkLmNyZWF0ZWQgfCBkYXRlOiAnc2hvcnRUaW1lJyB9fVxuICAgIDxjOHktbGkgZGF0YS1jeT1cImM4eS1kYXNoYm9hcmQtdmVyc2lvbi1oaXN0b3J5LS1oaXN0b3J5LXJvd1wiPlxuICAgICAgPGM4eS1saS1ib2R5PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGEtaS1zdGFydFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3dcIj5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZS13cmFwXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBkYXNoYm9hcmQuZGVzY3JpcHRpb25UZXh0IH19XCJcbiAgICAgICAgICAgICAgZGF0YS1jeT1cImM4eS1kYXNoYm9hcmQtdmVyc2lvbi1oaXN0b3J5LS1oaXN0b3J5LXRpdGxlXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgZGFzaGJvYXJkLmRlc2NyaXB0aW9uVGV4dCB9fVxuICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgIGRhc2hib2FyZC5oaXN0b3J5RGVzY3JpcHRpb24ucmVzdG9yZWRcbiAgICAgICAgICAgICAgICAgID8gKHJlc3RvcmVkRGFzaGJvYXJkTWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0b3JlZFN0YXRlQ3JlYXRpb25EYXRlOiBkYXNoYm9hcmQuaGlzdG9yeURlc2NyaXB0aW9uLnJlc3RvcmVkIHwgYzh5RGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIDogJydcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzbWFsbFxuICAgICAgICAgICAgICBjbGFzcz1cInRleHQtbXV0ZWRcIlxuICAgICAgICAgICAgICB0aXRsZT1cInt7ICdieWB1c2VyYCcgfCB0cmFuc2xhdGUgfX0ge3sgZGFzaGJvYXJkLmF1dGhvciB9fVwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiZGFzaGJvYXJkLmF1dGhvclwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uLWZsZXhcIj5cbiAgICAgICAgICAgICAgICA8aSBjOHlJY29uPVwiYzh5LXVzZXJcIj48L2k+XG4gICAgICAgICAgICAgICAge3sgZGFzaGJvYXJkLmF1dGhvciB9fVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgY2xhc3M9XCJsYWJlbCBsYWJlbC1wcmltYXJ5IG0tbC1hdXRvXCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ1RoZSBsYXN0IHNhdmVkIHN0YXR1cyBvZiB0aGUgZGFzaGJvYXJkJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAqbmdJZj1cImkgPT09IDBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7ICdDdXJyZW50YGRhc2hib2FyZCBzdGF0dXNgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgY2xhc3M9XCJtLWwtYXV0byBzaG93T25Ib3ZlclwiXG4gICAgICAgICAgICAqbmdJZj1cImRhc2hib2FyZEhpc3RvcnlFeHRlbmRlZC5sZW5ndGggPiAxICYmIGkgPiAwXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwie3sgJ1Jlc3RvcmUgdGhlIGRhc2hib2FyZCB0byB0aGlzIHN0YXR1cycgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInJldmVydERhc2hib2FyZChkYXNoYm9hcmQpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgJ1Jlc3RvcmUnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9jOHktbGktYm9keT5cbiAgICA8L2M4eS1saT5cbiAgPC9jOHktbGktdGltZWxpbmU+XG48L2M4eS1saXN0LWdyb3VwPlxuIl19