UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

122 lines 33.2 kB
import { Component, ViewChild } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { C8yJSONSchema, C8yStepper, GainsightService, gettext } from '@c8y/ngx-components'; import { BsModalRef } from 'ngx-bootstrap/modal'; import { RegisterDeviceService } from '../../register-device.service'; import { PRODUCT_EXPERIENCE_BASE_REGISTRATION } from '../base-device-registration.model'; import { BulkExtensibleDeviceRegistrationService } from './extensible-bulk-device-registration.service'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; import * as i2 from "./extensible-bulk-device-registration.service"; import * as i3 from "../../register-device.service"; import * as i4 from "ngx-bootstrap/modal"; import * as i5 from "@angular/common"; import * as i6 from "@angular/cdk/stepper"; import * as i7 from "@ngx-formly/core"; const extensibleDeviceRegistrationBulkSchema = { $schema: 'https://json-schema.org/draft/2019-09/schema', type: 'object', properties: { csvBulkFile: { type: 'array', title: gettext('CSV file upload'), description: gettext('You can use file upload component to let users send files. This input accepts only a single CSV file.'), contentMediaType: 'csv' } }, required: ['csvBulkFile'], additionalProperties: false }; export class ExtensibleBulkDeviceRegistrationModalComponent { constructor(jsonschema, bulkExtensibleDeviceRegistrationService, registerDeviceService, bsModalRef, gainsightService) { this.jsonschema = jsonschema; this.bulkExtensibleDeviceRegistrationService = bulkExtensibleDeviceRegistrationService; this.registerDeviceService = registerDeviceService; this.bsModalRef = bsModalRef; this.gainsightService = gainsightService; this.loadingError = false; this.pending = false; this.form = new FormGroup({}); this.model = {}; } async ngOnInit() { const { title, exampleFileUrls } = await this.bulkExtensibleDeviceRegistrationService .getBulkDescription(this.contextPath) .catch(error => { this.message = error.message; this.loadingError = true; return { title: gettext('Error'), exampleFileUrls: [] }; }); this.title = title; this.template = [this.jsonschema.toFieldConfig(extensibleDeviceRegistrationBulkSchema)]; this.examples = exampleFileUrls; } async upload() { this.pending = true; const { res, data } = await this.bulkExtensibleDeviceRegistrationService .upload(this.getFile(this.model), this.contextPath) .catch(() => { return { res: undefined, data: undefined }; }) .finally(() => { this.pending = false; this.stepper.next(); }); this.result = data; this.success = res?.status < 400; if (this.success) { this.message = gettext('Device registration created.'); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_BASE_REGISTRATION.EVENT, { result: PRODUCT_EXPERIENCE_BASE_REGISTRATION.RESULT.SUCCESS, component: PRODUCT_EXPERIENCE_BASE_REGISTRATION.COMPONENT.EXTENSIBLE_BULK }); this.model = {}; } if (res) { if (res.status >= 400 && res.status < 500) { this.message = gettext('Device registration failed.'); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_BASE_REGISTRATION.EVENT, { result: PRODUCT_EXPERIENCE_BASE_REGISTRATION.RESULT.FAILURE, component: PRODUCT_EXPERIENCE_BASE_REGISTRATION.COMPONENT.EXTENSIBLE_BULK }); } else if (res.status >= 500) { this.message = gettext('Error occurred while processing the uploaded file.'); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_BASE_REGISTRATION.EVENT, { result: PRODUCT_EXPERIENCE_BASE_REGISTRATION.RESULT.FAILURE, component: PRODUCT_EXPERIENCE_BASE_REGISTRATION.COMPONENT.EXTENSIBLE_BULK }); } } else { this.message = gettext('No internet connection. Unable to reach the microservice.'); } } getFile(model) { const csvBulkFile = model?.csvBulkFile; return csvBulkFile ? csvBulkFile[0]?.file : undefined; } complete() { this.registerDeviceService.list(); this.bsModalRef.hide(); } cancel() { this.bsModalRef.hide(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ExtensibleBulkDeviceRegistrationModalComponent, deps: [{ token: i1.C8yJSONSchema }, { token: i2.BulkExtensibleDeviceRegistrationService }, { token: i3.RegisterDeviceService }, { token: i4.BsModalRef }, { token: i1.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ExtensibleBulkDeviceRegistrationModalComponent, selector: "extensible-device-registration-modal-component", viewQueries: [{ propertyName: "stepper", first: true, predicate: C8yStepper, descendants: true, static: true }], ngImport: i0, template: "<c8y-modal\n [title]=\"title | translate\"\n [headerClasses]=\"'dialog-header'\"\n [customFooter]=\"true\"\n>\n <ng-container c8y-modal-title>\n <i c8yIcon=\"c8y-device-connect\"></i>\n </ng-container>\n <c8y-stepper [hideStepProgress]=\"true\" linear class=\"p-t-16\" c8y-modal-body>\n <ng-container *ngIf=\"!loadingError\">\n <cdk-step>\n <div class=\"sticky-top bg-component separator-bottom\">\n <p\n class=\"p-l-24 p-r-24 p-t-16 p-b-16 m-b-0 separator-bottom text-16 text-medium text-center bg-component\"\n translate\n >\n Register devices in bulk\n </p>\n <c8y-form-group class=\"p-24 p-t-16 p-b-8 m-b-0\">\n <formly-form [form]=\"form\" [fields]=\"template\" [model]=\"model\"></formly-form>\n </c8y-form-group>\n </div>\n <div\n *ngFor=\"let example of examples\"\n class=\"bg-gray-white separator-bottom p-t-16 p-b-16 p-l-24 p-r-24\"\n >\n <p class=\"m-b-8 text-medium\">\n {{ example.title | translate }}\n </p>\n <p class=\"small m-b-8\">{{ example.description | translate }}</p>\n <a\n title=\"{{ 'Download template' | translate }}\"\n class=\"btn btn-default btn-sm\"\n target=\"_self\"\n [href]=\"example.url\"\n download=\"{{ 'Example bulk registration - template.csv' | translate }}\"\n >\n <i c8yIcon=\"download\"></i>\n <span translate>Download template</span>\n </a>\n </div>\n <c8y-stepper-buttons\n class=\"sticky-bottom d-block p-t-16 p-b-16 separator-top bg-level-0\"\n [showButtons]=\"{ cancel: true, next: true }\"\n [disabled]=\"form.invalid\"\n [pending]=\"pending\"\n (onCancel)=\"cancel()\"\n (onNext)=\"upload()\"\n [labels]=\"{ next: 'Upload' }\"\n ></c8y-stepper-buttons>\n </cdk-step>\n </ng-container>\n <cdk-step state=\"final\">\n <div class=\"p-24\">\n <div *ngIf=\"success; else fail\">\n <c8y-operation-result\n text=\"{{ message | translate }}\"\n [size]=\"84\"\n [vertical]=\"true\"\n type=\"success\"\n class=\"lead\"\n data-cy=\"success\"\n ></c8y-operation-result>\n <c8y-list-group class=\"separator-top m-t-16\">\n <c8y-li>\n <c8y-li-icon class=\"text-success\" [icon]=\"'check-circle'\"></c8y-li-icon>\n <p translate>File successfully uploaded.</p>\n <c8y-li-collapse>\n <pre><code>{{ result | json }}</code></pre>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-list-group>\n </div>\n <ng-template #fail>\n <c8y-operation-result\n text=\"{{ message | translate }}\"\n [size]=\"84\"\n [vertical]=\"true\"\n type=\"error\"\n class=\"lead\"\n data-cy=\"error\"\n ></c8y-operation-result>\n <c8y-list-group *ngIf=\"result\" class=\"separator-top m-t-16\">\n <c8y-li>\n <c8y-li-icon class=\"text-danger\" [icon]=\"'ban'\"></c8y-li-icon>\n <p translate>Bulk operation failed.</p>\n <c8y-li-collapse>\n <pre><code>{{ result | json }}</code></pre>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-list-group>\n </ng-template>\n </div>\n <c8y-stepper-buttons\n class=\"sticky-bottom d-block p-t-16 p-b-16 separator-top bg-component\"\n [showButtons]=\"{ next: true }\"\n (onNext)=\"complete()\"\n [labels]=\"{ next: success ? 'Complete' : 'Cancel' }\"\n ></c8y-stepper-buttons>\n </cdk-step>\n </c8y-stepper>\n</c8y-modal>\n", dependencies: [{ kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1.OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "component", type: i1.ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.C8yStepper, selector: "c8y-stepper", inputs: ["disableDefaultIcons", "disableProgressButtons", "customClasses", "hideStepProgress", "useStepLabelsAsTitlesOnly"], outputs: ["onStepChange"] }, { kind: "component", type: i6.CdkStep, selector: "cdk-step", inputs: ["stepControl", "label", "errorMessage", "aria-label", "aria-labelledby", "state", "editable", "optional", "completed", "hasError"], outputs: ["interacted"], exportAs: ["cdkStep"] }, { kind: "component", type: i1.C8yStepperButtons, selector: "c8y-stepper-buttons", inputs: ["labels", "pending", "disabled", "showButtons"], outputs: ["onCancel", "onNext", "onBack", "onCustom"] }, { 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.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: i7.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i5.JsonPipe, name: "json" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ExtensibleBulkDeviceRegistrationModalComponent, decorators: [{ type: Component, args: [{ selector: 'extensible-device-registration-modal-component', template: "<c8y-modal\n [title]=\"title | translate\"\n [headerClasses]=\"'dialog-header'\"\n [customFooter]=\"true\"\n>\n <ng-container c8y-modal-title>\n <i c8yIcon=\"c8y-device-connect\"></i>\n </ng-container>\n <c8y-stepper [hideStepProgress]=\"true\" linear class=\"p-t-16\" c8y-modal-body>\n <ng-container *ngIf=\"!loadingError\">\n <cdk-step>\n <div class=\"sticky-top bg-component separator-bottom\">\n <p\n class=\"p-l-24 p-r-24 p-t-16 p-b-16 m-b-0 separator-bottom text-16 text-medium text-center bg-component\"\n translate\n >\n Register devices in bulk\n </p>\n <c8y-form-group class=\"p-24 p-t-16 p-b-8 m-b-0\">\n <formly-form [form]=\"form\" [fields]=\"template\" [model]=\"model\"></formly-form>\n </c8y-form-group>\n </div>\n <div\n *ngFor=\"let example of examples\"\n class=\"bg-gray-white separator-bottom p-t-16 p-b-16 p-l-24 p-r-24\"\n >\n <p class=\"m-b-8 text-medium\">\n {{ example.title | translate }}\n </p>\n <p class=\"small m-b-8\">{{ example.description | translate }}</p>\n <a\n title=\"{{ 'Download template' | translate }}\"\n class=\"btn btn-default btn-sm\"\n target=\"_self\"\n [href]=\"example.url\"\n download=\"{{ 'Example bulk registration - template.csv' | translate }}\"\n >\n <i c8yIcon=\"download\"></i>\n <span translate>Download template</span>\n </a>\n </div>\n <c8y-stepper-buttons\n class=\"sticky-bottom d-block p-t-16 p-b-16 separator-top bg-level-0\"\n [showButtons]=\"{ cancel: true, next: true }\"\n [disabled]=\"form.invalid\"\n [pending]=\"pending\"\n (onCancel)=\"cancel()\"\n (onNext)=\"upload()\"\n [labels]=\"{ next: 'Upload' }\"\n ></c8y-stepper-buttons>\n </cdk-step>\n </ng-container>\n <cdk-step state=\"final\">\n <div class=\"p-24\">\n <div *ngIf=\"success; else fail\">\n <c8y-operation-result\n text=\"{{ message | translate }}\"\n [size]=\"84\"\n [vertical]=\"true\"\n type=\"success\"\n class=\"lead\"\n data-cy=\"success\"\n ></c8y-operation-result>\n <c8y-list-group class=\"separator-top m-t-16\">\n <c8y-li>\n <c8y-li-icon class=\"text-success\" [icon]=\"'check-circle'\"></c8y-li-icon>\n <p translate>File successfully uploaded.</p>\n <c8y-li-collapse>\n <pre><code>{{ result | json }}</code></pre>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-list-group>\n </div>\n <ng-template #fail>\n <c8y-operation-result\n text=\"{{ message | translate }}\"\n [size]=\"84\"\n [vertical]=\"true\"\n type=\"error\"\n class=\"lead\"\n data-cy=\"error\"\n ></c8y-operation-result>\n <c8y-list-group *ngIf=\"result\" class=\"separator-top m-t-16\">\n <c8y-li>\n <c8y-li-icon class=\"text-danger\" [icon]=\"'ban'\"></c8y-li-icon>\n <p translate>Bulk operation failed.</p>\n <c8y-li-collapse>\n <pre><code>{{ result | json }}</code></pre>\n </c8y-li-collapse>\n </c8y-li>\n </c8y-list-group>\n </ng-template>\n </div>\n <c8y-stepper-buttons\n class=\"sticky-bottom d-block p-t-16 p-b-16 separator-top bg-component\"\n [showButtons]=\"{ next: true }\"\n (onNext)=\"complete()\"\n [labels]=\"{ next: success ? 'Complete' : 'Cancel' }\"\n ></c8y-stepper-buttons>\n </cdk-step>\n </c8y-stepper>\n</c8y-modal>\n" }] }], ctorParameters: () => [{ type: i1.C8yJSONSchema }, { type: i2.BulkExtensibleDeviceRegistrationService }, { type: i3.RegisterDeviceService }, { type: i4.BsModalRef }, { type: i1.GainsightService }], propDecorators: { stepper: [{ type: ViewChild, args: [C8yStepper, { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5zaWJsZS1idWxrLWRldmljZS1yZWdpc3RyYXRpb24tbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcmVnaXN0ZXItZGV2aWNlL2V4dGVuc2libGUvYnVsay9leHRlbnNpYmxlLWJ1bGstZGV2aWNlLXJlZ2lzdHJhdGlvbi1tb2RhbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9yZWdpc3Rlci1kZXZpY2UvZXh0ZW5zaWJsZS9idWxrL2V4dGVuc2libGUtYnVsay1kZXZpY2UtcmVnaXN0cmF0aW9uLW1vZGFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUzRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdEUsT0FBTyxFQUFFLG9DQUFvQyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFPekYsT0FBTyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sK0NBQStDLENBQUM7Ozs7Ozs7OztBQUN4RyxNQUFNLHNDQUFzQyxHQUFXO0lBQ3JELE9BQU8sRUFBRSw4Q0FBOEM7SUFDdkQsSUFBSSxFQUFFLFFBQVE7SUFDZCxVQUFVLEVBQUU7UUFDVixXQUFXLEVBQUU7WUFDWCxJQUFJLEVBQUUsT0FBTztZQUNiLEtBQUssRUFBRSxPQUFPLENBQUMsaUJBQWlCLENBQUM7WUFDakMsV0FBVyxFQUFFLE9BQU8sQ0FDbEIsdUdBQXVHLENBQ3hHO1lBQ0QsZ0JBQWdCLEVB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QUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDOytHQW5HVSw4Q0FBOEM7bUdBQTlDLDhDQUE4QywrSEFDOUMsVUFBVSw4RENyQ3ZCLDh6SEFzR0E7OzRGRGxFYSw4Q0FBOEM7a0JBSjFELFNBQVM7K0JBQ0UsZ0RBQWdEO29PQUlqQixPQUFPO3NCQUEvQyxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBJUmVzdWx0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQzh5SlNPTlNjaGVtYSwgQzh5U3RlcHBlciwgR2FpbnNpZ2h0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgRm9ybWx5RmllbGRDb25maWcgfSBmcm9tICdAbmd4LWZvcm1seS9jb3JlJztcbmltcG9ydCB7IEJzTW9kYWxSZWYgfSBmcm9tICduZ3gtYm9vdHN0cmFwL21vZGFsJztcbmltcG9ydCB7IFJlZ2lzdGVyRGV2aWNlU2VydmljZSB9IGZyb20gJy4uLy4uL3JlZ2lzdGVyLWRldmljZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBST0RVQ1RfRVhQRVJJRU5DRV9CQVNFX1JFR0lTVFJBVElPTiB9IGZyb20gJy4uL2Jhc2UtZGV2aWNlLXJlZ2lzdHJhdGlvbi5tb2RlbCc7XG5pbXBvcnQge1xuICBCdWxrRGVzY3JpcHRpb24sXG4gIEJ1bGtGYWlsZWRSZXN1bHQsXG4gIEJ1bGtGaWxlRXhhbXBsZSxcbiAgQnVsa1Jlc3VsdFxufSBmcm9tICcuL2V4dGVuc2libGUtYnVsay1kZXZpY2UtcmVnaXN0cmF0aW9uLm1vZGVsJztcbmltcG9ydCB7IEJ1bGtFeHRlbnNpYmxlRGV2aWNlUmVnaXN0cmF0aW9uU2VydmljZSB9IGZyb20gJy4vZXh0ZW5zaWJsZS1idWxrLWRldmljZS1yZWdpc3RyYXRpb24uc2VydmljZSc7XG5jb25zdCBleHRlbnNpYmxlRGV2aWNlUmVnaXN0cmF0aW9uQnVsa1NjaGVtYTogb2JqZWN0ID0ge1xuICAkc2NoZW1hOiAnaHR0cHM6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQvMjAxOS0wOS9zY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIGNzdkJ1bGtGaWxlOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgdGl0bGU6IGdldHRleHQoJ0NTViBmaWxlIHVwbG9hZCcpLFxuICAgICAgZGVzY3JpcHRpb246IGdldHRleHQoXG4gICAgICAgICdZb3UgY2FuIHVzZSBmaWxlIHVwbG9hZCBjb21wb25lbnQgdG8gbGV0IHVzZXJzIHNlbmQgZmlsZXMuIFRoaXMgaW5wdXQgYWNjZXB0cyBvbmx5IGEgc2luZ2xlIENTViBmaWxlLidcbiAgICAgICksXG4gICAgICBjb250ZW50TWVkaWFUeXBlOiAnY3N2J1xuICAgIH1cbiAgfSxcbiAgcmVxdWlyZWQ6IFsnY3N2QnVsa0ZpbGUnXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdleHRlbnNpYmxlLWRldmljZS1yZWdpc3RyYXRpb24tbW9kYWwtY29tcG9uZW50JyxcbiAgdGVtcGxhdGVVcmw6ICdleHRlbnNpYmxlLWJ1bGstZGV2aWNlLXJlZ2lzdHJhdGlvbi1tb2RhbC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgRXh0ZW5zaWJsZUJ1bGtEZXZpY2VSZWdpc3RyYXRpb25Nb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBWaWV3Q2hpbGQoQzh5U3RlcHBlciwgeyBzdGF0aWM6IHRydWUgfSkgc3RlcHBlcjogQzh5U3RlcHBlcjtcbiAgdGl0bGU6IHN0cmluZztcbiAgZXhhbXBsZXM6IEJ1bGtGaWxlRXhhbXBsZVtdO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGxvYWRpbmdFcnJvciA9IGZhbHNlO1xuICBwZW5kaW5nID0gZmFsc2U7XG4gIGNvbnRleHRQYXRoOiBzdHJpbmc7XG4gIHJlc3VsdDogQnVsa1Jlc3VsdCB8IEJ1bGtGYWlsZWRSZXN1bHQ7XG4gIGZvcm0gPSBuZXcgRm9ybUdyb3VwKHt9KTtcbiAgbW9kZWwgPSB7fTtcbiAgdGVtcGxhdGU6IEZvcm1seUZpZWxkQ29uZmlnW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBqc29uc2NoZW1hOiBDOHlKU09OU2NoZW1hLFxuICAgIHByaXZhdGUgYnVsa0V4dGVuc2libGVEZXZpY2VSZWdpc3RyYXRpb25TZXJ2aWNlOiBCdWxrRXh0ZW5zaWJsZURldmljZVJlZ2lzdHJhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWdpc3RlckRldmljZVNlcnZpY2U6IFJlZ2lzdGVyRGV2aWNlU2VydmljZSxcbiAgICBwcml2YXRlIGJzTW9kYWxSZWY6IEJzTW9kYWxSZWYsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBjb25zdCB7IHRpdGxlLCBleGFtcGxlRmlsZVVybHMgfTogQnVsa0Rlc2NyaXB0aW9uID1cbiAgICAgIGF3YWl0IHRoaXMuYnVsa0V4dGVuc2libGVEZXZpY2VSZWdpc3RyYXRpb25TZXJ2aWNlXG4gICAgICAgIC5nZXRCdWxrRGVzY3JpcHRpb24odGhpcy5jb250ZXh0UGF0aClcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgICAgIHRoaXMubG9hZGluZ0Vycm9yID0gdHJ1ZTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aXRsZTogZ2V0dGV4dCgnRXJyb3InKSxcbiAgICAgICAgICAgIGV4YW1wbGVGaWxlVXJsczogW11cbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgIHRoaXMudGl0bGUgPSB0aXRsZTtcbiAgICB0aGlzLnRlbXBsYXRlID0gW3RoaXMuanNvbnNjaGVtYS50b0ZpZWxkQ29uZmlnKGV4dGVuc2libGVEZXZpY2VSZWdpc3RyYXRpb25CdWxrU2NoZW1hKV07XG4gICAgdGhpcy5leGFtcGxlcyA9IGV4YW1wbGVGaWxlVXJscztcbiAgfVxuXG4gIGFzeW5jIHVwbG9hZCgpIHtcbiAgICB0aGlzLnBlbmRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHsgcmVzLCBkYXRhIH06IElSZXN1bHQ8QnVsa1Jlc3VsdD4gPSBhd2FpdCB0aGlzLmJ1bGtFeHRlbnNpYmxlRGV2aWNlUmVnaXN0cmF0aW9uU2VydmljZVxuICAgICAgLnVwbG9hZCh0aGlzLmdldEZpbGUodGhpcy5tb2RlbCksIHRoaXMuY29udGV4dFBhdGgpXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlczogdW5kZWZpbmVkLFxuICAgICAgICAgIGRhdGE6IHVuZGVmaW5lZFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgdGhpcy5wZW5kaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RlcHBlci5uZXh0KCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVzdWx0ID0gZGF0YTtcbiAgICB0aGlzLnN1Y2Nlc3MgPSByZXM/LnN0YXR1cyA8IDQwMDtcblxuICAgIGlmICh0aGlzLnN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMubWVzc2FnZSA9IGdldHRleHQoJ0RldmljZSByZWdpc3RyYXRpb24gY3JlYXRlZC4nKTtcbiAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoUFJPRFVDVF9FWFBFUklFTkNFX0JBU0VfUkVHSVNUUkFUSU9OLkVWRU5ULCB7XG4gICAgICAgIHJlc3VsdDogUFJPRFVDVF9FWFBFUklFTkNFX0JBU0VfUkVHSVNUUkFUSU9OLlJFU1VMVC5TVUNDRVNTLFxuICAgICAgICBjb21wb25lbnQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9CQVNFX1JFR0lTVFJBVElPTi5DT01QT05FTlQuRVhURU5TSUJMRV9CVUxLXG4gICAgICB9KTtcbiAgICAgIHRoaXMubW9kZWwgPSB7fTtcbiAgICB9XG5cbiAgICBpZiAocmVzKSB7XG4gICAgICBpZiAocmVzLnN0YXR1cyA+PSA0MDAgJiYgcmVzLnN0YXR1cyA8IDUwMCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBnZXR0ZXh0KCdEZXZpY2UgcmVnaXN0cmF0aW9uIGZhaWxlZC4nKTtcbiAgICAgICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChQUk9EVUNUX0VYUEVSSUVOQ0VfQkFTRV9SRUdJU1RSQVRJT04uRVZFTlQsIHtcbiAgICAgICAgICByZXN1bHQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9CQVNFX1JFR0lTVFJBVElPTi5SRVNVTFQuRkFJTFVSRSxcbiAgICAgICAgICBjb21wb25lbnQ6IFBST0RVQ1RfRVhQRVJJRU5DRV9CQVNFX1JFR0lTVFJBVElPTi5DT01QT05FTlQuRVhURU5TSUJMRV9CVUxLXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChyZXMuc3RhdHVzID49IDUwMCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBnZXR0ZXh0KCdFcnJvciBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIHRoZSB1cGxvYWRlZCBmaWxlLicpO1xuICAgICAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudHJpZ2dlckV2ZW50KFBST0RVQ1RfRVhQRVJJRU5DRV9CQVNFX1JFR0lTVFJBVElPTi5FVkVOVCwge1xuICAgICAgICAgIHJlc3VsdDogUFJPRFVDVF9FWFBFUklFTkNFX0JBU0VfUkVHSVNUUkFUSU9OLlJFU1VMVC5GQUlMVVJFLFxuICAgICAgICAgIGNvbXBvbmVudDogUFJPRFVDVF9FWFBFUklFTkNFX0JBU0VfUkVHSVNUUkFUSU9OLkNPTVBPTkVOVC5FWFRFTlNJQkxFX0JVTEtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWVzc2FnZSA9IGdldHRleHQoJ05vIGludGVybmV0IGNvbm5lY3Rpb24uIFVuYWJsZSB0byByZWFjaCB0aGUgbWljcm9zZXJ2aWNlLicpO1xuICAgIH1cbiAgfVxuXG4gIGdldEZpbGUobW9kZWwpIHtcbiAgICBjb25zdCBjc3ZCdWxrRmlsZSA9IChtb2RlbCBhcyBhbnkpPy5jc3ZCdWxrRmlsZTtcbiAgICByZXR1cm4gY3N2QnVsa0ZpbGUgPyBjc3ZCdWxrRmlsZVswXT8uZmlsZSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbXBsZXRlKCkge1xuICAgIHRoaXMucmVnaXN0ZXJEZXZpY2VTZXJ2aWNlLmxpc3QoKTtcbiAgICB0aGlzLmJzTW9kYWxSZWYuaGlkZSgpO1xuICB9XG5cbiAgY2FuY2VsKCkge1xuICAgIHRoaXMuYnNNb2RhbFJlZi5oaWRlKCk7XG4gIH1cbn1cbiIsIjxjOHktbW9kYWxcbiAgW3RpdGxlXT1cInRpdGxlIHwgdHJhbnNsYXRlXCJcbiAgW2hlYWRlckNsYXNzZXNdPVwiJ2RpYWxvZy1oZWFkZXInXCJcbiAgW2N1c3RvbUZvb3Rlcl09XCJ0cnVlXCJcbj5cbiAgPG5nLWNvbnRhaW5lciBjOHktbW9kYWwtdGl0bGU+XG4gICAgPGkgYzh5SWNvbj1cImM4eS1kZXZpY2UtY29ubmVjdFwiPjwvaT5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxjOHktc3RlcHBlciBbaGlkZVN0ZXBQcm9ncmVzc109XCJ0cnVlXCIgbGluZWFyIGNsYXNzPVwicC10LTE2XCIgYzh5LW1vZGFsLWJvZHk+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFsb2FkaW5nRXJyb3JcIj5cbiAgICAgIDxjZGstc3RlcD5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN0aWNreS10b3AgYmctY29tcG9uZW50IHNlcGFyYXRvci1ib3R0b21cIj5cbiAgICAgICAgICA8cFxuICAgICAgICAgICAgY2xhc3M9XCJwLWwtMjQgcC1yLTI0IHAtdC0xNiBwLWItMTYgbS1iLTAgc2VwYXJhdG9yLWJvdHRvbSB0ZXh0LTE2IHRleHQtbWVkaXVtIHRleHQtY2VudGVyIGJnLWNvbXBvbmVudFwiXG4gICAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICA+XG4gICAgICAgICAgICBSZWdpc3RlciBkZXZpY2VzIGluIGJ1bGtcbiAgICAgICAgICA8L3A+XG4gICAgICAgICAgPGM4eS1mb3JtLWdyb3VwIGNsYXNzPVwicC0yNCBwLXQtMTYgcC1iLTggbS1iLTBcIj5cbiAgICAgICAgICAgIDxmb3JtbHktZm9ybSBbZm9ybV09XCJmb3JtXCIgW2ZpZWxkc109XCJ0ZW1wbGF0ZVwiIFttb2RlbF09XCJtb2RlbFwiPjwvZm9ybWx5LWZvcm0+XG4gICAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgZXhhbXBsZSBvZiBleGFtcGxlc1wiXG4gICAgICAgICAgY2xhc3M9XCJiZy1ncmF5LXdoaXRlIHNlcGFyYXRvci1ib3R0b20gcC10LTE2IHAtYi0xNiBwLWwtMjQgcC1yLTI0XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxwIGNsYXNzPVwibS1iLTggdGV4dC1tZWRpdW1cIj5cbiAgICAgICAgICAgIHt7IGV4YW1wbGUudGl0bGUgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L3A+XG4gICAgICAgICAgPHAgY2xhc3M9XCJzbWFsbCBtLWItOFwiPnt7IGV4YW1wbGUuZGVzY3JpcHRpb24gfCB0cmFuc2xhdGUgfX08L3A+XG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ0Rvd25sb2FkIHRlbXBsYXRlJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBidG4tc21cIlxuICAgICAgICAgICAgdGFyZ2V0PVwiX3NlbGZcIlxuICAgICAgICAgICAgW2hyZWZdPVwiZXhhbXBsZS51cmxcIlxuICAgICAgICAgICAgZG93bmxvYWQ9XCJ7eyAnRXhhbXBsZSBidWxrIHJlZ2lzdHJhdGlvbiAtIHRlbXBsYXRlLmNzdicgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxpIGM4eUljb249XCJkb3dubG9hZFwiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5Eb3dubG9hZCB0ZW1wbGF0ZTwvc3Bhbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8Yzh5LXN0ZXBwZXItYnV0dG9uc1xuICAgICAgICAgIGNsYXNzPVwic3RpY2t5LWJvdHRvbSBkLWJsb2NrIHAtdC0xNiBwLWItMTYgc2VwYXJhdG9yLXRvcCBiZy1sZXZlbC0wXCJcbiAgICAgICAgICBbc2hvd0J1dHRvbnNdPVwieyBjYW5jZWw6IHRydWUsIG5leHQ6IHRydWUgfVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImZvcm0uaW52YWxpZFwiXG4gICAgICAgICAgW3BlbmRpbmddPVwicGVuZGluZ1wiXG4gICAgICAgICAgKG9uQ2FuY2VsKT1cImNhbmNlbCgpXCJcbiAgICAgICAgICAob25OZXh0KT1cInVwbG9hZCgpXCJcbiAgICAgICAgICBbbGFiZWxzXT1cInsgbmV4dDogJ1VwbG9hZCcgfVwiXG4gICAgICAgID48L2M4eS1zdGVwcGVyLWJ1dHRvbnM+XG4gICAgICA8L2Nkay1zdGVwPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxjZGstc3RlcCBzdGF0ZT1cImZpbmFsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicC0yNFwiPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwic3VjY2VzczsgZWxzZSBmYWlsXCI+XG4gICAgICAgICAgPGM4eS1vcGVyYXRpb24tcmVzdWx0XG4gICAgICAgICAgICB0ZXh0PVwie3sgbWVzc2FnZSB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBbc2l6ZV09XCI4NFwiXG4gICAgICAgICAgICBbdmVydGljYWxdPVwidHJ1ZVwiXG4gICAgICAgICAgICB0eXBlPVwic3VjY2Vzc1wiXG4gICAgICAgICAgICBjbGFzcz1cImxlYWRcIlxuICAgICAgICAgICAgZGF0YS1jeT1cInN1Y2Nlc3NcIlxuICAgICAgICAgID48L2M4eS1vcGVyYXRpb24tcmVzdWx0PlxuICAgICAgICAgIDxjOHktbGlzdC1ncm91cCBjbGFzcz1cInNlcGFyYXRvci10b3AgbS10LTE2XCI+XG4gICAgICAgICAgICA8Yzh5LWxpPlxuICAgICAgICAgICAgICA8Yzh5LWxpLWljb24gY2xhc3M9XCJ0ZXh0LXN1Y2Nlc3NcIiBbaWNvbl09XCInY2hlY2stY2lyY2xlJ1wiPjwvYzh5LWxpLWljb24+XG4gICAgICAgICAgICAgIDxwIHRyYW5zbGF0ZT5GaWxlIHN1Y2Nlc3NmdWxseSB1cGxvYWRlZC48L3A+XG4gICAgICAgICAgICAgIDxjOHktbGktY29sbGFwc2U+XG4gICAgICAgICAgICAgICAgPHByZT48Y29kZT57eyByZXN1bHQgfCBqc29uIH19PC9jb2RlPjwvcHJlPlxuICAgICAgICAgICAgICA8L2M4eS1saS1jb2xsYXBzZT5cbiAgICAgICAgICAgIDwvYzh5LWxpPlxuICAgICAgICAgIDwvYzh5LWxpc3QtZ3JvdXA+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bmctdGVtcGxhdGUgI2ZhaWw+XG4gICAgICAgICAgPGM4eS1vcGVyYXRpb24tcmVzdWx0XG4gICAgICAgICAgICB0ZXh0PVwie3sgbWVzc2FnZSB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBbc2l6ZV09XCI4NFwiXG4gICAgICAgICAgICBbdmVydGljYWxdPVwidHJ1ZVwiXG4gICAgICAgICAgICB0eXBlPVwiZXJyb3JcIlxuICAgICAgICAgICAgY2xhc3M9XCJsZWFkXCJcbiAgICAgICAgICAgIGRhdGEtY3k9XCJlcnJvclwiXG4gICAgICAgICAgPjwvYzh5LW9wZXJhdGlvbi1yZXN1bHQ+XG4gICAgICAgICAgPGM4eS1saXN0LWdyb3VwICpuZ0lmPVwicmVzdWx0XCIgY2xhc3M9XCJzZXBhcmF0b3ItdG9wIG0tdC0xNlwiPlxuICAgICAgICAgICAgPGM4eS1saT5cbiAgICAgICAgICAgICAgPGM4eS1saS1pY29uIGNsYXNzPVwidGV4dC1kYW5nZXJcIiBbaWNvbl09XCInYmFuJ1wiPjwvYzh5LWxpLWljb24+XG4gICAgICAgICAgICAgIDxwIHRyYW5zbGF0ZT5CdWxrIG9wZXJhdGlvbiBmYWlsZWQuPC9wPlxuICAgICAgICAgICAgICA8Yzh5LWxpLWNvbGxhcHNlPlxuICAgICAgICAgICAgICAgIDxwcmU+PGNvZGU+e3sgcmVzdWx0IHwganNvbiB9fTwvY29kZT48L3ByZT5cbiAgICAgICAgICAgICAgPC9jOHktbGktY29sbGFwc2U+XG4gICAgICAgICAgICA8L2M4eS1saT5cbiAgICAgICAgICA8L2M4eS1saXN0LWdyb3VwPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgICA8Yzh5LXN0ZXBwZXItYnV0dG9uc1xuICAgICAgICBjbGFzcz1cInN0aWNreS1ib3R0b20gZC1ibG9jayBwLXQtMTYgcC1iLTE2IHNlcGFyYXRvci10b3AgYmctY29tcG9uZW50XCJcbiAgICAgICAgW3Nob3dCdXR0b25zXT1cInsgbmV4dDogdHJ1ZSB9XCJcbiAgICAgICAgKG9uTmV4dCk9XCJjb21wbGV0ZSgpXCJcbiAgICAgICAgW2xhYmVsc109XCJ7IG5leHQ6IHN1Y2Nlc3MgPyAnQ29tcGxldGUnIDogJ0NhbmNlbCcgfVwiXG4gICAgICA+PC9jOHktc3RlcHBlci1idXR0b25zPlxuICAgIDwvY2RrLXN0ZXA+XG4gIDwvYzh5LXN0ZXBwZXI+XG48L2M4eS1tb2RhbD5cbiJdfQ==