@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
161 lines • 22.8 kB
JavaScript
import { Injectable } from '@angular/core';
import { Platform } from '@ionic/angular';
import { toError } from '@iotize/app-common';
import { bufferToHexString, hexStringToBuffer, } from '@iotize/common/byte-converter';
import { NEVER, ReplaySubject, Subject } from 'rxjs';
import { catchError, filter, share, switchMap } from 'rxjs/operators';
import { debug } from '../../logger';
import { NFC } from '../../nfc';
import * as i0 from "@angular/core";
import * as i1 from "../../nfc";
import * as i2 from "@ionic/angular";
const TAG = 'NfcService';
export class NfcService {
constructor(nfc, platform) {
this.nfc = nfc;
this.platform = platform;
this._tagDiscoveredListener = new Subject();
this.tagDiscoveredEvents = this._tagDiscoveredListener.pipe(switchMap((v) => v), share());
this._ndefDiscoveredListener = new ReplaySubject();
this.ndefDiscoveredEvents = this._ndefDiscoveredListener.pipe(switchMap((v) => v));
this._tapDeviceDiscoveredEvent = new ReplaySubject();
this.tapDeviceDiscoveredEvent = this._tapDeviceDiscoveredEvent.pipe(switchMap((v) => v));
}
async write(data) {
try {
await this.nfc.write(data);
}
catch (err) {
if (err === 'cordova_not_available') {
err = new Error(`NFC is not available on this device`);
}
throw err;
}
}
async transceive(data) {
const rawResponse = await this.nfc.transceive(data);
const response = parseNFCTransceiveResponse(data, rawResponse);
console.debug(`NFC transceive ${bufferToHexString(data)} => 0x${bufferToHexString(response)}`);
return response;
}
async isEnabled() {
try {
return await this.nfc.enabled();
}
catch (err) {
console.error('NFC enabled error', err);
return false;
}
}
async setupTagDiscoveredListenerOnce() {
if (this._setupTagDiscoveredListenerPromise) {
return await this._setupTagDiscoveredListenerPromise;
}
else {
return await this.setupTagDiscoveredListener();
}
}
async setupTapDeviceDiscoveredListener() {
this._setupTapDeviceDiscoveredListenerPromise =
createCatchSafePromise((resolve, reject) => {
const tapDeviceDiscoveredListener = this.nfc.addTapDeviceListener(() => {
resolve();
}, (err) => {
reject(err);
});
this._tapDeviceDiscoveredEvent.next(tapDeviceDiscoveredListener);
}, 5000);
await this._setupTapDeviceDiscoveredListenerPromise;
}
async setupTagDiscoveredListener() {
this._setupTagDiscoveredListenerPromise = createCatchSafePromise((resolve, reject) => {
debug(TAG, 'Adding TAG discovered listener...');
this._tagDiscoveredListener.next(this.nfc
.addTagDiscoveredListener(() => {
debug(TAG, 'NFC Tag discovered listener OK!');
resolve();
}, (error) => {
debug(TAG, `NFC Tag discovered listener didn't start`, error);
reject(error);
})
.pipe(catchError((err) => {
const error = toError(err);
console.warn(`NFC Tag listener failed to initialize: ${error.message}`, err);
reject(error);
return NEVER;
}), filter((event) => !!event) // First event is undefined ...
));
}, 5000);
await this._setupTagDiscoveredListenerPromise;
}
async setupNdefListener() {
return await createCatchSafePromise((resolve, _reject) => {
this._ndefDiscoveredListener.next(this.nfc
.addNdefListener() // @warning callbacks are never called...
.pipe(catchError((err) => {
const error = toError(err);
console.warn(`NDEF listener failed to initialize: ${error.message}`, err);
return NEVER;
})));
resolve();
}, 5000);
}
async closeNFC() {
await this.nfc.close();
}
/**
* iOS specific commands
*/
async beginSessionFromTech(tech, alertMessage) {
if (!this.platform.is('ios')) {
return;
}
return this.nfc.beginSessionFromTech(tech, alertMessage);
}
async closeSession() {
return this.nfc.closeSession();
}
}
/** @nocollapse */ NfcService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NfcService, deps: [{ token: i1.NFC }, { token: i2.Platform }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ NfcService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NfcService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NfcService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.NFC }, { type: i2.Platform }]; } });
function createCatchSafePromise(callback, timeout) {
return new Promise((resolve, reject) => {
if (timeout) {
setTimeout(() => {
reject(new Error(`Native code did not respond before timeout of ${timeout}ms`));
}, timeout);
}
try {
callback(resolve, reject);
}
catch (error) {
reject(error);
}
});
}
function parseNFCTransceiveResponse(frame, resultBufferOrString) {
if (!resultBufferOrString) {
return new Uint8Array(0);
}
if (typeof resultBufferOrString === 'object') {
if ('error' in resultBufferOrString) {
const errorString = resultBufferOrString.error === 'cordova_not_available'
? `NFC is not available`
: resultBufferOrString.error;
throw new Error(`Failed to NFC transceive frame 0x${bufferToHexString(frame)} (error: ${errorString})`);
}
}
if (typeof resultBufferOrString === 'string') {
return hexStringToBuffer(resultBufferOrString);
}
else {
return Buffer.from(resultBufferOrString);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmZjLXNlcnZpY2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9zcmMvbGliL3RhcC1zY2FubmVyL3RhcC1zY2FubmVyLW5mYy9uZmMtc2VydmljZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLCtCQUErQixDQUFDO0FBRXZDLE9BQU8sRUFBRSxLQUFLLEVBQWMsYUFBYSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFzQixNQUFNLFdBQVcsQ0FBQzs7OztBQUdwRCxNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUM7QUFlekIsTUFBTSxPQUFPLFVBQVU7SUE4QnJCLFlBQW1CLEdBQVEsRUFBVSxRQUFrQjtRQUFwQyxRQUFHLEdBQUgsR0FBRyxDQUFLO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQTdCL0MsMkJBQXNCLEdBQUcsSUFBSSxPQUFPLEVBRXpDLENBQUM7UUFFSyx3QkFBbUIsR0FDMUIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FDOUIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFDbkIsS0FBSyxFQUFFLENBQ1IsQ0FBQztRQUVhLDRCQUF1QixHQUFHLElBQUksYUFBYSxFQUV6RCxDQUFDO1FBRUsseUJBQW9CLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FDL0QsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FDcEIsQ0FBQztRQUVNLDhCQUF5QixHQUFHLElBQUksYUFBYSxFQUVsRCxDQUFDO1FBRUssNkJBQXdCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FDckUsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FDcEIsQ0FBQztJQUt3RCxDQUFDO0lBRTNELEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBVztRQUNyQixJQUFJO1lBQ0YsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM1QjtRQUFDLE9BQU8sR0FBRyxFQUFFO1lBQ1osSUFBSSxHQUFHLEtBQUssdUJBQXVCLEVBQUU7Z0JBQ25DLEdBQUcsR0FBRyxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO2FBQ3hEO1lBQ0QsTUFBTSxHQUFHLENBQUM7U0FDWDtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLElBQWdCO1FBQy9CLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsTUFBTSxRQUFRLEdBQUcsMEJBQTBCLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sQ0FBQyxLQUFLLENBQ1gsa0JBQWtCLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLGlCQUFpQixDQUNqRSxRQUFRLENBQ1QsRUFBRSxDQUNKLENBQUM7UUFDRixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsS0FBSyxDQUFDLFNBQVM7UUFDYixJQUFJO1lBQ0YsT0FBTyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDakM7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEMsT0FBTyxLQUFLLENBQUM7U0FDZDtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsOEJBQThCO1FBQ2xDLElBQUksSUFBSSxDQUFDLGtDQUFrQyxFQUFFO1lBQzNDLE9BQU8sTUFBTSxJQUFJLENBQUMsa0NBQWtDLENBQUM7U0FDdEQ7YUFBTTtZQUNMLE9BQU8sTUFBTSxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsZ0NBQWdDO1FBQ3BDLElBQUksQ0FBQyx3Q0FBd0M7WUFDM0Msc0JBQXNCLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQy9DLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FDL0QsR0FBRyxFQUFFO29CQUNILE9BQU8sRUFBRSxDQUFDO2dCQUNaLENBQUMsRUFDRCxDQUFDLEdBQVcsRUFBRSxFQUFFO29CQUNkLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDZCxDQUFDLENBQ0YsQ0FBQztnQkFDRixJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7WUFDbkUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ1gsTUFBTSxJQUFJLENBQUMsd0NBQXdDLENBQUM7SUFDdEQsQ0FBQztJQUVELEtBQUssQ0FBQywwQkFBMEI7UUFDOUIsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLHNCQUFzQixDQUM5RCxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNsQixLQUFLLENBQUMsR0FBRyxFQUFFLG1DQUFtQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FDOUIsSUFBSSxDQUFDLEdBQUc7aUJBQ0wsd0JBQXdCLENBQ3ZCLEdBQUcsRUFBRTtnQkFDSCxLQUFLLENBQUMsR0FBRyxFQUFFLGlDQUFpQyxDQUFDLENBQUM7Z0JBQzlDLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxFQUNELENBQUMsS0FBWSxFQUFFLEVBQUU7Z0JBQ2YsS0FBSyxDQUFDLEdBQUcsRUFBRSwwQ0FBMEMsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDOUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FDRjtpQkFDQSxJQUFJLENBQ0gsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ2pCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDM0IsT0FBTyxDQUFDLElBQUksQ0FDViwwQ0FBMEMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUN6RCxHQUFHLENBQ0osQ0FBQztnQkFDRixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2QsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDLENBQUMsRUFDRixNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQywrQkFBK0I7YUFDM0QsQ0FDSixDQUFDO1FBQ0osQ0FBQyxFQUNELElBQUksQ0FDTCxDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsa0NBQWtDLENBQUM7SUFDaEQsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUI7UUFDckIsT0FBTyxNQUFNLHNCQUFzQixDQUFPLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQzdELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQy9CLElBQUksQ0FBQyxHQUFHO2lCQUNMLGVBQWUsRUFBRSxDQUFDLHlDQUF5QztpQkFDM0QsSUFBSSxDQUNILFVBQVUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNqQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxJQUFJLENBQ1YsdUNBQXVDLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFDdEQsR0FBRyxDQUNKLENBQUM7Z0JBQ0YsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDLENBQUMsQ0FDSCxDQUNKLENBQUM7WUFDRixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUTtRQUNaLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsb0JBQW9CLENBQ3hCLElBQVksRUFDWixZQUFxQjtRQUVyQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDNUIsT0FBTztTQUNSO1FBQ0QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVk7UUFDaEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ2pDLENBQUM7OzJIQWpLVSxVQUFVOytIQUFWLFVBQVUsY0FGVCxNQUFNOzRGQUVQLFVBQVU7a0JBSHRCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COztBQXFLRCxTQUFTLHNCQUFzQixDQUM3QixRQUdTLEVBQ1QsT0FBZ0I7SUFFaEIsT0FBTyxJQUFJLE9BQU8sQ0FBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUN4QyxJQUFJLE9BQU8sRUFBRTtZQUNYLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsTUFBTSxDQUNKLElBQUksS0FBSyxDQUNQLGlEQUFpRCxPQUFPLElBQUksQ0FDN0QsQ0FDRixDQUFDO1lBQ0osQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQ2I7UUFDRCxJQUFJO1lBQ0YsUUFBUSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztTQUMzQjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2Y7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFTLDBCQUEwQixDQUNqQyxLQUFpQixFQUNqQixvQkFLUTtJQUVSLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtRQUN6QixPQUFPLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzFCO0lBQ0QsSUFBSSxPQUFPLG9CQUFvQixLQUFLLFFBQVEsRUFBRTtRQUM1QyxJQUFJLE9BQU8sSUFBSSxvQkFBb0IsRUFBRTtZQUNuQyxNQUFNLFdBQVcsR0FDZixvQkFBb0IsQ0FBQyxLQUFLLEtBQUssdUJBQXVCO2dCQUNwRCxDQUFDLENBQUMsc0JBQXNCO2dCQUN4QixDQUFDLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQ2Isb0NBQW9DLGlCQUFpQixDQUNuRCxLQUFLLENBQ04sWUFBWSxXQUFXLEdBQUcsQ0FDNUIsQ0FBQztTQUNIO0tBQ0Y7SUFFRCxJQUFJLE9BQU8sb0JBQW9CLEtBQUssUUFBUSxFQUFFO1FBQzVDLE9BQU8saUJBQWlCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztLQUNoRDtTQUFNO1FBQ0wsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7S0FDMUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyB0b0Vycm9yIH0gZnJvbSAnQGlvdGl6ZS9hcHAtY29tbW9uJztcbmltcG9ydCB7XG4gIGJ1ZmZlclRvSGV4U3RyaW5nLFxuICBoZXhTdHJpbmdUb0J1ZmZlcixcbn0gZnJvbSAnQGlvdGl6ZS9jb21tb24vYnl0ZS1jb252ZXJ0ZXInO1xuaW1wb3J0IHsgRW5jcnlwdGlvbk9wdGlvbnMgfSBmcm9tICdAaW90aXplL3RhcC9hdXRoJztcbmltcG9ydCB7IE5FVkVSLCBPYnNlcnZhYmxlLCBSZXBsYXlTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaWx0ZXIsIHNoYXJlLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGRlYnVnIH0gZnJvbSAnLi4vLi4vbG9nZ2VyJztcbmltcG9ydCB7IE5GQywgTmRlZkV2ZW50LCBOZGVmVGFnIH0gZnJvbSAnLi4vLi4vbmZjJztcbmltcG9ydCB7IFRhZ0Rpc2NvdmVyZWRFdmVudCB9IGZyb20gJy4vZGVmaW5pdGlvbnMnO1xuXG5jb25zdCBUQUcgPSAnTmZjU2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcmFibGVUYXBTdGF0ZUV2ZW50IHtcbiAgdGFnOiBOZGVmVGFnO1xuICB0YXA6IFJlY292ZXJhYmxlVGFwU3RhdGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcmFibGVUYXBTdGF0ZSB7XG4gIG5mY1BhaXJpbmdEb25lPzogYm9vbGVhbjtcbiAgZW5jcnlwdGlvbj86IEVuY3J5cHRpb25PcHRpb25zO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgTmZjU2VydmljZSB7XG4gIHByaXZhdGUgX3RhZ0Rpc2NvdmVyZWRMaXN0ZW5lciA9IG5ldyBTdWJqZWN0PFxuICAgIE9ic2VydmFibGU8VGFnRGlzY292ZXJlZEV2ZW50PlxuICA+KCk7XG5cbiAgcmVhZG9ubHkgdGFnRGlzY292ZXJlZEV2ZW50czogT2JzZXJ2YWJsZTxUYWdEaXNjb3ZlcmVkRXZlbnQ+ID1cbiAgICB0aGlzLl90YWdEaXNjb3ZlcmVkTGlzdGVuZXIucGlwZShcbiAgICAgIHN3aXRjaE1hcCgodikgPT4gdiksXG4gICAgICBzaGFyZSgpXG4gICAgKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9uZGVmRGlzY292ZXJlZExpc3RlbmVyID0gbmV3IFJlcGxheVN1YmplY3Q8XG4gICAgT2JzZXJ2YWJsZTxOZGVmRXZlbnQ+XG4gID4oKTtcblxuICByZWFkb25seSBuZGVmRGlzY292ZXJlZEV2ZW50cyA9IHRoaXMuX25kZWZEaXNjb3ZlcmVkTGlzdGVuZXIucGlwZShcbiAgICBzd2l0Y2hNYXAoKHYpID0+IHYpXG4gICk7XG5cbiAgcHJpdmF0ZSBfdGFwRGV2aWNlRGlzY292ZXJlZEV2ZW50ID0gbmV3IFJlcGxheVN1YmplY3Q8XG4gICAgT2JzZXJ2YWJsZTxSZWNvdmVyYWJsZVRhcFN0YXRlRXZlbnQ+XG4gID4oKTtcblxuICByZWFkb25seSB0YXBEZXZpY2VEaXNjb3ZlcmVkRXZlbnQgPSB0aGlzLl90YXBEZXZpY2VEaXNjb3ZlcmVkRXZlbnQucGlwZShcbiAgICBzd2l0Y2hNYXAoKHYpID0+IHYpXG4gICk7XG5cbiAgcHJpdmF0ZSBfc2V0dXBUYXBEZXZpY2VEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBfc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlPzogUHJvbWlzZTx2b2lkPjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbmZjOiBORkMsIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtKSB7fVxuXG4gIGFzeW5jIHdyaXRlKGRhdGE6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubmZjLndyaXRlKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciA9PT0gJ2NvcmRvdmFfbm90X2F2YWlsYWJsZScpIHtcbiAgICAgICAgZXJyID0gbmV3IEVycm9yKGBORkMgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGlzIGRldmljZWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHRyYW5zY2VpdmUoZGF0YTogVWludDhBcnJheSk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIGNvbnN0IHJhd1Jlc3BvbnNlID0gYXdhaXQgdGhpcy5uZmMudHJhbnNjZWl2ZShkYXRhKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHBhcnNlTkZDVHJhbnNjZWl2ZVJlc3BvbnNlKGRhdGEsIHJhd1Jlc3BvbnNlKTtcbiAgICBjb25zb2xlLmRlYnVnKFxuICAgICAgYE5GQyB0cmFuc2NlaXZlICR7YnVmZmVyVG9IZXhTdHJpbmcoZGF0YSl9ID0+IDB4JHtidWZmZXJUb0hleFN0cmluZyhcbiAgICAgICAgcmVzcG9uc2VcbiAgICAgICl9YFxuICAgICk7XG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgYXN5bmMgaXNFbmFibGVkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5uZmMuZW5hYmxlZCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignTkZDIGVuYWJsZWQgZXJyb3InLCBlcnIpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNldHVwVGFnRGlzY292ZXJlZExpc3RlbmVyT25jZSgpIHtcbiAgICBpZiAodGhpcy5fc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5fc2V0dXBUYWdEaXNjb3ZlcmVkTGlzdGVuZXJQcm9taXNlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZXR1cFRhZ0Rpc2NvdmVyZWRMaXN0ZW5lcigpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNldHVwVGFwRGV2aWNlRGlzY292ZXJlZExpc3RlbmVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuX3NldHVwVGFwRGV2aWNlRGlzY292ZXJlZExpc3RlbmVyUHJvbWlzZSA9XG4gICAgICBjcmVhdGVDYXRjaFNhZmVQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgdGFwRGV2aWNlRGlzY292ZXJlZExpc3RlbmVyID0gdGhpcy5uZmMuYWRkVGFwRGV2aWNlTGlzdGVuZXIoXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycj86IEVycm9yKSA9PiB7XG4gICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX3RhcERldmljZURpc2NvdmVyZWRFdmVudC5uZXh0KHRhcERldmljZURpc2NvdmVyZWRMaXN0ZW5lcik7XG4gICAgICB9LCA1MDAwKTtcbiAgICBhd2FpdCB0aGlzLl9zZXR1cFRhcERldmljZURpc2NvdmVyZWRMaXN0ZW5lclByb21pc2U7XG4gIH1cblxuICBhc3luYyBzZXR1cFRhZ0Rpc2NvdmVyZWRMaXN0ZW5lcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLl9zZXR1cFRhZ0Rpc2NvdmVyZWRMaXN0ZW5lclByb21pc2UgPSBjcmVhdGVDYXRjaFNhZmVQcm9taXNlPHZvaWQ+KFxuICAgICAgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBkZWJ1ZyhUQUcsICdBZGRpbmcgVEFHIGRpc2NvdmVyZWQgbGlzdGVuZXIuLi4nKTtcbiAgICAgICAgdGhpcy5fdGFnRGlzY292ZXJlZExpc3RlbmVyLm5leHQoXG4gICAgICAgICAgdGhpcy5uZmNcbiAgICAgICAgICAgIC5hZGRUYWdEaXNjb3ZlcmVkTGlzdGVuZXIoXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyhUQUcsICdORkMgVGFnIGRpc2NvdmVyZWQgbGlzdGVuZXIgT0shJyk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgZGVidWcoVEFHLCBgTkZDIFRhZyBkaXNjb3ZlcmVkIGxpc3RlbmVyIGRpZG4ndCBzdGFydGAsIGVycm9yKTtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSB0b0Vycm9yKGVycik7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgYE5GQyBUYWcgbGlzdGVuZXIgZmFpbGVkIHRvIGluaXRpYWxpemU6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgICAgZXJyXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIHJldHVybiBORVZFUjtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGZpbHRlcigoZXZlbnQpID0+ICEhZXZlbnQpIC8vIEZpcnN0IGV2ZW50IGlzIHVuZGVmaW5lZCAuLi5cbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgICA1MDAwXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLl9zZXR1cFRhZ0Rpc2NvdmVyZWRMaXN0ZW5lclByb21pc2U7XG4gIH1cblxuICBhc3luYyBzZXR1cE5kZWZMaXN0ZW5lcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gYXdhaXQgY3JlYXRlQ2F0Y2hTYWZlUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgX3JlamVjdCkgPT4ge1xuICAgICAgdGhpcy5fbmRlZkRpc2NvdmVyZWRMaXN0ZW5lci5uZXh0KFxuICAgICAgICB0aGlzLm5mY1xuICAgICAgICAgIC5hZGROZGVmTGlzdGVuZXIoKSAvLyBAd2FybmluZyBjYWxsYmFja3MgYXJlIG5ldmVyIGNhbGxlZC4uLlxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gdG9FcnJvcihlcnIpO1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgYE5ERUYgbGlzdGVuZXIgZmFpbGVkIHRvIGluaXRpYWxpemU6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgIGVyclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICByZXR1cm4gTkVWRVI7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIClcbiAgICAgICk7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSwgNTAwMCk7XG4gIH1cblxuICBhc3luYyBjbG9zZU5GQygpIHtcbiAgICBhd2FpdCB0aGlzLm5mYy5jbG9zZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIGlPUyBzcGVjaWZpYyBjb21tYW5kc1xuICAgKi9cbiAgYXN5bmMgYmVnaW5TZXNzaW9uRnJvbVRlY2goXG4gICAgdGVjaDogc3RyaW5nLFxuICAgIGFsZXJ0TWVzc2FnZT86IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMucGxhdGZvcm0uaXMoJ2lvcycpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiB0aGlzLm5mYy5iZWdpblNlc3Npb25Gcm9tVGVjaCh0ZWNoLCBhbGVydE1lc3NhZ2UpO1xuICB9XG5cbiAgYXN5bmMgY2xvc2VTZXNzaW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLm5mYy5jbG9zZVNlc3Npb24oKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDYXRjaFNhZmVQcm9taXNlPFQ+KFxuICBjYWxsYmFjazogKFxuICAgIHJlc29sdmU6ICh2YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+KSA9PiB2b2lkLFxuICAgIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZFxuICApID0+IHZvaWQsXG4gIHRpbWVvdXQ/OiBudW1iZXJcbik6IFByb21pc2U8VD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgcmVqZWN0KFxuICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBOYXRpdmUgY29kZSBkaWQgbm90IHJlc3BvbmQgYmVmb3JlIHRpbWVvdXQgb2YgJHt0aW1lb3V0fW1zYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0sIHRpbWVvdXQpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBwYXJzZU5GQ1RyYW5zY2VpdmVSZXNwb25zZShcbiAgZnJhbWU6IFVpbnQ4QXJyYXksXG4gIHJlc3VsdEJ1ZmZlck9yU3RyaW5nOlxuICAgIHwgQXJyYXlCdWZmZXJcbiAgICB8IHN0cmluZ1xuICAgIHwgeyBlcnJvcj86IHN0cmluZyB9XG4gICAgfCB1bmRlZmluZWRcbiAgICB8IG51bGxcbikge1xuICBpZiAoIXJlc3VsdEJ1ZmZlck9yU3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KDApO1xuICB9XG4gIGlmICh0eXBlb2YgcmVzdWx0QnVmZmVyT3JTdHJpbmcgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKCdlcnJvcicgaW4gcmVzdWx0QnVmZmVyT3JTdHJpbmcpIHtcbiAgICAgIGNvbnN0IGVycm9yU3RyaW5nID1cbiAgICAgICAgcmVzdWx0QnVmZmVyT3JTdHJpbmcuZXJyb3IgPT09ICdjb3Jkb3ZhX25vdF9hdmFpbGFibGUnXG4gICAgICAgICAgPyBgTkZDIGlzIG5vdCBhdmFpbGFibGVgXG4gICAgICAgICAgOiByZXN1bHRCdWZmZXJPclN0cmluZy5lcnJvcjtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBORkMgdHJhbnNjZWl2ZSBmcmFtZSAweCR7YnVmZmVyVG9IZXhTdHJpbmcoXG4gICAgICAgICAgZnJhbWVcbiAgICAgICAgKX0gKGVycm9yOiAke2Vycm9yU3RyaW5nfSlgXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgcmVzdWx0QnVmZmVyT3JTdHJpbmcgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGhleFN0cmluZ1RvQnVmZmVyKHJlc3VsdEJ1ZmZlck9yU3RyaW5nKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20ocmVzdWx0QnVmZmVyT3JTdHJpbmcpO1xuICB9XG59XG4iXX0=