UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

232 lines 31.4 kB
import { Injectable } from '@angular/core'; import { ApplicationService, FetchClient, InventoryService } from '@c8y/client'; import { AppStateService, OptionsService, gettext } from '@c8y/ngx-components'; import { TranslateService } from '@ngx-translate/core'; import { some } from 'lodash-es'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "@ngx-translate/core"; import * as i3 from "@c8y/ngx-components"; export var ActilityErrorName; (function (ActilityErrorName) { ActilityErrorName["NoConnectivityPlansError"] = "NoConnectivityPlansError"; ActilityErrorName["NoFreeSlotsInConnectivityPlansError"] = "NoFreeSlotsInConnectivityPlansError"; ActilityErrorName["NoConnectivitySettingsError"] = "NoConnectivitySettingsError"; ActilityErrorName["ConnectivitySettingsError"] = "ConnectivitySettingsError"; ActilityErrorName["NoDeviceProfilesError"] = "NoDeviceProfilesError"; ActilityErrorName["DeviceProfilesFetchError"] = "DeviceProfilesFetchError"; ActilityErrorName["NoDeviceProtocolsError"] = "NoDeviceProtocolsError"; ActilityErrorName["DeviceProtocolsFetchError"] = "DeviceProtocolsFetchError"; ActilityErrorName["RegistrationError"] = "RegistrationError"; })(ActilityErrorName || (ActilityErrorName = {})); export class ActilityDeviceRegistrationService { constructor(inventoryService, client, translateService, applicationService, optionsService, appState) { this.inventoryService = inventoryService; this.client = client; this.translateService = translateService; this.applicationService = applicationService; this.optionsService = optionsService; this.appState = appState; this.baseUrl = '/service/actility'; this.registrationUrl = `${this.baseUrl}/newDeviceRequest`; this.connectivityPlansUrl = `${this.baseUrl}/connectivityPlans`; this.deviceProfilesUrl = `${this.baseUrl}/deviceProfiles`; this.headers = { 'Content-Type': 'application/json' }; } async getConnections() { const options = { method: 'GET', headers: this.headers }; const res = await this.client.fetch(`${this.baseUrl}/lns-connection`, options); const data = await res.json(); if (res.status === 200) { if (data.length === 0) { await this.throwNoConnectivitySettingsError(); } } else { await this.throwConnectivitySettingsError(data); } return { res, data }; } /** * Gets connectivity plans from LoRa platform. * @param connectionName The name of connection for which connectivity plans will be retrieved * @returns The result list with connectivity plans, or throws an error with exception. */ async getConnectivityPlans(connectionName) { const options = { method: 'GET', headers: this.headers, params: { actilityConnectionName: connectionName } }; const res = await this.client.fetch(this.connectivityPlansUrl, options); const data = await res.json(); if (res.status === 200) { if (data.length === 0) { this.throwNoConnectivityPlansError(); } else { if (!this.hasAvailableConnections(data)) { this.throwNoFreeSlotsInConnectivityPlansError(); } } } else { await this.throwConnectivitySettingsError(data); } return { res, data }; } /** * Gets the device profiles from LoRa platform. * @param connectionName The name of connection for which device profiles will be retrieved * @returns The result list with device profiles, or throws an error with exception. */ async getDeviceProfiles(connectionName) { const options = { method: 'GET', headers: this.headers, params: { actilityConnectionName: connectionName } }; const res = await this.client.fetch(this.deviceProfilesUrl, options); const data = await res.json(); if (res.status === 200) { if (data.length === 0) { this.throwNoDeviceProfilesError(); } } else { this.throwDeviceProfilesFetchError(); } return { res, data }; } /** * Gets the device protocols */ async getDeviceProtocols(filter = { withTotalPages: true }) { const query = { __filter: { __and: [ { __has: 'c8y_IsDeviceType' }, { type: { __in: ['c8y_ActilityDeviceType', 'c8y_LoraDeviceType', 'c8y_LpwanDeviceType'] } } ] }, __orderby: [{ name: 1 }] }; const deviceProtocolsList = await this.inventoryService.listQuery(query, filter); const { res, data } = deviceProtocolsList; if (res.status === 200) { if (data.length === 0) { this.throwNoDeviceProtocolsError(); } } else { this.throwDeviceProtocolsFetchError(); } return deviceProtocolsList; } /** * Creates device registration */ async register(registration) { const options = { method: 'POST', headers: this.headers, body: JSON.stringify(registration) }; const res = await this.client.fetch(this.registrationUrl, options); const data = await res.json(); if (res.status !== 201) { this.throwRegistrationError(data); } return { res, data }; } /** * checks if used connections is less then granted connections */ hasAvailableConnections(connectivityPlans) { return some(connectivityPlans, plan => parseInt(plan.grantedConnections, 10) > parseInt(plan.usedConnections, 10)); } async throwNoConnectivitySettingsError() { const error = new Error(); error.name = ActilityErrorName.NoConnectivitySettingsError; if (await this.appState.isApplicationAvailable('administration')) { error.message = this.translateService.instant(gettext(`Could not get connectivity plans from the LoRa platform. Verify the ThingPark credentials in the Administration application under <a href="{{ link }}">Settings</a>.`), { link: '/apps/administration/index.html#/connectivitySettings/multiple_lns_connectors_actility' }); } else { error.message = gettext('Could not get connectivity plans from the LoRa platform. Please contact the administrator.'); } throw error; } throwConnectivitySettingsError(data) { const error = new Error(); error.name = ActilityErrorName.ConnectivitySettingsError; error.message = data.message; throw error; } throwNoConnectivityPlansError() { const error = new Error(); error.name = ActilityErrorName.NoConnectivityPlansError; error.message = gettext('No connectivity plans found. New connectivity plans must be created via the LoRa platform.'); throw error; } throwNoFreeSlotsInConnectivityPlansError() { const companyName = this.optionsService.get('companyName', 'Cumulocity IoT'); const error = new Error(); error.name = ActilityErrorName.NoFreeSlotsInConnectivityPlansError; error.message = this.translateService.instant(gettext(`No connectivity plans with free slots available. Please contact ThingPark on the device quota limits for your connectivity plans or remove unused devices from ThingPark and retry registering the device in the {{companyName}} platform.`), { companyName }); throw error; } throwDeviceProfilesFetchError() { const error = new Error(); error.name = ActilityErrorName.DeviceProfilesFetchError; error.message = gettext('Could not load device profiles from the LoRa platform.'); throw error; } throwNoDeviceProfilesError() { const error = new Error(); error.name = ActilityErrorName.NoDeviceProfilesError; error.message = gettext('No device profiles found. Create a new device profile via the LoRa platform.'); throw error; } throwDeviceProtocolsFetchError() { const error = new Error(); error.name = ActilityErrorName.DeviceProtocolsFetchError; error.message = gettext('Could not load device protocols.'); throw error; } throwNoDeviceProtocolsError() { const error = new Error(); error.name = ActilityErrorName.NoDeviceProtocolsError; error.message = this.translateService.instant(gettext(`No device protocols configured. Create a LoRa device protocol in <a href="{{ link }}">Device protocols</a>.`), { link: '/apps/devicemanagement/#/deviceprotocols' }); throw error; } throwRegistrationError(data) { const error = new Error(); error.name = ActilityErrorName.RegistrationError; error.message = data.message; throw error; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, deps: [{ token: i1.InventoryService }, { token: i1.FetchClient }, { token: i2.TranslateService }, { token: i1.ApplicationService }, { token: i3.OptionsService }, { token: i3.AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.InventoryService }, { type: i1.FetchClient }, { type: i2.TranslateService }, { type: i1.ApplicationService }, { type: i3.OptionsService }, { type: i3.AppStateService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi9hY3RpbGl0eS1kZXZpY2UtcmVnaXN0cmF0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLFdBQVcsRUFJWCxnQkFBZ0IsRUFDakIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQzs7Ozs7QUFPakMsTUFBTSxDQUFOLElBQVksaUJBVVg7QUFWRCxXQUFZLGlCQUFpQjtJQUMzQiwwRUFBcUQsQ0FBQTtJQUNyRCxnR0FBMkUsQ0FBQTtJQUMzRSxnRkFBMkQsQ0FBQTtJQUMzRCw0RUFBdUQsQ0FBQTtJQUN2RCxvRUFBK0MsQ0FBQTtJQUMvQywwRUFBcUQsQ0FBQTtJQUNyRCxzRUFBaUQsQ0FBQTtJQUNqRCw0RUFBdUQsQ0FBQTtJQUN2RCw0REFBdUMsQ0FBQTtBQUN6QyxDQUFDLEVBVlcsaUJBQWlCLEtBQWpCLGlCQUFpQixRQVU1QjtBQUdELE1BQU0sT0FBTyxpQ0FBaUM7SUFTNUMsWUFDVSxnQkFBa0MsRUFDbEMsTUFBbUIsRUFDbkIsZ0JBQWtDLEVBQ2xDLGtCQUFzQyxFQUN0QyxjQUE4QixFQUM5QixRQUF5QjtRQUx6QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLFdBQU0sR0FBTixNQUFNLENBQWE7UUFDbkIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyx1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Q0FBQztJQUNkLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxJQUF5QjtRQUN0RCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsaUJBQWlCLENBQUM7UUFDakQsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzdCLE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQzsrR0EzUFUsaUNBQWlDO21IQUFqQyxpQ0FBaUMsY0FEcEIsTUFBTTs7NEZBQ25CLGlDQUFpQztrQkFEN0MsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvblNlcnZpY2UsXG4gIEZldGNoQ2xpZW50LFxuICBJRmV0Y2hPcHRpb25zLFxuICBJTWFuYWdlZE9iamVjdCxcbiAgSVJlc3VsdExpc3QsXG4gIEludmVudG9yeVNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlLCBPcHRpb25zU2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgc29tZSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBBY3RpbGl0eURldmljZVByb2ZpbGUsXG4gIEFjdGlsaXR5RGV2aWNlUmVnaXN0cmF0aW9uLFxuICBDb25uZWN0aXZpdHlQbGFuXG59IGZyb20gJy4vYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi5tb2RlbCc7XG5cbmV4cG9ydCBlbnVtIEFjdGlsaXR5RXJyb3JOYW1lIHtcbiAgTm9Db25uZWN0aXZpdHlQbGFuc0Vycm9yID0gJ05vQ29ubmVjdGl2aXR5UGxhbnNFcnJvcicsXG4gIE5vRnJlZVNsb3RzSW5Db25uZWN0aXZpdHlQbGFuc0Vycm9yID0gJ05vRnJlZVNsb3RzSW5Db25uZWN0aXZpdHlQbGFuc0Vycm9yJyxcbiAgTm9Db25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yID0gJ05vQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcicsXG4gIENvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IgPSAnQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcicsXG4gIE5vRGV2aWNlUHJvZmlsZXNFcnJvciA9ICdOb0RldmljZVByb2ZpbGVzRXJyb3InLFxuICBEZXZpY2VQcm9maWxlc0ZldGNoRXJyb3IgPSAnRGV2aWNlUHJvZmlsZXNGZXRjaEVycm9yJyxcbiAgTm9EZXZpY2VQcm90b2NvbHNFcnJvciA9ICdOb0RldmljZVByb3RvY29sc0Vycm9yJyxcbiAgRGV2aWNlUHJvdG9jb2xzRmV0Y2hFcnJvciA9ICdEZXZpY2VQcm90b2NvbHNGZXRjaEVycm9yJyxcbiAgUmVnaXN0cmF0aW9uRXJyb3IgPSAnUmVnaXN0cmF0aW9uRXJyb3InXG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQWN0aWxpdHlEZXZpY2VSZWdpc3RyYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBiYXNlVXJsID0gJy9zZXJ2aWNlL2FjdGlsaXR5JztcbiAgcHJpdmF0ZSByZWdpc3RyYXRpb25VcmwgPSBgJHt0aGlzLmJhc2VVcmx9L25ld0RldmljZVJlcXVlc3RgO1xuICBwcml2YXRlIGNvbm5lY3Rpdml0eVBsYW5zVXJsID0gYCR7dGhpcy5iYXNlVXJsfS9jb25uZWN0aXZpdHlQbGFuc2A7XG4gIHByaXZhdGUgZGV2aWNlUHJvZmlsZXNVcmwgPSBgJHt0aGlzLmJhc2VVcmx9L2RldmljZVByb2ZpbGVzYDtcbiAgcHJpdmF0ZSBoZWFkZXJzOiBvYmplY3QgPSB7XG4gICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaW52ZW50b3J5U2VydmljZTogSW52ZW50b3J5U2VydmljZSxcbiAgICBwcml2YXRlIGNsaWVudDogRmV0Y2hDbGllbnQsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwbGljYXRpb25TZXJ2aWNlOiBBcHBsaWNhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBvcHRpb25zU2VydmljZTogT3B0aW9uc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBhcHBTdGF0ZTogQXBwU3RhdGVTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBnZXRDb25uZWN0aW9ucygpIHtcbiAgICBjb25zdCBvcHRpb25zOiBJRmV0Y2hPcHRpb25zID0ge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHRoaXMuaGVhZGVyc1xuICAgIH07XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jbGllbnQuZmV0Y2goYCR7dGhpcy5iYXNlVXJsfS9sbnMtY29ubmVjdGlvbmAsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMudGhyb3dOb0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy50aHJvd0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB7IHJlcywgZGF0YSB9O1xuICB9XG4gIC8qKlxuICAgKiBHZXRzIGNvbm5lY3Rpdml0eSBwbGFucyBmcm9tIExvUmEgcGxhdGZvcm0uXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uTmFtZSBUaGUgbmFtZSBvZiBjb25uZWN0aW9uIGZvciB3aGljaCBjb25uZWN0aXZpdHkgcGxhbnMgd2lsbCBiZSByZXRyaWV2ZWRcbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCBsaXN0IHdpdGggY29ubmVjdGl2aXR5IHBsYW5zLCBvciB0aHJvd3MgYW4gZXJyb3Igd2l0aCBleGNlcHRpb24uXG4gICAqL1xuICBhc3luYyBnZXRDb25uZWN0aXZpdHlQbGFucyhjb25uZWN0aW9uTmFtZTogc3RyaW5nKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxDb25uZWN0aXZpdHlQbGFuPj4ge1xuICAgIGNvbnN0IG9wdGlvbnM6IElGZXRjaE9wdGlvbnMgPSB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczogdGhpcy5oZWFkZXJzLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGFjdGlsaXR5Q29ubmVjdGlvbk5hbWU6IGNvbm5lY3Rpb25OYW1lXG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuY2xpZW50LmZldGNoKHRoaXMuY29ubmVjdGl2aXR5UGxhbnNVcmwsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMudGhyb3dOb0Nvbm5lY3Rpdml0eVBsYW5zRXJyb3IoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdGhpcy5oYXNBdmFpbGFibGVDb25uZWN0aW9ucyhkYXRhKSkge1xuICAgICAgICAgIHRoaXMudGhyb3dOb0ZyZWVTbG90c0luQ29ubmVjdGl2aXR5UGxhbnNFcnJvcigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMudGhyb3dDb25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yKGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB7IHJlcywgZGF0YSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGRldmljZSBwcm9maWxlcyBmcm9tIExvUmEgcGxhdGZvcm0uXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uTmFtZSBUaGUgbmFtZSBvZiBjb25uZWN0aW9uIGZvciB3aGljaCBkZXZpY2UgcHJvZmlsZXMgd2lsbCBiZSByZXRyaWV2ZWRcbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCBsaXN0IHdpdGggZGV2aWNlIHByb2ZpbGVzLCBvciB0aHJvd3MgYW4gZXJyb3Igd2l0aCBleGNlcHRpb24uXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VQcm9maWxlcyhjb25uZWN0aW9uTmFtZTogc3RyaW5nKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxBY3RpbGl0eURldmljZVByb2ZpbGU+PiB7XG4gICAgY29uc3Qgb3B0aW9uczogSUZldGNoT3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXG4gICAgICBwYXJhbXM6IHtcbiAgICAgICAgYWN0aWxpdHlDb25uZWN0aW9uTmFtZTogY29ubmVjdGlvbk5hbWVcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jbGllbnQuZmV0Y2godGhpcy5kZXZpY2VQcm9maWxlc1VybCwgb3B0aW9ucyk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy50aHJvd05vRGV2aWNlUHJvZmlsZXNFcnJvcigpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRocm93RGV2aWNlUHJvZmlsZXNGZXRjaEVycm9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcmVzLCBkYXRhIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGV2aWNlIHByb3RvY29sc1xuICAgKi9cbiAgYXN5bmMgZ2V0RGV2aWNlUHJvdG9jb2xzKFxuICAgIGZpbHRlcjogb2JqZWN0ID0geyB3aXRoVG90YWxQYWdlczogdHJ1ZSB9XG4gICk6IFByb21pc2U8SVJlc3VsdExpc3Q8SU1hbmFnZWRPYmplY3Q+PiB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICBfX2ZpbHRlcjoge1xuICAgICAgICBfX2FuZDogW1xuICAgICAgICAgIHsgX19oYXM6ICdjOHlfSXNEZXZpY2VUeXBlJyB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IHsgX19pbjogWydjOHlfQWN0aWxpdHlEZXZpY2VUeXBlJywgJ2M4eV9Mb3JhRGV2aWNlVHlwZScsICdjOHlfTHB3YW5EZXZpY2VUeXBlJ10gfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgIF9fb3JkZXJieTogW3sgbmFtZTogMSB9XVxuICAgIH07XG4gICAgY29uc3QgZGV2aWNlUHJvdG9jb2xzTGlzdCA9IGF3YWl0IHRoaXMuaW52ZW50b3J5U2VydmljZS5saXN0UXVlcnkocXVlcnksIGZpbHRlcik7XG4gICAgY29uc3QgeyByZXMsIGRhdGEgfSA9IGRldmljZVByb3RvY29sc0xpc3Q7XG5cbiAgICBpZiAocmVzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy50aHJvd05vRGV2aWNlUHJvdG9jb2xzRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aHJvd0RldmljZVByb3RvY29sc0ZldGNoRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGV2aWNlUHJvdG9jb2xzTGlzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGRldmljZSByZWdpc3RyYXRpb25cbiAgICovXG4gIGFzeW5jIHJlZ2lzdGVyKHJlZ2lzdHJhdGlvbjogQWN0aWxpdHlEZXZpY2VSZWdpc3RyYXRpb24pIHtcbiAgICBjb25zdCBvcHRpb25zOiBJRmV0Y2hPcHRpb25zID0ge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShyZWdpc3RyYXRpb24pXG4gICAgfTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuY2xpZW50LmZldGNoKHRoaXMucmVnaXN0cmF0aW9uVXJsLCBvcHRpb25zKTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcblxuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEpIHtcbiAgICAgIHRoaXMudGhyb3dSZWdpc3RyYXRpb25FcnJvcihkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByZXMsIGRhdGEgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjaGVja3MgaWYgdXNlZCBjb25uZWN0aW9ucyBpcyBsZXNzIHRoZW4gZ3JhbnRlZCBjb25uZWN0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBoYXNBdmFpbGFibGVDb25uZWN0aW9ucyhjb25uZWN0aXZpdHlQbGFucykge1xuICAgIHJldHVybiBzb21lKFxuICAgICAgY29ubmVjdGl2aXR5UGxhbnMsXG4gICAgICBwbGFuID0+IHBhcnNlSW50KHBsYW4uZ3JhbnRlZENvbm5lY3Rpb25zLCAxMCkgPiBwYXJzZUludChwbGFuLnVzZWRDb25uZWN0aW9ucywgMTApXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdGhyb3dOb0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuTm9Db25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yO1xuXG4gICAgaWYgKGF3YWl0IHRoaXMuYXBwU3RhdGUuaXNBcHBsaWNhdGlvbkF2YWlsYWJsZSgnYWRtaW5pc3RyYXRpb24nKSkge1xuICAgICAgZXJyb3IubWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICBnZXR0ZXh0KFxuICAgICAgICAgIGBDb3VsZCBub3QgZ2V0IGNvbm5lY3Rpdml0eSBwbGFucyBmcm9tIHRoZSBMb1JhIHBsYXRmb3JtLiBWZXJpZnkgdGhlIFRoaW5nUGFyayBjcmVkZW50aWFscyBpbiB0aGUgQWRtaW5pc3RyYXRpb24gYXBwbGljYXRpb24gdW5kZXIgPGEgaHJlZj1cInt7IGxpbmsgfX1cIj5TZXR0aW5nczwvYT4uYFxuICAgICAgICApLFxuICAgICAgICB7XG4gICAgICAgICAgbGluazogJy9hcHBzL2FkbWluaXN0cmF0aW9uL2luZGV4Lmh0bWwjL2Nvbm5lY3Rpdml0eVNldHRpbmdzL211bHRpcGxlX2xuc19jb25uZWN0b3JzX2FjdGlsaXR5J1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvci5tZXNzYWdlID0gZ2V0dGV4dChcbiAgICAgICAgJ0NvdWxkIG5vdCBnZXQgY29ubmVjdGl2aXR5IHBsYW5zIGZyb20gdGhlIExvUmEgcGxhdGZvcm0uIFBsZWFzZSBjb250YWN0IHRoZSBhZG1pbmlzdHJhdG9yLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBwcml2YXRlIHRocm93Q29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcihkYXRhOiB7IG1lc3NhZ2U6IHN0cmluZyB9KSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd05vQ29ubmVjdGl2aXR5UGxhbnNFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0Nvbm5lY3Rpdml0eVBsYW5zRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoXG4gICAgICAnTm8gY29ubmVjdGl2aXR5IHBsYW5zIGZvdW5kLiBOZXcgY29ubmVjdGl2aXR5IHBsYW5zIG11c3QgYmUgY3JlYXRlZCB2aWEgdGhlIExvUmEgcGxhdGZvcm0uJ1xuICAgICk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBwcml2YXRlIHRocm93Tm9GcmVlU2xvdHNJbkNvbm5lY3Rpdml0eVBsYW5zRXJyb3IoKSB7XG4gICAgY29uc3QgY29tcGFueU5hbWUgPSB0aGlzLm9wdGlvbnNTZXJ2aWNlLmdldCgnY29tcGFueU5hbWUnLCAnQ3VtdWxvY2l0eSBJb1QnKTtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0ZyZWVTbG90c0luQ29ubmVjdGl2aXR5UGxhbnNFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KFxuICAgICAgICBgTm8gY29ubmVjdGl2aXR5IHBsYW5zIHdpdGggZnJlZSBzbG90cyBhdmFpbGFibGUuIFBsZWFzZSBjb250YWN0IFRoaW5nUGFyayBvbiB0aGUgZGV2aWNlIHF1b3RhIGxpbWl0cyBmb3IgeW91ciBjb25uZWN0aXZpdHkgcGxhbnMgb3IgcmVtb3ZlIHVudXNlZCBkZXZpY2VzIGZyb20gVGhpbmdQYXJrIGFuZCByZXRyeSByZWdpc3RlcmluZyB0aGUgZGV2aWNlIGluIHRoZSB7e2NvbXBhbnlOYW1lfX0gcGxhdGZvcm0uYFxuICAgICAgKSxcbiAgICAgIHtcbiAgICAgICAgY29tcGFueU5hbWVcbiAgICAgIH1cbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd0RldmljZVByb2ZpbGVzRmV0Y2hFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5EZXZpY2VQcm9maWxlc0ZldGNoRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoJ0NvdWxkIG5vdCBsb2FkIGRldmljZSBwcm9maWxlcyBmcm9tIHRoZSBMb1JhIHBsYXRmb3JtLicpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd05vRGV2aWNlUHJvZmlsZXNFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0RldmljZVByb2ZpbGVzRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoXG4gICAgICAnTm8gZGV2aWNlIHByb2ZpbGVzIGZvdW5kLiBDcmVhdGUgYSBuZXcgZGV2aWNlIHByb2ZpbGUgdmlhIHRoZSBMb1JhIHBsYXRmb3JtLidcbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd0RldmljZVByb3RvY29sc0ZldGNoRXJyb3IoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuRGV2aWNlUHJvdG9jb2xzRmV0Y2hFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZ2V0dGV4dCgnQ291bGQgbm90IGxvYWQgZGV2aWNlIHByb3RvY29scy4nKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHByaXZhdGUgdGhyb3dOb0RldmljZVByb3RvY29sc0Vycm9yKCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3IubmFtZSA9IEFjdGlsaXR5RXJyb3JOYW1lLk5vRGV2aWNlUHJvdG9jb2xzRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgZ2V0dGV4dChcbiAgICAgICAgYE5vIGRldmljZSBwcm90b2NvbHMgY29uZmlndXJlZC4gQ3JlYXRlIGEgTG9SYSBkZXZpY2UgcHJvdG9jb2wgaW4gPGEgaHJlZj1cInt7IGxpbmsgfX1cIj5EZXZpY2UgcHJvdG9jb2xzPC9hPi5gXG4gICAgICApLFxuICAgICAge1xuICAgICAgICBsaW5rOiAnL2FwcHMvZGV2aWNlbWFuYWdlbWVudC8jL2RldmljZXByb3RvY29scydcbiAgICAgIH1cbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd1JlZ2lzdHJhdGlvbkVycm9yKGRhdGE6IHsgbWVzc2FnZTogc3RyaW5nIH0pIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5SZWdpc3RyYXRpb25FcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iXX0=