import byteConverter from '@iotize/common/byte-converter';
import rxjs from 'rxjs';
import operators from 'rxjs/operators';
import api from '@iotize/device-client.js/client/api';
import byteStream from '@iotize/common/byte-stream';
import common from '@iotize/common';
import buffer from 'buffer';
import tlv from '@iotize/common/tlv';

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function commonjsRequire () {
	throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
}

function unwrapExports (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

function createCommonjsModule(fn, module) {
	return module = { exports: {} }, fn(module, module.exports), module.exports;
}

function getCjsExportFromNamespace (n) {
	return n && n['default'] || n;
}

var clientErrors = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class TapClientError extends Error {
    constructor(code, message, cause) {
        super(message);
        this.cause = cause;
        this.code = code;
    }
    static illegalArgument(msg) {
        return new TapClientError(TapClientError.Code.IllegalArgumentError, msg);
    }
    static illegalStateError(msg) {
        return new TapClientError(TapClientError.Code.IllegalStateError, msg);
    }
    static encodeRequestError(command, cause) {
        return new TapClientError(TapClientError.Code.EncodeRequestError, 'Cannot encode this request: ' + command + '. Cause: ' + cause, cause);
    }
    static decodeResponseError(cause, frameOrCommand) {
        return new TapClientError(TapClientError.Code.DecodeResponseError, `Cannot decode response to command ${frameOrCommand instanceof Uint8Array
            ? `0x${byteConverter.bufferToHexString(frameOrCommand)}`
            : frameOrCommand.toString()}. Cause: ` + cause, cause);
    }
    static notConnectedError() {
        return new TapClientError(TapClientError.Code.NotConnectedError, 'Trying to execute command but device is not connected');
    }
}
exports.TapClientError = TapClientError;
(function (TapClientError) {
    let Code;
    (function (Code) {
        Code["NotConnectedError"] = "NotConnectedError";
        Code["EncodeRequestError"] = "EncodeRequestError";
        Code["IllegalArgumentError"] = "IllegalArgumentError";
        Code["IllegalStateError"] = "IllegalStateError";
        Code["DecodeResponseError"] = "DecodeResponseError";
    })(Code = TapClientError.Code || (TapClientError.Code = {}));
})(TapClientError = exports.TapClientError || (exports.TapClientError = {}));

});

var clientErrors$1 = unwrapExports(clientErrors);
var clientErrors_1 = clientErrors.TapClientError;

var apduCommand = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * Created by IoTize on 09/03/
 *
 * Model representing an application protocol data unit
 */
class APDUCommand {
    constructor() {
        /**
         * Instruction class - indicates the type of command, e.g. interindustry or proprietary
         */
        this.CLA = 0;
        /**
         * Instruction code - indicates the specific command, e.g. "write data"
         */
        this.instructionCode = 0;
        /**
         * Instruction parameters for the command, e.g. offset into file at which to write the data
         */
        this.instructionParameter = Uint8Array.from([0, 0]);
        /**
         * Encodes the number (Nc) of bytes of command data to follow
         * 0 bytes denotes Nc=0
         * 1 byte with a value from 1 to 255 denotes Nc with the same value
         * 3 bytes, the first of which must be 0, denotes Nc in the range 1 to 65 535 (all three bytes may not be zero)
         */
        this.expectedResponseSize = new Uint8Array(0);
        /**
         * Nc bytes of data
         */
        this.data = new Uint8Array(0);
        /**
         * Encodes the maximum number (Ne) of response bytes expected
         * 0 bytes denotes Ne=0
         * 1 byte in the range 1 to 255 denotes that value of Ne, or 0 denotes Ne=256
         * 2 bytes (if extended Lc was present in the command) in the range 1 to 65 535 denotes Ne of that value, or two zero bytes denotes 65 536
         * 3 bytes (if Lc was not present in the command), the first of which must be 0, denote Ne in the same way as two-byte Le
         */
        this.sizeOfCommandInBytes = new Uint8Array(0);
    }
    setCLA(CLA) {
        this.CLA = CLA;
        return this;
    }
    setInstructionCode(instructionCode) {
        this.instructionCode = instructionCode;
        return this;
    }
    // public setInstructionParameter(data: number[]): this {
    //     this.instructionParameter = Uint8Array.from(data);
    //     return this;
    // }
    setInstructionParameter(p1, p2) {
        this.instructionParameter = Uint8Array.from([p1, p2]);
        return this;
    }
    /**
     * Encodes the maximum number (Ne) of response bytes expected
     * - 0 bytes denotes Ne=0
     * - 1 byte in the range 1 to 255 denotes that value of Ne, or 0 denotes Ne=256
     * - 2 bytes (if extended Lc was present in the command) in the range 1 to 65 535 denotes Ne of that value, or two zero bytes denotes 65 536
     * - 3 bytes (if Lc was not present in the command), the first of which must be 0, denote Ne in the same way as two-byte Le
     *
     * @param expectedResponseSize
     * @return
     */
    setExpectedResponseSize(expectedResponseSize) {
        if (expectedResponseSize <= 0) {
            this.expectedResponseSize = Uint8Array.from([]);
        }
        else if (expectedResponseSize >= 1 && expectedResponseSize < 255) {
            this.expectedResponseSize = Uint8Array.from([expectedResponseSize]);
        }
        else if (expectedResponseSize == 256) {
            this.expectedResponseSize = Uint8Array.from([0]);
        }
        else {
            throw new Error('Not implemented yet');
        }
        return this;
    }
    // public setExpectedResponseSize(expectedResponseSize: number[]) {
    //     if (expectedResponseSize.length > 3) {
    //         throw new Error("Invalid expected byte size");
    //     }
    //     this.expectedResponseSize = expectedResponseSize;
    //     return this;
    // }
    setData(data) {
        this.data = data;
        var nbBytes = data != null ? data.length : 0;
        this.setSizeOfCommandInBytes(nbBytes);
        return this;
    }
    // public setSizeOfCommandInBytes(sizeOfCommandInBytes: number[]) {
    //     this.sizeOfCommandInBytes = sizeOfCommandInBytes;
    //     return this;
    // }
    /**
     * Encodes the number (Nc) of bytes of command data to follow
     * 0 bytes denotes Nc=0
     * 1 byte with a value from 1 to 255 denotes Nc with the same value
     * 3 bytes, the first of which must be 0, denotes Nc in the range 1 to 65 535 (all three bytes may not be zero)
     *
     * @param nbBytes
     */
    setSizeOfCommandInBytes(nbBytes) {
        if (nbBytes == 0) {
            this.sizeOfCommandInBytes = new Uint8Array(0);
        }
        else if (nbBytes >= 1 && nbBytes <= 255) {
            this.sizeOfCommandInBytes = Uint8Array.from([nbBytes & 0xff]);
        }
        else {
            this.sizeOfCommandInBytes = Uint8Array.from([0, nbBytes >> 8, nbBytes & 0xff]);
        }
    }
    getCLA() {
        return this.CLA;
    }
    getInstructionCode() {
        return this.instructionCode;
    }
    getParameters() {
        return this.instructionParameter;
    }
    getSizeOfCommandInBytes() {
        return this.sizeOfCommandInBytes;
    }
    getData() {
        return this.data;
    }
    getExpectedResponseSize() {
        return this.expectedResponseSize;
    }
    hasExpectedResponseSize() {
        return (this.expectedResponseSize != null &&
            this.expectedResponseSize.length > 0);
    }
}
exports.APDUCommand = APDUCommand;
APDUCommand.CLA_LENGTH = 1;
APDUCommand.INS_LENGTH = 1;
APDUCommand.P1P2_LENGTH = 2;

});

var apduCommand$1 = unwrapExports(apduCommand);
var apduCommand_1 = apduCommand.APDUCommand;

var converter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


/**
 * Created by IoTize on 09/03/
 *
 * Model representing an application protocol data unit
 */
class APDUCommandConverter {
    // public static HEADER_LENGTH = 4;
    // public static MIN_APDU_SIZE = 5;
    // private static APDU_BUFFER_SIZE = 255;
    constructor() {
    }
    /**
     * [(4) 0:3 HEADER][(1) 4:4 LENGTH][5:n PAYLOAD][ (4) STATUS CODE]
     *
     * @return
     * @throws Exception
     */
    encode(command, stream = new byteStream.KaitaiStreamWriter()) {
        stream.writeByte(command.getCLA());
        stream.writeByte(command.getInstructionCode());
        stream.writeBytes(command.getParameters(), 2);
        stream.writeBytes(command.getSizeOfCommandInBytes());
        stream.writeBytes(command.getData());
        if (command.hasExpectedResponseSize()) {
            stream.writeBytes(command.getExpectedResponseSize());
        }
        return stream.toBytes;
    }
    /**
     * [(4) 0:3 HEADER][(1) 4:4 LENGTH][5: PAYLOAD][ (4) STATUS CODE]
     *
     * @param stream the input encoded data
     * @return the APDUCommand model
     * @throws InvalidAPDUException if it's not a valid APDU encoded data
     */
    decode(stream) {
        stream = stream instanceof byteStream.KaitaiStreamReader
            ? stream
            : byteStream.KaitaiStreamReader.create(stream);
        var command = new apduCommand.APDUCommand();
        command.setCLA(stream.readU1());
        command.setInstructionCode(stream.readU1());
        command.setInstructionParameter(stream.readU1(), stream.readU1());
        if (stream.byteLeft > 0) {
            let size = stream.readU1();
            if (size == 0) {
                size = stream.readU2be();
            }
            command.setData(stream.readBytes(size));
        }
        // TODO proper error throw APDUError.frameSizePayloadTooSmall
        return command;
    }
}
exports.APDUCommandConverter = APDUCommandConverter;

});

var converter$1 = unwrapExports(converter);
var converter_1 = converter.APDUCommandConverter;

var error = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ConverterError extends Error {
    constructor(code, msg, cause) {
        super(msg);
        this.code = code;
        this.cause = cause;
    }
    static unexpectedBufferSize(expected, buffer) {
        return new ConverterError(ConverterError.Code.UnexpectedBufferSizeError, 'Expected buffer of ' +
            expected +
            ' byte(s) but found only ' +
            buffer.length +
            ' byte(s)');
    }
    static nullBufferError(msg) {
        return new ConverterError(ConverterError.Code.NullBufferError, msg);
    }
}
exports.ConverterError = ConverterError;
(function (ConverterError) {
    let Code;
    (function (Code) {
        Code["UnexpectedBufferSizeError"] = "UnexpectedBufferSizeError";
        Code["NullBufferError"] = "NullBufferError";
    })(Code = ConverterError.Code || (ConverterError.Code = {}));
})(ConverterError = exports.ConverterError || (exports.ConverterError = {}));

});

var error$1 = unwrapExports(error);
var error_1 = error.ConverterError;

var numberDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class NumberConverter {
    constructor(options) {
        this.options = options;
    }
    /**
     * @deprecated in favor of {@link NumberConverter.uint8()}
     * @param lsb
     */
    static uint8Instance(lsb = false) {
        return NumberConverter.uint8(lsb);
    }
    /**
     * Number as unsigned 8 bits converter
     * @param lsb true for least significant bit first
     */
    static uint8(lsb = false) {
        return new NumberConverter({
            signed: false,
            sizeOf: 8,
            leastSignificantBitFirst: lsb
        });
    }
    /**
     * @deprecated in favor of {@link NumberConverter.uint16()}
     * @param lsb  true for least significant bit first
     */
    static uint16Instance(lsb = false) {
        return NumberConverter.uint16(lsb);
    }
    /**
     * Number as unsigned 16 bits converter
     * @param lsb true for least significant bit first
     */
    static uint16(lsb = false) {
        return new NumberConverter({
            signed: false,
            sizeOf: 16,
            leastSignificantBitFirst: lsb
        });
    }
    /**
     * @deprecated in favor of {@link NumberConverter.uint32()}
     * @param lsb  true for least significant bit first
     */
    static uint32Instance(lsb = false) {
        return NumberConverter.uint32(lsb);
    }
    /**
     * Number as unsigned 32 bits converter
     * @param lsb true for least significant bit first
     */
    static uint32(lsb = false) {
        return new NumberConverter({
            signed: false,
            sizeOf: 32,
            leastSignificantBitFirst: lsb
        });
    }
    /**
     * @deprecated in favor of {@link NumberConverter.int8()}
     * @param lsb  true for least significant bit first
     */
    static int8Instance(lsb = false) {
        return NumberConverter.int8(lsb);
    }
    /**
     * Number as signed 8 bits converter
     * @param lsb  true for least significant bit first
     */
    static int8(lsb = false) {
        return new NumberConverter({
            signed: true,
            sizeOf: 8,
            leastSignificantBitFirst: lsb
        });
    }
    /**
     * @deprecated in favor of {@link NumberConverter.int16()}
     * @param lsb  true for least significant bit first
     */
    static int16Instance(lsb = false) {
        return NumberConverter.int16(lsb);
    }
    /**
     * Number as signed 16 bits converter
     * @param lsb  true for least significant bit first
     */
    static int16(lsb = false) {
        return new NumberConverter({
            signed: true,
            sizeOf: 16,
            leastSignificantBitFirst: lsb
        });
    }
    /**
     * @deprecated in favor of {@link NumberConverter.int32()}
     * @param lsb  true for least significant bit first
     */
    static int32Instance(lsb = false) {
        return NumberConverter.int32(lsb);
    }
    /**
     * Number as signed 32 bits converter
     * @param lsb  true for least significant bit first
     */
    static int32(lsb = false) {
        return new NumberConverter({
            signed: true,
            sizeOf: 32,
            leastSignificantBitFirst: lsb
        });
    }
    decode(body) {
        if (body.length * 8 < this.options.sizeOf) {
            throw error.ConverterError.unexpectedBufferSize(this.options.sizeOf / 8, body);
        }
        return NumberConverter.fromBytes(body, this.options.sizeOf / 8, this.options.signed, this.options.leastSignificantBitFirst);
    }
    encode(value) {
        var result = new Uint8Array(this.options.sizeOf >> 3);
        for (var i = 0; i < result.length; i++) {
            var decalage = (result.length - i - 1) * 8;
            result[i] = (value >> decalage) & 0xff;
        }
        if (this.options.leastSignificantBitFirst) {
            result.reverse();
        }
        return result;
    }
    static toOpaqueMsb(input, sizeOf) {
        if (sizeOf == 8) {
            return new Uint8Array([input & 0xff]);
        }
        else if (sizeOf == 16) {
            return new Uint8Array([(input >> 8) & 0xff, input & 0xff]);
        }
        else if (sizeOf == 32) {
            return new Uint8Array([
                (input >> 24) & 0xff,
                (input >> 16) & 0xff,
                (input >> 8) & 0xff,
                input & 0xff
            ]);
        }
        else {
            throw new Error(`Invalid size ${sizeOf}. Must be 8, 16 or 32`);
        }
    }
    static fromOpaqueMsb(data, sizeOf) {
        if (!sizeOf) {
            sizeOf = data.length * 8;
        }
        if (sizeOf == 8) {
            return data[0] & 0xff;
        }
        if (sizeOf == 16) {
            return (data[1] & 0xff) + ((data[0] & 0xff) << 8);
        }
        if (sizeOf == 32) {
            return ((data[3] & 0xff) +
                ((data[2] & 0xff) << 8) +
                ((data[1] & 0xff) << 16) +
                ((data[0] & 0xff) << 24));
        }
        throw new Error(`Invalid size ${sizeOf}. Must be 8, 16 or 32`);
    }
    /**
     * @param size size in bytes
     */
    static fromBytes(data, size, signed, lsb) {
        if (lsb) {
            data = data.reverse();
        }
        var result = 0;
        var last = 0;
        var decalage;
        for (var i = 0; i < size; i++) {
            decalage = (size - i - 1) * 8;
            result += ((data[i] & 0xff) << decalage) >>> 0;
            if (last > result && !signed) {
                throw new Error('Overflow. Last value: ' + last + ' but new is ' + result);
            }
            last = result;
        }
        if (signed && (data[0] & 0x80) == 0x80) {
            result = -(Math.pow(2, 8 * size) - result);
        }
        return result;
    }
}
exports.NumberConverter = NumberConverter;

});

var numberDecoder$1 = unwrapExports(numberDecoder);
var numberDecoder_1 = numberDecoder.NumberConverter;

var crc = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

// import { crc32 } from "crc";
class CRC {
    // public static default(data: Uint8Array){
    //     return crc32(data.buffer);
    // }
    static fromBytes(data, polynomial = CRC.DEFAULT_POLYNOMIAL) {
        if (data.length % CRC.MODULO != 0) {
            throw new Error(`Cannot compute CRC, input size must be a multiple of 4. Length is ${data.length} % ${CRC.MODULO} = ${data.length % CRC.MODULO}`);
        }
        let uint32Data = new Uint32Array(data.length / 4);
        for (let offset = 0; offset < uint32Data.byteLength; offset++) {
            uint32Data[offset] = numberDecoder.NumberConverter.fromOpaqueMsb(data.slice(offset * 4, (offset + 1) * 4), 32);
        }
        return CRC.fromWord(uint32Data, polynomial);
    }
    //crc 32 calculation by word.
    static fromWord(buffer, polynomial = CRC.DEFAULT_POLYNOMIAL) {
        //don't follow null pointers
        if (!buffer) {
            throw new Error('Buffer is null');
        }
        //don't accept buffers larger than 16MB
        if (buffer.byteLength > 16 * 1024 * 1024) {
            throw new Error('Buffers larger than 16MB');
        }
        let i;
        let myword;
        let crc;
        let length = buffer.length;
        // let remain: number = length/4;
        // const number * buf = ((const number *)(buffer));
        //don't accept length not multiple of 4
        // if ( length % 4 ){
        //     throw new Error("Not module 4");
        // }
        i = 0;
        crc = 0xffffffff;
        for (i = 0; i < length; i++) {
            myword = buffer[i]; // Get next word.
            crc = CRC._crc32(crc, myword, polynomial);
        }
        return crc;
    }
    static _crc32(Crc, Data, polynomial) {
        Crc = Crc ^ Data;
        for (let i = 0; i < 32; i++) {
            if (Crc & 0x80000000) {
                Crc = ((Crc << 1) ^ polynomial) >>> 0; // Polynomial
                //Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32
            }
            else {
                Crc = (Crc << 1) >>> 0;
            }
        }
        return Crc;
    }
}
exports.CRC = CRC;
CRC.DEFAULT_POLYNOMIAL = 0x4c11db7;
CRC.MODULO = 4;

});

var crc$1 = unwrapExports(crc);
var crc_1 = crc.CRC;

var checksum = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Checksum {
    static compute(data) {
        let computedChecksum = 0;
        for (let i = 0; i < data.length; i++) {
            computedChecksum = computedChecksum + data[i];
        }
        return computedChecksum;
    }
}
exports.Checksum = Checksum;

});

var checksum$1 = unwrapExports(checksum);
var checksum_1 = checksum.Checksum;

var errorDetection = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(crc);
__export(checksum);

});

var index = unwrapExports(errorDetection);

var debug = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

const prefix = '@iotize:device-client.js:client/impl';
exports.debug = common.createDebugger(prefix);

});

var debug$1 = unwrapExports(debug);
var debug_1 = debug.debug;

var tapStreamCore = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });




class TapStreamReader extends byteStream.KaitaiStreamReader {
    static fromArray(array) {
        const buffer = byteConverter.typedArrayToBuffer(array);
        return new TapStreamReader(buffer);
    }
    static create(packet) {
        return packet instanceof Uint8Array
            ? TapStreamReader.fromArray(packet)
            : packet;
    }
    readStr(n) {
        return String.fromCharCode.apply(null, this.readBytes(n));
    }
    readU2() {
        return this._isBigEndian ? this.readU2be() : this.readU2le();
    }
    readU4() {
        return this._isBigEndian ? this.readU4be() : this.readU4le();
    }
    readF4() {
        return this._isBigEndian ? this.readF4be() : this.readF4le();
    }
    subStream(length) {
        return TapStreamReader.fromArray(this.readBytes(length));
    }
}
exports.TapStreamReader = TapStreamReader;
class TapStreamWriter extends byteStream.KaitaiStreamWriter {
    constructor(lengthOrBuffer = 512, byteOffset, isBigEndian = true) {
        if (typeof lengthOrBuffer === 'number') {
            lengthOrBuffer = new ArrayBuffer(lengthOrBuffer);
        }
        super(lengthOrBuffer, byteOffset, isBigEndian);
    }
    static create(size) {
        return new TapStreamWriter(new ArrayBuffer(size));
    }
    writeFunction(type, options, fieldValue, fieldSize) {
        switch (type) {
            case 'crc32':
                return this.addCRC(options);
            case 'padding':
                if (fieldValue) {
                    debug.debug('Padding is already set');
                    return this.writeBytes(fieldValue);
                }
                else {
                    if (typeof fieldSize == undefined) {
                        throw new Error(`Padding function expect padding size as a second argument. Args: ${JSON.stringify(arguments)}`);
                    }
                    return this.addPadding(fieldSize);
                }
            default:
                throw new Error(`Invalid writer function type: ${type}`);
        }
    }
    addPadding(padSize) {
        this.writeBytes(new Uint8Array(padSize));
        return this;
    }
    addCRC(options) {
        let buffer = this.toBytes;
        if (options && options.offset) {
            buffer = buffer.slice(options.offset);
        }
        const crc = errorDetection.CRC.fromBytes(buffer);
        this.writeU4(crc);
        // console.info(`TODO REMOVE Compute CRC from ${options ? options.offset : 0}:${buffer.length} 0x${bufferToHexString(buffer)} => 0x${crc.toString(16)}`)
        return this;
    }
    writeU4(value) {
        this.writeU(value, 4);
        return this;
    }
    writeU2(value) {
        this.writeU(value, 2);
        return this;
    }
    writeU1(value) {
        this.writeU(value, 1);
        return this;
    }
    writeF4(value) {
        this.writeF(value, 4);
        return this;
    }
    writeStr(value, length = value.length) {
        let i = 1;
        const stringWriteLength = Math.min(value.length, length);
        for (; i <= stringWriteLength; i++) {
            this.writeByte(value.charCodeAt(i - 1));
        }
        const remaining = length - stringWriteLength;
        if (remaining > 0) {
            this.writeBytes(new Uint8Array(remaining));
        }
        return this;
    }
    writeBitsInt(value, n) {
        this.writeB(value, n);
        return this;
    }
}
exports.TapStreamWriter = TapStreamWriter;

});

var tapStreamCore$1 = unwrapExports(tapStreamCore);
var tapStreamCore_1 = tapStreamCore.TapStreamReader;
var tapStreamCore_2 = tapStreamCore.TapStreamWriter;

var importAdapter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

exports.TapStreamReader = tapStreamCore.TapStreamReader;
exports.TapStreamWriter = tapStreamCore.TapStreamWriter;

});

var importAdapter$1 = unwrapExports(importAdapter);
var importAdapter_1 = importAdapter.TapStreamReader;
var importAdapter_2 = importAdapter.TapStreamWriter;

var streamGenerated = createCommonjsModule(function (module, exports) {
"use strict";
/**
 * This file has been generated
 * DO NOT EDIT, IT MAY BE OVERWRITTEN
 */
Object.defineProperty(exports, "__esModule", { value: true });

importAdapter.TapStreamReader.prototype.readTapRequest = function () {
    let model = {};
    model.header = this.readTapRequestHeader();
    model.payload = this.readBytesFull();
    return model;
};
importAdapter.TapStreamReader.prototype.readTapRequestHeader = function () {
    let model = {};
    model.methodType = /*TapRequest.MethodType[*/ this.readU1();
    model.path = this.readTapRequestPath();
    return model;
};
importAdapter.TapStreamReader.prototype.readTapRequestPath = function () {
    let model = {};
    model.objectId = this.readU2();
    model.objectInstanceId = this.readU2();
    model.resourceId = this.readU2();
    return model;
};
importAdapter.TapStreamReader.prototype.readTapResponse = function () {
    let model = {};
    model.codeRet = this.readU1();
    model.data = this.readBytesFull();
    return model;
};
importAdapter.TapStreamReader.prototype.readApduResponse = function () {
    let model = {};
    model.data = this.readBytes(this.getStreamSize() - 2);
    model.status = this.readU2();
    return model;
};
importAdapter.TapStreamReader.prototype.readApduRequest = function () {
    let model = {};
    model.header = this.readApduRequestHeader();
    model.data = this.readBytes(model.header.lc);
    return model;
};
importAdapter.TapStreamReader.prototype.readApduRequestHeader = function () {
    let model = {};
    model.cla = this.readU1();
    model.ins = this.readU1();
    model.p1 = this.readU1();
    model.p2 = this.readU1();
    model.lc = this.readU1();
    return model;
};
importAdapter.TapStreamReader.prototype.readTapApduRequest = function () {
    let model = {};
    return model;
};
importAdapter.TapStreamReader.prototype.readTapEncryptedFrame = function () {
    let model = {};
    model.id = this.readU2();
    model.len = this.readU2();
    model.payload = this.readBytes(model.len);
    model.padding = this.readBytes((16 - ((2 + 2 + model.len + 4) % 16)) % 16);
    model.crc = this.readU4();
    return model;
};
// TapStreamWriter.prototype.write(model: TapRequest) : TapStreamWriter{
//     return this.writeTapRequest(model)
// }
importAdapter.TapStreamWriter.prototype.writeTapRequest = function (model) {
    this.writeTapRequestHeader(model.header);
    this.writeBytes(model.payload);
    return this;
};
importAdapter.TapStreamWriter.prototype.writeTapRequestHeader = function (model) {
    this.writeBitsInt(
    /*parseInt(TapRequest.MethodType[*/ model.methodType /*])*/, 8);
    this.writeTapRequestPath(model.path);
    return this;
};
importAdapter.TapStreamWriter.prototype.writeTapRequestPath = function (model) {
    this.writeU2(model.objectId);
    this.writeU2(model.objectInstanceId);
    this.writeU2(model.resourceId);
    return this;
};
// TapStreamWriter.prototype.write(model: TapResponse) : TapStreamWriter{
//     return this.writeTapResponse(model)
// }
importAdapter.TapStreamWriter.prototype.writeTapResponse = function (model) {
    this.writeU1(model.codeRet);
    this.writeBytes(model.data);
    return this;
};
// TapStreamWriter.prototype.write(model: ApduResponse) : TapStreamWriter{
//     return this.writeApduResponse(model)
// }
importAdapter.TapStreamWriter.prototype.writeApduResponse = function (model) {
    this.writeBytes(model.data, this.getStreamSize() - 2);
    this.writeU2(model.status);
    return this;
};
// TapStreamWriter.prototype.write(model: ApduRequest) : TapStreamWriter{
//     return this.writeApduRequest(model)
// }
importAdapter.TapStreamWriter.prototype.writeApduRequest = function (model) {
    this.writeApduRequestHeader(model.header);
    this.writeBytes(model.data, model.header.lc);
    return this;
};
importAdapter.TapStreamWriter.prototype.writeApduRequestHeader = function (model) {
    this.writeU1(model.cla);
    this.writeU1(model.ins);
    this.writeU1(model.p1);
    this.writeU1(model.p2);
    this.writeU1(model.lc);
    return this;
};
// TapStreamWriter.prototype.write(model: TapApduRequest) : TapStreamWriter{
//     return this.writeTapApduRequest(model)
// }
importAdapter.TapStreamWriter.prototype.writeTapApduRequest = function (model) {
    return this;
};
// TapStreamWriter.prototype.write(model: TapEncryptedFrame) : TapStreamWriter{
//     return this.writeTapEncryptedFrame(model)
// }
importAdapter.TapStreamWriter.prototype.writeTapEncryptedFrame = function (model) {
    this.writeU2(model.id);
    this.writeU2(model.len);
    this.writeBytes(model.payload, model.len);
    this.writeFunction('padding', null, model.padding, (16 - ((2 + 2 + model.len + 4) % 16)) % 16);
    this.writeFunction('crc32', null, model.crc);
    return this;
};

});

var streamGenerated$1 = unwrapExports(streamGenerated);

var tapStream = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(tapStreamCore);


});

var tapStream$1 = unwrapExports(tapStream);

var header = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class Header {
    constructor(path, resourceInstance = undefined) {
        this.path = path;
        this.resourceInstance = resourceInstance;
    }
    getResourceInstance() {
        return this.resourceInstance;
    }
    getPath() {
        return ('/' +
            this.path.objectId +
            '/' +
            (this.path.objectInstanceId == Header.MAX_ID
                ? ''
                : this.path.objectInstanceId) +
            '/' +
            this.path.resourceId +
            (this.resourceInstance ? '/' + this.resourceInstance : ''));
    }
    get objectId() {
        return this.path.objectId;
    }
    get objectInstanceId() {
        return this.path.objectInstanceId;
    }
    get resourceId() {
        return this.path.resourceId;
    }
    static fromBytes(bytes) {
        let path = tapStream.TapStreamReader.fromArray(bytes).readTapRequestPath();
        let header = new Header(path);
        if (bytes.length == 8) {
            // What is that ???
            header.resourceInstance =
                ((bytes[6] << 8) & Header.MAX_ID) + (bytes[7] & 0xff);
            header.resourceInstance &= Header.MAX_ID;
        }
        // return header;
        return header;
    }
    static fromString(command) {
        if (command == null || command.length == 0) {
            throw new Error('Invalid command: null');
        }
        command = command.trim();
        let result = command.match(Header.PATH_EXPRESSION);
        if (!result || result.length === 0) {
            throw new Error(`Invalid header "${command}". Format is invalid`); // TODO better error
        }
        let header = new Header({
            objectId: this.validateId(parseInt(result[1])),
            objectInstanceId: result[2] ? parseInt(result[2]) : 0xffff,
            resourceId: parseInt(result[3])
        }, result[4] ? parseInt(result[4]) : undefined);
        return header;
    }
    static validateId(id) {
        if (id < 0 || id > Header.MAX_ID) {
            throw new Error(`Invalid identifier "${id}". It must be a number between ${id} and ${Header.MAX_ID}`);
        }
        return id;
    }
}
exports.Header = Header;
// TODO move to config global
Header.PATH_EXPRESSION = /^\/?([0-9]+)\/([0-9]+)?\/([0-9]+)\/?([0-9]+)?$/;
Header.MAX_ID = 0xffff;

});

var header$1 = unwrapExports(header);
var header_1 = header.Header;

var apiRequest = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



class ApiRequest {
    constructor(method, url, data) {
        // if (Cmd != null) {
        //     // Check if getVar/setVar with only variable index
        //     if (Cmd.indexOf('/') == -1) {
        //         if (method == MethodType.GET)
        //             Cmd = Header.ID_OBJ_VAR + Cmd + Header.ID_VAR_VALUE_READ;
        //         else
        //             Cmd = Header.ID_OBJ_VAR + Cmd + Header.ID_VAR_VALUE_WRITE;
        //     }
        // }
        this.method = method;
        this.commandUrl = url;
        this.data = data || new Uint8Array(0);
    }
    getCommandUrl() {
        return this.commandUrl;
    }
    setCommandUrl(commandUrl) {
        this.commandUrl = commandUrl;
        return this;
    }
    getHeader() {
        return header.Header.fromString(this.commandUrl);
    }
    setHeader(id) {
        this.commandUrl = id;
    }
    setMethod(type) {
        this.method = type;
    }
    getMethod() {
        return this.method;
    }
    getData() {
        return this.data ? this.data : new Uint8Array(0);
    }
    setData(data) {
        this.data = data;
    }
    hasData() {
        return this.data != null && this.data.length > 0;
    }
    toString() {
        return (api.MethodType[this.method] +
            ' ' +
            this.commandUrl +
            ' ' +
            (this.data ? byteConverter.bufferToHexString(this.data) : ''));
    }
    static GET(url, data) {
        let requestMessage = new ApiRequest(api.MethodType.GET, url, data);
        return requestMessage;
    }
    static PUT(url, body) {
        let requestMessage = new ApiRequest(api.MethodType.PUT, url, body);
        return requestMessage;
    }
    static POST(url, body) {
        let requestMessage = new ApiRequest(api.MethodType.POST, url, body);
        return requestMessage;
    }
    static create(from, header, data) {
        return new ApiRequest(from, header, data);
    }
}
exports.ApiRequest = ApiRequest;
ApiRequest.TAG = 'ApiRequestMessage';

});

var apiRequest$1 = unwrapExports(apiRequest);
var apiRequest_1 = apiRequest.ApiRequest;

var request = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(header);
__export(apiRequest);

});

var index$1 = unwrapExports(request);

var lwm2mCommandConverter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



class IotizeLWM2MCommandConverter {
    constructor() {
    }
    static instance() {
        return new IotizeLWM2MCommandConverter();
    }
    decode(frame) {
        let tapRequest = tapStream.TapStreamReader.fromArray(frame).readTapRequest();
        let header$1 = new header.Header(tapRequest.header.path);
        return request.ApiRequest.create(tapRequest.header.methodType, header$1.getPath(), tapRequest.payload);
    }
    encode(command) {
        let header = command.getHeader();
        let tapRequest = {
            header: {
                path: header,
                methodType: command.getMethod()
            },
            payload: command.getData()
        };
        let stream = new tapStream.TapStreamWriter().writeTapRequestHeader(tapRequest.header);
        if (header.getResourceInstance() !== undefined) {
            stream.writeU2(header.getResourceInstance());
        }
        return stream.writeBytes(tapRequest.payload).toBytes;
    }
}
exports.IotizeLWM2MCommandConverter = IotizeLWM2MCommandConverter;
IotizeLWM2MCommandConverter.HEADER_LENGTH = 7;

});

var lwm2mCommandConverter$1 = unwrapExports(lwm2mCommandConverter);
var lwm2mCommandConverter_1 = lwm2mCommandConverter.IotizeLWM2MCommandConverter;

var defaultCommandEncoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });




/**
 * TODO replace with generated frame converter
 */
class DefaultCommandEncoder {
    constructor() {
        this.apduCommandConverter = new converter.APDUCommandConverter();
        this.iotizeCommandConverter = new lwm2mCommandConverter.IotizeLWM2MCommandConverter();
    }
    static instance() {
        return new DefaultCommandEncoder();
    }
    encode(request) {
        const iotizeTram = this.encodeAsIoTizeTrame(request);
        return this.encodeAsAPDU(request, iotizeTram);
    }
    encodeAsAPDU(request, iotizeFrame) {
        var command = new apduCommand.APDUCommand();
        command.setCLA(DefaultCommandEncoder.IOTIZE_CLA);
        switch (request.getMethod()) {
            case api.MethodType.GET:
                command.setInstructionCode(DefaultCommandEncoder.IOTIZE_INSTRUCTION_CODE_GET);
                break;
            case api.MethodType.POST:
            case api.MethodType.PUT:
            default:
                command.setInstructionCode(DefaultCommandEncoder.IOTIZE_INSTRUCTION_CODE_PUT);
        }
        command.setData(iotizeFrame);
        var apduResponse = this.apduCommandConverter.encode(command);
        return apduResponse;
    }
    encodeAsIoTizeTrame(command) {
        return this.iotizeCommandConverter.encode(command);
    }
}
exports.DefaultCommandEncoder = DefaultCommandEncoder;
DefaultCommandEncoder.IOTIZE_CLA = 0xa2;
DefaultCommandEncoder.IOTIZE_INSTRUCTION_CODE_GET = 0xca;
DefaultCommandEncoder.IOTIZE_INSTRUCTION_CODE_PUT = 0xda;

});

var defaultCommandEncoder$1 = unwrapExports(defaultCommandEncoder);
var defaultCommandEncoder_1 = defaultCommandEncoder.DefaultCommandEncoder;

var apduStatusCode = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class APDUStatusCode {
}
exports.APDUStatusCode = APDUStatusCode;
// "OK" status word sent in response to command (0x9000)
APDUStatusCode.SUCCESSFUL = Uint8Array.from([0x90, 0x00]);
// CRC or MAC does not match data
APDUStatusCode.INVALID_CRC_OR_MAC = Uint8Array.from([0x91, 0x1e]);

});

var apduStatusCode$1 = unwrapExports(apduStatusCode);
var apduStatusCode_1 = apduStatusCode.APDUStatusCode;

var invalidAdpuError = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class APDUError extends Error {
    constructor(code, message, frame) {
        super(message);
        this.code = code;
        this.frame = frame;
    }
    static responseCodeError(responseCode, data) {
        throw new APDUError(APDUError.Code.APDUResponseCodeError, 'APDU response code is an error code (0x' +
            byteConverter.bufferToHexString(responseCode) +
            '). Frame: 0x' +
            byteConverter.bufferToHexString(data), data);
    }
    static frameSizePayloadTooSmall(expectedSize, frame) {
        return new APDUError(APDUError.Code.APDUSizeTooSmall, `Frame is too small: ${frame.length} byte(s). Expected size ${expectedSize} byte(s)`, frame);
    }
    static frameSizeTooSmall(frame, minSize) {
        return new APDUError(APDUError.Code.APDUSizeTooSmall, `Frame is too small: ${frame.length} byte(s). Minimal frame size for an APDU is ${minSize}`, frame);
    }
}
exports.APDUError = APDUError;
(function (APDUError) {
    let Code;
    (function (Code) {
        Code["APDUSizeTooSmall"] = "APDUSizeTooSmall";
        Code["APDUResponseCodeError"] = "APDUResponseCodeError";
    })(Code = APDUError.Code || (APDUError.Code = {}));
})(APDUError = exports.APDUError || (exports.APDUError = {}));

});

var invalidAdpuError$1 = unwrapExports(invalidAdpuError);
var invalidAdpuError_1 = invalidAdpuError.APDUError;

var apduResponse = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

/**
 *
 * <p>
 * Model representing a response application protocol data unit (response APDU)
 */
class APDUResponse {
    constructor() {
        this.data = new Uint8Array(0);
        this.status = Uint8Array.from([0, 0]);
    }
    getData() {
        return this.data;
    }
    getStatus() {
        return this.status;
    }
    setStatus(status) {
        this.status = status;
        return this;
    }
    setData(data) {
        this.data = data;
        return this;
    }
    statusEquals(status) {
        return (status.length === 2 &&
            this.status.length === 2 &&
            status[0] == this.status[0] &&
            status[1] == this.status[1]);
    }
    toString() {
        return `APDUResponse[data=${byteConverter.bufferToHexString(this.data)}; status=${byteConverter.bufferToHexString(this.status)}]`;
    }
}
exports.APDUResponse = APDUResponse;

});

var apduResponse$1 = unwrapExports(apduResponse);
var apduResponse_1 = apduResponse.APDUResponse;

var converter$2 = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

/**
 *
 *
 * Encoder/Decoder for an APDUResponse.
 *
 * Encode to bytes and decode from bytes
 */
class APDUResponseConverter {
    constructor() {
    }
    encode(apduResponse) {
        var dataLength = apduResponse.getData().length;
        var buffer = new Uint8Array(dataLength + apduResponse.getStatus().length);
        var offset = 0;
        buffer.set(apduResponse.getData(), offset);
        offset += dataLength;
        buffer.set(apduResponse.getStatus(), offset);
        return buffer;
    }
    decode(buffer) {
        var response = new apduResponse.APDUResponse();
        response
            .setStatus(buffer.subarray(-APDUResponseConverter.STATUS_WORD_LENGTH))
            .setData(buffer.subarray(0, -APDUResponseConverter.STATUS_WORD_LENGTH));
        return response;
    }
}
exports.APDUResponseConverter = APDUResponseConverter;
APDUResponseConverter.STATUS_WORD_LENGTH = 2;

});

var converter$3 = unwrapExports(converter$2);
var converter_1$1 = converter$2.APDUResponseConverter;

var resultCodeTranslation = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResultCodeTranslation = {
    0: 'No error',
    1: 'PENDING',
    65: 'CREATED',
    66: 'DELETED',
    68: 'CHANGED',
    69: 'CONTENT',
    70: 'BUSY',
    128: 'Bad request. Meaning device cannot understand your request.',
    129: 'UNAUTHORIZED',
    132: 'NOT_FOUND',
    133: 'METHOD_NOT_ALLOWED',
    134: 'NOT_ACCEPTABLE',
    160: 'INTERNAL_SERVER_ERROR',
    161: 'This resource has not been implemented yet',
    163: 'SERVICE_UNAVAILABLE',
    164: 'NVM_ERROR',
    165: 'UNABLE_TO_CONNECT_TO_TARGET',
    166: 'TARGET_POWER_FAILURE',
    167: 'NVM_FUL',
    176: 'TARGET_PROTOCOL_ERROR',
    177: 'TARGET_PROTOCOL_BUSY',
    178: 'TARGET_PROTOCOL_REAL',
    179: 'TARGET_PROTOCOL_WRONG_PARAM',
    180: 'TARGET_PROTOCOL_FORBIDDEN',
    181: 'TARGET_PROTOCOL_DATA',
    182: 'TARGET_PROTOCOL_COM',
    183: 'TARGET_PROTOCOL_LOST_COM',
    184: 'TARGET_PROTOCOL_PARAM',
    185: 'TARGET_PROTOCOL_INT',
    186: 'TARGET_PROTOCOL_ABORT',
    187: 'TARGET_PROTOCOL_NOT_IMPLEMENTED'
};

});

var resultCodeTranslation$1 = unwrapExports(resultCodeTranslation);
var resultCodeTranslation_1 = resultCodeTranslation.ResultCodeTranslation;

var responseError = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


// export const TapResponseErrorCode = 'TapResponseError';
class ResponseError extends Error {
    // public code: string;
    constructor(response, request) {
        super(ResponseError.createErrorMessage(response, request));
        this.response = response;
        this.request = request;
        // this.code = TapResponseErrorCode;
    }
    static createErrorMessage(response, request) {
        const codeRet = response.codeRet();
        let msg = 'Tap request failed. ';
        if (request) {
            msg = `Tap request ${api.MethodType[request.getMethod()] +
                ' ' +
                request.getHeader().getPath()} failed. `;
        }
        const errorExplained = codeRet in resultCodeTranslation.ResultCodeTranslation
            ? resultCodeTranslation.ResultCodeTranslation[codeRet]
            : 'an unknown error';
        msg += `${errorExplained} (code=0x${codeRet.toString(16)})`;
        return msg;
    }
}
exports.ResponseError = ResponseError;

});

var responseError$1 = unwrapExports(responseError);
var responseError_1 = responseError.ResponseError;

var responseImpl = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



class Response {
    constructor(data) {
        this.data = data;
        this._body = undefined;
    }
    static SUCCESS(data) {
        return Response.create(api.ResultCode.IOTIZE_200_NO_ERROR, data);
    }
    static ERROR(errorCode) {
        errorCode = errorCode || api.ResultCode.IOTIZE_400_BAD_REQUEST;
        return Response.create(errorCode);
    }
    static create(codeRet, data) {
        if (data && data.length > 0) {
            var frame = new Uint8Array(1 + data.length);
            frame[0] = codeRet;
            frame.set(data, 1);
            var response = new Response(frame);
            return response;
        }
        else {
            return new Response(Uint8Array.from([codeRet]));
        }
    }
    body(decoder) {
        this.successful();
        if (decoder) {
            return decoder.decode(this.rawBody());
        }
        else if (this._body === undefined) {
            if (this.decoder) {
                this._body = this.decoder.decode(this.rawBody());
            }
            else {
                this._body = this.rawBody();
            }
        }
        return this._body;
    }
    rawBody() {
        if (this.data != null && this.data.length > 1) {
            return this.data.slice(1);
        }
        else {
            return new Uint8Array(0);
        }
    }
    setBodyDecoder(decoder) {
        this.decoder = decoder;
        return this;
    }
    hasBody() {
        return this.rawBody() != null;
    }
    codeRet() {
        return this.data[0];
    }
    toString() {
        return `ResponseMessage[codeRet="${this.codeRet()}";data="${this.hasBody()
            ? byteConverter.bufferToHexString(this.rawBody())
            : 'NO DATA'}";decoder=${this.decoder ? this.decoder.constructor.name : 'NONE'}]`;
    }
    toBytes() {
        return this.data;
    }
    setBody(body) {
        this._body = body;
    }
    isSuccess() {
        return (this.codeRet() & 0x80) == 0;
    }
    isSuccessful() {
        return (this.codeRet() & 0x80) == 0;
    }
    successful() {
        if (!this.isSuccessful()) {
            throw new responseError.ResponseError(this, this._request);
        }
    }
    setRequest(request) {
        this._request = request;
    }
}
exports.Response = Response;
exports.ResponseImpl = Response;

});

var responseImpl$1 = unwrapExports(responseImpl);
var responseImpl_1 = responseImpl.Response;
var responseImpl_2 = responseImpl.ResponseImpl;

var response = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(responseImpl);
__export(resultCodeTranslation);
__export(responseError);

});

var index$2 = unwrapExports(response);

var responseDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });




/**
 * Created by Stephane on 02/02/2018.
 */
class DefaultResponseDecoder {
    constructor() {
        this.apduDecoder = new converter$2.APDUResponseConverter();
    }
    decode(data) {
        var apduResponse = this.apduDecoder.decode(data);
        //        Log.d(TAG, "APDU status: " + Helper.ByteArrayToHexString(apduStatus));
        //        Log.d(TAG, "Expected: " + Helper.ByteArrayToHexString(APDUStatusCode.SUCCESSFUL));
        if (apduResponse.statusEquals(apduStatusCode.APDUStatusCode.SUCCESSFUL)) {
            var payload = apduResponse.getData();
            var response$1 = new response.Response(payload);
            return response$1;
        }
        else {
            throw invalidAdpuError.APDUError.responseCodeError(apduResponse.getStatus(), data);
        }
    }
}
exports.DefaultResponseDecoder = DefaultResponseDecoder;

});

var responseDecoder$1 = unwrapExports(responseDecoder);
var responseDecoder_1 = responseDecoder.DefaultResponseDecoder;

var interceptorChain = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class InterceptorChain {
    constructor(target) {
        this.target = target;
        this.interceptors = [];
    }
    addInterceptor(interceptor) {
        this.interceptors.push(typeof interceptor == 'function'
            ? {
                intercept: interceptor
            }
            : interceptor);
        return this;
    }
    execute(context) {
        let runner = {
            index: 0,
            run: (context) => {
                if (runner.index < this.interceptors.length) {
                    runner.index++;
                    return this.interceptors[runner.index - 1].intercept(context, {
                        handle: context => {
                            return runner.run(context);
                        }
                    });
                }
                else {
                    return this.target(context);
                }
            }
        };
        return runner.run(context);
    }
}
exports.InterceptorChain = InterceptorChain;

});

var interceptorChain$1 = unwrapExports(interceptorChain);
var interceptorChain_1 = interceptorChain.InterceptorChain;

var defaultIotizeClient = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });









const TAG = 'Client';
class DefaultIoTizeClient {
    constructor(requestEncoder, responseDecoder) {
        this._onProtocolChange = new rxjs.Subject();
        this._commandEncoder = requestEncoder;
        this._responseDecoder = responseDecoder;
        this.protocols = {};
        this._interceptorChain = new interceptorChain.InterceptorChain((context) => {
            try {
                let command = context.command;
                let bodyDecoder = context.bodyDecoder;
                return this._command(command, bodyDecoder);
            }
            catch (err) {
                return rxjs.throwError(err);
            }
        });
    }
    static create(protocol) {
        let client = new DefaultIoTizeClient(new defaultCommandEncoder.DefaultCommandEncoder(), new responseDecoder.DefaultResponseDecoder());
        if (protocol) {
            client.addComProtocol(protocol);
        }
        return client;
    }
    // public isEncryptionEnabled(): boolean {
    //     return this._options.encryption;
    // }
    // public get cryptedFrameConverter() {
    //     return this._cryptedFrameConverter;
    // }
    get interceptorChain() {
        return this._interceptorChain;
    }
    addInterceptor(interceptor) {
        this.interceptorChain.addInterceptor(interceptor);
        return this;
    }
    // /**
    //  * Enable/Disable encrytion when communicating with a device
    //  * @param value true if requests must be encrypted
    //  * @param algo optional if you have already provided the algo with @{link setEncryptionAlgo(algo)} method
    //  */
    // public enableEncryption(value: boolean, algo?: EncryptionAlgo): Promise<any> {
    //     if (value) {
    //         algo = algo || this._encryptionAlgo;
    //         if (!algo) {
    //             return Promise.reject(
    //                 TapClientError.illegalArgument(
    //                     'Illegal argument, encryption algo must be set'
    //                 )
    //             );
    //         }
    //         return this._startEncryption(algo);
    //     }
    //     else {
    //         return this._stopEncryption();
    //     }
    // }
    isConnected() {
        return (this.hasProtocol(this.currentProtocolId) &&
            this.getCurrentProtocol().isConnected());
    }
    /**
     * see {@link getCurrentProtocol}
     */
    get protocol() {
        return this.getCurrentProtocol();
    }
    get commandEncoder() {
        return this._commandEncoder;
    }
    get responseDecoder() {
        return this._responseDecoder;
    }
    /**
     * Get current protocol or throw an error if no protocol
     */
    getCurrentProtocol() {
        if (!this.currentProtocolId) {
            throw clientErrors.TapClientError.illegalStateError('No protocol');
        }
        if (!this.hasProtocol(this.currentProtocolId)) {
            throw clientErrors.TapClientError.illegalArgument('Protocol ' + this.currentProtocolId + ' does not exist');
        }
        return this.protocols[this.currentProtocolId];
    }
    /**
     * Register/replace a communication protocol with given id
     * If no communication protocol is selected yet, it will select it.
     * @param newProtocol
     * @param id
     */
    addComProtocol(newProtocol, id = 'default') {
        this.protocols[id] = newProtocol;
        if (!this.currentProtocolId) {
            this.currentProtocolId = id;
        }
        return this;
    }
    /**
     * Switch to given communication protocol identifier
     * @throws if protocol identifier does not exist
     * @param name
     */
    switchProtocol(name) {
        if (!this.hasProtocol(name)) {
            throw clientErrors.TapClientError.illegalArgument('Unkonwn protocol: ' + name);
        }
        let oldProtocol = this.getCurrentProtocol();
        this.currentProtocolId = name;
        debug.debug(TAG, `Changing protocol to: ${name}`);
        this._onProtocolChange.next({
            newProtocol: this.getCurrentProtocol(),
            oldProtocol: oldProtocol
        });
        return this;
    }
    /**
     * Change communication protocol
     * @throws if protocol identifier does not exist
     * @param protocol can either be the communication protocol instance or a string identifier
     */
    useComProtocol(protocol) {
        let protocolId;
        if (typeof protocol == 'string') {
            protocolId = protocol;
        }
        else {
            protocolId = protocol.constructor.name;
            this.addComProtocol(protocol, protocolId);
        }
        this.switchProtocol(protocolId);
        return this;
    }
    /**
     * Return true if protocol identifier is registered
     * @param id
     */
    hasProtocol(id) {
        return id in this.protocols;
    }
    connect() {
        try {
            return this.getCurrentProtocol().connect();
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
    disconnect() {
        try {
            return this.getCurrentProtocol().disconnect();
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
    /**
     * Send command
     * @param command
     * @param bodyDecoder
     */
    command(command, bodyDecoder) {
        return this._interceptorChain.execute({
            bodyDecoder: bodyDecoder,
            command: command,
            client: this
        });
    }
    /**
     * Send raw request
     * No interceptors/No encryption will be triggered
     * @param dataIn request bytes
     * @param bodyDecoder optional body decoder to use
     */
    send(dataIn, bodyDecoder) {
        try {
            return this.getCurrentProtocol()
                .send(dataIn)
                .pipe(operators.map((result) => {
                // debug(
                //     TAG,
                //     'Received result: ',
                //     bufferToHexString(result),
                //     'DECODER: ',
                //     bodyDecoder ? bodyDecoder.constructor.name : 'NO'
                // );
                try {
                    let response = this._responseDecoder.decode(result);
                    if (bodyDecoder) {
                        // debug(TAG, `SETTING BODY DECODER: `, bodyDecoder);
                        response.setBodyDecoder(bodyDecoder);
                    }
                    return response;
                }
                catch (err) {
                    throw clientErrors.TapClientError.decodeResponseError(err, dataIn);
                }
            }));
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
    /**
     * Listen to connection state change event
     * We have to resubscribe when protocol change..
     */
    onConnectionStateChange() {
        try {
            return this.getCurrentProtocol().onConnectionStateChange();
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
    onProtocolChange() {
        try {
            return this._onProtocolChange.asObservable();
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
    // protected _encryptedCommand<T>(command: Command, bodyDecoder?: BodyDecoder<T>): Observable<Response<T>> {
    //     if (!this._cryptedFrameConverter) {
    //         return throwError(
    //             TapClientError.illegalStateError(`Crypted convert has not been specified yet`)
    //         );
    //     }
    //     if (!this._encryptionAlgo) {
    //         return throwError(
    //             TapClientError.illegalStateError(`Cryto algo has not been specified yet`)
    //         );
    //     }
    //     let iotizeFrame = this._lwm2mCommandConverter.encode(command);
    //     let cryptedFrameWarpper = this._cryptedFrameConverter.encode(iotizeFrame);
    //     let cryptedFrame = this._encryptionAlgo.encode(cryptedFrameWarpper);
    //     return this
    //         ._command<Uint8Array>(ApiRequest.GET("/1024//48", cryptedFrame)) // TODO constants
    //         .pipe(
    //             map<Response<Uint8Array>, Response<T>>((crypterWarpperResponse: Response<Uint8Array>) => {
    //                 debug(TAG, `Iotize client crypted frame: ${crypterWarpperResponse}`);
    //                 crypterWarpperResponse.successful();
    //                 if (!this._encryptionAlgo) {
    //                     throw TapClientError.illegalStateError(`Encryption algo has not been set yet`)
    //                 }
    //                 let cryptedFrameContent = this._encryptionAlgo.decode(crypterWarpperResponse.rawBody());
    //                 debug(TAG, `Decrypted frame value: ${bufferToHexString(cryptedFrameContent)}`);
    //                 let apduFrame = this._cryptedFrameConverter.decode(cryptedFrameContent);
    //                 let lwm2mResponseFrame = this._apduResponseConverter.decode(apduFrame);
    //                 // TODO do we need to check apdu status ?
    //                 let response: Response<any> = this.lwm2mResponseConverter.decode(lwm2mResponseFrame.data);
    //                 if (bodyDecoder) {
    //                     response.setBodyDecoder(bodyDecoder);
    //                 }
    //                 debug(TAG, `Iotize client decoded response: ${response}`)
    //                 return response as any as Response<T>;
    //             })
    //         );
    // }
    _command(command, bodyDecoder) {
        try {
            if (!this.isConnected()) {
                return rxjs.throwError(clientErrors.TapClientError.notConnectedError());
            }
            let dataIn;
            try {
                dataIn = this._commandEncoder.encode(command);
            }
            catch (e) {
                return rxjs.throwError(clientErrors.TapClientError.encodeRequestError(command, e));
            }
            debug.debug(TAG, `Sending ${dataIn.length} bytes 0x${byteConverter.bufferToHexString(dataIn)}`);
            return this.getCurrentProtocol()
                .send(dataIn)
                .pipe(operators.map((result) => {
                // debug(
                //     TAG,
                //     'Received result: ',
                //     bufferToHexString(result),
                //     'DECODER: ',
                //     bodyDecoder ? bodyDecoder.constructor.name : 'NO'
                // );
                try {
                    let response = this._responseDecoder.decode(result);
                    if (bodyDecoder) {
                        response.setBodyDecoder(bodyDecoder);
                    }
                    return response;
                }
                catch (err) {
                    throw clientErrors.TapClientError.decodeResponseError(err, command);
                }
            }), operators.map(response$1 => {
                debug.debug(TAG, `Command "${command.toString()}" => Response: ${response$1.toString()}`);
                if (response$1 instanceof response.ResponseImpl) {
                    response$1.setRequest(command);
                }
                return response$1;
            }));
        }
        catch (err) {
            return rxjs.throwError(err);
        }
    }
}
exports.DefaultIoTizeClient = DefaultIoTizeClient;

});

var defaultIotizeClient$1 = unwrapExports(defaultIotizeClient);
var defaultIotizeClient_1 = defaultIotizeClient.DefaultIoTizeClient;

var pathParameter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class PathParameter {
    static fillParam(path, key, value) {
        var map = {};
        map[key] = value;
        return PathParameter.fillParams(path, map);
    }
    /**
     * Same as fillParams but will throw an error if some parameters has not been replaced
     */
    static fillAllParams(path, pathParameters) {
        path = PathParameter.fillParams(path, pathParameters);
        const remainingArgs = PathParameter.extractParams(path);
        if (remainingArgs.length > 0) {
            throw new Error(`Bad request. Some parameter have not been substitute: ${remainingArgs}`);
        }
        return path;
    }
    static fillParams(path, mapping) {
        for (var key in mapping) {
            var match = '{' + key + '}';
            if (path.indexOf(match) >= 0) {
                path = path.replace(match, mapping[key].toString());
            }
            else {
                throw new Error('Parameter ' + key + ' does not exist in path: ' + path);
            }
        }
        return path;
    }
    /**
     *
     * @param path
     * @returns names of path parameters
     */
    static extractParams(path) {
        var found = [], rxp = PathParameter.PARAMETER_REGEX, curMatch;
        while ((curMatch = rxp.exec(path))) {
            found.push(curMatch[1]);
        }
        return found;
    }
    static hasParams(path) {
        return PathParameter.extractParams(path).length > 0;
    }
}
exports.PathParameter = PathParameter;
PathParameter.PARAMETER_REGEX = /{([^}]+)}/g;

});

var pathParameter$1 = unwrapExports(pathParameter);
var pathParameter_1 = pathParameter.PathParameter;

var multipleMaskDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

function swapMap(val) {
    var ret = {};
    for (var key in val) {
        ret[val[key]] = key;
    }
    return ret;
}
class MultipleMaskConverter {
    // protected static _instance: UniqMaskDecoder;
    constructor(mapping) {
        this._mapping = mapping;
        // this._mapping[0x00] = (null as any as OutputType);
        // this._mapping[0x01] = (null as any as OutputType);
    }
    decode(body) {
        return MultipleMaskConverter.decodeAll(body, this._mapping);
    }
    /**
     * TODO check that not use more than the first 7 bits
     * @param types
     */
    encode(types) {
        return MultipleMaskConverter.encodeAll(types, this._mapping);
    }
    static encodeAll(values, mapping) {
        var _reverseMapping = swapMap(mapping);
        var result = 0x0;
        for (var type of values) {
            if (type in _reverseMapping) {
                var mask = parseInt(_reverseMapping[type]);
                result = result | mask;
            }
        }
        return Uint8Array.from([result & 0xff]);
    }
    static decodeAll(value, mapping) {
        var results = [];
        if (typeof value !== 'number') {
            value = numberDecoder.NumberConverter.fromOpaqueMsb(value, Math.min(value.length * 8, 32));
        }
        for (var key in mapping) {
            var mask = parseInt(key);
            if (mask == 0 && value == 0) {
                results.push(mapping[mask]);
            }
            else if ((mask & value) != 0) {
                results.push(mapping[mask]);
            }
        }
        return results;
    }
}
exports.MultipleMaskConverter = MultipleMaskConverter;

});

var multipleMaskDecoder$1 = unwrapExports(multipleMaskDecoder);
var multipleMaskDecoder_1 = multipleMaskDecoder.MultipleMaskConverter;

var uniqMaskDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });




const TAG = 'Converter';
/**
 * TODO improv it . We don't know the size of input buffer...
 */
class UniqMaskConverter {
    // protected _reverseMapping: { [key: number]: OutputType };
    constructor(mapping) {
        this._mapping = mapping;
    }
    decode(body) {
        return UniqMaskConverter.decodeOne(body, this._mapping);
    }
    encode(value) {
        return UniqMaskConverter.encodeOneAsBuffer(value, this._mapping);
    }
    static decodeOneExact(data, mapping) {
        if (typeof data !== 'number') {
            data = numberDecoder.NumberConverter.fromOpaqueMsb(data);
        }
        for (var key in mapping) {
            var mask = parseInt(key);
            if (data == mask) {
                return mapping[mask];
            }
        }
        throw new Error(`Cannot decode ${typeof data === 'number'
            ? 'number ' + data
            : '0x' + byteConverter.bufferToHexString(data)}. Available keys are ${Object.keys(mapping)}`);
    }
    static decodeOne(data, mapping) {
        var results = multipleMaskDecoder.MultipleMaskConverter.decodeAll(data, mapping);
        if (results.length == 0) {
            throw new Error(`Cannot decode value ${typeof data === 'number'
                ? data
                : '0x' + byteConverter.bufferToHexString(data)}. Available keys are ${Object.keys(mapping)}`);
        }
        else if (results.length > 1) {
            debug.debug(TAG, 'Multiple result for data : ', results, data, mapping);
        }
        return results[0];
    }
    static encodeOneAsNumber(data, mapping) {
        let swappedMap = UniqMaskConverter.swapKeyValue(mapping);
        let dataAsString = data.toString();
        if (!(dataAsString in swappedMap)) {
            throw new Error(`Key ${dataAsString} does not exist in mapping. Available keys are ${Object.keys(swappedMap)}`);
        }
        return parseInt(swappedMap[dataAsString]);
    }
    static encodeOneAsBuffer(data, mapping) {
        let result = new Uint8Array(1); // TODO change according to conf
        let encodedValue = UniqMaskConverter.encodeOneAsNumber(data, mapping);
        result[0] = encodedValue & 0xff;
        return result;
    }
    static swapKeyValue(input) {
        var ret = {};
        for (var key in input) {
            ret[input[key]] = key;
        }
        return ret;
    }
}
exports.UniqMaskConverter = UniqMaskConverter;

});

var uniqMaskDecoder$1 = unwrapExports(uniqMaskDecoder);
var uniqMaskDecoder_1 = uniqMaskDecoder.UniqMaskConverter;

var stringDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class StringConverter {
    constructor(encoding = 'ascii') {
        this.encoding = encoding;
    }
    encode(value) {
        let buffer$1 = buffer.Buffer.from(value, this.encoding);
        return Uint8Array.from(buffer$1);
    }
    decode(value) {
        return buffer.Buffer.from(value).toString(this.encoding);
    }
    /**
     * Get ascii instance
     * @deprecated use constructor instead
     */
    static instance() {
        return StringConverter.ascii();
    }
    /**
     * Get ascii instance
     * @deprecated use constructor instead
     */
    static ascii() {
        if (!StringConverter._ascii) {
            StringConverter._ascii = new StringConverter('ascii');
        }
        return StringConverter._ascii;
    }
}
exports.StringConverter = StringConverter;

});

var stringDecoder$1 = unwrapExports(stringDecoder);
var stringDecoder_1 = stringDecoder.StringConverter;

var booleanDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class BooleanConverter {
    constructor(_mask = 0x1) {
        this._mask = _mask;
    }
    decode(data) {
        var value = numberDecoder.NumberConverter.fromBytes(data, data.length, false, BooleanConverter.IS_LEAST_SIGNIFICANT_BIT_FIRST);
        return BooleanConverter.decodeFromNumber(this._mask, value);
    }
    encode(value) {
        return Uint8Array.from([value ? this._mask : ~this._mask]);
    }
    static decodeFromNumber(mask, value) {
        return (mask == 0 && value == 0) || (value & mask) != 0;
    }
    static instanceBit0() {
        if (!BooleanConverter._instance) {
            BooleanConverter._instance = new BooleanConverter(0b1);
        }
        return BooleanConverter._instance;
    }
}
exports.BooleanConverter = BooleanConverter;
BooleanConverter.IS_LEAST_SIGNIFICANT_BIT_FIRST = true;

});

var booleanDecoder$1 = unwrapExports(booleanDecoder);
var booleanDecoder_1 = booleanDecoder.BooleanConverter;

var ipv4StringDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class Ipv4StringConverter {
    decode(body) {
        if (body == null || body.length != 4) {
            throw error.ConverterError.unexpectedBufferSize(4, body);
        }
        var result = '';
        var values = Array.from(body);
        for (var part of values) {
            result += part.toString() + '.';
        }
        return result.substr(0, result.length - 1);
    }
    encode(ip) {
        var parts = ip.split('.');
        if (parts.length != 4) {
            throw new Error('Invalid ip format. Should be x.x.x.x');
        }
        var result = new Uint8Array(4);
        parts.map((value, index) => {
            result[index] = parseInt(value) & 0xff;
        });
        return result;
    }
    static instance() {
        if (!Ipv4StringConverter._instance) {
            Ipv4StringConverter._instance = new Ipv4StringConverter();
        }
        return Ipv4StringConverter._instance;
    }
}
exports.Ipv4StringConverter = Ipv4StringConverter;

});

var ipv4StringDecoder$1 = unwrapExports(ipv4StringDecoder);
var ipv4StringDecoder_1 = ipv4StringDecoder.Ipv4StringConverter;

var macAddressStringDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });


class MacAddressStringConverter {
    decode(body) {
        if (body == null ||
            body.length != MacAddressStringConverter.EXPECTED_ARRAY_LENGTH) {
            throw error.ConverterError.unexpectedBufferSize(MacAddressStringConverter.EXPECTED_ARRAY_LENGTH, body);
        }
        var result = '';
        for (var i = 0; i < body.length; i++) {
            var part = body.slice(i, i + 1);
            result += byteConverter.bufferToHexString(part).toUpperCase() + ':';
        }
        return result.substr(0, result.length - 1);
    }
    encode(value) {
        var parts = value.split(':');
        if (parts.length != 6) {
            throw new Error('Invalid mac address format: ' + value);
        }
        var result = new Uint8Array(parts.length);
        parts.map((value, index) => {
            result[index] = parseInt(value) & 0xff;
        });
        return result;
    }
    static instance() {
        if (!MacAddressStringConverter._instance) {
            MacAddressStringConverter._instance = new MacAddressStringConverter();
        }
        return MacAddressStringConverter._instance;
    }
}
exports.MacAddressStringConverter = MacAddressStringConverter;
MacAddressStringConverter.EXPECTED_ARRAY_LENGTH = 6;

});

var macAddressStringDecoder$1 = unwrapExports(macAddressStringDecoder);
var macAddressStringDecoder_1 = macAddressStringDecoder.MacAddressStringConverter;

var hexString = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class HexStringConverter {
    decode(value) {
        return byteConverter.bufferToHexString(value);
    }
    encode(value) {
        if (!value || value.length == 0) {
            return new Uint8Array(0);
        }
        if (value.length % 2 > 0) {
            // Prefix with 0
            value = '0' + value;
        }
        var result = [];
        for (var i = 0, len = value.length; i < len; i += 2) {
            result.push(parseInt(value.substr(i, 2), 16));
        }
        return new Uint8Array(result);
    }
    static instance() {
        if (!HexStringConverter._instance) {
            HexStringConverter._instance = new HexStringConverter();
        }
        return HexStringConverter._instance;
    }
}
exports.HexStringConverter = HexStringConverter;

});

var hexString$1 = unwrapExports(hexString);
var hexString_1 = hexString.HexStringConverter;

var floatConverter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class FloatConverter {
    constructor(options) {
        this.options = options;
    }
    encode(value) {
        return numberDecoder.NumberConverter.toOpaqueMsb(FloatConverter.toArray(value), 32);
    }
    decode(body) {
        return FloatConverter.toFloat(body);
    }
    /**
     *
     * @see https://stackoverflow.com/questions/3096646/how-to-convert-a-floating-point-number-to-its-binary-representation-ieee-754-i
     * @param number
     */
    static toArray(number) {
        var n = +number, status = n !== n || n == -Infinity || n == +Infinity ? n : 0, exp = 0, len = 281, // 2 * 127 + 1 + 23 + 3,
        bin = new Array(len), signal = (n = status !== 0 ? 0 : n) < 0, n = Math.abs(n), intPart = Math.floor(n), floatPart = n - intPart, i, lastBit, rounded, j, exponent;
        if (status !== 0) {
            if (n !== n) {
                return 0x7fc00000;
            }
            if (n === Infinity) {
                return 0x7f800000;
            }
            if (n === -Infinity) {
                return 0xff800000;
            }
        }
        i = len;
        while (i) {
            bin[--i] = 0;
        }
        i = 129;
        while (intPart && i) {
            bin[--i] = intPart % 2;
            intPart = Math.floor(intPart / 2);
        }
        i = 128;
        while (floatPart > 0 && i) {
            (bin[++i] = (floatPart *= 2) >= 1 ? 1 : 0) && --floatPart;
        }
        i = -1;
        while (++i < len && !bin[i])
            ;
        if (bin[(lastBit =
            22 +
                (i =
                    (exp = 128 - i) >= -126 && exp <= 127
                        ? i + 1
                        : 128 - (exp = -127))) + 1]) {
            if (!(rounded = bin[lastBit])) {
                j = lastBit + 2;
                while (!rounded && j < len) {
                    rounded = bin[j++];
                }
            }
            j = lastBit + 1;
            while (rounded && --j >= 0) {
                (bin[j] = !bin[j] - 0) && (rounded = 0);
            }
        }
        i = i - 2 < 0 ? -1 : i - 3;
        while (++i < len && !bin[i])
            ;
        (exp = 128 - i) >= -126 && exp <= 127
            ? ++i
            : exp < -126 && ((i = 255), (exp = -127));
        (intPart || status !== 0) &&
            ((exp = 128),
                (i = 129),
                status == -Infinity
                    ? (signal = true)
                    : status !== status && (bin[i] = 1));
        n = Math.abs(exp + 127);
        exponent = 0;
        j = 0;
        while (j < 8) {
            exponent += n % 2 << j;
            n >>= 1;
            j++;
        }
        var mantissa = 0;
        n = i + 23;
        for (; i < n; i++) {
            mantissa = (mantissa << 1) + bin[i];
        }
        return ((signal ? 0x80000000 : 0) + (exponent << 23) + mantissa) | 0;
    }
    static toFloat(val) {
        return FloatConverter.numberToFloat(numberDecoder.NumberConverter.fromOpaqueMsb(val, 32));
    }
    static numberToFloat(val) {
        var bits = 1 * val;
        var sign = (bits & 0x80000000) == 0 ? 1 : -1;
        var exponent = (bits & 0x7f800000) >> 23;
        var mantissa = bits & 0x007fffff;
        mantissa |= 0x00800000;
        var f = 1.0 * (sign * mantissa * Math.pow(2, exponent - 150));
        return parseFloat(f.toFixed(5));
    }
    static instance32() {
        if (!FloatConverter._instance32) {
            FloatConverter._instance32 = new FloatConverter();
        }
        return FloatConverter._instance32;
    }
}
exports.FloatConverter = FloatConverter;

});

var floatConverter$1 = unwrapExports(floatConverter);
var floatConverter_1 = floatConverter.FloatConverter;

var body = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(uniqMaskDecoder);
__export(numberDecoder);
__export(stringDecoder);
__export(booleanDecoder);
__export(multipleMaskDecoder);
__export(ipv4StringDecoder);
__export(macAddressStringDecoder);
__export(hexString);
__export(floatConverter);

});

var index$3 = unwrapExports(body);

var command = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(converter);
__export(apduCommand);

});

var index$4 = unwrapExports(command);

var response$1 = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(apduResponse);
__export(converter$2);

});

var index$5 = unwrapExports(response$1);

var apdu = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(invalidAdpuError);
__export(apduStatusCode);

exports.Command = command;

exports.Response = response$1;

});

var index$6 = unwrapExports(apdu);
var apdu_1 = apdu.Command;
var apdu_2 = apdu.Response;

var responseEncoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



/**
 * Created by Stephane on 02/02/2018.
 */
class DefaultResponseEncoder {
    constructor() {
        this.encoder = new converter$2.APDUResponseConverter();
    }
    encode(response) {
        var apduResponse$1 = new apduResponse.APDUResponse();
        apduResponse$1.setData(response.toBytes());
        apduResponse$1.setStatus(apdu.APDUStatusCode.SUCCESSFUL);
        return this.encoder.encode(apduResponse$1);
    }
}
exports.DefaultResponseEncoder = DefaultResponseEncoder;

});

var responseEncoder$1 = unwrapExports(responseEncoder);
var responseEncoder_1 = responseEncoder.DefaultResponseEncoder;

var defaultCommandDecoder = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



class DefaultCommandDecoder {
    constructor() {
        this.iotizeFrameConverter = new lwm2mCommandConverter.IotizeLWM2MCommandConverter();
        this.apduDecoder = new converter.APDUCommandConverter();
    }
    static instance() {
        return new DefaultCommandDecoder();
    }
    decode(iotizeEncodedCommandWithAPDU) {
        // debug(TAG, DefaultCommandDecoder.TAG, "Decoding command (with APDU): ", bufferToHexString(iotizeEncodedCommandWithAPDU));
        var apduModel = this.apduDecoder.decode(iotizeEncodedCommandWithAPDU);
        //        byte cmd = apduModel.getInstructionCode();
        // Data
        //        var data;
        //        if (lenData > 0) {
        //            data = new byte[lenData];
        //            System.arraycopy(buffer, 12, data, 0, lenData);
        //        }
        //        else{
        //            data = null;
        //        }
        var frame = apduModel.getData();
        if (frame == null || frame.length == 0) {
            throw error.ConverterError.nullBufferError('Cannot decode command, buffer is empty');
        }
        else if (frame.length < DefaultCommandDecoder.IOTIZE_TRAME_HEADER_LENGTH) {
            throw new Error('Frame is smaller than the minimum iotize trame size');
        }
        return this.iotizeFrameConverter.decode(frame);
    }
}
exports.DefaultCommandDecoder = DefaultCommandDecoder;
DefaultCommandDecoder.IOTIZE_TRAME_HEADER_LENGTH = 7;
DefaultCommandDecoder.TAG = 'DefaultCommandDecoder';

});

var defaultCommandDecoder$1 = unwrapExports(defaultCommandDecoder);
var defaultCommandDecoder_1 = defaultCommandDecoder.DefaultCommandDecoder;

var tlvConverter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class TLVConverter {
    constructor() {
        this.serializer = new tlv.TLV.Serializer();
        this.parser = new tlv.TLV.Parser();
    }
    encode(data) {
        return this.serializer.serialize(data);
    }
    decode(data) {
        let tlvTree = this.parser.parse(data);
        return tlvTree;
    }
}
exports.TLVConverter = TLVConverter;

});

var tlvConverter$1 = unwrapExports(tlvConverter);
var tlvConverter_1 = tlvConverter.TLVConverter;

var models_extensions = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function createTapEncryptedFrame(id, payload, paddingGenerator) {
    let len = payload.length;
    // let padSize = computePadding(8 + len, 16)
    // let padding = paddingGenerator ? paddingGenerator(padSize) : undefined
    return {
        id: id,
        len: len,
        payload: payload
        // padding: padding
    };
}
exports.createTapEncryptedFrame = createTapEncryptedFrame;

});

var models_extensions$1 = unwrapExports(models_extensions);
var models_extensions_1 = models_extensions.createTapEncryptedFrame;

var cryptedFrameConverter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });



/**
 *
 */
class CryptedFrameConverter {
    constructor(frameIdGenerator) {
        this.frameIdGenerator = frameIdGenerator;
    }
    encode(data) {
        let encryptedModel = models_extensions.createTapEncryptedFrame(this.frameIdGenerator.next(), data
        // this.paddingGenerator
        );
        return new tapStream.TapStreamWriter().writeTapEncryptedFrame(encryptedModel)
            .toBytes;
    }
    decode(frame) {
        if (!frame) {
            throw error.ConverterError.nullBufferError('Illegal data: frame is null');
        }
        let encryptedFrame = tapStream.TapStreamReader.fromArray(frame).readTapEncryptedFrame();
        let subData = encryptedFrame.payload;
        // TODO add back crc
        // let crc = encryptedFrame.crc;
        // let computedCrc = this._computeCRC(byteBuffer.data);
        // if (crc != computedCrc){
        //     if (this.options.skipCRCCheck){
        //     }
        //     else{
        //         throw new Error(`Invalid crc read ${crc}. Should be ${computedCrc}`);
        //     }
        // }
        return subData;
    }
}
exports.CryptedFrameConverter = CryptedFrameConverter;

});

var cryptedFrameConverter$1 = unwrapExports(cryptedFrameConverter);
var cryptedFrameConverter_1 = cryptedFrameConverter.CryptedFrameConverter;

var lwm2mResponseConverter = createCommonjsModule(function (module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

class IotizeLWM2MResponseConverter {
    decode(frame) {
        var response$1 = new response.Response(frame);
        return response$1;
    }
    encode(response) {
        return response.toBytes();
    }
}
exports.IotizeLWM2MResponseConverter = IotizeLWM2MResponseConverter;

});

var lwm2mResponseConverter$1 = unwrapExports(lwm2mResponseConverter);
var lwm2mResponseConverter_1 = lwm2mResponseConverter.IotizeLWM2MResponseConverter;

var converter$4 = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(body);
__export(responseDecoder);
__export(responseEncoder);
__export(defaultCommandDecoder);
__export(defaultCommandEncoder);
__export(tlvConverter);
__export(error);
__export(defaultCommandDecoder);
__export(defaultCommandEncoder);
__export(cryptedFrameConverter);
__export(lwm2mCommandConverter);
__export(lwm2mResponseConverter);

});

var index$7 = unwrapExports(converter$4);

var models = createCommonjsModule(function (module, exports) {
"use strict";
/**
 * This file has been generated
 * DO NOT EDIT, IT MAY BE OVERWRITTEN
 */
Object.defineProperty(exports, "__esModule", { value: true });
var TapRequest;
(function (TapRequest) {
    let MethodType;
    (function (MethodType) {
        MethodType[MethodType["GET"] = 1] = "GET";
        MethodType[MethodType["POST"] = 2] = "POST";
        MethodType[MethodType["PUT"] = 3] = "PUT";
    })(MethodType = TapRequest.MethodType || (TapRequest.MethodType = {}));
})(TapRequest = exports.TapRequest || (exports.TapRequest = {}));
var TapApduRequest;
(function (TapApduRequest) {
    let MethodType;
    (function (MethodType) {
        MethodType[MethodType["GET"] = 202] = "GET";
        MethodType[MethodType["PUT_OR_POST"] = 218] = "PUT_OR_POST";
    })(MethodType = TapApduRequest.MethodType || (TapApduRequest.MethodType = {}));
    let Default;
    (function (Default) {
        Default[Default["CLA"] = 162] = "CLA";
    })(Default = TapApduRequest.Default || (TapApduRequest.Default = {}));
})(TapApduRequest = exports.TapApduRequest || (exports.TapApduRequest = {}));

});

var models$1 = unwrapExports(models);
var models_1 = models.TapRequest;
var models_2 = models.TapApduRequest;

var public_api = createCommonjsModule(function (module, exports) {
"use strict";
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(defaultIotizeClient);
__export(clientErrors);
__export(request);
__export(response);
__export(pathParameter);
__export(converter$4);
__export(models);
__export(models_extensions);
__export(tapStream);
__export(crc);
__export(checksum);

});

var public_api$1 = unwrapExports(public_api);

var iotizeDeviceClient_jsClientImpl = createCommonjsModule(function (module, exports) {
"use strict";
/**
 * Generated bundle index. Do not edit.
 */
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(public_api);

});

var iotizeDeviceClient_jsClientImpl$1 = unwrapExports(iotizeDeviceClient_jsClientImpl);

export default iotizeDeviceClient_jsClientImpl$1;
//# sourceMappingURL=iotize-device-client.js-client-impl.js.map
