UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

181 lines 21.9 kB
import { ChangeDetectorRef, Component, EventEmitter, Inject, Input, Output, TemplateRef, } from '@angular/core'; import { LoadingController } from '@ionic/angular'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { TAP_BLE_SCANNER } from '../../../injection-types'; import * as i0 from "@angular/core"; import * as i1 from "@ionic/angular"; import * as i2 from "@angular/common"; import * as i3 from "./tap-scan-results/tap-scan-results.component"; /** * Scanner for bluetooth */ export class TapScannerBleComponent { tapScanner; changeDetector; loadingCtrl; /** * Scan result template to use to display scan results. * * If not provided, it will use a default component to display devices. * * @example * <!-- Display devices with tap-ble-scan-result component --> * <tap-scanner-ble [scanResultsTemplate]="scanResultsTemplate"> * <ng-template #scanResultsTemplate let-devices> * <tap-ble-scan-result [devices]="devices" [showSignalStrenght]="false"></tap-ble-scan-result> * </ng-template> * </tap-scanner-ble> * */ scanResultsTemplate; /** * @deprecated Not used anymore. start/stop buttons must be define by user */ showScanButton = true; /** * RSSI update threshold. * If device list is the same, we will only emit a device update event * if the Math.abs(previousRSSI - newRSSI) >= rssiUpdateThreshold */ rssiUpdateThreshold = 10; showMacAddress = true; showSignalStrength = true; /** * Event emitted when a scan result has been selected * @deprecated see protocolSelected */ onProtocolSelected = new EventEmitter(); /** * Event emitted when a scan result has been selected */ protocolSelected = new EventEmitter(); /** * Event emitted when an error occurs */ onError = new EventEmitter(); results = []; destroyed = new Subject(); isScanning = false; constructor(tapScanner, changeDetector, loadingCtrl) { this.tapScanner = tapScanner; this.changeDetector = changeDetector; this.loadingCtrl = loadingCtrl; } ngOnInit() { this.tapScanner.results .pipe(takeUntil(this.destroyed)) .subscribe((values) => { this.mergeScanResults(values); }); this.tapScanner.scanning.pipe(takeUntil(this.destroyed)).subscribe((v) => { if (v !== this.isScanning) { this.isScanning = v; } }); } notifyError(error) { console.error('BLEScannerError', error); this.onError.emit(error); } ngOnDestroy() { this.stopScan(); this.destroyed.next(); this.destroyed.complete(); } onItemClicked(device) { const protocolMeta = { type: 'ble', info: { id: device.address, mac: device.address, name: device.name, }, }; const event = { meta: protocolMeta, }; this.protocolSelected.emit(event); this.onProtocolSelected.emit(event); } startScan() { // this.devices = this.devices.filter(device => device.address == this.tapScanner.selectedDevice); // this.devices.splice(0, this.devices.length); this.tapScanner.start().catch((err) => { this.notifyError(err); }); // this.onScanStateChanged.emit(true); } stopScan() { this.tapScanner.stop().catch((err) => { this.notifyError(err); }); // this.onScanStateChanged.emit(false); } mergeScanResults(newResults) { /* newResults.forEach((newResult) => { this.addOrRefreshScanResultList(newResult); }); const indexToRemove = this.results.map((oldDevice) => { return newResults.findIndex( (entry) => entry.address === oldDevice.address ); }, []); indexToRemove.forEach((resultIndex) => { if (resultIndex < 0) { this.results.splice(resultIndex, 1); } }); */ this.results = newResults; this.changeDetector.detectChanges(); } addOrRefreshScanResultList(newDevice) { const devices = this.results; let hasChanged = false; const storedDeviceIndex = devices.findIndex((entry) => entry.address === newDevice.address); if (storedDeviceIndex >= 0) { const storedDevice = devices[storedDeviceIndex]; if (storedDevice.name !== newDevice.name) { storedDevice.name = newDevice.name; hasChanged = true; } if (Math.abs(storedDevice.rssi - newDevice.rssi) >= this.rssiUpdateThreshold) { storedDevice.rssi = newDevice.rssi; hasChanged = true; } } else { devices.push(newDevice); hasChanged = true; } return hasChanged; } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TapScannerBleComponent, deps: [{ token: TAP_BLE_SCANNER }, { token: i0.ChangeDetectorRef }, { token: i1.LoadingController }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TapScannerBleComponent, selector: "tap-scanner-ble", inputs: { scanResultsTemplate: "scanResultsTemplate", showScanButton: "showScanButton", rssiUpdateThreshold: "rssiUpdateThreshold", showMacAddress: "showMacAddress", showSignalStrength: "showSignalStrength" }, outputs: { onProtocolSelected: "onProtocolSelected", protocolSelected: "protocolSelected", onError: "onError" }, ngImport: i0, template: "<ng-container\n *ngTemplateOutlet=\"scanResultsContainer; context: { $implicit: results }\"\n></ng-container>\n\n<ng-template #scanResultsContainer let-devices>\n <!-- <ng-content #scanResultsInner select=\"[scan-results]\"></ng-content> -->\n <ng-template\n *ngTemplateOutlet=\"scanResultsTemplate; context: { $implicit: results }\"\n ></ng-template>\n <tap-ble-scan-result\n *ngIf=\"!scanResultsTemplate\"\n [devices]=\"devices\"\n [showMacAddress]=\"showMacAddress\"\n [showSignalStrength]=\"showSignalStrength\"\n (onItemClicked)=\"onItemClicked($event)\"\n ></tap-ble-scan-result>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.TapScanResultsComponent, selector: "tap-ble-scan-result", inputs: ["lines", "showMacAddress", "showSignalStrenght", "showSignalStrength", "devices"], outputs: ["onItemClicked"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TapScannerBleComponent, decorators: [{ type: Component, args: [{ selector: 'tap-scanner-ble', template: "<ng-container\n *ngTemplateOutlet=\"scanResultsContainer; context: { $implicit: results }\"\n></ng-container>\n\n<ng-template #scanResultsContainer let-devices>\n <!-- <ng-content #scanResultsInner select=\"[scan-results]\"></ng-content> -->\n <ng-template\n *ngTemplateOutlet=\"scanResultsTemplate; context: { $implicit: results }\"\n ></ng-template>\n <tap-ble-scan-result\n *ngIf=\"!scanResultsTemplate\"\n [devices]=\"devices\"\n [showMacAddress]=\"showMacAddress\"\n [showSignalStrength]=\"showSignalStrength\"\n (onItemClicked)=\"onItemClicked($event)\"\n ></tap-ble-scan-result>\n</ng-template>\n" }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [TAP_BLE_SCANNER] }] }, { type: i0.ChangeDetectorRef }, { type: i1.LoadingController }], propDecorators: { scanResultsTemplate: [{ type: Input }], showScanButton: [{ type: Input }], rssiUpdateThreshold: [{ type: Input }], showMacAddress: [{ type: Input }], showSignalStrength: [{ type: Input }], onProtocolSelected: [{ type: Output }], protocolSelected: [{ type: Output }], onError: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwLXNjYW5uZXItYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL3RhcC1zY2FubmVyL3RhcC1zY2FubmVyLWJsZS90YXAtc2Nhbm5lci1ibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL3NyYy9saWIvdGFwLXNjYW5uZXIvdGFwLXNjYW5uZXItYmxlL3RhcC1zY2FubmVyLWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEVBQ04sV0FBVyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7QUFLM0Q7O0dBRUc7QUFNSCxNQUFNLE9BQU8sc0JBQXNCO0lBdUR4QjtJQUNBO0lBQ0E7SUF4RFQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNNLG1CQUFtQixDQUFvQjtJQUVoRDs7T0FFRztJQUNNLGNBQWMsR0FBRyxJQUFJLENBQUM7SUFFL0I7Ozs7T0FJRztJQUNNLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztJQUV6QixjQUFjLEdBQUcsSUFBSSxDQUFDO0lBRXRCLGtCQUFrQixHQUFHLElBQUksQ0FBQztJQUVuQzs7O09BR0c7SUFDTyxrQkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBeUIsQ0FBQztJQUN6RTs7T0FFRztJQUNPLGdCQUFn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TUFBTTsyQkFBQyxlQUFlO3lHQXZDaEIsbUJBQW1CO3NCQUEzQixLQUFLO2dCQUtHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBT0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQU1JLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFJRyxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBS0csT0FBTztzQkFBaEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTG9hZGluZ0NvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBEZXZpY2VTY2FubmVyIH0gZnJvbSAnQGlvdGl6ZS90YXAvc2Nhbm5lci9hcGknO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBUQVBfQkxFX1NDQU5ORVIgfSBmcm9tICcuLi8uLi8uLi9pbmplY3Rpb24tdHlwZXMnO1xuaW1wb3J0IHsgUHJvdG9jb2xNZXRhQmxlIH0gZnJvbSAnLi4vLi4vZXh0ZW5zaW9ucy9wcm90b2NvbC1pbmZvJztcbmltcG9ydCB7IFByb3RvY29sU2VsZWN0ZWRFdmVudCB9IGZyb20gJy4uL2FwaSc7XG5pbXBvcnQgeyBEaXNjb3ZlcmVkRGV2aWNlVHlwZSB9IGZyb20gJy4vZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIFNjYW5uZXIgZm9yIGJsdWV0b290aFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0YXAtc2Nhbm5lci1ibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFwLXNjYW5uZXItYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGFwLXNjYW5uZXItYmxlLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFRhcFNjYW5uZXJCbGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBTY2FuIHJlc3VsdCB0ZW1wbGF0ZSB0byB1c2UgdG8gZGlzcGxheSBzY2FuIHJlc3VsdHMuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgaXQgd2lsbCB1c2UgYSBkZWZhdWx0IGNvbXBvbmVudCB0byBkaXNwbGF5IGRldmljZXMuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIDwhLS0gRGlzcGxheSBkZXZpY2VzIHdpdGggdGFwLWJsZS1zY2FuLXJlc3VsdCBjb21wb25lbnQgLS0+XG4gICAqIDx0YXAtc2Nhbm5lci1ibGUgW3NjYW5SZXN1bHRzVGVtcGxhdGVdPVwic2NhblJlc3VsdHNUZW1wbGF0ZVwiPlxuICAgKiAgICA8bmctdGVtcGxhdGUgI3NjYW5SZXN1bHRzVGVtcGxhdGUgbGV0LWRldmljZXM+XG4gICAqICAgICAgICA8dGFwLWJsZS1zY2FuLXJlc3VsdCBbZGV2aWNlc109XCJkZXZpY2VzXCIgW3Nob3dTaWduYWxTdHJlbmdodF09XCJmYWxzZVwiPjwvdGFwLWJsZS1zY2FuLXJlc3VsdD5cbiAgICogICAgPC9uZy10ZW1wbGF0ZT5cbiAgICogPC90YXAtc2Nhbm5lci1ibGU+XG4gICAqXG4gICAqL1xuICBASW5wdXQoKSBzY2FuUmVzdWx0c1RlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgTm90IHVzZWQgYW55bW9yZS4gc3RhcnQvc3RvcCBidXR0b25zIG11c3QgYmUgZGVmaW5lIGJ5IHVzZXJcbiAgICovXG4gIEBJbnB1dCgpIHNob3dTY2FuQnV0dG9uID0gdHJ1ZTtcblxuICAvKipcbiAgICogUlNTSSB1cGRhdGUgdGhyZXNob2xkLlxuICAgKiBJZiBkZXZpY2UgbGlzdCBpcyB0aGUgc2FtZSwgd2Ugd2lsbCBvbmx5IGVtaXQgYSBkZXZpY2UgdXBkYXRlIGV2ZW50XG4gICAqIGlmIHRoZSBNYXRoLmFicyhwcmV2aW91c1JTU0kgLSBuZXdSU1NJKSA+PSByc3NpVXBkYXRlVGhyZXNob2xkXG4gICAqL1xuICBASW5wdXQoKSByc3NpVXBkYXRlVGhyZXNob2xkID0gMTA7XG5cbiAgQElucHV0KCkgc2hvd01hY0FkZHJlc3MgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIHNob3dTaWduYWxTdHJlbmd0aCA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiBhIHNjYW4gcmVzdWx0IGhhcyBiZWVuIHNlbGVjdGVkXG4gICAqIEBkZXByZWNhdGVkIHNlZSBwcm90b2NvbFNlbGVjdGVkXG4gICAqL1xuICBAT3V0cHV0KCkgb25Qcm90b2NvbFNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxQcm90b2NvbFNlbGVjdGVkRXZlbnQ+KCk7XG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gYSBzY2FuIHJlc3VsdCBoYXMgYmVlbiBzZWxlY3RlZFxuICAgKi9cbiAgQE91dHB1dCgpIHByb3RvY29sU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFByb3RvY29sU2VsZWN0ZWRFdmVudD4oKTtcblxuICAvKipcbiAgICogRXZlbnQgZW1pdHRlZCB3aGVuIGFuIGVycm9yIG9jY3Vyc1xuICAgKi9cbiAgQE91dHB1dCgpIG9uRXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEVycm9yPigpO1xuXG4gIHJlc3VsdHM6IERpc2NvdmVyZWREZXZpY2VUeXBlW10gPSBbXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3llZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIGlzU2Nhbm5pbmcgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFRBUF9CTEVfU0NBTk5FUilcbiAgICBwdWJsaWMgdGFwU2Nhbm5lcjogRGV2aWNlU2Nhbm5lcjxEaXNjb3ZlcmVkRGV2aWNlVHlwZT4sXG4gICAgcHVibGljIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgbG9hZGluZ0N0cmw6IExvYWRpbmdDb250cm9sbGVyXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnRhcFNjYW5uZXIucmVzdWx0c1xuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSlcbiAgICAgIC5zdWJzY3JpYmUoKHZhbHVlcykgPT4ge1xuICAgICAgICB0aGlzLm1lcmdlU2NhblJlc3VsdHModmFsdWVzKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy50YXBTY2FubmVyLnNjYW5uaW5nLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSkuc3Vic2NyaWJlKCh2KSA9PiB7XG4gICAgICBpZiAodiAhPT0gdGhpcy5pc1NjYW5uaW5nKSB7XG4gICAgICAgIHRoaXMuaXNTY2FubmluZyA9IHY7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBub3RpZnlFcnJvcihlcnJvcjogYW55KSB7XG4gICAgY29uc29sZS5lcnJvcignQkxFU2Nhbm5lckVycm9yJywgZXJyb3IpO1xuICAgIHRoaXMub25FcnJvci5lbWl0KGVycm9yKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3RvcFNjYW4oKTtcbiAgICB0aGlzLmRlc3Ryb3llZC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQuY29tcGxldGUoKTtcbiAgfVxuXG4gIG9uSXRlbUNsaWNrZWQoZGV2aWNlOiBEaXNjb3ZlcmVkRGV2aWNlVHlwZSkge1xuICAgIGNvbnN0IHByb3RvY29sTWV0YTogUHJvdG9jb2xNZXRhQmxlID0ge1xuICAgICAgdHlwZTogJ2JsZScsXG4gICAgICBpbmZvOiB7XG4gICAgICAgIGlkOiBkZXZpY2UuYWRkcmVzcyxcbiAgICAgICAgbWFjOiBkZXZpY2UuYWRkcmVzcyxcbiAgICAgICAgbmFtZTogZGV2aWNlLm5hbWUsXG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgZXZlbnQgPSB7XG4gICAgICBtZXRhOiBwcm90b2NvbE1ldGEsXG4gICAgfTtcbiAgICB0aGlzLnByb3RvY29sU2VsZWN0ZWQuZW1pdChldmVudCk7XG4gICAgdGhpcy5vblByb3RvY29sU2VsZWN0ZWQuZW1pdChldmVudCk7XG4gIH1cblxuICBzdGFydFNjYW4oKSB7XG4gICAgLy8gdGhpcy5kZXZpY2VzID0gdGhpcy5kZXZpY2VzLmZpbHRlcihkZXZpY2UgPT4gZGV2aWNlLmFkZHJlc3MgPT0gdGhpcy50YXBTY2FubmVyLnNlbGVjdGVkRGV2aWNlKTtcbiAgICAvLyB0aGlzLmRldmljZXMuc3BsaWNlKDAsIHRoaXMuZGV2aWNlcy5sZW5ndGgpO1xuICAgIHRoaXMudGFwU2Nhbm5lci5zdGFydCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIHRoaXMubm90aWZ5RXJyb3IoZXJyKTtcbiAgICB9KTtcbiAgICAvLyB0aGlzLm9uU2NhblN0YXRlQ2hhbmdlZC5lbWl0KHRydWUpO1xuICB9XG5cbiAgc3RvcFNjYW4oKSB7XG4gICAgdGhpcy50YXBTY2FubmVyLnN0b3AoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICB0aGlzLm5vdGlmeUVycm9yKGVycik7XG4gICAgfSk7XG4gICAgLy8gdGhpcy5vblNjYW5TdGF0ZUNoYW5nZWQuZW1pdChmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG1lcmdlU2NhblJlc3VsdHMobmV3UmVzdWx0czogRGlzY292ZXJlZERldmljZVR5cGVbXSkge1xuICAgIC8qXG4gICAgbmV3UmVzdWx0cy5mb3JFYWNoKChuZXdSZXN1bHQpID0+IHtcbiAgICAgIHRoaXMuYWRkT3JSZWZyZXNoU2NhblJlc3VsdExpc3QobmV3UmVzdWx0KTtcbiAgICB9KTtcbiAgICBjb25zdCBpbmRleFRvUmVtb3ZlID0gdGhpcy5yZXN1bHRzLm1hcCgob2xkRGV2aWNlKSA9PiB7XG4gICAgICByZXR1cm4gbmV3UmVzdWx0cy5maW5kSW5kZXgoXG4gICAgICAgIChlbnRyeSkgPT4gZW50cnkuYWRkcmVzcyA9PT0gb2xkRGV2aWNlLmFkZHJlc3NcbiAgICAgICk7XG4gICAgfSwgW10pO1xuICAgIGluZGV4VG9SZW1vdmUuZm9yRWFjaCgocmVzdWx0SW5kZXgpID0+IHtcbiAgICAgIGlmIChyZXN1bHRJbmRleCA8IDApIHtcbiAgICAgICAgdGhpcy5yZXN1bHRzLnNwbGljZShyZXN1bHRJbmRleCwgMSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgKi9cbiAgICB0aGlzLnJlc3VsdHMgPSBuZXdSZXN1bHRzO1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRPclJlZnJlc2hTY2FuUmVzdWx0TGlzdChuZXdEZXZpY2U6IERpc2NvdmVyZWREZXZpY2VUeXBlKSB7XG4gICAgY29uc3QgZGV2aWNlcyA9IHRoaXMucmVzdWx0cztcbiAgICBsZXQgaGFzQ2hhbmdlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHN0b3JlZERldmljZUluZGV4ID0gZGV2aWNlcy5maW5kSW5kZXgoXG4gICAgICAoZW50cnkpID0+IGVudHJ5LmFkZHJlc3MgPT09IG5ld0RldmljZS5hZGRyZXNzXG4gICAgKTtcbiAgICBpZiAoc3RvcmVkRGV2aWNlSW5kZXggPj0gMCkge1xuICAgICAgY29uc3Qgc3RvcmVkRGV2aWNlID0gZGV2aWNlc1tzdG9yZWREZXZpY2VJbmRleF07XG4gICAgICBpZiAoc3RvcmVkRGV2aWNlLm5hbWUgIT09IG5ld0RldmljZS5uYW1lKSB7XG4gICAgICAgIHN0b3JlZERldmljZS5uYW1lID0gbmV3RGV2aWNlLm5hbWU7XG4gICAgICAgIGhhc0NoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICBNYXRoLmFicyhzdG9yZWREZXZpY2UucnNzaSAtIG5ld0RldmljZS5yc3NpKSA+PSB0aGlzLnJzc2lVcGRhdGVUaHJlc2hvbGRcbiAgICAgICkge1xuICAgICAgICBzdG9yZWREZXZpY2UucnNzaSA9IG5ld0RldmljZS5yc3NpO1xuICAgICAgICBoYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGV2aWNlcy5wdXNoKG5ld0RldmljZSk7XG4gICAgICBoYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0NoYW5nZWQ7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXJcbiAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzY2FuUmVzdWx0c0NvbnRhaW5lcjsgY29udGV4dDogeyAkaW1wbGljaXQ6IHJlc3VsdHMgfVwiXG4+PC9uZy1jb250YWluZXI+XG5cbjxuZy10ZW1wbGF0ZSAjc2NhblJlc3VsdHNDb250YWluZXIgbGV0LWRldmljZXM+XG4gIDwhLS0gPG5nLWNvbnRlbnQgI3NjYW5SZXN1bHRzSW5uZXIgc2VsZWN0PVwiW3NjYW4tcmVzdWx0c11cIj48L25nLWNvbnRlbnQ+IC0tPlxuICA8bmctdGVtcGxhdGVcbiAgICAqbmdUZW1wbGF0ZU91dGxldD1cInNjYW5SZXN1bHRzVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiByZXN1bHRzIH1cIlxuICA+PC9uZy10ZW1wbGF0ZT5cbiAgPHRhcC1ibGUtc2Nhbi1yZXN1bHRcbiAgICAqbmdJZj1cIiFzY2FuUmVzdWx0c1RlbXBsYXRlXCJcbiAgICBbZGV2aWNlc109XCJkZXZpY2VzXCJcbiAgICBbc2hvd01hY0FkZHJlc3NdPVwic2hvd01hY0FkZHJlc3NcIlxuICAgIFtzaG93U2lnbmFsU3RyZW5ndGhdPVwic2hvd1NpZ25hbFN0cmVuZ3RoXCJcbiAgICAob25JdGVtQ2xpY2tlZCk9XCJvbkl0ZW1DbGlja2VkKCRldmVudClcIlxuICA+PC90YXAtYmxlLXNjYW4tcmVzdWx0PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==