(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@iotize/tap'), require('@iotize/tap/client/api'), require('@iotize/tap/client/impl'), require('@iotize/tap/service/core'), require('@iotize/common/error'), require('@iotize/common/byte-converter'), require('@iotize/common/crypto'), require('@iotize/tap/auth'), require('@iotize/tap/crypto'), require('@iotize/common/task-manager'), require('@iotize/common/utility'), require('@iotize/common/debug'), require('@iotize/common/array'), require('@iotize/common/byte-stream')) :
    typeof define === 'function' && define.amd ? define('@iotize/tap/service/impl/single-packet', ['exports', '@iotize/tap', '@iotize/tap/client/api', '@iotize/tap/client/impl', '@iotize/tap/service/core', '@iotize/common/error', '@iotize/common/byte-converter', '@iotize/common/crypto', '@iotize/tap/auth', '@iotize/tap/crypto', '@iotize/common/task-manager', '@iotize/common/utility', '@iotize/common/debug', '@iotize/common/array', '@iotize/common/byte-stream'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.iotize = global.iotize || {}, global.iotize.tap = global.iotize.tap || {}, global.iotize.tap.service = global.iotize.tap.service || {}, global.iotize.tap.service.impl = global.iotize.tap.service.impl || {}, global.iotize.tap.service.impl["single-packet"] = {}), global.iotize.tap, global.iotize.tap.client.api, global.iotize.tap.client.impl, global.iotize.tap.service.core, global.error, global.byteConverter, global.crypto$1, global.iotize.tap.auth, global.iotize.tap.crypto, global.taskManager, global.utility, global.debug$1, global.array, global.byteStream));
})(this, (function (exports, tap, api, impl, core, error, byteConverter, crypto$1, auth, crypto, taskManager, utility, debug$1, array, byteStream) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (Object.prototype.hasOwnProperty.call(b, p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    var __assign = function () {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s)
                    if (Object.prototype.hasOwnProperty.call(s, p))
                        t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    function __rest(s, e) {
        var t = {};
        for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
                t[p] = s[p];
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                    t[p[i]] = s[p[i]];
            }
        return t;
    }
    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
            r = Reflect.decorate(decorators, target, key, desc);
        else
            for (var i = decorators.length - 1; i >= 0; i--)
                if (d = decorators[i])
                    r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }
    function __param(paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); };
    }
    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
            return Reflect.metadata(metadataKey, metadataValue);
    }
    function __awaiter$1(thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try {
                step(generator.next(value));
            }
            catch (e) {
                reject(e);
            } }
            function rejected(value) { try {
                step(generator["throw"](value));
            }
            catch (e) {
                reject(e);
            } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }
    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function () { if (t[0] & 1)
                throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f)
                throw new TypeError("Generator is already executing.");
            while (_)
                try {
                    if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
                        return t;
                    if (y = 0, t)
                        op = [op[0] & 2, t.value];
                    switch (op[0]) {
                        case 0:
                        case 1:
                            t = op;
                            break;
                        case 4:
                            _.label++;
                            return { value: op[1], done: false };
                        case 5:
                            _.label++;
                            y = op[1];
                            op = [0];
                            continue;
                        case 7:
                            op = _.ops.pop();
                            _.trys.pop();
                            continue;
                        default:
                            if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
                                _ = 0;
                                continue;
                            }
                            if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
                                _.label = op[1];
                                break;
                            }
                            if (op[0] === 6 && _.label < t[1]) {
                                _.label = t[1];
                                t = op;
                                break;
                            }
                            if (t && _.label < t[2]) {
                                _.label = t[2];
                                _.ops.push(op);
                                break;
                            }
                            if (t[2])
                                _.ops.pop();
                            _.trys.pop();
                            continue;
                    }
                    op = body.call(thisArg, _);
                }
                catch (e) {
                    op = [6, e];
                    y = 0;
                }
                finally {
                    f = t = 0;
                }
            if (op[0] & 5)
                throw op[1];
            return { value: op[0] ? op[1] : void 0, done: true };
        }
    }
    var __createBinding = Object.create ? (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
    }) : (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        o[k2] = m[k];
    });
    function __exportStar(m, o) {
        for (var p in m)
            if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
                __createBinding(o, m, p);
    }
    function __values(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m)
            return m.call(o);
        if (o && typeof o.length === "number")
            return {
                next: function () {
                    if (o && i >= o.length)
                        o = void 0;
                    return { value: o && o[i++], done: !o };
                }
            };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    }
    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m)
            return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                ar.push(r.value);
        }
        catch (error) {
            e = { error: error };
        }
        finally {
            try {
                if (r && !r.done && (m = i["return"]))
                    m.call(i);
            }
            finally {
                if (e)
                    throw e.error;
            }
        }
        return ar;
    }
    /** @deprecated */
    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }
    /** @deprecated */
    function __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++)
            s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    }
    function __spreadArray(to, from, pack) {
        if (pack || arguments.length === 2)
            for (var i = 0, l = from.length, ar; i < l; i++) {
                if (ar || !(i in from)) {
                    if (!ar)
                        ar = Array.prototype.slice.call(from, 0, i);
                    ar[i] = from[i];
                }
            }
        return to.concat(ar || Array.prototype.slice.call(from));
    }
    function __await(v) {
        return this instanceof __await ? (this.v = v, this) : new __await(v);
    }
    function __asyncGenerator(thisArg, _arguments, generator) {
        if (!Symbol.asyncIterator)
            throw new TypeError("Symbol.asyncIterator is not defined.");
        var g = generator.apply(thisArg, _arguments || []), i, q = [];
        return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
        function verb(n) { if (g[n])
            i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
        function resume(n, v) { try {
            step(g[n](v));
        }
        catch (e) {
            settle(q[0][3], e);
        } }
        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
        function fulfill(value) { resume("next", value); }
        function reject(value) { resume("throw", value); }
        function settle(f, v) { if (f(v), q.shift(), q.length)
            resume(q[0][0], q[0][1]); }
    }
    function __asyncDelegator(o) {
        var i, p;
        return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
    }
    function __asyncValues(o) {
        if (!Symbol.asyncIterator)
            throw new TypeError("Symbol.asyncIterator is not defined.");
        var m = o[Symbol.asyncIterator], i;
        return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
    }
    function __makeTemplateObject(cooked, raw) {
        if (Object.defineProperty) {
            Object.defineProperty(cooked, "raw", { value: raw });
        }
        else {
            cooked.raw = raw;
        }
        return cooked;
    }
    ;
    var __setModuleDefault = Object.create ? (function (o, v) {
        Object.defineProperty(o, "default", { enumerable: true, value: v });
    }) : function (o, v) {
        o["default"] = v;
    };
    function __importStar(mod) {
        if (mod && mod.__esModule)
            return mod;
        var result = {};
        if (mod != null)
            for (var k in mod)
                if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
                    __createBinding(result, mod, k);
        __setModuleDefault(result, mod);
        return result;
    }
    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }
    function __classPrivateFieldGet(receiver, state, kind, f) {
        if (kind === "a" && !f)
            throw new TypeError("Private accessor was defined without a getter");
        if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
            throw new TypeError("Cannot read private member from an object whose class did not declare it");
        return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
    }
    function __classPrivateFieldSet(receiver, state, value, kind, f) {
        if (kind === "m")
            throw new TypeError("Private method is not writable");
        if (kind === "a" && !f)
            throw new TypeError("Private accessor was defined without a setter");
        if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
            throw new TypeError("Cannot write private member to an object whose class did not declare it");
        return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
    }

    exports.SinglePacketStoreInfo = void 0;
    (function (SinglePacketStoreInfo) {
        /* eslint-disable */
        /**
         * This file was automatically generated by json-schema-to-typescript.
         * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
         * and run json-schema-to-typescript to regenerate this file.
         */
        var State;
        (function (State) {
            State[State["UNAVAILABLE"] = 0] = "UNAVAILABLE";
            State[State["EMPTY"] = 1] = "EMPTY";
            State[State["USED"] = 2] = "USED";
            State[State["FULL"] = 3] = "FULL";
            State[State["ERROR"] = 4] = "ERROR";
        })(State = SinglePacketStoreInfo.State || (SinglePacketStoreInfo.State = {}));
    })(exports.SinglePacketStoreInfo || (exports.SinglePacketStoreInfo = {}));
    exports.SinglePacket = void 0;
    (function (SinglePacket) {
        /* eslint-disable */
        /**
         * This file was automatically generated by json-schema-to-typescript.
         * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
         * and run json-schema-to-typescript to regenerate this file.
         */
        /* eslint-disable */
        /**
         * This file was automatically generated by json-schema-to-typescript.
         * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
         * and run json-schema-to-typescript to regenerate this file.
         */
        var PacketType;
        (function (PacketType) {
            PacketType[PacketType["DATA_LOG"] = 1] = "DATA_LOG";
            PacketType[PacketType["COMMAND"] = 2] = "COMMAND";
            PacketType[PacketType["CODE_EXEC"] = 3] = "CODE_EXEC";
            PacketType[PacketType["CONF_UPDATE"] = 4] = "CONF_UPDATE";
            PacketType[PacketType["SECURITY_TOKEN"] = 5] = "SECURITY_TOKEN";
            PacketType[PacketType["TARGET_FW_UPDATE"] = 6] = "TARGET_FW_UPDATE";
            PacketType[PacketType["MASK"] = 7] = "MASK";
        })(PacketType = SinglePacket.PacketType || (SinglePacket.PacketType = {}));
    })(exports.SinglePacket || (exports.SinglePacket = {}));
    exports.SinglePacketChunk = void 0;
    (function (SinglePacketChunk) {
        /* eslint-disable */
        /**
         * This file was automatically generated by json-schema-to-typescript.
         * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
         * and run json-schema-to-typescript to regenerate this file.
         */
        var Format;
        (function (Format) {
            Format[Format["OFFSET_ON_2_BYTES"] = 0] = "OFFSET_ON_2_BYTES";
            Format[Format["OFFSET_ON_4_BYTES"] = 8] = "OFFSET_ON_4_BYTES";
        })(Format = SinglePacketChunk.Format || (SinglePacketChunk.Format = {}));
    })(exports.SinglePacketChunk || (exports.SinglePacketChunk = {}));

    /**
     *   Generated file. Do not edit
     */
    impl.TapStreamReader.prototype.readSinglePacketStoreInfo =
        function () {
            var model = {};
            this.forwardBits(24);
            model.state = this.readUnsigned(1);
            return model;
        };
    impl.TapStreamReader.prototype.readSinglePacket = function () {
        var model = {};
        model.sendTime = this.readUnsigned(4);
        model.header = this.readSinglePacketHeader();
        model.payload = this.readSinglePacketPayload();
        return model;
    };
    impl.TapStreamReader.prototype.readSinglePacketHeader =
        function () {
            var model = {};
            model.packetLength = this.readUnsigned(2);
            model.packetId = this.readUnsigned(2);
            model.configVersion = this.readUnsigned(4);
            model.messageType = this.readBits(4);
            this.forwardBits(1);
            model.isExtended = this.readBoolean(1);
            model.encryption = this.readBoolean(1);
            model.ack = this.readBoolean(1);
            model.senderId = this.readUnsigned(1);
            model.salt = this.readUnsigned(2);
            return model;
        };
    impl.TapStreamReader.prototype.readSinglePacketPayload =
        function () {
            var model = {};
            model.logTime = this.readUnsigned(4);
            model.dataSize = this.readUnsigned(2);
            model.data = this.readBytes((model.dataSize === undefined ? 0 : model.dataSize) == 0
                ? this.getStreamSize() - 4
                : model.dataSize === undefined
                    ? 0
                    : model.dataSize);
            model.padding = this.readBytes((4 - ((model.data.length + 10) % 4)) % 4);
            model.crc = this.readUnsigned(4);
            return model;
        };
    impl.TapStreamReader.prototype.readSinglePacketChunk =
        function () {
            var model = {};
            model.format = this.readBits(4);
            model.length = this.readBits(12);
            model.offset = this.readUnsigned(model.format == 8 ? 4 : 2);
            model.data = this.readBytes((model.length === undefined ? 0 : model.length) * 16);
            return model;
        };
    // TapStreamWriter.prototype.write(model: SinglePacketStoreInfo) : TapStreamWriter{
    //     return this.writeSinglePacketStoreInfo(model)
    // }
    impl.TapStreamWriter.prototype.writeSinglePacketStoreInfo = function (model) {
        this.forwardBits(24);
        this.writeBitsInt(impl.enumKeyOrValueToNumber(model.state, exports.SinglePacketStoreInfo.State), 8);
        return this;
    };
    // TapStreamWriter.prototype.write(model: SinglePacket) : TapStreamWriter{
    //     return this.writeSinglePacket(model)
    // }
    impl.TapStreamWriter.prototype.writeSinglePacket = function (model) {
        this.writeUnsigned(model.sendTime, 4);
        this.writeSinglePacketHeader(model.header);
        this.writeSinglePacketPayload(model.payload);
        return this;
    };
    impl.TapStreamWriter.prototype.writeSinglePacketHeader = function (model) {
        this.writeUnsigned(model.packetLength, 2);
        this.writeUnsigned(model.packetId, 2);
        this.writeUnsigned(model.configVersion, 4);
        this.writeBitsInt(impl.enumKeyOrValueToNumber(model.messageType, exports.SinglePacket.PacketType), 4);
        this.forwardBits(1);
        this.writeBoolean(model.isExtended, 1);
        this.writeBoolean(model.encryption, 1);
        this.writeBoolean(model.ack, 1);
        this.writeUnsigned(model.senderId, 1);
        this.writeUnsigned(model.salt, 2);
        return this;
    };
    impl.TapStreamWriter.prototype.writeSinglePacketPayload = function (model) {
        this.writeUnsigned(model.logTime, 4);
        this.writeUnsigned(model.dataSize !== undefined
            ? model.dataSize
            : model.data.length > 0xffff
                ? 0
                : model.data.length, 2);
        this.writeBytes(model.data, (model.dataSize === undefined ? 0 : model.dataSize) == 0
            ? model.data.length
            : model.dataSize === undefined
                ? 0
                : model.dataSize);
        this.writeFunction('padding', undefined, model.padding, (4 - ((model.data.length + 10) % 4)) % 4);
        this.writeFunction('crc32', {
            offset: 4,
        }, model.crc, 4);
        return this;
    };
    // TapStreamWriter.prototype.write(model: SinglePacketChunk) : TapStreamWriter{
    //     return this.writeSinglePacketChunk(model)
    // }
    impl.TapStreamWriter.prototype.writeSinglePacketChunk = function (model) {
        this.writeBitsInt(impl.enumKeyOrValueToNumber(model.format, exports.SinglePacketChunk.Format), 4);
        this.writeBits(model.length !== undefined ? model.length : model.data.length / 16, 12);
        this.writeUnsigned(model.offset, model.format == 8 ? 4 : 2);
        this.writeBytes(model.data, (model.length === undefined ? 0 : model.length) == 0
            ? model.data.length
            : (model.length === undefined ? 0 : model.length) * 16);
        return this;
    };

    /**
     *   Generated file. Do not edit
     */
    var SinglePacketStoreInfoConverter = /** @class */ (function () {
        function SinglePacketStoreInfoConverter() {
        }
        SinglePacketStoreInfoConverter.prototype.encode = function (model, stream) {
            if (stream === void 0) { stream = new impl.TapStreamWriter(); }
            stream.writeSinglePacketStoreInfo(model);
            return stream.toBytes;
        };
        SinglePacketStoreInfoConverter.prototype.decode = function (data) {
            var stream = data instanceof impl.TapStreamReader ? data : impl.TapStreamReader.create(data);
            return stream.readSinglePacketStoreInfo();
        };
        return SinglePacketStoreInfoConverter;
    }());
    var SinglePacketConverter = /** @class */ (function () {
        function SinglePacketConverter() {
        }
        SinglePacketConverter.prototype.encode = function (model, stream) {
            if (stream === void 0) { stream = new impl.TapStreamWriter(); }
            stream.writeSinglePacket(model);
            return stream.toBytes;
        };
        SinglePacketConverter.prototype.decode = function (data) {
            var stream = data instanceof impl.TapStreamReader ? data : impl.TapStreamReader.create(data);
            return stream.readSinglePacket();
        };
        return SinglePacketConverter;
    }());
    var SinglePacketChunkConverter = /** @class */ (function () {
        function SinglePacketChunkConverter() {
        }
        SinglePacketChunkConverter.prototype.encode = function (model, stream) {
            if (stream === void 0) { stream = new impl.TapStreamWriter(); }
            stream.writeSinglePacketChunk(model);
            return stream.toBytes;
        };
        SinglePacketChunkConverter.prototype.decode = function (data) {
            var stream = data instanceof impl.TapStreamReader ? data : impl.TapStreamReader.create(data);
            return stream.readSinglePacketChunk();
        };
        return SinglePacketChunkConverter;
    }());

    /**
     *   Generated file. Do not edit
     */
    var singlePacketStoreInfo = new SinglePacketStoreInfoConverter();
    var singlePacket = new SinglePacketConverter();
    var singlePacketChunk = new SinglePacketChunkConverter();

    var serviceConverters = /*#__PURE__*/Object.freeze({
        __proto__: null,
        singlePacketStoreInfo: singlePacketStoreInfo,
        singlePacket: singlePacket,
        singlePacketChunk: singlePacketChunk
    });

    /**
     *   Generated file. Do not edit
     */
    var allConverters = Object.assign(Object.assign({}, core.converters), serviceConverters);
    var SERVICE_CALLS = {
        getInfo: {
            method: api.TapRequestFrame.MethodType.GET,
            pathAlias: '/single-packet/info',
            path: '/1024//81',
            responseBodyDecoder: allConverters.singlePacketStoreInfo,
        },
        writeAndExecuteBytes: {
            method: api.TapRequestFrame.MethodType.POST,
            pathAlias: '/single-packet/write-and-execute-bytes',
            path: '/1024//80',
        },
        writeAndExecute: {
            method: api.TapRequestFrame.MethodType.POST,
            pathAlias: '/single-packet/write-and-execute',
            path: '/1024//80',
            bodyEncoder: allConverters.singlePacket,
        },
        writeChunk: {
            method: api.TapRequestFrame.MethodType.POST,
            pathAlias: '/single-packet/write-chunk',
            path: '/1024//82',
            bodyEncoder: allConverters.singlePacketChunk,
        },
        executeSinglePacketInStore: {
            method: api.TapRequestFrame.MethodType.POST,
            pathAlias: '/single-packet/execute-single-packet-in-store',
            path: '/1024//83',
            bodyEncoder: allConverters.uint32,
        },
    };

    var SinglePacketService = /** @class */ (function (_super) {
        __extends(SinglePacketService, _super);
        function SinglePacketService() {
            var _this = _super.apply(this, __spreadArray([], __read(arguments))) || this;
            _this.resources = SERVICE_CALLS;
            return _this;
        }
        /**
         * Get information concerning Single Packet Store Status
         *
         * LWM2M path: /1024//81
         *
         * @tapVersion(">=1.13")
         * @return
         */
        SinglePacketService.prototype.getInfo = function () {
            return this.serviceCallRunner.execute(this.getInfoCall());
        };
        /**
         *
         *
         * LWM2M path: /1024//81
         *
         * @tapVersion(">=1.13")
         * @return call options
         */
        SinglePacketService.prototype.getInfoCall = function () {
            var callOptions = Object.assign({}, this.resources.getInfo);
            return callOptions;
        };
        /**
         * Send a complete Small Single Packet
         *
         * LWM2M path: /1024//80
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return
         */
        SinglePacketService.prototype.writeAndExecuteBytes = function (
        /*
         *
         */
        data) {
            return this.serviceCallRunner.execute(this.writeAndExecuteBytesCall(data));
        };
        /**
         *
         *
         * LWM2M path: /1024//80
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return call options
         */
        SinglePacketService.prototype.writeAndExecuteBytesCall = function (
        /*
         *
         */
        data) {
            var callOptions = Object.assign({}, this.resources.writeAndExecuteBytes);
            callOptions.body = data;
            return callOptions;
        };
        /**
         * Send and execute the given Single Packet in one request
         *
         * LWM2M path: /1024//80
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return
         */
        SinglePacketService.prototype.writeAndExecute = function (
        /*
         *
         */
        data) {
            return this.serviceCallRunner.execute(this.writeAndExecuteCall(data));
        };
        /**
         *
         *
         * LWM2M path: /1024//80
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return call options
         */
        SinglePacketService.prototype.writeAndExecuteCall = function (
        /*
         *
         */
        data) {
            var callOptions = Object.assign({}, this.resources.writeAndExecute);
            callOptions.body = data;
            return callOptions;
        };
        /**
         * Write single packet chunk
         *
         * LWM2M path: /1024//82
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return
         */
        SinglePacketService.prototype.writeChunk = function (
        /*
         *
         */
        data) {
            return this.serviceCallRunner.execute(this.writeChunkCall(data));
        };
        /**
         *
         *
         * LWM2M path: /1024//82
         *
         * @tapVersion(">=1.13")
         * @param data input
         * @return call options
         */
        SinglePacketService.prototype.writeChunkCall = function (
        /*
         *
         */
        data) {
            var callOptions = Object.assign({}, this.resources.writeChunk);
            callOptions.body = data;
            return callOptions;
        };
        /**
         * Execute single packet stored in Tap storage
         *
         * LWM2M path: /1024//83
         *
         * @tapVersion(">=1.13")
         * @param crc input
         * @return
         */
        SinglePacketService.prototype.executeSinglePacketInStore = function (
        /*
         * CRC of the single packet stored in Tap storage.
         */
        crc) {
            return this.serviceCallRunner.execute(this.executeSinglePacketInStoreCall(crc));
        };
        /**
         *
         *
         * LWM2M path: /1024//83
         *
         * @tapVersion(">=1.13")
         * @param crc input
         * @return call options
         */
        SinglePacketService.prototype.executeSinglePacketInStoreCall = function (
        /*
         * CRC of the single packet stored in Tap storage.
         */
        crc) {
            var callOptions = Object.assign({}, this.resources.executeSinglePacketInStore);
            callOptions.body = crc;
            return callOptions;
        };
        return SinglePacketService;
    }(tap.AbstractService));

    var _TAP_SERVICE_EXTENSION_SINGLEPACKET_ = tap.extendServiceContainer('singlePacket', SinglePacketService);

    exports.SinglePacketError = /** @class */ (function (_super) {
        __extends(SinglePacketError, _super);
        function SinglePacketError(code, msg) {
            return _super.call(this, msg, code) || this;
        }
        SinglePacketError.authSessionRequiredToEncryptSinglePacket = function () {
            return new SinglePacketError(SinglePacketError.Code.AuthSessionRequiredToEncryptSinglePacket, "A valid authenticated Tap session is required to encrypt single packet");
        };
        SinglePacketError.credentialsRequiredForEncryptedSinglePacket = function () {
            return new SinglePacketError(SinglePacketError.Code.CredentialsRequiredForEncryptedSinglePacket, "Single packet encryption is enabled, you need to provid encryption credentials");
        };
        SinglePacketError.internalError = function (msg) {
            return new SinglePacketError(SinglePacketError.Code.SinglePacketInternalError, "Single packet related internal error: " + msg);
        };
        SinglePacketError.maxSinglePacketPartSizeExceeded = function (packet, max) {
            return new SinglePacketError(SinglePacketError.Code.MaxSinglePacketPartSizeExceeded, "Single packet part size of " + packet.data.length + " bytes is above single packet maximum size of " + max + " bytes");
        };
        SinglePacketError.maxSinglePacketSizeExceeded = function (length, max) {
            return new SinglePacketError(SinglePacketError.Code.MaxSinglePacketSizeExceeded, "Single packet size of " + length + " bytes is above single packet maximum size of " + max + " bytes");
        };
        return SinglePacketError;
    }(error.CodeError));
    (function (SinglePacketError) {
        var Code;
        (function (Code) {
            Code["SinglePacketInternalError"] = "SinglePacketErrorInternalError";
            Code["AuthSessionRequiredToEncryptSinglePacket"] = "SinglePacketErrorAuthSessionRequiredToEncryptSinglePacket";
            Code["MaxSinglePacketPartSizeExceeded"] = "SinglePacketErrorMaxSinglePacketPartSizeExceeded";
            Code["MaxSinglePacketSizeExceeded"] = "SinglePacketErrorMaxSinglePacketSizeExceeded";
            Code["CredentialsRequiredForEncryptedSinglePacket"] = "SinglePacketErrorCredentialsRequiredForEncryptedSinglePacket";
        })(Code = SinglePacketError.Code || (SinglePacketError.Code = {}));
    })(exports.SinglePacketError || (exports.SinglePacketError = {}));

    var DefaultSinglePacketKeyGenerator = /** @class */ (function () {
        function DefaultSinglePacketKeyGenerator() {
        }
        /**
         * HMsg = UserName | IoTizeSN | PacketHeader1
         */
        DefaultSinglePacketKeyGenerator.prototype.generate = function (options) {
            var stream = new impl.TapStreamWriter();
            if (options.username.length > 16) {
                // TODO constant
                throw new Error("Invalid username too long: " + options.username);
            }
            stream.writeStr(options.username);
            if (options.serialNumber.length !== 18) {
                // TODO constant
                // TODO constant
                throw new Error("Invalid sn: " + options.serialNumber + ". Length must be 18");
            }
            stream.writeStr(options.serialNumber, 18);
            if (options.headerBytes.length !== 12) {
                throw new Error("Invalid header length " + options.headerBytes.length + ". Expected 12");
            }
            stream.writeBytes(options.headerBytes);
            var data = stream.toBytes;
            var key = crypto.hmacSHA256(data, options.hashKey).slice(0, 16);
            return key;
        };
        return DefaultSinglePacketKeyGenerator;
    }());

    var TAG$1 = 'SinglePacket';
    impl.TapStreamReader.prototype.readSinglePacketPayloadFullData =
        function () {
            var model = {};
            model.logTime = this.readU4();
            model.dataSize = this.readU2();
            model.data = this.readBytes(-4);
            model.crc = this.readU4();
            return model;
        };
    var SinglePacketEncryptionOptionsBuilder = /** @class */ (function () {
        function SinglePacketEncryptionOptionsBuilder() {
        }
        SinglePacketEncryptionOptionsBuilder.fromBlankKey = function (username) {
            return {
                hashKey: new Uint8Array(32),
                serialNumber: 'IoTize_FWUpdate_SP',
                username: username,
            };
        };
        SinglePacketEncryptionOptionsBuilder.fromHashKey = function (hashKey, username) {
            return {
                hashKey: hashKey,
                serialNumber: 'IoTize_FWUpdate_SP',
                username: username,
            };
        };
        SinglePacketEncryptionOptionsBuilder.fromUserCredentials = function (credentials, options) {
            var keys = auth.ScramAuth.computeBaseKeys(credentials.password, options);
            return SinglePacketEncryptionOptionsBuilder.fromCurrentSessionData({
                username: credentials.username,
                serverKey: keys.serverKey,
                storedKey: keys.storedKey,
            });
        };
        SinglePacketEncryptionOptionsBuilder.fromCurrentSessionData = function (sessionData) {
            var hashKey = impl.TapStreamWriter.create(32)
                .writeBytes(sessionData.storedKey)
                .writeBytes(sessionData.serverKey).toBytes;
            if (hashKey.length !== 32) {
                // TODO constant
                throw new Error("Single packet encryption not available");
            }
            return {
                hashKey: hashKey,
                serialNumber: 'IoTize_FWUpdate_SP',
                username: sessionData.username,
            };
        };
        return SinglePacketEncryptionOptionsBuilder;
    }());
    var EncryptedSinglePacketConverter = /** @class */ (function () {
        function EncryptedSinglePacketConverter(options, encryptionAlgo, keyGenerator) {
            if (encryptionAlgo === void 0) { encryptionAlgo = new crypto$1.AesEcb128Converter(); }
            if (keyGenerator === void 0) { keyGenerator = new DefaultSinglePacketKeyGenerator(); }
            this.options = options;
            this.encryptionAlgo = encryptionAlgo;
            this.keyGenerator = keyGenerator;
        }
        EncryptedSinglePacketConverter.createWithBlankKey = function () {
            return new EncryptedSinglePacketConverter(SinglePacketEncryptionOptionsBuilder.fromBlankKey('IoTize'));
        };
        EncryptedSinglePacketConverter.prototype.setEncryptionOptions = function (options) {
            this.options = Object.assign(Object.assign({}, this.options), options);
        };
        EncryptedSinglePacketConverter.prototype.encode = function (packet) {
            var stream = new impl.TapStreamWriter();
            stream.writeU4(packet.sendTime);
            stream.writeSinglePacketHeader(packet.header);
            var payloadBytesPosition = stream.pos;
            stream.writeSinglePacketPayload(packet.payload);
            if (packet.header.encryption) {
                var bytes = stream.toBytes;
                // debug(`SinglePacket before encryption: ${toHexString(bytes)}`);
                var encryptionAlgo = this._getEncryptionAlgo(packet.header);
                var encryptedPayloadBytes = bytes.slice(payloadBytesPosition);
                encryptedPayloadBytes = encryptionAlgo.encode(encryptedPayloadBytes);
                stream.pos = payloadBytesPosition;
                stream.writeBytes(encryptedPayloadBytes);
            }
            return stream.toBytes;
        };
        EncryptedSinglePacketConverter.prototype.decode = function (packetData) {
            var stream = impl.TapStreamReader.fromArray(packetData);
            var sendTime = stream.readU4();
            var header = stream.readSinglePacketHeader();
            var payload;
            if (header.encryption) {
                var encryptedData = stream.readBytesFull();
                var encryptionAlgo = this._getEncryptionAlgo(header);
                var decryptedData = encryptionAlgo.decode(encryptedData);
                var payloadStream = impl.TapStreamReader.fromArray(decryptedData);
                // if (header.messageType == SinglePacketModel.PacketType.CODE_EXEC) {
                payload = payloadStream.readSinglePacketPayloadFullData();
                // } else {
                //     payload = payloadStream.readSinglePacketPayload();
                // }
            }
            else {
                payload = stream.readSinglePacketPayload();
            }
            var packet = {
                sendTime: sendTime,
                header: header,
                payload: payload,
            };
            // TODO check CRC
            // let computedCrc = 0;
            // if (computedCrc !== packet.payload.crc){
            //     CRC.fromBytes()
            // }
            return packet;
        };
        EncryptedSinglePacketConverter.prototype._getEncryptionAlgo = function (header) {
            var encryptionKey = this.computeKey(header);
            this.encryptionAlgo.setOptions({
                iv: '00000000000000000000000000000000',
                key: byteConverter.bufferToHexString(encryptionKey),
            });
            return this.encryptionAlgo;
        };
        EncryptedSinglePacketConverter.prototype.computeKey = function (header) {
            if (!(header instanceof Uint8Array)) {
                var stream = new impl.TapStreamWriter(12);
                header = stream.writeSinglePacketHeader(header).toBytes;
            }
            var generateOptions = Object.assign(Object.assign({}, this.options), {
                headerBytes: header,
            });
            var key = this.keyGenerator.generate(generateOptions);
            return key;
        };
        return EncryptedSinglePacketConverter;
    }());

    var debug = debug$1.createDebugger('@iotize/tap/single-packet');

    function computePadding(size, modulo) {
        return (modulo - (size % modulo)) % modulo;
    }
    function senderIdToUserId(senderId) {
        if (senderId >= 0x80) {
            senderId += 0xff00;
        }
        return senderId;
    }
    function userIdToSenderId(userId) {
        if (userId > 0xffff) {
            throw new Error("Invalid user id. Should be between 0 and " + 0xffff); // TODO custom error
        }
        if (userId > 0x7f && userId < 0xff80) {
            throw new Error("Invalid user id. Should be between 0 and " + 0 + " and " + 0x7f + " or " + 0xffff + " and " + 0xff80);
        } // TODO custom error
        return 0xff & userId;
    }
    function usernameToSenderId(username) {
        switch (username) {
            case 'IoTize':
                return 0xfd;
            case 'admin':
                return userIdToSenderId(0xffff); // TODO constant
            case 'anonymous':
                return userIdToSenderId(0x0);
            case 'supervisor':
                return userIdToSenderId(0xfffe);
            default:
                return 0;
        }
    }
    // function createCredentialsFromCurrentSessionData() {
    //     const authSessionState = this.tap.auth.sessionStateSnapshot;
    //     const authSessionData = this.tap.auth.sessionDataSnapshot;
    //     console.info('Session data: ', authSessionState);
    //     if (!authSessionData.serverKey || !authSessionData.storedKey || !authSessionState.name) {
    //         throw SinglePacketError.authSessionRequiredToEncryptSinglePacket();
    //     }
    //     return SinglePacketEncryptionOptionsBuilder.fromCurrentSessionData({
    //         username: authSessionState.name,
    //         serverKey: authSessionData.serverKey,
    //         storedKey: authSessionData.storedKey
    //     });
    // }

    var TAG = 'SinglePacketBuilder';
    var ZEROS_PADDING_GENERATOR = function (length) { return new Uint8Array(length); };
    var SinglePacketBuilder = /** @class */ (function () {
        function SinglePacketBuilder(type, paddingGenerator) {
            if (paddingGenerator === void 0) { paddingGenerator = ZEROS_PADDING_GENERATOR; }
            this.paddingGenerator = paddingGenerator;
            this.model = {
                sendTime: 0,
                header: {
                    ack: false,
                    configVersion: 0,
                    encryption: false,
                    isExtended: false,
                    messageType: type,
                    packetId: 0,
                    packetLength: 0,
                    salt: Math.round(Math.random() * 0xffff),
                    senderId: 0,
                },
                payload: {
                    data: new Uint8Array(),
                    dataSize: 0,
                    logTime: SinglePacketBuilder.getTimestampInSeconds(),
                    padding: undefined, // TODO
                },
            };
        }
        // static fillComputedField(packet: SinglePacket): SinglePacket {
        //     if (!packet.sendTime) {
        //         packet.sendTime = SinglePacketBuilder.getTimestampInSeconds();
        //     }
        //     packet.payload.dataSize = packet.payload.data.length;
        //     packet.header.packetLength =
        //         computePadding(packet.payload.data.length + 10, 4) +
        //         packet.payload.data.length +
        //         SinglePacketBuilder.PACKET_HEADER_SIZE_WITH_SEND_TIME;
        //     let multiplicator = SinglePacketBuilder.getLengthMultiplicator(packet);
        //     if (packet.header.packetLength % multiplicator !==  0){
        //         throw new Error(`Packet length must be a multiple of ${multiplicator}. But length is ${packet.header.packetLength}`);
        //     }
        //     return packet;
        // }
        SinglePacketBuilder.getTimestampInSeconds = function () {
            return Math.round(new Date().getTime() / 1000);
        };
        SinglePacketBuilder.getLengthMultiplicator = function (packet) {
            if (packet.header.isExtended) {
                return 256;
            }
            else if (packet.header.encryption ||
                packet.header.messageType === exports.SinglePacket.PacketType.CODE_EXEC) {
                return 16;
            }
            else {
                return 1;
            }
        };
        SinglePacketBuilder.create = function (data, type, paddingGenertor) {
            if (paddingGenertor === void 0) { paddingGenertor = ZEROS_PADDING_GENERATOR; }
            var builder = new SinglePacketBuilder(type, paddingGenertor);
            builder.setData(data);
            return builder;
        };
        SinglePacketBuilder.prototype.setLogTime = function (logTime) {
            this.model.payload.logTime = logTime;
            return this;
        };
        /**
         *
         * @param id
         */
        SinglePacketBuilder.prototype.setPacketId = function (id) {
            // TODO check length ?
            this.model.header.packetId = id;
            return this;
        };
        SinglePacketBuilder.prototype.setSalt = function (salt) {
            this.model.header.salt = salt;
            return this;
        };
        SinglePacketBuilder.prototype.setExtended = function (value) {
            this.model.header.isExtended = value;
            return this;
        };
        /**
         *
         * @param id
         */
        SinglePacketBuilder.prototype.setEncryption = function (enabled) {
            // TODO check length ?
            this.model.header.encryption = enabled;
            return this;
        };
        /**
         *
         * @param id
         */
        SinglePacketBuilder.prototype.setSenderId = function (id) {
            // TODO check length ?
            this.model.header.senderId = id;
            return this;
        };
        /**
         *
         * @param id
         */
        SinglePacketBuilder.prototype.setSendTime = function (time) {
            this.model.sendTime = time;
            return this;
        };
        /**
         *
         * @param id
         */
        SinglePacketBuilder.prototype.setConfigVersion = function (configVersion) {
            this.model.header.configVersion = configVersion;
            return this;
        };
        SinglePacketBuilder.prototype.setData = function (data) {
            this.model.payload.data = data;
            return this;
        };
        SinglePacketBuilder.prototype.getLengthMultiplicator = function () {
            return SinglePacketBuilder.getLengthMultiplicator(this.model);
        };
        SinglePacketBuilder.prototype.build = function () {
            if (!this.model.sendTime) {
                this.model.sendTime = SinglePacketBuilder.getTimestampInSeconds();
            }
            var multiplicator = this.getLengthMultiplicator();
            if (this.model.payload.data.length > 0xffff * multiplicator) {
                this.model.header.isExtended = true;
            }
            multiplicator = this.getLengthMultiplicator(); // Refresh multiplicator if isExtended
            var paddingMultiple = Math.max(4, multiplicator); // TODO constant
            // debug(TAG, 'Multiplicator', multiplicator, 'padding mult', paddingMultiple);
            var requiredPadding = computePadding(this.model.payload.data.length +
                SinglePacketBuilder.PACKET_PAYLOAD_HEADER_SIZE, paddingMultiple);
            // debug(TAG, 'requiredPadding', requiredPadding);
            this.model.payload.padding = this.paddingGenerator(requiredPadding);
            // debug(TAG, 'this.model.payload.padding', this.model.payload.padding);
            var payloadLengthInBytes = this.model.payload.data.length +
                SinglePacketBuilder.PACKET_PAYLOAD_HEADER_SIZE +
                this.model.payload.padding.length;
            var packetLengthInBytes = SinglePacketBuilder.PACKET_HEADER_SIZE +
                this.model.payload.data.length +
                this.model.payload.padding.length;
            this.model.payload.dataSize =
                this.model.payload.data.length > 0xffff
                    ? undefined
                    : this.model.payload.data.length;
            if (payloadLengthInBytes % multiplicator !== 0) {
                throw exports.SinglePacketError.internalError("Packet length " + packetLengthInBytes + " must be a multiple of " + multiplicator);
            }
            if (packetLengthInBytes > SinglePacketBuilder.MAX_FULL_SIZE) {
                throw exports.SinglePacketError.maxSinglePacketSizeExceeded(packetLengthInBytes, SinglePacketBuilder.MAX_FULL_SIZE);
            }
            this.model.header.packetLength = payloadLengthInBytes / multiplicator;
            if (multiplicator === 1) {
                this.model.header.packetLength +=
                    SinglePacketBuilder.PACKET_OUTER_HEADER_SIZE;
            }
            return this.model;
        };
        return SinglePacketBuilder;
    }());
    SinglePacketBuilder.MAX_FULL_SIZE = 0x200000;
    SinglePacketBuilder.MAX_PART_SIZE = 0xc0;
    SinglePacketBuilder.PACKET_PAYLOAD_HEADER_SIZE = 4 + 2 + 4;
    SinglePacketBuilder.PACKET_OUTER_HEADER_SIZE = 12;
    SinglePacketBuilder.PACKET_HEADER_SIZE = SinglePacketBuilder.PACKET_OUTER_HEADER_SIZE +
        SinglePacketBuilder.PACKET_PAYLOAD_HEADER_SIZE;
    SinglePacketBuilder.PACKET_HEADER_SIZE_WITH_SEND_TIME = SinglePacketBuilder.PACKET_HEADER_SIZE + 4;
    SinglePacketBuilder.MAX_DATA_SIZE = SinglePacketBuilder.MAX_FULL_SIZE -
        (SinglePacketBuilder.PACKET_HEADER_SIZE_WITH_SEND_TIME + 0xff);

    /**
     * Utility class to split a big single packet data into {@link SinglePacketChunk}
     */
    var SinglePacketSplitter = /** @class */ (function () {
        /**
         * @throws {@link #chunkSize} < {@link #unitBlockSize}
         */
        function SinglePacketSplitter(options) {
            if (options === void 0) { options = {}; }
            if (!options.sizeMultiplicator) {
                options.sizeMultiplicator = SinglePacketSplitter.SIZE_MULTIPLICATOR;
            }
            if (!options.chunkSize) {
                options.chunkSize = SinglePacketBuilder.MAX_PART_SIZE;
            }
            if (!options.format) {
                options.format = exports.SinglePacketChunk.Format.OFFSET_ON_2_BYTES;
            }
            if (!options.pad) {
                options.pad = false;
            }
            this.options = options;
            this.checkOptions();
        }
        Object.defineProperty(SinglePacketSplitter.prototype, "sizeMultiplicator", {
            get: function () {
                return this.options.sizeMultiplicator;
            },
            enumerable: false,
            configurable: true
        });
        SinglePacketSplitter.prototype.checkOptions = function () {
            // Maybe we should force chunk size to be a multiple of unitBlockSize ?
            if (this.options.chunkSize < this.sizeMultiplicator) {
                throw new Error("Chunk size must be greater than " + this.sizeMultiplicator + ". Given: " + this.options.chunkSize);
            }
            if (!this.options.pad &&
                this.options.chunkSize % this.sizeMultiplicator !== 0) {
                throw new Error("Chunk size \"" + this.options.chunkSize + "\" is not a multiple of length multiplicator \"" + this.sizeMultiplicator + "\"");
            }
        };
        /**
         * @return an array of single packet parts
         */
        SinglePacketSplitter.prototype.chunk = function (data) {
            var _this = this;
            if (!this.options.pad) {
                if (data.length % this.sizeMultiplicator !== 0) {
                    throw new Error("Padding is disabled and data length (" + data.length + " byte(s)) is not a multiple of length multiplicator " + this.sizeMultiplicator + ")");
                }
            }
            else {
                var padding = computePadding(data.length, this.sizeMultiplicator);
                if (padding > 0) {
                    data = byteStream.KaitaiStreamWriter.mergeArrays(data, new Uint8Array(padding));
                }
            }
            var packets = array.chunkArray(Array.from(data), this.options.chunkSize).map(function (value) { return Uint8Array.from(value); });
            var offset = 0;
            return packets.map(function (chunk) {
                var part = {
                    data: chunk,
                    length: Math.ceil(chunk.length / _this.sizeMultiplicator),
                    offset: Math.ceil(offset / _this.sizeMultiplicator),
                    format: _this.options.format,
                };
                offset += chunk.length;
                return part;
            });
        };
        return SinglePacketSplitter;
    }());
    SinglePacketSplitter.SIZE_MULTIPLICATOR = 16;

    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try {
                step(generator.next(value));
            }
            catch (e) {
                reject(e);
            } }
            function rejected(value) { try {
                step(generator["throw"](value));
            }
            catch (e) {
                reject(e);
            } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    exports.SinglePacketStoreLoader = /** @class */ (function (_super) {
        __extends(SinglePacketStoreLoader, _super);
        function SinglePacketStoreLoader(steps, 
        // public readonly crc: number,
        singlePacketService) {
            var _this = _super.call(this, taskManager.StepOperations.createSequentialContainers(steps)) || this;
            _this.singlePacketService = singlePacketService;
            return _this;
        }
        SinglePacketStoreLoader.createOperationsFromBytes = function (data, singlePacketService, options) {
            var chunkSize = (options === null || options === void 0 ? void 0 : options.chunkSize) || SinglePacketBuilder.MAX_PART_SIZE;
            var offsetFitsOn2Bytes = data.length / chunkSize <= 0xffff;
            var singlePacketSplitter = new SinglePacketSplitter({
                chunkSize: chunkSize,
                format: offsetFitsOn2Bytes
                    ? exports.SinglePacketChunk.Format.OFFSET_ON_2_BYTES
                    : exports.SinglePacketChunk.Format.OFFSET_ON_4_BYTES,
                pad: options && 'pad' in options ? options.pad : true,
            });
            var packets = singlePacketSplitter.chunk(data);
            return SinglePacketStoreLoader.createOperationsFromChunk(packets, singlePacketService, options);
        };
        SinglePacketStoreLoader.createFromBytes = function (data, singlePacketService, options) {
            var steps = SinglePacketStoreLoader.createOperationsFromBytes(data, singlePacketService, options);
            return new SinglePacketStoreLoader(steps, 
            // expectedCRC,
            singlePacketService);
        };
        /**
         * Create single packet loading operations
         * @param packets Single packet chunks to load to the Tap
         * @param expectedCRC expected CRC sent to the Tap when executing the single packet. if you don't plan to execute single packet, you pass a dummy value
         * @param singlePacketService
         * @param options
         */
        SinglePacketStoreLoader.createOperationsFromChunk = function (packets, singlePacketService, options, output) {
            var _this = this;
            if (output === void 0) { output = {
                expectedCRC: 0,
            }; }
            output.expectedCRC = impl.CRC.FIRST_VALUE;
            var operations = packets.map(function (packet, index) {
                return function (observer, context) { return __awaiter(_this, void 0, void 0, function () {
                    var retryCount, maxRetry, response;
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                if (packet.data.length > SinglePacketBuilder.MAX_PART_SIZE) {
                                    throw exports.SinglePacketError.maxSinglePacketPartSizeExceeded(packet, SinglePacketBuilder.MAX_PART_SIZE);
                                }
                                debug('createSinglePacketLoadOperations', "sendSinglePacket", "sending packet " + (index + 1) + "/" + packets.length + " offset: " + packet.offset + "..." + (packet.offset + (packet.length || 0)));
                                retryCount = 0;
                                maxRetry = (options === null || options === void 0 ? void 0 : options.maxRetry) || 3;
                                output.expectedCRC = impl.CRC.fromBytes(packet.data, output.expectedCRC);
                                _a.label = 1;
                            case 1:
                                if (!true) return [3 /*break*/, 5];
                                retryCount++;
                                return [4 /*yield*/, singlePacketService.writeChunk(packet)];
                            case 2:
                                response = _a.sent();
                                if (!(retryCount < maxRetry &&
                                    (response.status === api.ResultCode.SERVICE_UNAVAILABLE ||
                                        response.status === api.ResultCode.NVM_ERROR))) return [3 /*break*/, 4];
                                debug('createSinglePacketLoadOperations', "Attempt " + (retryCount + 1) + "/" + maxRetry + " failed with error " + tap.TapError.reponseStatusError(response).toString());
                                return [4 /*yield*/, utility.sleep((options === null || options === void 0 ? void 0 : options.retryDelay) || 500)];
                            case 3:
                                _a.sent();
                                return [3 /*break*/, 1];
                            case 4:
                                response.successful();
                                observer.next({
                                    step: SinglePacketStoreLoader.Step.loadPacketChunk,
                                    progress: {
                                        total: packets.length,
                                        loaded: index + 1,
                                    },
                                });
                                return [2 /*return*/];
                            case 5: return [2 /*return*/];
                        }
                    });
                }); };
            });
            if (options === null || options === void 0 ? void 0 : options.execute) {
                operations.push(function (observer, context) { return __awaiter(_this, void 0, void 0, function () {
                    return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0:
                                observer.next({
                                    step: SinglePacketStoreLoader.Step.executeSinglePacket,
                                    expectedCRC: output.expectedCRC,
                                });
                                return [4 /*yield*/, singlePacketService.executeSinglePacketInStore(output.expectedCRC)];
                            case 1:
                                (_a.sent()).successful();
                                return [2 /*return*/];
                        }
                    });
                }); });
            }
            return operations;
        };
        SinglePacketStoreLoader.createFromChunks = function (packets, singlePacketService, options) {
            return new SinglePacketStoreLoader(SinglePacketStoreLoader.createOperationsFromChunk(packets, singlePacketService, options), singlePacketService);
        };
        SinglePacketStoreLoader.computeCRC = function (data) {
            if (data instanceof Uint8Array) {
                return impl.CRC.mpeg2().compute(data);
            }
            else {
                return data.reduce(function (crc, packet) {
                    return impl.CRC.mpeg2().compute(packet.data, crc);
                }, impl.CRC.FIRST_VALUE);
            }
        };
        return SinglePacketStoreLoader;
    }(taskManager.StepOperations));
    (function (SinglePacketStoreLoader) {
        var Step;
        (function (Step) {
            Step["loadPacketChunk"] = "loadPacketChunk";
            Step["executeSinglePacket"] = "executeSinglePacket";
        })(Step = SinglePacketStoreLoader.Step || (SinglePacketStoreLoader.Step = {}));
    })(exports.SinglePacketStoreLoader || (exports.SinglePacketStoreLoader = {}));

    /**
     * Load single packet model to store
     * SinglePacket will be encoded to a single packet frame.
     * If credentials parameter is given, it will be encrypted with it and sender id will be filled
     * If no credential is given and SinglePacket.header.encryption is set to true, it will throw an error
     *
     * @param packet
     * @param credentials
     */
    SinglePacketService.prototype.createStoreLoader = function (packet, options, credentials) {
        var encoder = EncryptedSinglePacketConverter.createWithBlankKey();
        if (credentials) {
            encoder.setEncryptionOptions(credentials);
            packet.header.encryption = true;
            packet.header.senderId = usernameToSenderId(credentials.username);
        }
        else if (packet.header.encryption) {
            throw exports.SinglePacketError.credentialsRequiredForEncryptedSinglePacket();
        }
        var encodedPacket = encoder.encode(packet);
        return this.createStoreLoaderFromBytes(encodedPacket, options);
    };
    SinglePacketService.prototype.createStoreLoaderFromBytes = function (data, options) {
        return exports.SinglePacketStoreLoader.createFromBytes(data, this, options);
    };
    // SinglePacketService.prototype.loadChunksToStore = function (
    //     this: SinglePacketService,
    //     packets: SinglePacketChunk[]
    // ): Observable<any> {
    //     return this.createChunksToStoreLoader.asObservable();
    // };
    // SinglePacketService.prototype.createChunksToStoreLoader = function (
    //     this: SinglePacketService,
    //     packets: SinglePacketChunk[]
    // ): SinglePacketStoreLoader {
    //     return SinglePacketStoreLoader.createFromChunks(
    //         packets,
    //         this
    //     );
    // };

    /**
     *   Generated file. Do not edit
     */
    var ResourceMetaData = {};

    /**
     * Generated bundle index. Do not edit.
     */

    exports.EncryptedSinglePacketConverter = EncryptedSinglePacketConverter;
    exports.SINGLEPACKET_SERVICE_CALLS = SERVICE_CALLS;
    exports.SinglePacketBuilder = SinglePacketBuilder;
    exports.SinglePacketChunkConverter = SinglePacketChunkConverter;
    exports.SinglePacketConverter = SinglePacketConverter;
    exports.SinglePacketResourceMetaData = ResourceMetaData;
    exports.SinglePacketService = SinglePacketService;
    exports.SinglePacketSplitter = SinglePacketSplitter;
    exports.SinglePacketStoreInfoConverter = SinglePacketStoreInfoConverter;
    exports._TAP_SERVICE_EXTENSION_SINGLEPACKET_ = _TAP_SERVICE_EXTENSION_SINGLEPACKET_;
    exports.singlePacketConverters = serviceConverters;
    exports["ɵa"] = SinglePacketEncryptionOptionsBuilder;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=iotize-tap-service-impl-single-packet.umd.js.map
