@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
120 lines • 27.5 kB
JavaScript
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { InventoryService, OperationStatus } from '@c8y/client';
import { AlertService, gettext } from '@c8y/ngx-components';
import { DeviceConfigurationOperation, RepositoryService } from '@c8y/ngx-components/repository/shared';
import { DeviceConfigurationService } from './device-configuration.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@c8y/ngx-components/repository/shared";
import * as i4 from "./device-configuration.service";
import * as i5 from "@c8y/client";
import * as i6 from "@angular/common";
import * as i7 from "@angular/forms";
import * as i8 from "@c8y/ngx-components/operations/operation-details";
export class TextBasedConfigurationComponent {
constructor(route, alertService, repositoryService, deviceConfigurationService, inventoryService) {
this.route = route;
this.alertService = alertService;
this.repositoryService = repositoryService;
this.deviceConfigurationService = deviceConfigurationService;
this.inventoryService = inventoryService;
this.reloadingConfig = false;
}
async ngOnInit() {
await this.load();
}
async load() {
this.device = this.route.snapshot.parent.data.contextData;
await this.loadDevice();
await this.loadOperation();
this.showTextBasedConfigReload = this.deviceConfigurationService.hasAnySupportedOperation(this.device, [DeviceConfigurationOperation.SEND_CONFIG]);
this.showTextBasedConfigSave = this.deviceConfigurationService.hasAnySupportedOperation(this.device, [DeviceConfigurationOperation.CONFIG]);
if (this.device.c8y_Configuration && this.device.c8y_Configuration.config) {
this.config = this.device.c8y_Configuration.config;
}
}
async loadOperation() {
const operation = await this.repositoryService.getLastConfigUpdateOperation(this.device.id);
if (operation !== null) {
this.reloadingConfig =
!!operation.c8y_SendConfiguration &&
(operation.status === OperationStatus.PENDING ||
operation.status === OperationStatus.EXECUTING);
this.repositoryService.observeOperation(operation).subscribe(operationUpdate => {
if (operationUpdate.status === OperationStatus.PENDING ||
operationUpdate.status === OperationStatus.EXECUTING) {
this.latestOperation = operationUpdate;
}
else
this.latestOperation = null;
});
}
}
get savingConfig() {
return this.latestOperation
? !!this.latestOperation.c8y_Configuration &&
(this.latestOperation.status === OperationStatus.PENDING ||
this.latestOperation.status === OperationStatus.EXECUTING)
: false;
}
async reloadConfiguration() {
this.reloadingConfig = true;
const operationCfg = await this.repositoryService.createTextBasedConfigurationReloadOperation(this.device);
try {
this.repositoryService.createObservedOperation(operationCfg).subscribe(operationUpdate => this.onOperationReloadSuccess(operationUpdate), operationUpdate => this.onOperationReloadError(operationUpdate), () => this.onOperationReloadComplete());
}
catch (ex) {
this.alertService.addServerFailure(ex);
}
}
async updateConfiguration(config) {
const operationCfg = await this.repositoryService.createTextBasedConfigurationUpdateOperation(this.device, config);
try {
this.repositoryService.createObservedOperation(operationCfg).subscribe(operationUpdate => this.onOperationUpdateSuccess(operationUpdate), operationUpdate => this.onOperationUpdateError(operationUpdate), () => this.onOperationUpdateComplete());
}
catch (ex) {
this.alertService.addServerFailure(ex);
}
}
onOperationReloadSuccess(operationUpdate) {
this.latestOperation = operationUpdate;
if (operationUpdate.status === OperationStatus.PENDING) {
this.alertService.success(gettext('Configuration will be reloaded.'));
}
}
onOperationReloadError(operationUpdate) {
this.latestOperation = operationUpdate;
this.reloadingConfig = false;
}
async onOperationReloadComplete() {
await this.loadDevice();
this.config = this.device.c8y_Configuration.config;
this.reloadingConfig = false;
}
onOperationUpdateSuccess(operationUpdate) {
this.latestOperation = operationUpdate;
if (operationUpdate.status === OperationStatus.PENDING) {
this.alertService.success(gettext('Configuration will be updated.'));
}
}
onOperationUpdateError(operationUpdate) {
this.latestOperation = operationUpdate;
}
onOperationUpdateComplete() {
this.device.c8y_Configuration.config = this.config;
}
async loadDevice() {
this.device = (await this.inventoryService.detail(this.device.id, {
withChildren: false
})).data;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextBasedConfigurationComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.AlertService }, { token: i3.RepositoryService }, { token: i4.DeviceConfigurationService }, { token: i5.InventoryService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TextBasedConfigurationComponent, selector: "c8y-text-based-configuration", ngImport: i0, template: "<div class=\"d-flex d-col fit-h\">\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50\">\n <div class=\"m-l-auto d-flex\">\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n *ngIf=\"showTextBasedConfigReload\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig || savingConfig\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n *ngIf=\"reloadingConfig\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig }\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"download\"\n *ngIf=\"!reloadingConfig\"\n ></i>\n\n {{ 'Get configuration from device' | translate }}\n </button>\n </div>\n </div>\n </fieldset>\n <div class=\"flex-grow\">\n <textarea\n class=\"form-control fit-h p-r-16 p-l-16\"\n [attr.aria-label]=\"'Operations' | translate\"\n [(ngModel)]=\"config\"\n [disabled]=\"reloadingConfig || savingConfig\"\n c8y-spellcheck=\"false\"\n ></textarea>\n </div>\n <c8y-operation-details\n class=\"bg-level-2 p-0\"\n *ngIf=\"latestOperation !== undefined\"\n [operation]=\"latestOperation\"\n ></c8y-operation-details>\n <div\n class=\"card-footer fit-w separator\"\n *ngIf=\"showTextBasedConfigSave\"\n >\n <button\n class=\"btn btn-primary\"\n id=\"send-config-btn\"\n type=\"button\"\n (click)=\"updateConfiguration(config)\"\n [disabled]=\"reloadingConfig || savingConfig || !config\"\n [ngClass]=\"{ 'btn-pending': savingConfig }\"\n >\n <span\n title=\"{{ 'Send' | translate }}\"\n *ngIf=\"!savingConfig\"\n >\n {{ 'Send configuration to device' | translate }}\n </span>\n <span\n title=\"{{ 'Sending\u2026' | translate }}\"\n *ngIf=\"savingConfig\"\n >\n {{ 'Sending\u2026' | translate }}\n </span>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i7.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: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.OperationDetailsComponent, selector: "c8y-operation-details", inputs: ["operation"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TextBasedConfigurationComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-text-based-configuration', template: "<div class=\"d-flex d-col fit-h\">\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50\">\n <div class=\"m-l-auto d-flex\">\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n *ngIf=\"showTextBasedConfigReload\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig || savingConfig\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n *ngIf=\"reloadingConfig\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig }\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"download\"\n *ngIf=\"!reloadingConfig\"\n ></i>\n\n {{ 'Get configuration from device' | translate }}\n </button>\n </div>\n </div>\n </fieldset>\n <div class=\"flex-grow\">\n <textarea\n class=\"form-control fit-h p-r-16 p-l-16\"\n [attr.aria-label]=\"'Operations' | translate\"\n [(ngModel)]=\"config\"\n [disabled]=\"reloadingConfig || savingConfig\"\n c8y-spellcheck=\"false\"\n ></textarea>\n </div>\n <c8y-operation-details\n class=\"bg-level-2 p-0\"\n *ngIf=\"latestOperation !== undefined\"\n [operation]=\"latestOperation\"\n ></c8y-operation-details>\n <div\n class=\"card-footer fit-w separator\"\n *ngIf=\"showTextBasedConfigSave\"\n >\n <button\n class=\"btn btn-primary\"\n id=\"send-config-btn\"\n type=\"button\"\n (click)=\"updateConfiguration(config)\"\n [disabled]=\"reloadingConfig || savingConfig || !config\"\n [ngClass]=\"{ 'btn-pending': savingConfig }\"\n >\n <span\n title=\"{{ 'Send' | translate }}\"\n *ngIf=\"!savingConfig\"\n >\n {{ 'Send configuration to device' | translate }}\n </span>\n <span\n title=\"{{ 'Sending\u2026' | translate }}\"\n *ngIf=\"savingConfig\"\n >\n {{ 'Sending\u2026' | translate }}\n </span>\n </button>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.AlertService }, { type: i3.RepositoryService }, { type: i4.DeviceConfigurationService }, { type: i5.InventoryService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1iYXNlZC1jb25maWd1cmF0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3JlcG9zaXRvcnkvY29uZmlndXJhdGlvbi9kZXZpY2UtdGFiL3RleHQtYmFzZWQtY29uZmlndXJhdGlvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9yZXBvc2l0b3J5L2NvbmZpZ3VyYXRpb24vZGV2aWNlLXRhYi90ZXh0LWJhc2VkLWNvbmZpZ3VyYXRpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUNsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUE4QixnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUYsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1RCxPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLGlCQUFpQixFQUNsQixNQUFNLHVDQUF1QyxDQUFDO0FBQy9DLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7Ozs7Ozs7O0FBTTVFLE1BQU0sT0FBTywrQkFBK0I7SUFRMUMsWUFDVSxLQUFxQixFQUNyQixZQUEwQixFQUMxQixpQkFBb0MsRUFDcEMsMEJBQXNELEVBQ3RELGdCQUFrQztRQUpsQyxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUNyQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLCtCQUEwQixHQUExQiwwQkFBMEIsQ0FBNEI7UUFDdEQscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQVI1QyxvQkFBZSxHQUFHLEtBQUssQ0FBQztJQVNyQixDQUFDO0lBRUosS0FBSyxDQUFDLFFBQVE7UUFD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cnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgSU1hbmFnZWRPYmplY3QsIElPcGVyYXRpb24sIEludmVudG9yeVNlcnZpY2UsIE9wZXJhdGlvblN0YXR1cyB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHtcbiAgRGV2aWNlQ29uZmlndXJhdGlvbk9wZXJhdGlvbixcbiAgUmVwb3NpdG9yeVNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9yZXBvc2l0b3J5L3NoYXJlZCc7XG5pbXBvcnQgeyBEZXZpY2VDb25maWd1cmF0aW9uU2VydmljZSB9IGZyb20gJy4vZGV2aWNlLWNvbmZpZ3VyYXRpb24uc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS10ZXh0LWJhc2VkLWNvbmZpZ3VyYXRpb24nLFxuICB0ZW1wbGF0ZVVybDogJy4vdGV4dC1iYXNlZC1jb25maWd1cmF0aW9uLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBUZXh0QmFzZWRDb25maWd1cmF0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgZGV2aWNlOiBJTWFuYWdlZE9iamVjdDtcbiAgbGF0ZXN0T3BlcmF0aW9uOiBJT3BlcmF0aW9uO1xuICBzaG93VGV4dEJhc2VkQ29uZmlnUmVsb2FkOiBib29sZWFuO1xuICBzaG93VGV4dEJhc2VkQ29uZmlnU2F2ZTogYm9vbGVhbjtcbiAgcmVsb2FkaW5nQ29uZmlnID0gZmFsc2U7XG4gIGNvbmZpZzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZXBvc2l0b3J5U2VydmljZTogUmVwb3NpdG9yeVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBkZXZpY2VDb25maWd1cmF0aW9uU2VydmljZTogRGV2aWNlQ29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBpbnZlbnRvcnlTZXJ2aWNlOiBJbnZlbnRvcnlTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBhd2FpdCB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgdGhpcy5kZXZpY2UgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmVudC5kYXRhLmNvbnRleHREYXRhO1xuICAgIGF3YWl0IHRoaXMubG9hZERldmljZSgpO1xuICAgIGF3YWl0IHRoaXMubG9hZE9wZXJhdGlvbigpO1xuICAgIHRoaXMuc2hvd1RleHRCYXNlZENvbmZpZ1JlbG9hZCA9IHRoaXMuZGV2aWNlQ29uZmlndXJhdGlvblNlcnZpY2UuaGFzQW55U3VwcG9ydGVkT3BlcmF0aW9uKFxuICAgICAgdGhpcy5kZXZpY2UsXG4gICAgICBbRGV2aWNlQ29uZmlndXJhdGlvbk9wZXJhdGlvbi5TRU5EX0NPTkZJR11cbiAgICApO1xuICAgIHRoaXMuc2hvd1RleHRCYXNlZENvbmZpZ1NhdmUgPSB0aGlzLmRldmljZUNvbmZpZ3VyYXRpb25TZXJ2aWNlLmhhc0FueVN1cHBvcnRlZE9wZXJhdGlvbihcbiAgICAgIHRoaXMuZGV2aWNlLFxuICAgICAgW0RldmljZUNvbmZpZ3VyYXRpb25PcGVyYXRpb24uQ09ORklHXVxuICAgICk7XG4gICAgaWYgKHRoaXMuZGV2aWNlLmM4eV9Db25maWd1cmF0aW9uICYmIHRoaXMuZGV2aWNlLmM4eV9Db25maWd1cmF0aW9uLmNvbmZpZykge1xuICAgICAgdGhpcy5jb25maWcgPSB0aGlzLmRldmljZS5jOHlfQ29uZmlndXJhdGlvbi5jb25maWc7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbG9hZE9wZXJhdGlvbigpIHtcbiAgICBjb25zdCBvcGVyYXRpb24gPSBhd2FpdCB0aGlzLnJlcG9zaXRvcnlTZXJ2aWNlLmdldExhc3RDb25maWdVcGRhdGVPcGVyYXRpb24odGhpcy5kZXZpY2UuaWQpO1xuICAgIGlmIChvcGVyYXRpb24gIT09IG51bGwpIHtcbiAgICAgIHRoaXMucmVsb2FkaW5nQ29uZmlnID1cbiAgICAgICAgISFvcGVyYXRpb24uYzh5X1NlbmRDb25maWd1cmF0aW9uICYmXG4gICAgICAgIChvcGVyYXRpb24uc3RhdHVzID09PSBPcGVyYXRpb25TdGF0dXMuUEVORElORyB8fFxuICAgICAgICAgIG9wZXJhdGlvbi5zdGF0dXMgPT09IE9wZXJhdGlvblN0YXR1cy5FWEVDVVRJTkcpO1xuICAgICAgdGhpcy5yZXBvc2l0b3J5U2VydmljZS5vYnNlcnZlT3BlcmF0aW9uKG9wZXJhdGlvbikuc3Vic2NyaWJlKG9wZXJhdGlvblVwZGF0ZSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBvcGVyYXRpb25VcGRhdGUuc3RhdHVzID09PSBPcGVyYXRpb25TdGF0dXMuUEVORElORyB8fFxuICAgICAgICAgIG9wZXJhdGlvblVwZGF0ZS5zdGF0dXMgPT09IE9wZXJhdGlvblN0YXR1cy5FWEVDVVRJTkdcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5sYXRlc3RPcGVyYXRpb24gPSBvcGVyYXRpb25VcGRhdGU7XG4gICAgICAgIH0gZWxzZSB0aGlzLmxhdGVzdE9wZXJhdGlvbiA9IG51bGw7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgc2F2aW5nQ29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLmxhdGVzdE9wZXJhdGlvblxuICAgICAgPyAhIXRoaXMubGF0ZXN0T3BlcmF0aW9uLmM4eV9Db25maWd1cmF0aW9uICYmXG4gICAgICAgICAgKHRoaXMubGF0ZXN0T3BlcmF0aW9uLnN0YXR1cyA9PT0gT3BlcmF0aW9uU3RhdHVzLlBFTkRJTkcgfHxcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0T3BlcmF0aW9uLnN0YXR1cyA9PT0gT3BlcmF0aW9uU3RhdHVzLkVYRUNVVElORylcbiAgICAgIDogZmFsc2U7XG4gIH1cblxuICBhc3luYyByZWxvYWRDb25maWd1cmF0aW9uKCkge1xuICAgIHRoaXMucmVsb2FkaW5nQ29uZmlnID0gdHJ1ZTtcbiAgICBjb25zdCBvcGVyYXRpb25DZmcgPSBhd2FpdCB0aGlzLnJlcG9zaXRvcnlTZXJ2aWNlLmNyZWF0ZVRleHRCYXNlZENvbmZpZ3VyYXRpb25SZWxvYWRPcGVyYXRpb24oXG4gICAgICB0aGlzLmRldmljZVxuICAgICk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVwb3NpdG9yeVNlcnZpY2UuY3JlYXRlT2JzZXJ2ZWRPcGVyYXRpb24ob3BlcmF0aW9uQ2ZnKS5zdWJzY3JpYmUoXG4gICAgICAgIG9wZXJhdGlvblVwZGF0ZSA9PiB0aGlzLm9uT3BlcmF0aW9uUmVsb2FkU3VjY2VzcyhvcGVyYXRpb25VcGRhdGUpLFxuICAgICAgICBvcGVyYXRpb25VcGRhdGUgPT4gdGhpcy5vbk9wZXJhdGlvblJlbG9hZEVycm9yKG9wZXJhdGlvblVwZGF0ZSksXG4gICAgICAgICgpID0+IHRoaXMub25PcGVyYXRpb25SZWxvYWRDb21wbGV0ZSgpXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGV4KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyB1cGRhdGVDb25maWd1cmF0aW9uKGNvbmZpZykge1xuICAgIGNvbnN0IG9wZXJhdGlvbkNmZyA9IGF3YWl0IHRoaXMucmVwb3NpdG9yeVNlcnZpY2UuY3JlYXRlVGV4dEJhc2VkQ29uZmlndXJhdGlvblVwZGF0ZU9wZXJhdGlvbihcbiAgICAgIHRoaXMuZGV2aWNlLFxuICAgICAgY29uZmlnXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXBvc2l0b3J5U2VydmljZS5jcmVhdGVPYnNlcnZlZE9wZXJhdGlvbihvcGVyYXRpb25DZmcpLnN1YnNjcmliZShcbiAgICAgICAgb3BlcmF0aW9uVXBkYXRlID0+IHRoaXMub25PcGVyYXRpb25VcGRhdGVTdWNjZXNzKG9wZXJhdGlvblVwZGF0ZSksXG4gICAgICAgIG9wZXJhdGlvblVwZGF0ZSA9PiB0aGlzLm9uT3BlcmF0aW9uVXBkYXRlRXJyb3Iob3BlcmF0aW9uVXBkYXRlKSxcbiAgICAgICAgKCkgPT4gdGhpcy5vbk9wZXJhdGlvblVwZGF0ZUNvbXBsZXRlKClcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25PcGVyYXRpb25SZWxvYWRTdWNjZXNzKG9wZXJhdGlvblVwZGF0ZSkge1xuICAgIHRoaXMubGF0ZXN0T3BlcmF0aW9uID0gb3BlcmF0aW9uVXBkYXRlO1xuICAgIGlmIChvcGVyYXRpb25VcGRhdGUuc3RhdHVzID09PSBPcGVyYXRpb25TdGF0dXMuUEVORElORykge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2Uuc3VjY2VzcyhnZXR0ZXh0KCdDb25maWd1cmF0aW9uIHdpbGwgYmUgcmVsb2FkZWQuJykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25PcGVyYXRpb25SZWxvYWRFcnJvcihvcGVyYXRpb25VcGRhdGUpIHtcbiAgICB0aGlzLmxhdGVzdE9wZXJhdGlvbiA9IG9wZXJhdGlvblVwZGF0ZTtcbiAgICB0aGlzLnJlbG9hZGluZ0NvbmZpZyA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBvbk9wZXJhdGlvblJlbG9hZENvbXBsZXRlKCkge1xuICAgIGF3YWl0IHRoaXMubG9hZERldmljZSgpO1xuICAgIHRoaXMuY29uZmlnID0gdGhpcy5kZXZpY2UuYzh5X0NvbmZpZ3VyYXRpb24uY29uZmlnO1xuICAgIHRoaXMucmVsb2FkaW5nQ29uZmlnID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9uT3BlcmF0aW9uVXBkYXRlU3VjY2VzcyhvcGVyYXRpb25VcGRhdGUpIHtcbiAgICB0aGlzLmxhdGVzdE9wZXJhdGlvbiA9IG9wZXJhdGlvblVwZGF0ZTtcbiAgICBpZiAob3BlcmF0aW9uVXBkYXRlLnN0YXR1cyA9PT0gT3BlcmF0aW9uU3RhdHVzLlBFTkRJTkcpIHtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLnN1Y2Nlc3MoZ2V0dGV4dCgnQ29uZmlndXJhdGlvbiB3aWxsIGJlIHVwZGF0ZWQuJykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25PcGVyYXRpb25VcGRhdGVFcnJvcihvcGVyYXRpb25VcGRhdGUpIHtcbiAgICB0aGlzLmxhdGVzdE9wZXJhdGlvbiA9IG9wZXJhdGlvblVwZGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgb25PcGVyYXRpb25VcGRhdGVDb21wbGV0ZSgpIHtcbiAgICB0aGlzLmRldmljZS5jOHlfQ29uZmlndXJhdGlvbi5jb25maWcgPSB0aGlzLmNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZERldmljZSgpIHtcbiAgICB0aGlzLmRldmljZSA9IChcbiAgICAgIGF3YWl0IHRoaXMuaW52ZW50b3J5U2VydmljZS5kZXRhaWwodGhpcy5kZXZpY2UuaWQsIHtcbiAgICAgICAgd2l0aENoaWxkcmVuOiBmYWxzZVxuICAgICAgfSlcbiAgICApLmRhdGE7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJkLWZsZXggZC1jb2wgZml0LWhcIj5cbiAgPGZpZWxkc2V0IGNsYXNzPVwiY2FyZC1ibG9jayBiZy1sZXZlbC0xIGZpdC13XCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtZmxleC01MFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm0tbC1hdXRvIGQtZmxleFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLXNtIGEtcy1jZW50ZXIgbS10LTggbS1iLThcIlxuICAgICAgICAgIHRpdGxlPVwie3sgJ0dldCBjb25maWd1cmF0aW9uIGZyb20gZGV2aWNlJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgKm5nSWY9XCJzaG93VGV4dEJhc2VkQ29uZmlnUmVsb2FkXCJcbiAgICAgICAgICAoY2xpY2spPVwicmVsb2FkQ29uZmlndXJhdGlvbigpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwicmVsb2FkaW5nQ29uZmlnIHx8IHNhdmluZ0NvbmZpZ1wiXG4gICAgICAgID5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJtLXItNFwiXG4gICAgICAgICAgICBjOHlJY29uPVwicmVmcmVzaFwiXG4gICAgICAgICAgICAqbmdJZj1cInJlbG9hZGluZ0NvbmZpZ1wiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdpY29uLXNwaW4nOiByZWxvYWRpbmdDb25maWcgfVwiXG4gICAgICAgICAgPjwvaT5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJtLXItNFwiXG4gICAgICAgICAgICBjOHlJY29uPVwiZG93bmxvYWRcIlxuICAgICAgICAgICAgKm5nSWY9XCIhcmVsb2FkaW5nQ29uZmlnXCJcbiAgICAgICAgICA+PC9pPlxuXG4gICAgICAgICAge3sgJ0dldCBjb25maWd1cmF0aW9uIGZyb20gZGV2aWNlJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2ZpZWxkc2V0PlxuICA8ZGl2IGNsYXNzPVwiZmxleC1ncm93XCI+XG4gICAgPHRleHRhcmVhXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBmaXQtaCBwLXItMTYgcC1sLTE2XCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ09wZXJhdGlvbnMnIHwgdHJhbnNsYXRlXCJcbiAgICAgIFsobmdNb2RlbCldPVwiY29uZmlnXCJcbiAgICAgIFtkaXNhYmxlZF09XCJyZWxvYWRpbmdDb25maWcgfHwgc2F2aW5nQ29uZmlnXCJcbiAgICAgIGM4eS1zcGVsbGNoZWNrPVwiZmFsc2VcIlxuICAgID48L3RleHRhcmVhPlxuICA8L2Rpdj5cbiAgPGM4eS1vcGVyYXRpb24tZGV0YWlsc1xuICAgIGNsYXNzPVwiYmctbGV2ZWwtMiBwLTBcIlxuICAgICpuZ0lmPVwibGF0ZXN0T3BlcmF0aW9uICE9PSB1bmRlZmluZWRcIlxuICAgIFtvcGVyYXRpb25dPVwibGF0ZXN0T3BlcmF0aW9uXCJcbiAgPjwvYzh5LW9wZXJhdGlvbi1kZXRhaWxzPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJjYXJkLWZvb3RlciBmaXQtdyBzZXBhcmF0b3JcIlxuICAgICpuZ0lmPVwic2hvd1RleHRCYXNlZENvbmZpZ1NhdmVcIlxuICA+XG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxuICAgICAgaWQ9XCJzZW5kLWNvbmZpZy1idG5cIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAoY2xpY2spPVwidXBkYXRlQ29uZmlndXJhdGlvbihjb25maWcpXCJcbiAgICAgIFtkaXNhYmxlZF09XCJyZWxvYWRpbmdDb25maWcgfHwgc2F2aW5nQ29uZmlnIHx8ICFjb25maWdcIlxuICAgICAgW25nQ2xhc3NdPVwieyAnYnRuLXBlbmRpbmcnOiBzYXZpbmdDb25maWcgfVwiXG4gICAgPlxuICAgICAgPHNwYW5cbiAgICAgICAgdGl0bGU9XCJ7eyAnU2VuZCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAqbmdJZj1cIiFzYXZpbmdDb25maWdcIlxuICAgICAgPlxuICAgICAgICB7eyAnU2VuZCBjb25maWd1cmF0aW9uIHRvIGRldmljZScgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxzcGFuXG4gICAgICAgIHRpdGxlPVwie3sgJ1NlbmRpbmfigKYnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgKm5nSWY9XCJzYXZpbmdDb25maWdcIlxuICAgICAgPlxuICAgICAgICB7eyAnU2VuZGluZ+KApicgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==