Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/components/certviewer/content/vendor/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 932 kB image not shown  

Quelle  pkijs.js   Sprache: JAVA

 

/*!
 * Copyright (c) 2014, GlobalSign
 * Copyright (c) 2015-2019, Peculiar Ventures
 * All rights reserved.
 * 
 * Author 2014-2019, Yury Strozhevsky
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 * 
 * * Neither the name of the {organization} nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */


/*!
 * MIT License
 * 
 * Copyright (c) 2017-2024 Peculiar Ventures, LLC
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 */


const ARRAY_BUFFER_NAME = "[object ArrayBuffer]";
class BufferSourceConverter {
    static isArrayBuffer(data) {
        return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME;
    }
    static toArrayBuffer(data) {
        if (this.isArrayBuffer(data)) {
            return data;
        }
        if (data.byteLength === data.buffer.byteLength) {
            return data.buffer;
        }
        if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
            return data.buffer;
        }
        return this.toUint8Array(data.buffer)
            .slice(data.byteOffset, data.byteOffset + data.byteLength)
            .buffer;
    }
    static toUint8Array(data) {
        return this.toView(data, Uint8Array);
    }
    static toView(data, type) {
        if (data.constructor === type) {
            return data;
        }
        if (this.isArrayBuffer(data)) {
            return new type(data);
        }
        if (this.isArrayBufferView(data)) {
            return new type(data.buffer, data.byteOffset, data.byteLength);
        }
        throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
    }
    static isBufferSource(data) {
        return this.isArrayBufferView(data)
            || this.isArrayBuffer(data);
    }
    static isArrayBufferView(data) {
        return ArrayBuffer.isView(data)
            || (data && this.isArrayBuffer(data.buffer));
    }
    static isEqual(a, b) {
        const aView = BufferSourceConverter.toUint8Array(a);
        const bView = BufferSourceConverter.toUint8Array(b);
        if (aView.length !== bView.byteLength) {
            return false;
        }
        for (let i = 0; i < aView.length; i++) {
            if (aView[i] !== bView[i]) {
                return false;
            }
        }
        return true;
    }
    static concat(...args) {
        let buffers;
        if (Array.isArray(args[0]) && !(args[1] instanceof Function)) {
            buffers = args[0];
        }
        else if (Array.isArray(args[0]) && args[1] instanceof Function) {
            buffers = args[0];
        }
        else {
            if (args[args.length - 1] instanceof Function) {
                buffers = args.slice(0, args.length - 1);
            }
            else {
                buffers = args;
            }
        }
        let size = 0;
        for (const buffer of buffers) {
            size += buffer.byteLength;
        }
        const res = new Uint8Array(size);
        let offset = 0;
        for (const buffer of buffers) {
            const view = this.toUint8Array(buffer);
            res.set(view, offset);
            offset += view.length;
        }
        if (args[args.length - 1] instanceof Function) {
            return this.toView(res, args[args.length - 1]);
        }
        return res.buffer;
    }
}

const STRING_TYPE = "string";
const HEX_REGEX = /^[0-9a-f\s]+$/i;
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
class Utf8Converter {
    static fromString(text) {
        const s = unescape(encodeURIComponent(text));
        const uintArray = new Uint8Array(s.length);
        for (let i = 0; i < s.length; i++) {
            uintArray[i] = s.charCodeAt(i);
        }
        return uintArray.buffer;
    }
    static toString(buffer) {
        const buf = BufferSourceConverter.toUint8Array(buffer);
        let encodedString = "";
        for (let i = 0; i < buf.length; i++) {
            encodedString += String.fromCharCode(buf[i]);
        }
        const decodedString = decodeURIComponent(escape(encodedString));
        return decodedString;
    }
}
class Utf16Converter {
    static toString(buffer, littleEndian = false) {
        const arrayBuffer = BufferSourceConverter.toArrayBuffer(buffer);
        const dataView = new DataView(arrayBuffer);
        let res = "";
        for (let i = 0; i < arrayBuffer.byteLength; i += 2) {
            const code = dataView.getUint16(i, littleEndian);
            res += String.fromCharCode(code);
        }
        return res;
    }
    static fromString(text, littleEndian = false) {
        const res = new ArrayBuffer(text.length * 2);
        const dataView = new DataView(res);
        for (let i = 0; i < text.length; i++) {
            dataView.setUint16(i * 2, text.charCodeAt(i), littleEndian);
        }
        return res;
    }
}
class Convert {
    static isHex(data) {
        return typeof data === STRING_TYPE
            && HEX_REGEX.test(data);
    }
    static isBase64(data) {
        return typeof data === STRING_TYPE
            && BASE64_REGEX.test(data);
    }
    static isBase64Url(data) {
        return typeof data === STRING_TYPE
            && BASE64URL_REGEX.test(data);
    }
    static ToString(buffer, enc = "utf8") {
        const buf = BufferSourceConverter.toUint8Array(buffer);
        switch (enc.toLowerCase()) {
            case "utf8":
                return this.ToUtf8String(buf);
            case "binary":
                return this.ToBinary(buf);
            case "hex":
                return this.ToHex(buf);
            case "base64":
                return this.ToBase64(buf);
            case "base64url":
                return this.ToBase64Url(buf);
            case "utf16le":
                return Utf16Converter.toString(buf, true);
            case "utf16":
            case "utf16be":
                return Utf16Converter.toString(buf);
            default:
                throw new Error(`Unknown type of encoding '${enc}'`);
        }
    }
    static FromString(str, enc = "utf8") {
        if (!str) {
            return new ArrayBuffer(0);
        }
        switch (enc.toLowerCase()) {
            case "utf8":
                return this.FromUtf8String(str);
            case "binary":
                return this.FromBinary(str);
            case "hex":
                return this.FromHex(str);
            case "base64":
                return this.FromBase64(str);
            case "base64url":
                return this.FromBase64Url(str);
            case "utf16le":
                return Utf16Converter.fromString(str, true);
            case "utf16":
            case "utf16be":
                return Utf16Converter.fromString(str);
            default:
                throw new Error(`Unknown type of encoding '${enc}'`);
        }
    }
    static ToBase64(buffer) {
        const buf = BufferSourceConverter.toUint8Array(buffer);
        if (typeof btoa !== "undefined") {
            const binary = this.ToString(buf, "binary");
            return btoa(binary);
        }
        else {
            return Buffer.from(buf).toString("base64");
        }
    }
    static FromBase64(base64) {
        const formatted = this.formatString(base64);
        if (!formatted) {
            return new ArrayBuffer(0);
        }
        if (!Convert.isBase64(formatted)) {
            throw new TypeError("Argument 'base64Text' is not Base64 encoded");
        }
        if (typeof atob !== "undefined") {
            return this.FromBinary(atob(formatted));
        }
        else {
            return new Uint8Array(Buffer.from(formatted, "base64")).buffer;
        }
    }
    static FromBase64Url(base64url) {
        const formatted = this.formatString(base64url);
        if (!formatted) {
            return new ArrayBuffer(0);
        }
        if (!Convert.isBase64Url(formatted)) {
            throw new TypeError("Argument 'base64url' is not Base64Url encoded");
        }
        return this.FromBase64(this.Base64Padding(formatted.replace(/\-/g, "+").replace(/\_/g, "/")));
    }
    static ToBase64Url(data) {
        return this.ToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/\=/g, "");
    }
    static FromUtf8String(text, encoding = Convert.DEFAULT_UTF8_ENCODING) {
        switch (encoding) {
            case "ascii":
                return this.FromBinary(text);
            case "utf8":
                return Utf8Converter.fromString(text);
            case "utf16":
            case "utf16be":
                return Utf16Converter.fromString(text);
            case "utf16le":
            case "usc2":
                return Utf16Converter.fromString(text, true);
            default:
                throw new Error(`Unknown type of encoding '${encoding}'`);
        }
    }
    static ToUtf8String(buffer, encoding = Convert.DEFAULT_UTF8_ENCODING) {
        switch (encoding) {
            case "ascii":
                return this.ToBinary(buffer);
            case "utf8":
                return Utf8Converter.toString(buffer);
            case "utf16":
            case "utf16be":
                return Utf16Converter.toString(buffer);
            case "utf16le":
            case "usc2":
                return Utf16Converter.toString(buffer, true);
            default:
                throw new Error(`Unknown type of encoding '${encoding}'`);
        }
    }
    static FromBinary(text) {
        const stringLength = text.length;
        const resultView = new Uint8Array(stringLength);
        for (let i = 0; i < stringLength; i++) {
            resultView[i] = text.charCodeAt(i);
        }
        return resultView.buffer;
    }
    static ToBinary(buffer) {
        const buf = BufferSourceConverter.toUint8Array(buffer);
        let res = "";
        for (let i = 0; i < buf.length; i++) {
            res += String.fromCharCode(buf[i]);
        }
        return res;
    }
    static ToHex(buffer) {
        const buf = BufferSourceConverter.toUint8Array(buffer);
        let result = "";
        const len = buf.length;
        for (let i = 0; i < len; i++) {
            const byte = buf[i];
            if (byte < 16) {
                result += "0";
            }
            result += byte.toString(16);
        }
        return result;
    }
    static FromHex(hexString) {
        let formatted = this.formatString(hexString);
        if (!formatted) {
            return new ArrayBuffer(0);
        }
        if (!Convert.isHex(formatted)) {
            throw new TypeError("Argument 'hexString' is not HEX encoded");
        }
        if (formatted.length % 2) {
            formatted = `0${formatted}`;
        }
        const res = new Uint8Array(formatted.length / 2);
        for (let i = 0; i < formatted.length; i = i + 2) {
            const c = formatted.slice(i, i + 2);
            res[i / 2] = parseInt(c, 16);
        }
        return res.buffer;
    }
    static ToUtf16String(buffer, littleEndian = false) {
        return Utf16Converter.toString(buffer, littleEndian);
    }
    static FromUtf16String(text, littleEndian = false) {
        return Utf16Converter.fromString(text, littleEndian);
    }
    static Base64Padding(base64) {
        const padCount = 4 - (base64.length % 4);
        if (padCount < 4) {
            for (let i = 0; i < padCount; i++) {
                base64 += "=";
            }
        }
        return base64;
    }
    static formatString(data) {
        return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || "";
    }
}
Convert.DEFAULT_UTF8_ENCODING = "utf8";

/*!
 Copyright (c) Peculiar Ventures, LLC
*/


function getParametersValue(parameters, name, defaultValue) {
    var _a;
    if ((parameters instanceof Object) === false) {
        return defaultValue;
    }
    return (_a = parameters[name]) !== null && _a !== void 0 ? _a : defaultValue;
}
function bufferToHexCodes(inputBuffer, inputOffset = 0, inputLength = (inputBuffer.byteLength - inputOffset), insertSpace = false) {
    let result = "";
    for (const item of (new Uint8Array(inputBuffer, inputOffset, inputLength))) {
        const str = item.toString(16).toUpperCase();
        if (str.length === 1) {
            result += "0";
        }
        result += str;
        if (insertSpace) {
            result += " ";
        }
    }
    return result.trim();
}
function utilFromBase(inputBuffer, inputBase) {
    let result = 0;
    if (inputBuffer.length === 1) {
        return inputBuffer[0];
    }
    for (let i = (inputBuffer.length - 1); i >= 0; i--) {
        result += inputBuffer[(inputBuffer.length - 1) - i] * Math.pow(2, inputBase * i);
    }
    return result;
}
function utilToBase(value, base, reserved = (-1)) {
    const internalReserved = reserved;
    let internalValue = value;
    let result = 0;
    let biggest = Math.pow(2, base);
    for (let i = 1; i < 8; i++) {
        if (value < biggest) {
            let retBuf;
            if (internalReserved < 0) {
                retBuf = new ArrayBuffer(i);
                result = i;
            }
            else {
                if (internalReserved < i) {
                    return (new ArrayBuffer(0));
                }
                retBuf = new ArrayBuffer(internalReserved);
                result = internalReserved;
            }
            const retView = new Uint8Array(retBuf);
            for (let j = (i - 1); j >= 0; j--) {
                const basis = Math.pow(2, j * base);
                retView[result - j - 1] = Math.floor(internalValue / basis);
                internalValue -= (retView[result - j - 1]) * basis;
            }
            return retBuf;
        }
        biggest *= Math.pow(2, base);
    }
    return new ArrayBuffer(0);
}
function utilConcatBuf(...buffers) {
    let outputLength = 0;
    let prevLength = 0;
    for (const buffer of buffers) {
        outputLength += buffer.byteLength;
    }
    const retBuf = new ArrayBuffer(outputLength);
    const retView = new Uint8Array(retBuf);
    for (const buffer of buffers) {
        retView.set(new Uint8Array(buffer), prevLength);
        prevLength += buffer.byteLength;
    }
    return retBuf;
}
function utilConcatView(...views) {
    let outputLength = 0;
    let prevLength = 0;
    for (const view of views) {
        outputLength += view.length;
    }
    const retBuf = new ArrayBuffer(outputLength);
    const retView = new Uint8Array(retBuf);
    for (const view of views) {
        retView.set(view, prevLength);
        prevLength += view.length;
    }
    return retView;
}
function utilDecodeTC() {
    const buf = new Uint8Array(this.valueHex);
    if (this.valueHex.byteLength >= 2) {
        const condition1 = (buf[0] === 0xFF) && (buf[1] & 0x80);
        const condition2 = (buf[0] === 0x00) && ((buf[1] & 0x80) === 0x00);
        if (condition1 || condition2) {
            this.warnings.push("Needlessly long format");
        }
    }
    const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength);
    const bigIntView = new Uint8Array(bigIntBuffer);
    for (let i = 0; i < this.valueHex.byteLength; i++) {
        bigIntView[i] = 0;
    }
    bigIntView[0] = (buf[0] & 0x80);
    const bigInt = utilFromBase(bigIntView, 8);
    const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength);
    const smallIntView = new Uint8Array(smallIntBuffer);
    for (let j = 0; j < this.valueHex.byteLength; j++) {
        smallIntView[j] = buf[j];
    }
    smallIntView[0] &= 0x7F;
    const smallInt = utilFromBase(smallIntView, 8);
    return (smallInt - bigInt);
}
function utilEncodeTC(value) {
    const modValue = (value < 0) ? (value * (-1)) : value;
    let bigInt = 128;
    for (let i = 1; i < 8; i++) {
        if (modValue <= bigInt) {
            if (value < 0) {
                const smallInt = bigInt - modValue;
                const retBuf = utilToBase(smallInt, 8, i);
                const retView = new Uint8Array(retBuf);
                retView[0] |= 0x80;
                return retBuf;
            }
            let retBuf = utilToBase(modValue, 8, i);
            let retView = new Uint8Array(retBuf);
            if (retView[0] & 0x80) {
                const tempBuf = retBuf.slice(0);
                const tempView = new Uint8Array(tempBuf);
                retBuf = new ArrayBuffer(retBuf.byteLength + 1);
                retView = new Uint8Array(retBuf);
                for (let k = 0; k < tempBuf.byteLength; k++) {
                    retView[k + 1] = tempView[k];
                }
                retView[0] = 0x00;
            }
            return retBuf;
        }
        bigInt *= Math.pow(2, 8);
    }
    return (new ArrayBuffer(0));
}
function isEqualBuffer(inputBuffer1, inputBuffer2) {
    if (inputBuffer1.byteLength !== inputBuffer2.byteLength) {
        return false;
    }
    const view1 = new Uint8Array(inputBuffer1);
    const view2 = new Uint8Array(inputBuffer2);
    for (let i = 0; i < view1.length; i++) {
        if (view1[i] !== view2[i]) {
            return false;
        }
    }
    return true;
}
function padNumber(inputNumber, fullLength) {
    const str = inputNumber.toString(10);
    if (fullLength < str.length) {
        return "";
    }
    const dif = fullLength - str.length;
    const padding = new Array(dif);
    for (let i = 0; i < dif; i++) {
        padding[i] = "0";
    }
    const paddingString = padding.join("");
    return paddingString.concat(str);
}
const base64Template = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const base64UrlTemplate = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
function toBase64(input, useUrlTemplate = false, skipPadding = false, skipLeadingZeros = false) {
    let i = 0;
    let flag1 = 0;
    let flag2 = 0;
    let output = "";
    const template = (useUrlTemplate) ? base64UrlTemplate : base64Template;
    if (skipLeadingZeros) {
        let nonZeroPosition = 0;
        for (let i = 0; i < input.length; i++) {
            if (input.charCodeAt(i) !== 0) {
                nonZeroPosition = i;
                break;
            }
        }
        input = input.slice(nonZeroPosition);
    }
    while (i < input.length) {
        const chr1 = input.charCodeAt(i++);
        if (i >= input.length) {
            flag1 = 1;
        }
        const chr2 = input.charCodeAt(i++);
        if (i >= input.length) {
            flag2 = 1;
        }
        const chr3 = input.charCodeAt(i++);
        const enc1 = chr1 >> 2;
        const enc2 = ((chr1 & 0x03) << 4) | (chr2 >> 4);
        let enc3 = ((chr2 & 0x0F) << 2) | (chr3 >> 6);
        let enc4 = chr3 & 0x3F;
        if (flag1 === 1) {
            enc3 = enc4 = 64;
        }
        else {
            if (flag2 === 1) {
                enc4 = 64;
            }
        }
        if (skipPadding) {
            if (enc3 === 64) {
                output += `${template.charAt(enc1)}${template.charAt(enc2)}`;
            }
            else {
                if (enc4 === 64) {
                    output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}`;
                }
                else {
                    output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`;
                }
            }
        }
        else {
            output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`;
        }
    }
    return output;
}
function fromBase64(input, useUrlTemplate = false, cutTailZeros = false) {
    const template = (useUrlTemplate) ? base64UrlTemplate : base64Template;
    function indexOf(toSearch) {
        for (let i = 0; i < 64; i++) {
            if (template.charAt(i) === toSearch)
                return i;
        }
        return 64;
    }
    function test(incoming) {
        return ((incoming === 64) ? 0x00 : incoming);
    }
    let i = 0;
    let output = "";
    while (i < input.length) {
        const enc1 = indexOf(input.charAt(i++));
        const enc2 = (i >= input.length) ? 0x00 : indexOf(input.charAt(i++));
        const enc3 = (i >= input.length) ? 0x00 : indexOf(input.charAt(i++));
        const enc4 = (i >= input.length) ? 0x00 : indexOf(input.charAt(i++));
        const chr1 = (test(enc1) << 2) | (test(enc2) >> 4);
        const chr2 = ((test(enc2) & 0x0F) << 4) | (test(enc3) >> 2);
        const chr3 = ((test(enc3) & 0x03) << 6) | test(enc4);
        output += String.fromCharCode(chr1);
        if (enc3 !== 64) {
            output += String.fromCharCode(chr2);
        }
        if (enc4 !== 64) {
            output += String.fromCharCode(chr3);
        }
    }
    if (cutTailZeros) {
        const outputLength = output.length;
        let nonZeroStart = (-1);
        for (let i = (outputLength - 1); i >= 0; i--) {
            if (output.charCodeAt(i) !== 0) {
                nonZeroStart = i;
                break;
            }
        }
        if (nonZeroStart !== (-1)) {
            output = output.slice(0, nonZeroStart + 1);
        }
        else {
            output = "";
        }
    }
    return output;
}
function arrayBufferToString(buffer) {
    let resultString = "";
    const view = new Uint8Array(buffer);
    for (const element of view) {
        resultString += String.fromCharCode(element);
    }
    return resultString;
}
function stringToArrayBuffer(str) {
    const stringLength = str.length;
    const resultBuffer = new ArrayBuffer(stringLength);
    const resultView = new Uint8Array(resultBuffer);
    for (let i = 0; i < stringLength; i++) {
        resultView[i] = str.charCodeAt(i);
    }
    return resultBuffer;
}
const log2 = Math.log(2);
function nearestPowerOf2(length) {
    const base = (Math.log(length) / log2);
    const floor = Math.floor(base);
    const round = Math.round(base);
    return ((floor === round) ? floor : round);
}
function clearProps(object, propsArray) {
    for (const prop of propsArray) {
        delete object[prop];
    }
}

/*!
 * Copyright (c) 2014, GMO GlobalSign
 * Copyright (c) 2015-2022, Peculiar Ventures
 * All rights reserved.
 * 
 * Author 2014-2019, Yury Strozhevsky
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 * 
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */



function assertBigInt() {
    if (typeof BigInt === "undefined") {
        throw new Error("BigInt is not defined. Your environment doesn't implement BigInt.");
    }
}
function concat(buffers) {
    let outputLength = 0;
    let prevLength = 0;
    for (let i = 0; i < buffers.length; i++) {
        const buffer = buffers[i];
        outputLength += buffer.byteLength;
    }
    const retView = new Uint8Array(outputLength);
    for (let i = 0; i < buffers.length; i++) {
        const buffer = buffers[i];
        retView.set(new Uint8Array(buffer), prevLength);
        prevLength += buffer.byteLength;
    }
    return retView.buffer;
}
function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) {
    if (!(inputBuffer instanceof Uint8Array)) {
        baseBlock.error = "Wrong parameter: inputBuffer must be 'Uint8Array'";
        return false;
    }
    if (!inputBuffer.byteLength) {
        baseBlock.error = "Wrong parameter: inputBuffer has zero length";
        return false;
    }
    if (inputOffset < 0) {
        baseBlock.error = "Wrong parameter: inputOffset less than zero";
        return false;
    }
    if (inputLength < 0) {
        baseBlock.error = "Wrong parameter: inputLength less than zero";
        return false;
    }
    if ((inputBuffer.byteLength - inputOffset - inputLength) < 0) {
        baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
        return false;
    }
    return true;
}

class ViewWriter {
    constructor() {
        this.items = [];
    }
    write(buf) {
        this.items.push(buf);
    }
    final() {
        return concat(this.items);
    }
}

const powers2 = [new Uint8Array([1])];
const digitsString = "0123456789";
const NAME = "name";
const VALUE_HEX_VIEW = "valueHexView";
const IS_HEX_ONLY = "isHexOnly";
const ID_BLOCK = "idBlock";
const TAG_CLASS = "tagClass";
const TAG_NUMBER = "tagNumber";
const IS_CONSTRUCTED = "isConstructed";
const FROM_BER = "fromBER";
const TO_BER = "toBER";
const LOCAL = "local";
const EMPTY_STRING$1 = "";
const EMPTY_BUFFER$1 = new ArrayBuffer(0);
const EMPTY_VIEW = new Uint8Array(0);
const END_OF_CONTENT_NAME = "EndOfContent";
const OCTET_STRING_NAME = "OCTET STRING";
const BIT_STRING_NAME = "BIT STRING";

function HexBlock(BaseClass) {
    var _a;
    return _a = class Some extends BaseClass {
            get valueHex() {
                return this.valueHexView.slice().buffer;
            }
            set valueHex(value) {
                this.valueHexView = new Uint8Array(value);
            }
            constructor(...args) {
                var _b;
                super(...args);
                const params = args[0] || {};
                this.isHexOnly = (_b = params.isHexOnly) !== null && _b !== void 0 ? _b : false;
                this.valueHexView = params.valueHex ? BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW;
            }
            fromBER(inputBuffer, inputOffset, inputLength) {
                const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer;
                if (!checkBufferParams(this, view, inputOffset, inputLength)) {
                    return -1;
                }
                const endLength = inputOffset + inputLength;
                import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
                if (!this.valueHexView.length) {
                    this.warnings.push("Zero buffer length");
                    return inputOffset;
                }
this. = ;
                return ;
            }
toBER  ) java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
                java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                    this.=" isHexOnly  set,;
returnEMPTY_BUFFERjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
                }
          if(){
                      ArrayBuffer.alueHexView);
                
                 this.byteLength ==thisvalueHexViewbuffer)
                    ? this..buffer
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
            ;
            toJSON:}
                return {
                    ...super.toJSON(),
                    isHexOnly: this.isHexOnly,
                    valueHex: Convert.ToHex(this.valueHexView),
                };
            }
        },
        _a.NAME = "hexBlock",
        _a;
}

class LocalBaseBlock {
    static blockName() {
        return this.NAME;
    }
    get valueBeforeDecode() {
        return this.valueBeforeDecodeView.slice().buffer;
    }
    set valueBeforeDecode(value) {
        this.valueBeforeDecodeView = new Uint8Array(value);
    }
    constructor({ blockLength = 0, error = EMPTY_STRING$1, warnings = [], valueBeforeDecode = EMPTY_VIEW, } = {}) {
        this.blockLength = blockLength;
        this.error = error;
        this.warnings = warnings;
        this.valueBeforeDecodeView = BufferSourceConverter.toUint8Array(valueBeforeDecode);
    }
    toJSON() {
        return {
            blockName: this.constructor.NAME,
            blockLength: this.blockLength,
            error: this.error,
            warnings: this.warnings,
            valueBeforeDecode: Convert.ToHex(this.valueBeforeDecodeView),
        };
    }
}
LocalBaseBlock.NAME = "baseBlock";

class ValueBlock extends LocalBaseBlock {
    fromBER(_inputBuffer, _inputOffset, _inputLength) {
        throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'");
    }
    toBER(_sizeOnly, _writer) {
        throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'");
    }
}
ValueBlock.NAME = "valueBlock";

class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
    constructor({ idBlock = {} } = {}) {
        var _a, _b, _c, _d;
        super();
        if (idBlock) {
            this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== void 0 ? _a : false;
            this.valueHexView = idBlock.valueHex
                ? BufferSourceConverter.toUint8Array(idBlock.valueHex)
                : EMPTY_VIEW;
            this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1;
            this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1;
            this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false;
        }
        else {
            this.tagClass = -1;
            this.tagNumber = -1;
            this.isConstructed = false;
        }
    }
    toBER(sizeOnly = false) {
        let firstOctet = 0;
        switch (this.tagClass) {
            case 1:
                firstOctet |= 0x00;
                break;
            case 2:
                firstOctet |= 0x40;
                break;
            case 3:
                firstOctet |= 0x80;
                break;
            case 4:
                firstOctet |= 0xC0;
                break;
            default:
                this.error = "Unknown tag class";
                return EMPTY_BUFFER$1;
        }
        if (this.isConstructed)
            firstOctet |= 0x20;
        if (this.tagNumber < 31 && !this.isHexOnly) {
            const retView = new Uint8Array(1);
            if (!sizeOnly) {
                let number = this.tagNumber;
                number &= 0x1F;
                firstOctet |= number;
                retView[0] = firstOctet;
            }
            return retView.buffer;
        }
        if (!this.isHexOnly) {
            const encodedBuf = utilToBase(this.tagNumber, 7);
            const encodedView = new Uint8Array(encodedBuf);
            const size = encodedBuf.byteLength;
            const retView = new Uint8Array(size + 1);
            retView[0] = (firstOctet | 0x1F);
            if (!sizeOnly) {
                for (let i = 0; i < (size - 1); i++)
                    retView[i + 1] = encodedView[i] | 0x80;
                retView[size] = encodedView[size - 1];
            }
            return retView.buffer;
        }
        const retView = new Uint8Array(this.valueHexView.byteLength + 1);
        retView[0] = (firstOctet | 0x1F);
        if (!sizeOnly) {
            const curView = this.valueHexView;
            for (let i = 0; i < (curView.length - 1); i++)
                retView[i + 1] = curView[i] | 0x80;
            retView[this.valueHexView.byteLength] = curView[curView.length - 1];
        }
        return retView.buffer;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const inputView = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
            return -1;
        }
        const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
        if (intBuffer.length === 0) {
            this.error = "Zero buffer length";
            return -1;
        }
        const tagClassMask = intBuffer[0] & 0xC0;
        switch (tagClassMask) {
            case 0x00:
                this.tagClass = (1);
                break;
            case 0x40:
                this.tagClass = (2);
                break;
            case 0x80:
                this.tagClass = (3);
                break;
            case 0xC0:
                this.tagClass = (4);
                break;
            default:
                this.error = "Unknown tag class";
                return -1;
        }
        this.isConstructed = (intBuffer[0] & 0x20) === 0x20;
        this.isHexOnly = false;
        const tagNumberMask = intBuffer[0] & 0x1F;
        if (tagNumberMask !== 0x1F) {
            this.tagNumber = (tagNumberMask);
            this.blockLength = 1;
        }
        else {
            let count = 1;
            let intTagNumberBuffer = this.valueHexView = new Uint8Array(255);
            let tagNumberBufferMaxLength = 255;
            while (intBuffer[count] & 0x80) {
                intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F;
                count++;
                if (count >= intBuffer.length) {
                    this.error = "End of input reached before message was fully decoded";
                    return -1;
                }
                if (count === tagNumberBufferMaxLength) {
                    tagNumberBufferMaxLength += 255;
                    const tempBufferView = new Uint8Array(tagNumberBufferMaxLength);
                    for (let i = 0; i < intTagNumberBuffer.length; i++)
                        tempBufferView[i] = intTagNumberBuffer[i];
                    intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength);
                }
            }
            this.blockLength = (count + 1);
            intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F;
            const tempBufferView = new Uint8Array(count);
            for (let i = 0; i < count; i++)
                tempBufferView[i] = intTagNumberBuffer[i];
            intTagNumberBuffer = this.valueHexView = new Uint8Array(count);
            intTagNumberBuffer.set(tempBufferView);
            if (this.blockLength <= 9)
                this.tagNumber = utilFromBase(intTagNumberBuffer, 7);
            else {
                this.isHexOnly = true;
                this.warnings.push("Tag too long, represented as hex-coded");
            }
        }
        if (((this.tagClass === 1))
            && (this.isConstructed)) {
            switch (this.tagNumber) {
                case 1:
                case 2:
                case 5:
                case 6:
                case 9:
                case 13:
                case 14:
                case 23:
                case 24:
                case 31:
                case 32:
                case 33:
                case 34:
                    this.error = "Constructed encoding used for primitive type";
                    return -1;
            }
        }
        return (inputOffset + this.blockLength);
    }
    toJSON() {
        return {
            ...super.toJSON(),
            tagClass: this.tagClass,
            tagNumber: this.tagNumber,
            isConstructed: this.isConstructed,
        };
    }
}
LocalIdentificationBlock.NAME = "identificationBlock";

class LocalLengthBlock extends LocalBaseBlock {
    constructor({ lenBlock = {} } = {}) {
        var _a, _b, _c;
        super();
        this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== void 0 ? _a : false;
        this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false;
        this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const view = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, view, inputOffset, inputLength)) {
            return -1;
        }
        const intBuffer = view.subarray(inputOffset, inputOffset + inputLength);
        if (intBuffer.length === 0) {
            this.error = "Zero buffer length";
            return -1;
        }
        if (intBuffer[0] === 0xFF) {
            this.error = "Length block 0xFF is reserved by standard";
            return -1;
        }
        this.isIndefiniteForm = intBuffer[0] === 0x80;
        if (this.isIndefiniteForm) {
            this.blockLength = 1;
            return (inputOffset + this.blockLength);
        }
        this.longFormUsed = !!(intBuffer[0] & 0x80);
        if (this.longFormUsed === false) {
            this.length = (intBuffer[0]);
            this.blockLength = 1;
            return (inputOffset + this.blockLength);
        }
        const count = intBuffer[0] & 0x7F;
        if (count > 8) {
            this.error = "Too big integer";
            return -1;
        }
        if ((count + 1) > intBuffer.length) {
            this.error = "End of input reached before message was fully decoded";
            return -1;
        }
        const lenOffset = inputOffset + 1;
        const lengthBufferView = view.subarray(lenOffset, lenOffset + count);
        if (lengthBufferView[count - 1] === 0x00)
            this.warnings.push("Needlessly long encoded length");
        this.length = utilFromBase(lengthBufferView, 8);
        if (this.longFormUsed && (this.length <= 127))
            this.warnings.push("Unnecessary usage of long length form");
        this.blockLength = count + 1;
        return (inputOffset + this.blockLength);
    }
    toBER(sizeOnly = false) {
        let retBuf;
        let retView;
        if (this.length > 127)
            this.longFormUsed = true;
        if (this.isIndefiniteForm) {
            retBuf = new ArrayBuffer(1);
            if (sizeOnly === false) {
                retView = new Uint8Array(retBuf);
                retView[0] = 0x80;
            }
            return retBuf;
        }
        if (this.longFormUsed) {
            const encodedBuf = utilToBase(this.length, 8);
            if (encodedBuf.byteLength > 127) {
                this.error = "Too big length";
                return (EMPTY_BUFFER$1);
            }
            retBuf = new ArrayBuffer(encodedBuf.byteLength + 1);
            if (sizeOnly)
                return retBuf;
            const encodedView = new Uint8Array(encodedBuf);
            retView = new Uint8Array(retBuf);
            retView[0] = encodedBuf.byteLength | 0x80;
            for (let i = 0; i < encodedBuf.byteLength; i++)
                retView[i + 1] = encodedView[i];
            return retBuf;
        }
        retBuf = new ArrayBuffer(1);
        if (sizeOnly === false) {
            retView = new Uint8Array(retBuf);
            retView[0] = this.length;
        }
        return retBuf;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            isIndefiniteForm: this.isIndefiniteForm,
            longFormUsed: this.longFormUsed,
            length: this.length,
        };
    }
}
LocalLengthBlock.NAME = "lengthBlock";

const typeStore = {};

class BaseBlock extends LocalBaseBlock {
    constructor({ name = EMPTY_STRING$1, optional = false, primitiveSchema, ...parameters } = {}, valueBlockType) {
        super(parameters);
        this.name = name;
        this.optional = optional;
        if (primitiveSchema) {
            this.primitiveSchema = primitiveSchema;
        }
        this.idBlock = new LocalIdentificationBlock(parameters);
        this.lenBlock = new LocalLengthBlock(parameters);
        this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters);
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm)
            ? inputLength
            : this.lenBlock.length);
        if (resultOffset === -1) {
            this.error = this.valueBlock.error;
            return resultOffset;
        }
        if (!this.idBlock.error.length)
            this.blockLength += this.idBlock.blockLength;
        if (!this.lenBlock.error.length)
            this.blockLength += this.lenBlock.blockLength;
        if (!this.valueBlock.error.length)
            this.blockLength += this.valueBlock.blockLength;
        return resultOffset;
    }
    toBER(sizeOnly, writer) {
        const _writer = writer || new ViewWriter();
        if (!writer) {
            prepareIndefiniteForm(this);
        }
        const idBlockBuf = this.idBlock.toBER(sizeOnly);
        _writer.write(idBlockBuf);
        if (this.lenBlock.isIndefiniteForm) {
            _writer.write(new Uint8Array([0x80]).buffer);
            this.valueBlock.toBER(sizeOnly, _writer);
            _writer.write(new ArrayBuffer(2));
        }
        else {
            const valueBlockBuf = this.valueBlock.toBER(sizeOnly);
            this.lenBlock.length = valueBlockBuf.byteLength;
            const lenBlockBuf = this.lenBlock.toBER(sizeOnly);
            _writer.write(lenBlockBuf);
            _writer.write(valueBlockBuf);
        }
        if (!writer) {
            return _writer.final();
        }
        return EMPTY_BUFFER$1;
    }
    toJSON() {
        const object = {
            ...super.toJSON(),
            idBlock: this.idBlock.toJSON(),
            lenBlock: this.lenBlock.toJSON(),
            valueBlock: this.valueBlock.toJSON(),
            name: this.name,
            optional: this.optional,
        };
        if (this.primitiveSchema)
            object.primitiveSchema = this.primitiveSchema.toJSON();
        return object;
    }
    toString(encoding = "ascii") {
        if (encoding === "ascii") {
            return this.onAsciiEncoding();
        }
        return Convert.ToHex(this.toBER());
    }
    onAsciiEncoding() {
        const name = this.constructor.NAME;
        const value = Convert.ToHex(this.valueBlock.valueBeforeDecodeView);
        return `${name} : ${value}`;
    }
    isEqual(other) {
        if (this === other) {
            return true;
        }
        if (!(other instanceof this.constructor)) {
            return false;
        }
        const thisRaw = this.toBER();
        const otherRaw = other.toBER();
        return isEqualBuffer(thisRaw, otherRaw);
    }
}
BaseBlock.NAME = "BaseBlock";
function prepareIndefiniteForm(baseBlock) {
    var _a;
    if (baseBlock instanceof typeStore.Constructed) {
        for (const value of baseBlock.valueBlock.value) {
            if (prepareIndefiniteForm(value)) {
                baseBlock.lenBlock.isIndefiniteForm = true;
            }
        }
    }
    return !!((_a = baseBlock.lenBlock) === null || _a === void 0 ? void 0 : _a.isIndefiniteForm);
}

class BaseStringBlock extends BaseBlock {
    getValue() {
        return this.valueBlock.value;
    }
    setValue(value) {
        this.valueBlock.value = value;
    }
    constructor({ value = EMPTY_STRING$1, ...parameters } = {}, stringValueBlockType) {
        super(parameters, stringValueBlockType);
        if (value) {
            this.fromString(value);
        }
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm)
            ? inputLength
            : this.lenBlock.length);
        if (resultOffset === -1) {
            this.error = this.valueBlock.error;
            return resultOffset;
        }
        this.fromBuffer(this.valueBlock.valueHexView);
        if (!this.idBlock.error.length)
            this.blockLength += this.idBlock.blockLength;
        if (!this.lenBlock.error.length)
            this.blockLength += this.lenBlock.blockLength;
        if (!this.valueBlock.error.length)
            this.blockLength += this.valueBlock.blockLength;
        return resultOffset;
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : '${this.valueBlock.value}'`;
    }
}
BaseStringBlock.NAME = "BaseStringBlock";

class LocalPrimitiveValueBlock extends HexBlock(ValueBlock) {
    constructor({ isHexOnly = true, ...parameters } = {}) {
        super(parameters);
        this.isHexOnly = isHexOnly;
    }
}
LocalPrimitiveValueBlock.NAME = "PrimitiveValueBlock";

var _a$w;
class Primitive extends BaseBlock {
    constructor(parameters = {}) {
        super(parameters, LocalPrimitiveValueBlock);
        this.idBlock.isConstructed = false;
    }
}
_a$w = Primitive;
(() => {
    typeStore.Primitive = _a$w;
})();
Primitive.NAME = "PRIMITIVE";

function localChangeType(inputObject, newType) {
    if (inputObject instanceof newType) {
        return inputObject;
    }
    const newObject = new newType();
    newObject.idBlock = inputObject.idBlock;
    newObject.lenBlock = inputObject.lenBlock;
    newObject.warnings = inputObject.warnings;
    newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView;
    return newObject;
}
function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) {
    const incomingOffset = inputOffset;
    let returnObject = new BaseBlock({}, ValueBlock);
    const baseBlock = new LocalBaseBlock();
    if (!checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength)) {
        returnObject.error = baseBlock.error;
        return {
            offset: -1,
            result: returnObject,
        };
    }
    const intBuffer = inputBuffer.subarray(inputOffset, inputOffset + inputLength);
    if (!intBuffer.length) {
        returnObject.error = "Zero buffer length";
        return {
            offset: -1,
            result: returnObject,
        };
    }
    let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength);
    if (returnObject.idBlock.warnings.length) {
        returnObject.warnings.concat(returnObject.idBlock.warnings);
    }
    if (resultOffset === -1) {
        returnObject.error = returnObject.idBlock.error;
        return {
            offset: -1,
            result: returnObject,
        };
    }
    inputOffset = resultOffset;
    inputLength -= returnObject.idBlock.blockLength;
    resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength);
    if (returnObject.lenBlock.warnings.length) {
        returnObject.warnings.concat(returnObject.lenBlock.warnings);
    }
    if (resultOffset === -1) {
        returnObject.error = returnObject.lenBlock.error;
        return {
            offset: -1,
            result: returnObject,
        };
    }
    inputOffset = resultOffset;
    inputLength -= returnObject.lenBlock.blockLength;
    if (!returnObject.idBlock.isConstructed
        && returnObject.lenBlock.isIndefiniteForm) {
        returnObject.error = "Indefinite length form used for primitive encoding form";
        return {
            offset: -1,
            result: returnObject,
        };
    }
    let newASN1Type = BaseBlock;
    switch (returnObject.idBlock.tagClass) {
        case 1:
            if ((returnObject.idBlock.tagNumber >= 37)
                && (returnObject.idBlock.isHexOnly === false)) {
                returnObject.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard";
                return {
                    offset: -1,
                    result: returnObject,
                };
            }
            switch (returnObject.idBlock.tagNumber) {
                case 0:
                    if ((returnObject.idBlock.isConstructed)
                        && (returnObject.lenBlock.length > 0)) {
                        returnObject.error = "Type [UNIVERSAL 0] is reserved";
                        return {
                            offset: -1,
                            result: returnObject,
                        };
                    }
                    newASN1Type = typeStore.EndOfContent;
                    break;
                case 1:
                    newASN1Type = typeStore.Boolean;
                    break;
                case 2:
                    newASN1Type = typeStore.Integer;
                    break;
                case 3:
                    newASN1Type = typeStore.BitString;
                    break;
                case 4:
                    newASN1Type = typeStore.OctetString;
                    break;
                case 5:
                    newASN1Type = typeStore.Null;
                    break;
                case 6:
                    newASN1Type = typeStore.ObjectIdentifier;
                    break;
                case 10:
                    newASN1Type = typeStore.Enumerated;
                    break;
                case 12:
                    newASN1Type = typeStore.Utf8String;
                    break;
                case 13:
                    newASN1Type = typeStore.RelativeObjectIdentifier;
                    break;
                case 14:
                    newASN1Type = typeStore.TIME;
                    break;
                case 15:
                    returnObject.error = "[UNIVERSAL 15] is reserved by ASN.1 standard";
                    return {
                        offset: -1,
                        result: returnObject,
                    };
                case 16:
                    newASN1Type = typeStore.Sequence;
                    break;
                case 17:
                    newASN1Type = typeStore.Set;
                    break;
                case 18:
                    newASN1Type = typeStore.NumericString;
                    break;
                case 19:
                    newASN1Type = typeStore.PrintableString;
                    break;
                case 20:
                    newASN1Type = typeStore.TeletexString;
                    break;
                case 21:
                    newASN1Type = typeStore.VideotexString;
                    break;
                case 22:
                    newASN1Type = typeStore.IA5String;
                    break;
                case 23:
                    newASN1Type = typeStore.UTCTime;
                    break;
                case 24:
                    newASN1Type = typeStore.GeneralizedTime;
                    break;
                case 25:
                    newASN1Type = typeStore.GraphicString;
                    break;
                case 26:
                    newASN1Type = typeStore.VisibleString;
                    break;
                case 27:
                    newASN1Type = typeStore.GeneralString;
                    break;
                case 28:
                    newASN1Type = typeStore.UniversalString;
                    break;
                case 29:
                    newASN1Type = typeStore.CharacterString;
                    break;
                case 30:
                    newASN1Type = typeStore.BmpString;
                    break;
                case 31:
                    newASN1Type = typeStore.DATE;
                    break;
                case 32:
                    newASN1Type = typeStore.TimeOfDay;
                    break;
                case 33:
                    newASN1Type = typeStore.DateTime;
                    break;
                case 34:
                    newASN1Type = typeStore.Duration;
                    break;
                default: {
                    const newObject = returnObject.idBlock.isConstructed
                        ? new typeStore.Constructed()
                        : new typeStore.Primitive();
                    newObject.idBlock = returnObject.idBlock;
                    newObject.lenBlock = returnObject.lenBlock;
                    newObject.warnings = returnObject.warnings;
                    returnObject = newObject;
                }
            }
            break;
        case 2:
        case 3:
        case 4:
        default: {
            newASN1Type = returnObject.idBlock.isConstructed
                ? typeStore.Constructed
                : typeStore.Primitive;
        }
    }
    returnObject = localChangeType(returnObject, newASN1Type);
    resultOffset = returnObject.fromBER(inputBuffer, inputOffset, returnObject.lenBlock.isIndefiniteForm ? inputLength : returnObject.lenBlock.length);
    returnObject.valueBeforeDecodeView = inputBuffer.subarray(incomingOffset, incomingOffset + returnObject.blockLength);
    return {
        offset: resultOffset,
        result: returnObject,
    };
}
function fromBER(inputBuffer) {
    if (!inputBuffer.byteLength) {
        const result = new BaseBlock({}, ValueBlock);
        result.error = "Input buffer has zero length";
        return {
            offset: -1,
            result,
        };
    }
    return localFromBER(BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength);
}

function checkLen(indefiniteLength, length) {
    if (indefiniteLength) {
        return 1;
    }
    return length;
}
class LocalConstructedValueBlock extends ValueBlock {
    constructor({ value = [], isIndefiniteForm = false, ...parameters } = {}) {
        super(parameters);
        this.value = value;
        this.isIndefiniteForm = isIndefiniteForm;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const view = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, view, inputOffset, inputLength)) {
            return -1;
        }
        this.valueBeforeDecodeView = view.subarray(inputOffset, inputOffset + inputLength);
        if (this.valueBeforeDecodeView.length === 0) {
            this.warnings.push("Zero buffer length");
            return inputOffset;
        }
        let currentOffset = inputOffset;
        while (checkLen(this.isIndefiniteForm, inputLength) > 0) {
            const returnObject = localFromBER(view, currentOffset, inputLength);
            if (returnObject.offset === -1) {
                this.error = returnObject.result.error;
                this.warnings.concat(returnObject.result.warnings);
                return -1;
            }
            currentOffset = returnObject.offset;
            this.blockLength += returnObject.result.blockLength;
            inputLength -= returnObject.result.blockLength;
            this.value.push(returnObject.result);
            if (this.isIndefiniteForm && returnObject.result.constructor.NAME === END_OF_CONTENT_NAME) {
                break;
            }
        }
        if (this.isIndefiniteForm) {
            if (this.value[this.value.length - 1].constructor.NAME === END_OF_CONTENT_NAME) {
                this.value.pop();
            }
            else {
                this.warnings.push("No EndOfContent block encoded");
            }
        }
        return currentOffset;
    }
    toBER(sizeOnly, writer) {
        const _writer = writer || new ViewWriter();
        for (let i = 0; i < this.value.length; i++) {
            this.value[i].toBER(sizeOnly, _writer);
        }
        if (!writer) {
            return _writer.final();
        }
        return EMPTY_BUFFER$1;
    }
    toJSON() {
        const object = {
            ...super.toJSON(),
            isIndefiniteForm: this.isIndefiniteForm,
            value: [],
        };
        for (const value of this.value) {
            object.value.push(value.toJSON());
        }
        return object;
    }
}
LocalConstructedValueBlock.NAME = "ConstructedValueBlock";

var _a$v;
class Constructed extends BaseBlock {
    constructor(parameters = {}) {
        super(parameters, LocalConstructedValueBlock);
        this.idBlock.isConstructed = true;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
        const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm) ? inputLength : this.lenBlock.length);
        if (resultOffset === -1) {
            this.error = this.valueBlock.error;
            return resultOffset;
        }
        if (!this.idBlock.error.length)
            this.blockLength += this.idBlock.blockLength;
        if (!this.lenBlock.error.length)
            this.blockLength += this.lenBlock.blockLength;
        if (!this.valueBlock.error.length)
            this.blockLength += this.valueBlock.blockLength;
        return resultOffset;
    }
    onAsciiEncoding() {
        const values = [];
        for (const value of this.valueBlock.value) {
            values.push(value.toString("ascii").split("\n").map((o) => `  ${o}`).join("\n"));
        }
        const blockName = this.idBlock.tagClass === 3
            ? `[${this.idBlock.tagNumber}]`
            : this.constructor.NAME;
        return values.length
            ? `${blockName} :\n${values.join("\n")}`
            : `${blockName} :`;
    }
}
_a$v = Constructed;
(() => {
    typeStore.Constructed = _a$v;
})();
Constructed.NAME = "CONSTRUCTED";

class LocalEndOfContentValueBlock extends ValueBlock {
    fromBER(inputBuffer, inputOffset, _inputLength) {
        return inputOffset;
    }
    toBER(_sizeOnly) {
        return EMPTY_BUFFER$1;
    }
}
LocalEndOfContentValueBlock.override = "EndOfContentValueBlock";

var _a$u;
class EndOfContent extends BaseBlock {
    constructor(parameters = {}) {
        super(parameters, LocalEndOfContentValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 0;
    }
}
_a$u = EndOfContent;
(() => {
    typeStore.EndOfContent = _a$u;
})();
EndOfContent.NAME = END_OF_CONTENT_NAME;

var _a$t;
class Null extends BaseBlock {
    constructor(parameters = {}) {
        super(parameters, ValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 5;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        if (this.lenBlock.length > 0)
            this.warnings.push("Non-zero length of value block for Null type");
        if (!this.idBlock.error.length)
            this.blockLength += this.idBlock.blockLength;
        if (!this.lenBlock.error.length)
            this.blockLength += this.lenBlock.blockLength;
        this.blockLength += inputLength;
        if ((inputOffset + inputLength) > inputBuffer.byteLength) {
            this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
            return -1;
        }
        return (inputOffset + inputLength);
    }
    toBER(sizeOnly, writer) {
        const retBuf = new ArrayBuffer(2);
        if (!sizeOnly) {
            const retView = new Uint8Array(retBuf);
            retView[0] = 0x05;
            retView[1] = 0x00;
        }
        if (writer) {
            writer.write(retBuf);
        }
        return retBuf;
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME}`;
    }
}
_a$t = Null;
(() => {
    typeStore.Null = _a$t;
})();
Null.NAME = "NULL";

class LocalBooleanValueBlock extends HexBlock(ValueBlock) {
    get value() {
        for (const octet of this.valueHexView) {
            if (octet > 0) {
                return true;
            }
        }
        return false;
    }
    set value(value) {
        this.valueHexView[0] = value ? 0xFF : 0x00;
    }
    constructor({ value, ...parameters } = {}) {
        super(parameters);
        if (parameters.valueHex) {
            this.valueHexView = BufferSourceConverter.toUint8Array(parameters.valueHex);
        }
        else {
            this.valueHexView = new Uint8Array(1);
        }
        if (value) {
            this.value = value;
        }
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const inputView = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
            return -1;
        }
        this.valueHexView = inputView.subarray(inputOffset, inputOffset + inputLength);
        if (inputLength > 1)
            this.warnings.push("Boolean value encoded in more then 1 octet");
        this.isHexOnly = true;
        utilDecodeTC.call(this);
        this.blockLength = inputLength;
        return (inputOffset + inputLength);
    }
    toBER() {
        return this.valueHexView.slice();
    }
    toJSON() {
        return {
            ...super.toJSON(),
            value: this.value,
        };
    }
}
LocalBooleanValueBlock.NAME = "BooleanValueBlock";

var _a$s;
class Boolean extends BaseBlock {
    getValue() {
        return this.valueBlock.value;
    }
    setValue(value) {
        this.valueBlock.value = value;
    }
    constructor(parameters = {}) {
        super(parameters, LocalBooleanValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 1;
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : ${this.getValue}`;
    }
}
_a$s = Boolean;
(() => {
    typeStore.Boolean = _a$s;
})();
Boolean.NAME = "BOOLEAN";

class LocalOctetStringValueBlock extends HexBlock(LocalConstructedValueBlock) {
    constructor({ isConstructed = false, ...parameters } = {}) {
        super(parameters);
        this.isConstructed = isConstructed;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        let resultOffset = 0;
        if (this.isConstructed) {
            this.isHexOnly = false;
            resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
            if (resultOffset === -1)
                return resultOffset;
            for (let i = 0; i < this.value.length; i++) {
                const currentBlockName = this.value[i].constructor.NAME;
                if (currentBlockName === END_OF_CONTENT_NAME) {
                    if (this.isIndefiniteForm)
                        break;
                    else {
                        this.error = "EndOfContent is unexpected, OCTET STRING may consists of OCTET STRINGs only";
                        return -1;
                    }
                }
                if (currentBlockName !== OCTET_STRING_NAME) {
                    this.error = "OCTET STRING may consists of OCTET STRINGs only";
                    return -1;
                }
            }
        }
        else {
            this.isHexOnly = true;
            resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength);
            this.blockLength = inputLength;
        }
        return resultOffset;
    }
    toBER(sizeOnly, writer) {
        if (this.isConstructed)
            return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer);
        return sizeOnly
            ? new ArrayBuffer(this.valueHexView.byteLength)
            : this.valueHexView.slice().buffer;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            isConstructed: this.isConstructed,
        };
    }
}
LocalOctetStringValueBlock.NAME = "OctetStringValueBlock";

var _a$r;
class OctetString extends BaseBlock {
    constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
        var _b, _c;
        (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
        super({
            idBlock: {
                isConstructed: parameters.isConstructed,
                ...idBlock,
            },
            lenBlock: {
                ...lenBlock,
                isIndefiniteForm: !!parameters.isIndefiniteForm,
            },
            ...parameters,
        }, LocalOctetStringValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 4;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        this.valueBlock.isConstructed = this.idBlock.isConstructed;
        this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
        if (inputLength === 0) {
            if (this.idBlock.error.length === 0)
                this.blockLength += this.idBlock.blockLength;
            if (this.lenBlock.error.length === 0)
                this.blockLength += this.lenBlock.blockLength;
            return inputOffset;
        }
        if (!this.valueBlock.isConstructed) {
            const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer;
            const buf = view.subarray(inputOffset, inputOffset + inputLength);
            try {
                if (buf.byteLength) {
                    const asn = localFromBER(buf, 0, buf.byteLength);
                    if (asn.offset !== -1 && asn.offset === inputLength) {
                        this.valueBlock.value = [asn.result];
                    }
                }
            }
            catch {
            }
        }
        return super.fromBER(inputBuffer, inputOffset, inputLength);
    }
    onAsciiEncoding() {
        if (this.valueBlock.isConstructed || (this.valueBlock.value && this.valueBlock.value.length)) {
            return Constructed.prototype.onAsciiEncoding.call(this);
        }
        const name = this.constructor.NAME;
        const value = Convert.ToHex(this.valueBlock.valueHexView);
        return `${name} : ${value}`;
    }
    getValue() {
        if (!this.idBlock.isConstructed) {
            return this.valueBlock.valueHexView.slice().buffer;
        }
        const array = [];
        for (const content of this.valueBlock.value) {
            if (content instanceof _a$r) {
                array.push(content.valueBlock.valueHexView);
            }
        }
        return BufferSourceConverter.concat(array);
    }
}
_a$r = OctetString;
(() => {
    typeStore.OctetString = _a$r;
})();
OctetString.NAME = OCTET_STRING_NAME;

class LocalBitStringValueBlock extends HexBlock(LocalConstructedValueBlock) {
    constructor({ unusedBits = 0, isConstructed = false, ...parameters } = {}) {
        super(parameters);
        this.unusedBits = unusedBits;
        this.isConstructed = isConstructed;
        this.blockLength = this.valueHexView.byteLength;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        if (!inputLength) {
            return inputOffset;
        }
        let resultOffset = -1;
        if (this.isConstructed) {
            resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
            if (resultOffset === -1)
                return resultOffset;
            for (const value of this.value) {
                const currentBlockName = value.constructor.NAME;
                if (currentBlockName === END_OF_CONTENT_NAME) {
                    if (this.isIndefiniteForm)
                        break;
                    else {
                        this.error = "EndOfContent is unexpected, BIT STRING may consists of BIT STRINGs only";
                        return -1;
                    }
                }
                if (currentBlockName !== BIT_STRING_NAME) {
                    this.error = "BIT STRING may consists of BIT STRINGs only";
                    return -1;
                }
                const valueBlock = value.valueBlock;
                if ((this.unusedBits > 0) && (valueBlock.unusedBits > 0)) {
                    this.error = "Using of \"unused bits\" inside constructive BIT STRING allowed for least one only";
                    return -1;
                }
                this.unusedBits = valueBlock.unusedBits;
            }
            return resultOffset;
        }
        const inputView = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
            return -1;
        }
        const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
        this.unusedBits = intBuffer[0];
        if (this.unusedBits > 7) {
            this.error = "Unused bits for BitString must be in range 0-7";
            return -1;
        }
        if (!this.unusedBits) {
            const buf = intBuffer.subarray(1);
            try {
                if (buf.byteLength) {
                    const asn = localFromBER(buf, 0, buf.byteLength);
                    if (asn.offset !== -1 && asn.offset === (inputLength - 1)) {
                        this.value = [asn.result];
                    }
                }
            }
            catch {
            }
        }
        this.valueHexView = intBuffer.subarray(1);
        this.blockLength = intBuffer.length;
        return (inputOffset + inputLength);
    }
    toBER(sizeOnly, writer) {
        if (this.isConstructed) {
            return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer);
        }
        if (sizeOnly) {
            return new ArrayBuffer(this.valueHexView.byteLength + 1);
        }
        if (!this.valueHexView.byteLength) {
            return EMPTY_BUFFER$1;
        }
        const retView = new Uint8Array(this.valueHexView.length + 1);
        retView[0] = this.unusedBits;
        retView.set(this.valueHexView, 1);
        return retView.buffer;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            unusedBits: this.unusedBits,
            isConstructed: this.isConstructed,
        };
    }
}
LocalBitStringValueBlock.NAME = "BitStringValueBlock";

var _a$q;
class BitString extends BaseBlock {
    constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
        var _b, _c;
        (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
        super({
            idBlock: {
                isConstructed: parameters.isConstructed,
                ...idBlock,
            },
            lenBlock: {
                ...lenBlock,
                isIndefiniteForm: !!parameters.isIndefiniteForm,
            },
            ...parameters,
        }, LocalBitStringValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 3;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        this.valueBlock.isConstructed = this.idBlock.isConstructed;
        this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
        return super.fromBER(inputBuffer, inputOffset, inputLength);
    }
    onAsciiEncoding() {
        if (this.valueBlock.isConstructed || (this.valueBlock.value && this.valueBlock.value.length)) {
            return Constructed.prototype.onAsciiEncoding.call(this);
        }
        else {
            const bits = [];
            const valueHex = this.valueBlock.valueHexView;
            for (const byte of valueHex) {
                bits.push(byte.toString(2).padStart(8, "0"));
            }
            const bitsStr = bits.join("");
            const name = this.constructor.NAME;
            const value = bitsStr.substring(0, bitsStr.length - this.valueBlock.unusedBits);
            return `${name} : ${value}`;
        }
    }
}
_a$q = BitString;
(() => {
    typeStore.BitString = _a$q;
})();
BitString.NAME = BIT_STRING_NAME;

var _a$p;
function viewAdd(first, second) {
    const c = new Uint8Array([0]);
    const firstView = new Uint8Array(first);
    const secondView = new Uint8Array(second);
    let firstViewCopy = firstView.slice(0);
    const firstViewCopyLength = firstViewCopy.length - 1;
    const secondViewCopy = secondView.slice(0);
    const secondViewCopyLength = secondViewCopy.length - 1;
    let value = 0;
    const max = (secondViewCopyLength < firstViewCopyLength) ? firstViewCopyLength : secondViewCopyLength;
    let counter = 0;
    for (let i = max; i >= 0; i--, counter++) {
        switch (true) {
            case (counter < secondViewCopy.length):
                value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0];
                break;
            default:
                value = firstViewCopy[firstViewCopyLength - counter] + c[0];
        }
        c[0] = value / 10;
        switch (true) {
            case (counter >= firstViewCopy.length):
                firstViewCopy = utilConcatView(new Uint8Array([value % 10]), firstViewCopy);
                break;
            default:
                firstViewCopy[firstViewCopyLength - counter] = value % 10;
        }
    }
    if (c[0] > 0)
        firstViewCopy = utilConcatView(c, firstViewCopy);
    return firstViewCopy;
}
function power2(n) {
    if (n >= powers2.length) {
        for (let p = powers2.length; p <= n; p++) {
            const c = new Uint8Array([0]);
            let digits = (powers2[p - 1]).slice(0);
            for (let i = (digits.length - 1); i >= 0; i--) {
                const newValue = new Uint8Array([(digits[i] << 1) + c[0]]);
                c[0] = newValue[0] / 10;
                digits[i] = newValue[0] % 10;
            }
            if (c[0] > 0)
                digits = utilConcatView(c, digits);
            powers2.push(digits);
        }
    }
    return powers2[n];
}
function viewSub(first, second) {
    let b = 0;
    const firstView = new Uint8Array(first);
    const secondView = new Uint8Array(second);
    const firstViewCopy = firstView.slice(0);
    const firstViewCopyLength = firstViewCopy.length - 1;
    const secondViewCopy = secondView.slice(0);
    const secondViewCopyLength = secondViewCopy.length - 1;
    let value;
    let counter = 0;
    for (let i = secondViewCopyLength; i >= 0; i--, counter++) {
        value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b;
        switch (true) {
            case (value < 0):
                b = 1;
                firstViewCopy[firstViewCopyLength - counter] = value + 10;
                break;
            default:
                b = 0;
                firstViewCopy[firstViewCopyLength - counter] = value;
        }
    }
    if (b > 0) {
        for (let i = (firstViewCopyLength - secondViewCopyLength + 1); i >= 0; i--, counter++) {
            value = firstViewCopy[firstViewCopyLength - counter] - b;
            if (value < 0) {
                b = 1;
                firstViewCopy[firstViewCopyLength - counter] = value + 10;
            }
            else {
                b = 0;
                firstViewCopy[firstViewCopyLength - counter] = value;
                break;
            }
        }
    }
    return firstViewCopy.slice();
}
class LocalIntegerValueBlock extends HexBlock(ValueBlock) {
    setValueHex() {
        if (this.valueHexView.length >= 4) {
            this.warnings.push("Too big Integer for decoding, hex only");
            this.isHexOnly = true;
            this._valueDec = 0;
        }
        else {
            this.isHexOnly = false;
            if (this.valueHexView.length > 0) {
                this._valueDec = utilDecodeTC.call(this);
            }
        }
    }
    constructor({ value, ...parameters } = {}) {
        super(parameters);
        this._valueDec = 0;
        if (parameters.valueHex) {
            this.setValueHex();
        }
        if (value !== undefined) {
            this.valueDec = value;
        }
    }
    set valueDec(v) {
        this._valueDec = v;
        this.isHexOnly = false;
        this.valueHexView = new Uint8Array(utilEncodeTC(v));
    }
    get valueDec() {
        return this._valueDec;
    }
    fromDER(inputBuffer, inputOffset, inputLength, expectedLength = 0) {
        const offset = this.fromBER(inputBuffer, inputOffset, inputLength);
        if (offset === -1)
            return offset;
        const view = this.valueHexView;
        if ((view[0] === 0x00) && ((view[1] & 0x80) !== 0)) {
            this.valueHexView = view.subarray(1);
        }
        else {
            if (expectedLength !== 0) {
                if (view.length < expectedLength) {
                    if ((expectedLength - view.length) > 1)
                        expectedLength = view.length + 1;
                    this.valueHexView = view.subarray(expectedLength - view.length);
                }
            }
        }
        return offset;
    }
    toDER(sizeOnly = false) {
        const view = this.valueHexView;
        switch (true) {
            case ((view[0] & 0x80) !== 0):
                {
                    const updatedView = new Uint8Array(this.valueHexView.length + 1);
                    updatedView[0] = 0x00;
                    updatedView.set(view, 1);
                    this.valueHexView = updatedView;
                }
                break;
            case ((view[0] === 0x00) && ((view[1] & 0x80) === 0)):
                {
                    this.valueHexView = this.valueHexView.subarray(1);
                }
                break;
        }
        return this.toBER(sizeOnly);
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength);
        if (resultOffset === -1) {
            return resultOffset;
        }
        this.setValueHex();
        return resultOffset;
    }
    toBER(sizeOnly) {
        return sizeOnly
            ? new ArrayBuffer(this.valueHexView.length)
            : this.valueHexView.slice().buffer;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            valueDec: this.valueDec,
        };
    }
    toString() {
        const firstBit = (this.valueHexView.length * 8) - 1;
        let digits = new Uint8Array((this.valueHexView.length * 8) / 3);
        let bitNumber = 0;
        let currentByte;
        const asn1View = this.valueHexView;
        let result = "";
        let flag = false;
        for (let byteNumber = (asn1View.byteLength - 1); byteNumber >= 0; byteNumber--) {
            currentByte = asn1View[byteNumber];
            for (let i = 0; i < 8; i++) {
                if ((currentByte & 1) === 1) {
                    switch (bitNumber) {
                        case firstBit:
                            digits = viewSub(power2(bitNumber), digits);
                            result = "-";
                            break;
                        default:
                            digits = viewAdd(digits, power2(bitNumber));
                    }
                }
                bitNumber++;
                currentByte >>= 1;
            }
        }
        for (let i = 0; i < digits.length; i++) {
            if (digits[i])
                flag = true;
            if (flag)
                result += digitsString.charAt(digits[i]);
        }
        if (flag === false)
            result += digitsString.charAt(0);
        return result;
    }
}
_a$p = LocalIntegerValueBlock;
LocalIntegerValueBlock.NAME = "IntegerValueBlock";
(() => {
    Object.defineProperty(_a$p.prototype, "valueHex", {
        set: function (v) {
            this.valueHexView = new Uint8Array(v);
            this.setValueHex();
        },
        get: function () {
            return this.valueHexView.slice().buffer;
        },
    });
})();

var _a$o;
class Integer extends BaseBlock {
    constructor(parameters = {}) {
        super(parameters, LocalIntegerValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 2;
    }
    toBigInt() {
        assertBigInt();
        return BigInt(this.valueBlock.toString());
    }
    static fromBigInt(value) {
        assertBigInt();
        const bigIntValue = BigInt(value);
        const writer = new ViewWriter();
        const hex = bigIntValue.toString(16).replace(/^-/, "");
        const view = new Uint8Array(Convert.FromHex(hex));
        if (bigIntValue < 0) {
            const first = new Uint8Array(view.length + (view[0] & 0x80 ? 1 : 0));
            first[0] |= 0x80;
            const firstInt = BigInt(`0x${Convert.ToHex(first)}`);
            const secondInt = firstInt + bigIntValue;
            const second = BufferSourceConverter.toUint8Array(Convert.FromHex(secondInt.toString(16)));
            second[0] |= 0x80;
            writer.write(second);
        }
        else {
            if (view[0] & 0x80) {
                writer.write(new Uint8Array([0]));
            }
            writer.write(view);
        }
        const res = new _a$o({ valueHex: writer.final() });
        return res;
    }
    convertToDER() {
        const integer = new _a$o({ valueHex: this.valueBlock.valueHexView });
        integer.valueBlock.toDER();
        return integer;
    }
    convertFromDER() {
        return new _a$o({
            valueHex: this.valueBlock.valueHexView[0] === 0
                ? this.valueBlock.valueHexView.subarray(1)
                : this.valueBlock.valueHexView,
        });
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : ${this.valueBlock.toString()}`;
    }
}
_a$o = Integer;
(() => {
    typeStore.Integer = _a$o;
})();
Integer.NAME = "INTEGER";

var _a$n;
class Enumerated extends Integer {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 10;
    }
}
_a$n = Enumerated;
(() => {
    typeStore.Enumerated = _a$n;
})();
Enumerated.NAME = "ENUMERATED";

class LocalSidValueBlock extends HexBlock(ValueBlock) {
    constructor({ valueDec = -1, isFirstSid = false, ...parameters } = {}) {
        super(parameters);
        this.valueDec = valueDec;
        this.isFirstSid = isFirstSid;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        if (!inputLength) {
            return inputOffset;
        }
        const inputView = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
            return -1;
        }
        const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
        this.valueHexView = new Uint8Array(inputLength);
        for (let i = 0; i < inputLength; i++) {
            this.valueHexView[i] = intBuffer[i] & 0x7F;
            this.blockLength++;
            if ((intBuffer[i] & 0x80) === 0x00)
                break;
        }
        const tempView = new Uint8Array(this.blockLength);
        for (let i = 0; i < this.blockLength; i++) {
            tempView[i] = this.valueHexView[i];
        }
        this.valueHexView = tempView;
        if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) {
            this.error = "End of input reached before message was fully decoded";
            return -1;
        }
        if (this.valueHexView[0] === 0x00)
            this.warnings.push("Needlessly long format of SID encoding");
        if (this.blockLength <= 8)
            this.valueDec = utilFromBase(this.valueHexView, 7);
        else {
            this.isHexOnly = true;
            this.warnings.push("Too big SID for decoding, hex only");
        }
        return (inputOffset + this.blockLength);
    }
    set valueBigInt(value) {
        assertBigInt();
        let bits = BigInt(value).toString(2);
        while (bits.length % 7) {
            bits = "0" + bits;
        }
        const bytes = new Uint8Array(bits.length / 7);
        for (let i = 0; i < bytes.length; i++) {
            bytes[i] = parseInt(bits.slice(i * 7, i * 7 + 7), 2) + (i + 1 < bytes.length ? 0x80 : 0);
        }
        this.fromBER(bytes.buffer, 0, bytes.length);
    }
    toBER(sizeOnly) {
        if (this.isHexOnly) {
            if (sizeOnly)
                return (new ArrayBuffer(this.valueHexView.byteLength));
            const curView = this.valueHexView;
            const retView = new Uint8Array(this.blockLength);
            for (let i = 0; i < (this.blockLength - 1); i++)
                retView[i] = curView[i] | 0x80;
            retView[this.blockLength - 1] = curView[this.blockLength - 1];
            return retView.buffer;
        }
        const encodedBuf = utilToBase(this.valueDec, 7);
        if (encodedBuf.byteLength === 0) {
            this.error = "Error during encoding SID value";
            return EMPTY_BUFFER$1;
        }
        const retView = new Uint8Array(encodedBuf.byteLength);
        if (!sizeOnly) {
            const encodedView = new Uint8Array(encodedBuf);
            const len = encodedBuf.byteLength - 1;
            for (let i = 0; i < len; i++)
                retView[i] = encodedView[i] | 0x80;
            retView[len] = encodedView[len];
        }
        return retView;
    }
    toString() {
        let result = "";
        if (this.isHexOnly)
            result = Convert.ToHex(this.valueHexView);
        else {
            if (this.isFirstSid) {
                let sidValue = this.valueDec;
                if (this.valueDec <= 39)
                    result = "0.";
                else {
                    if (this.valueDec <= 79) {
                        result = "1.";
                        sidValue -= 40;
                    }
                    else {
                        result = "2.";
                        sidValue -= 80;
                    }
                }
                result += sidValue.toString();
            }
            else
                result = this.valueDec.toString();
        }
        return result;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            valueDec: this.valueDec,
            isFirstSid: this.isFirstSid,
        };
    }
}
LocalSidValueBlock.NAME = "sidBlock";

class LocalObjectIdentifierValueBlock extends ValueBlock {
    constructor({ value = EMPTY_STRING$1, ...parameters } = {}) {
        super(parameters);
        this.value = [];
        if (value) {
            this.fromString(value);
        }
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        let resultOffset = inputOffset;
        while (inputLength > 0) {
            const sidBlock = new LocalSidValueBlock();
            resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength);
            if (resultOffset === -1) {
                this.blockLength = 0;
                this.error = sidBlock.error;
                return resultOffset;
            }
            if (this.value.length === 0)
                sidBlock.isFirstSid = true;
            this.blockLength += sidBlock.blockLength;
            inputLength -= sidBlock.blockLength;
            this.value.push(sidBlock);
        }
        return resultOffset;
    }
    toBER(sizeOnly) {
        const retBuffers = [];
        for (let i = 0; i < this.value.length; i++) {
            const valueBuf = this.value[i].toBER(sizeOnly);
            if (valueBuf.byteLength === 0) {
                this.error = this.value[i].error;
                return EMPTY_BUFFER$1;
            }
            retBuffers.push(valueBuf);
        }
        return concat(retBuffers);
    }
    fromString(string) {
        this.value = [];
        let pos1 = 0;
        let pos2 = 0;
        let sid = "";
        let flag = false;
        do {
            pos2 = string.indexOf(".", pos1);
            if (pos2 === -1)
                sid = string.substring(pos1);
            else
                sid = string.substring(pos1, pos2);
            pos1 = pos2 + 1;
            if (flag) {
                const sidBlock = this.value[0];
                let plus = 0;
                switch (sidBlock.valueDec) {
                    case 0:
                        break;
                    case 1:
                        plus = 40;
                        break;
                    case 2:
                        plus = 80;
                        break;
                    default:
                        this.value = [];
                        return;
                }
                const parsedSID = parseInt(sid, 10);
                if (isNaN(parsedSID))
                    return;
                sidBlock.valueDec = parsedSID + plus;
                flag = false;
            }
            else {
                const sidBlock = new LocalSidValueBlock();
                if (sid > Number.MAX_SAFE_INTEGER) {
                    assertBigInt();
                    const sidValue = BigInt(sid);
                    sidBlock.valueBigInt = sidValue;
                }
                else {
                    sidBlock.valueDec = parseInt(sid, 10);
                    if (isNaN(sidBlock.valueDec))
                        return;
                }
                if (!this.value.length) {
                    sidBlock.isFirstSid = true;
                    flag = true;
                }
                this.value.push(sidBlock);
            }
        } while (pos2 !== -1);
    }
    toString() {
        let result = "";
        let isHexOnly = false;
        for (let i = 0; i < this.value.length; i++) {
            isHexOnly = this.value[i].isHexOnly;
            let sidStr = this.value[i].toString();
            if (i !== 0)
                result = `${result}.`;
            if (isHexOnly) {
                sidStr = `{${sidStr}}`;
                if (this.value[i].isFirstSid)
                    result = `2.{${sidStr} - 80}`;
                else
                    result += sidStr;
            }
            else
                result += sidStr;
        }
        return result;
    }
    toJSON() {
        const object = {
            ...super.toJSON(),
            value: this.toString(),
            sidArray: [],
        };
        for (let i = 0; i < this.value.length; i++) {
            object.sidArray.push(this.value[i].toJSON());
        }
        return object;
    }
}
LocalObjectIdentifierValueBlock.NAME = "ObjectIdentifierValueBlock";

var _a$m;
class ObjectIdentifier extends BaseBlock {
    getValue() {
        return this.valueBlock.toString();
    }
    setValue(value) {
        this.valueBlock.fromString(value);
    }
    constructor(parameters = {}) {
        super(parameters, LocalObjectIdentifierValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 6;
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            value: this.getValue(),
        };
    }
}
_a$m = ObjectIdentifier;
(() => {
    typeStore.ObjectIdentifier = _a$m;
})();
ObjectIdentifier.NAME = "OBJECT IDENTIFIER";

class LocalRelativeSidValueBlock extends HexBlock(LocalBaseBlock) {
    constructor({ valueDec = 0, ...parameters } = {}) {
        super(parameters);
        this.valueDec = valueDec;
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        if (inputLength === 0)
            return inputOffset;
        const inputView = BufferSourceConverter.toUint8Array(inputBuffer);
        if (!checkBufferParams(this, inputView, inputOffset, inputLength))
            return -1;
        const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
        this.valueHexView = new Uint8Array(inputLength);
        for (let i = 0; i < inputLength; i++) {
            this.valueHexView[i] = intBuffer[i] & 0x7F;
            this.blockLength++;
            if ((intBuffer[i] & 0x80) === 0x00)
                break;
        }
        const tempView = new Uint8Array(this.blockLength);
        for (let i = 0; i < this.blockLength; i++)
            tempView[i] = this.valueHexView[i];
        this.valueHexView = tempView;
        if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) {
            this.error = "End of input reached before message was fully decoded";
            return -1;
        }
        if (this.valueHexView[0] === 0x00)
            this.warnings.push("Needlessly long format of SID encoding");
        if (this.blockLength <= 8)
            this.valueDec = utilFromBase(this.valueHexView, 7);
        else {
            this.isHexOnly = true;
            this.warnings.push("Too big SID for decoding, hex only");
        }
        return (inputOffset + this.blockLength);
    }
    toBER(sizeOnly) {
        if (this.isHexOnly) {
            if (sizeOnly)
                return (new ArrayBuffer(this.valueHexView.byteLength));
            const curView = this.valueHexView;
            const retView = new Uint8Array(this.blockLength);
            for (let i = 0; i < (this.blockLength - 1); i++)
                retView[i] = curView[i] | 0x80;
            retView[this.blockLength - 1] = curView[this.blockLength - 1];
            return retView.buffer;
        }
        const encodedBuf = utilToBase(this.valueDec, 7);
        if (encodedBuf.byteLength === 0) {
            this.error = "Error during encoding SID value";
            return EMPTY_BUFFER$1;
        }
        const retView = new Uint8Array(encodedBuf.byteLength);
        if (!sizeOnly) {
            const encodedView = new Uint8Array(encodedBuf);
            const len = encodedBuf.byteLength - 1;
            for (let i = 0; i < len; i++)
                retView[i] = encodedView[i] | 0x80;
            retView[len] = encodedView[len];
        }
        return retView.buffer;
    }
    toString() {
        let result = "";
        if (this.isHexOnly)
            result = Convert.ToHex(this.valueHexView);
        else {
            result = this.valueDec.toString();
        }
        return result;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            valueDec: this.valueDec,
        };
    }
}
LocalRelativeSidValueBlock.NAME = "relativeSidBlock";

class LocalRelativeObjectIdentifierValueBlock extends ValueBlock {
    constructor({ value = EMPTY_STRING$1, ...parameters } = {}) {
        super(parameters);
        this.value = [];
        if (value) {
            this.fromString(value);
        }
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        let resultOffset = inputOffset;
        while (inputLength > 0) {
            const sidBlock = new LocalRelativeSidValueBlock();
            resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength);
            if (resultOffset === -1) {
                this.blockLength = 0;
                this.error = sidBlock.error;
                return resultOffset;
            }
            this.blockLength += sidBlock.blockLength;
            inputLength -= sidBlock.blockLength;
            this.value.push(sidBlock);
        }
        return resultOffset;
    }
    toBER(sizeOnly, _writer) {
        const retBuffers = [];
        for (let i = 0; i < this.value.length; i++) {
            const valueBuf = this.value[i].toBER(sizeOnly);
            if (valueBuf.byteLength === 0) {
                this.error = this.value[i].error;
                return EMPTY_BUFFER$1;
            }
            retBuffers.push(valueBuf);
        }
        return concat(retBuffers);
    }
    fromString(string) {
        this.value = [];
        let pos1 = 0;
        let pos2 = 0;
        let sid = "";
        do {
            pos2 = string.indexOf(".", pos1);
            if (pos2 === -1)
                sid = string.substring(pos1);
            else
                sid = string.substring(pos1, pos2);
            pos1 = pos2 + 1;
            const sidBlock = new LocalRelativeSidValueBlock();
            sidBlock.valueDec = parseInt(sid, 10);
            if (isNaN(sidBlock.valueDec))
                return true;
            this.value.push(sidBlock);
        } while (pos2 !== -1);
        return true;
    }
    toString() {
        let result = "";
        let isHexOnly = false;
        for (let i = 0; i < this.value.length; i++) {
            isHexOnly = this.value[i].isHexOnly;
            let sidStr = this.value[i].toString();
            if (i !== 0)
                result = `${result}.`;
            if (isHexOnly) {
                sidStr = `{${sidStr}}`;
                result += sidStr;
            }
            else
                result += sidStr;
        }
        return result;
    }
    toJSON() {
        const object = {
            ...super.toJSON(),
            value: this.toString(),
            sidArray: [],
        };
        for (let i = 0; i < this.value.length; i++)
            object.sidArray.push(this.value[i].toJSON());
        return object;
    }
}
LocalRelativeObjectIdentifierValueBlock.NAME = "RelativeObjectIdentifierValueBlock";

var _a$l;
class RelativeObjectIdentifier extends BaseBlock {
    getValue() {
        return this.valueBlock.toString();
    }
    setValue(value) {
        this.valueBlock.fromString(value);
    }
    constructor(parameters = {}) {
        super(parameters, LocalRelativeObjectIdentifierValueBlock);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 13;
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            value: this.getValue(),
        };
    }
}
_a$l = RelativeObjectIdentifier;
(() => {
    typeStore.RelativeObjectIdentifier = _a$l;
})();
RelativeObjectIdentifier.NAME = "RelativeObjectIdentifier";

var _a$k;
class Sequence extends Constructed {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 16;
    }
}
_a$k = Sequence;
(() => {
    typeStore.Sequence = _a$k;
})();
Sequence.NAME = "SEQUENCE";

var _a$j;
class Set extends Constructed {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 17;
    }
}
_a$j = Set;
(() => {
    typeStore.Set = _a$j;
})();
Set.NAME = "SET";

class LocalStringValueBlock extends HexBlock(ValueBlock) {
    constructor({ ...parameters } = {}) {
        super(parameters);
        this.isHexOnly = true;
        this.value = EMPTY_STRING$1;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            value: this.value,
        };
    }
}
LocalStringValueBlock.NAME = "StringValueBlock";

class LocalSimpleStringValueBlock extends LocalStringValueBlock {
}
LocalSimpleStringValueBlock.NAME = "SimpleStringValueBlock";

class LocalSimpleStringBlock extends BaseStringBlock {
    constructor({ ...parameters } = {}) {
        super(parameters, LocalSimpleStringValueBlock);
    }
    fromBuffer(inputBuffer) {
        this.valueBlock.value = String.fromCharCode.apply(null, BufferSourceConverter.toUint8Array(inputBuffer));
    }
    fromString(inputString) {
        const strLen = inputString.length;
        const view = this.valueBlock.valueHexView = new Uint8Array(strLen);
        for (let i = 0; i < strLen; i++)
            view[i] = inputString.charCodeAt(i);
        this.valueBlock.value = inputString;
    }
}
LocalSimpleStringBlock.NAME = "SIMPLE STRING";

class LocalUtf8StringValueBlock extends LocalSimpleStringBlock {
    fromBuffer(inputBuffer) {
        this.valueBlock.valueHexView = BufferSourceConverter.toUint8Array(inputBuffer);
        try {
            this.valueBlock.value = Convert.ToUtf8String(inputBuffer);
        }
        catch (ex) {
            this.warnings.push(`Error during "decodeURIComponent": ${ex}, using raw string`);
            this.valueBlock.value = Convert.ToBinary(inputBuffer);
        }
    }
    fromString(inputString) {
        this.valueBlock.valueHexView = new Uint8Array(Convert.FromUtf8String(inputString));
        this.valueBlock.value = inputString;
    }
}
LocalUtf8StringValueBlock.NAME = "Utf8StringValueBlock";

var _a$i;
class Utf8String extends LocalUtf8StringValueBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 12;
    }
}
_a$i = Utf8String;
(() => {
    typeStore.Utf8String = _a$i;
})();
Utf8String.NAME = "UTF8String";

class LocalBmpStringValueBlock extends LocalSimpleStringBlock {
    fromBuffer(inputBuffer) {
        this.valueBlock.value = Convert.ToUtf16String(inputBuffer);
        this.valueBlock.valueHexView = BufferSourceConverter.toUint8Array(inputBuffer);
    }
    fromString(inputString) {
        this.valueBlock.value = inputString;
        this.valueBlock.valueHexView = new Uint8Array(Convert.FromUtf16String(inputString));
    }
}
LocalBmpStringValueBlock.NAME = "BmpStringValueBlock";

var _a$h;
class BmpString extends LocalBmpStringValueBlock {
    constructor({ ...parameters } = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 30;
    }
}
_a$h = BmpString;
(() => {
    typeStore.BmpString = _a$h;
})();
BmpString.NAME = "BMPString";

class LocalUniversalStringValueBlock extends LocalSimpleStringBlock {
    fromBuffer(inputBuffer) {
        const copyBuffer = ArrayBuffer.isView(inputBuffer) ? inputBuffer.slice().buffer : inputBuffer.slice(0);
        const valueView = new Uint8Array(copyBuffer);
        for (let i = 0; i < valueView.length; i += 4) {
            valueView[i] = valueView[i + 3];
            valueView[i + 1] = valueView[i + 2];
            valueView[i + 2] = 0x00;
            valueView[i + 3] = 0x00;
        }
        this.valueBlock.value = String.fromCharCode.apply(null, new Uint32Array(copyBuffer));
    }
    fromString(inputString) {
        const strLength = inputString.length;
        const valueHexView = this.valueBlock.valueHexView = new Uint8Array(strLength * 4);
        for (let i = 0; i < strLength; i++) {
            const codeBuf = utilToBase(inputString.charCodeAt(i), 8);
            const codeView = new Uint8Array(codeBuf);
            if (codeView.length > 4)
                continue;
            const dif = 4 - codeView.length;
            for (let j = (codeView.length - 1); j >= 0; j--)
                valueHexView[i * 4 + j + dif] = codeView[j];
        }
        this.valueBlock.value = inputString;
    }
}
LocalUniversalStringValueBlock.NAME = "UniversalStringValueBlock";

var _a$g;
class UniversalString extends LocalUniversalStringValueBlock {
    constructor({ ...parameters } = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 28;
    }
}
_a$g = UniversalString;
(() => {
    typeStore.UniversalString = _a$g;
})();
UniversalString.NAME = "UniversalString";

var _a$f;
class NumericString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 18;
    }
}
_a$f = NumericString;
(() => {
    typeStore.NumericString = _a$f;
})();
NumericString.NAME = "NumericString";

var _a$e;
class PrintableString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 19;
    }
}
_a$e = PrintableString;
(() => {
    typeStore.PrintableString = _a$e;
})();
PrintableString.NAME = "PrintableString";

var _a$d;
class TeletexString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 20;
    }
}
_a$d = TeletexString;
(() => {
    typeStore.TeletexString = _a$d;
})();
TeletexString.NAME = "TeletexString";

var _a$c;
class VideotexString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 21;
    }
}
_a$c = VideotexString;
(() => {
    typeStore.VideotexString = _a$c;
})();
VideotexString.NAME = "VideotexString";

var _a$b;
class IA5String extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 22;
    }
}
_a$b = IA5String;
(() => {
    typeStore.IA5String = _a$b;
})();
IA5String.NAME = "IA5String";

var _a$a;
class GraphicString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 25;
    }
}
_a$a = GraphicString;
(() => {
    typeStore.GraphicString = _a$a;
})();
GraphicString.NAME = "GraphicString";

var _a$9;
class VisibleString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 26;
    }
}
_a$9 = VisibleString;
(() => {
    typeStore.VisibleString = _a$9;
})();
VisibleString.NAME = "VisibleString";

var _a$8;
class GeneralString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 27;
    }
}
_a$8 = GeneralString;
(() => {
    typeStore.GeneralString = _a$8;
})();
GeneralString.NAME = "GeneralString";

var _a$7;
class CharacterString extends LocalSimpleStringBlock {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 29;
    }
}
_a$7 = CharacterString;
(() => {
    typeStore.CharacterString = _a$7;
})();
CharacterString.NAME = "CharacterString";

var _a$6;
class UTCTime extends VisibleString {
    constructor({ value, valueDate, ...parameters } = {}) {
        super(parameters);
        this.year = 0;
        this.month = 0;
        this.day = 0;
        this.hour = 0;
        this.minute = 0;
        this.second = 0;
        if (value) {
            this.fromString(value);
            this.valueBlock.valueHexView = new Uint8Array(value.length);
            for (let i = 0; i < value.length; i++)
                this.valueBlock.valueHexView[i] = value.charCodeAt(i);
        }
        if (valueDate) {
            this.fromDate(valueDate);
            this.valueBlock.valueHexView = new Uint8Array(this.toBuffer());
        }
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 23;
    }
    fromBuffer(inputBuffer) {
        this.fromString(String.fromCharCode.apply(null, BufferSourceConverter.toUint8Array(inputBuffer)));
    }
    toBuffer() {
        const str = this.toString();
        const buffer = new ArrayBuffer(str.length);
        const view = new Uint8Array(buffer);
        for (let i = 0; i < str.length; i++)
            view[i] = str.charCodeAt(i);
        return buffer;
    }
    fromDate(inputDate) {
        this.year = inputDate.getUTCFullYear();
        this.month = inputDate.getUTCMonth() + 1;
        this.day = inputDate.getUTCDate();
        this.hour = inputDate.getUTCHours();
        this.minute = inputDate.getUTCMinutes();
        this.second = inputDate.getUTCSeconds();
    }
    toDate() {
        return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)));
    }
    fromString(inputString) {
        const parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig;
        const parserArray = parser.exec(inputString);
        if (parserArray === null) {
            this.error = "Wrong input string for conversion";
            return;
        }
        const year = parseInt(parserArray[1], 10);
        if (year >= 50)
            this.year = 1900 + year;
        else
            this.year = 2000 + year;
        this.month = parseInt(parserArray[2], 10);
        this.day = parseInt(parserArray[3], 10);
        this.hour = parseInt(parserArray[4], 10);
        this.minute = parseInt(parserArray[5], 10);
        this.second = parseInt(parserArray[6], 10);
    }
    toString(encoding = "iso") {
        if (encoding === "iso") {
            const outputArray = new Array(7);
            outputArray[0] = padNumber(((this.year < 2000) ? (this.year - 1900) : (this.year - 2000)), 2);
            outputArray[1] = padNumber(this.month, 2);
            outputArray[2] = padNumber(this.day, 2);
            outputArray[3] = padNumber(this.hour, 2);
            outputArray[4] = padNumber(this.minute, 2);
            outputArray[5] = padNumber(this.second, 2);
            outputArray[6] = "Z";
            return outputArray.join("");
        }
        return super.toString(encoding);
    }
    onAsciiEncoding() {
        return `${this.constructor.NAME} : ${this.toDate().toISOString()}`;
    }
    toJSON() {
        return {
            ...super.toJSON(),
            year: this.year,
            month: this.month,
            day: this.day,
            hour: this.hour,
            minute: this.minute,
            second: this.second,
        };
    }
}
_a$6 = UTCTime;
(() => {
    typeStore.UTCTime = _a$6;
})();
UTCTime.NAME = "UTCTime";

var _a$5;
class GeneralizedTime extends UTCTime {
    constructor(parameters = {}) {
        var _b;
        super(parameters);
        (_b = this.millisecond) !== null && _b !== void 0 ? _b : (this.millisecond = 0);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 24;
    }
    fromDate(inputDate) {
        super.fromDate(inputDate);
        this.millisecond = inputDate.getUTCMilliseconds();
    }
    toDate() {
        const utcDate = Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond);
        return (new Date(utcDate));
    }
    fromString(inputString) {
        let isUTC = false;
        let timeString = "";
        let dateTimeString = "";
        let fractionPart = 0;
        let parser;
        let hourDifference = 0;
        let minuteDifference = 0;
        if (inputString[inputString.length - 1] === "Z") {
            timeString = inputString.substring(0, inputString.length - 1);
            isUTC = true;
        }
        else {
            const number = new Number(inputString[inputString.length - 1]);
            if (isNaN(number.valueOf()))
                throw new Error("Wrong input string for conversion");
            timeString = inputString;
        }
        if (isUTC) {
            if (timeString.indexOf("+") !== -1)
                throw new Error("Wrong input string for conversion");
            if (timeString.indexOf("-") !== -1)
                throw new Error("Wrong input string for conversion");
        }
        else {
            let multiplier = 1;
            let differencePosition = timeString.indexOf("+");
            let differenceString = "";
            if (differencePosition === -1) {
                differencePosition = timeString.indexOf("-");
                multiplier = -1;
            }
            if (differencePosition !== -1) {
                differenceString = timeString.substring(differencePosition + 1);
                timeString = timeString.substring(0, differencePosition);
                if ((differenceString.length !== 2) && (differenceString.length !== 4))
                    throw new Error("Wrong input string for conversion");
                let number = parseInt(differenceString.substring(0, 2), 10);
                if (isNaN(number.valueOf()))
                    throw new Error("Wrong input string for conversion");
                hourDifference = multiplier * number;
                if (differenceString.length === 4) {
                    number = parseInt(differenceString.substring(2, 4), 10);
                    if (isNaN(number.valueOf()))
                        throw new Error("Wrong input string for conversion");
                    minuteDifference = multiplier * number;
                }
            }
        }
        let fractionPointPosition = timeString.indexOf(".");
        if (fractionPointPosition === -1)
            fractionPointPosition = timeString.indexOf(",");
        if (fractionPointPosition !== -1) {
            const fractionPartCheck = new Number(`0${timeString.substring(fractionPointPosition)}`);
            if (isNaN(fractionPartCheck.valueOf()))
                throw new Error("Wrong input string for conversion");
            fractionPart = fractionPartCheck.valueOf();
            dateTimeString = timeString.substring(0, fractionPointPosition);
        }
        else
            dateTimeString = timeString;
        switch (true) {
            case (dateTimeString.length === 8):
                parser = /(\d{4})(\d{2})(\d{2})/ig;
                if (fractionPointPosition !== -1)
                    throw new Error("Wrong input string for conversion");
                break;
            case (dateTimeString.length === 10):
                parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig;
                if (fractionPointPosition !== -1) {
                    let fractionResult = 60 * fractionPart;
                    this.minute = Math.floor(fractionResult);
                    fractionResult = 60 * (fractionResult - this.minute);
                    this.second = Math.floor(fractionResult);
                    fractionResult = 1000 * (fractionResult - this.second);
                    this.millisecond = Math.floor(fractionResult);
                }
                break;
            case (dateTimeString.length === 12):
                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
                if (fractionPointPosition !== -1) {
                    let fractionResult = 60 * fractionPart;
                    this.second = Math.floor(fractionResult);
                    fractionResult = 1000 * (fractionResult - this.second);
                    this.millisecond = Math.floor(fractionResult);
                }
                break;
            case (dateTimeString.length === 14):
                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
                if (fractionPointPosition !== -1) {
                    const fractionResult = 1000 * fractionPart;
                    this.millisecond = Math.floor(fractionResult);
                }
                break;
            default:
                throw new Error("Wrong input string for conversion");
        }
        const parserArray = parser.exec(dateTimeString);
        if (parserArray === null)
            throw new Error("Wrong input string for conversion");
        for (let j = 1; j < parserArray.length; j++) {
            switch (j) {
                case 1:
                    this.year = parseInt(parserArray[j], 10);
                    break;
                case 2:
                    this.month = parseInt(parserArray[j], 10);
                    break;
                case 3:
                    this.day = parseInt(parserArray[j], 10);
                    break;
                case 4:
                    this.hour = parseInt(parserArray[j], 10) + hourDifference;
                    break;
                case 5:
                    this.minute = parseInt(parserArray[j], 10) + minuteDifference;
                    break;
                case 6:
                    this.second = parseInt(parserArray[j], 10);
                    break;
                default:
                    throw new Error("Wrong input string for conversion");
            }
        }
        if (isUTC === false) {
            const tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
            this.year = tempDate.getUTCFullYear();
            this.month = tempDate.getUTCMonth();
            this.day = tempDate.getUTCDay();
            this.hour = tempDate.getUTCHours();
            this.minute = tempDate.getUTCMinutes();
            this.second = tempDate.getUTCSeconds();
            this.millisecond = tempDate.getUTCMilliseconds();
        }
    }
    toString(encoding = "iso") {
        if (encoding === "iso") {
            const outputArray = [];
            outputArray.push(padNumber(this.year, 4));
            outputArray.push(padNumber(this.month, 2));
            outputArray.push(padNumber(this.day, 2));
            outputArray.push(padNumber(this.hour, 2));
            outputArray.push(padNumber(this.minute, 2));
            outputArray.push(padNumber(this.second, 2));
            if (this.millisecond !== 0) {
                outputArray.push(".");
                outputArray.push(padNumber(this.millisecond, 3));
            }
            outputArray.push("Z");
            return outputArray.join("");
        }
        return super.toString(encoding);
    }
    toJSON() {
        return {
            ...super.toJSON(),
            millisecond: this.millisecond,
        };
    }
}
_a$5 = GeneralizedTime;
(() => {
    typeStore.GeneralizedTime = _a$5;
})();
GeneralizedTime.NAME = "GeneralizedTime";

var _a$4;
let DATE$2 = class DATE extends Utf8String {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 31;
    }
};
_a$4 = DATE$2;
(() => {
    typeStore.DATE = _a$4;
})();
DATE$2.NAME = "DATE";

var _a$3;
class TimeOfDay extends Utf8String {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 32;
    }
}
_a$3 = TimeOfDay;
(() => {
    typeStore.TimeOfDay = _a$3;
})();
TimeOfDay.NAME = "TimeOfDay";

var _a$2;
class DateTime extends Utf8String {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 33;
    }
}
_a$2 = DateTime;
(() => {
    typeStore.DateTime = _a$2;
})();
DateTime.NAME = "DateTime";

var _a$1;
class Duration extends Utf8String {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 34;
    }
}
_a$1 = Duration;
(() => {
    typeStore.Duration = _a$1;
})();
Duration.NAME = "Duration";

var _a$x;
class TIME extends Utf8String {
    constructor(parameters = {}) {
        super(parameters);
        this.idBlock.tagClass = 1;
        this.idBlock.tagNumber = 14;
    }
}
_a$x = TIME;
(() => {
    typeStore.TIME = _a$x;
})();
TIME.NAME = "TIME";

class Any {
    constructor({ name = EMPTY_STRING$1, optional = false } = {}) {
        this.name = name;
        this.optional = optional;
    }
}

class Choice extends Any {
    constructor({ value = [], ...parameters } = {}) {
        super(parameters);
        this.value = value;
    }
}

class Repeated extends Any {
    constructor({ value = new Any(), local = false, ...parameters } = {}) {
        super(parameters);
        this.value = value;
        this.local = local;
    }
}

class RawData {
    get data() {
        return this.dataView.slice().buffer;
    }
    set data(value) {
        this.dataView = BufferSourceConverter.toUint8Array(value);
    }
    constructor({ data = EMPTY_VIEW } = {}) {
        this.dataView = BufferSourceConverter.toUint8Array(data);
    }
    fromBER(inputBuffer, inputOffset, inputLength) {
        const endLength = inputOffset + inputLength;
        this.dataView = BufferSourceConverter.toUint8Array(inputBuffer).subarray(inputOffset, endLength);
        return endLength;
    }
    toBER(_sizeOnly) {
        return this.dataView.slice().buffer;
    }
}

function compareSchema(root, inputData, inputSchema) {
    if (inputSchema instanceof Choice) {
        for (const element of inputSchema.value) {
            const result = compareSchema(root, inputData, element);
            if (result.verified) {
                return {
                    verified: true,
                    result: root,
                };
            }
        }
        {
            const _result = {
                verified: false,
                result: { error: "Wrong values for Choice type" },
            };
            if (inputSchema.hasOwnProperty(NAME))
                _result.name = inputSchema.name;
            return _result;
        }
    }
    if (inputSchema instanceof Any) {
        if (inputSchema.hasOwnProperty(NAME))
            root[inputSchema.name] = inputData;
        return {
            verified: true,
            result: root,
        };
    }
    if ((root instanceof Object) === false) {
        return {
            verified: false,
            result: { error: "Wrong root object" },
        };
    }
    if ((inputData instanceof Object) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 data" },
        };
    }
    if ((inputSchema instanceof Object) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if ((ID_BLOCK in inputSchema) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if ((FROM_BER in inputSchema.idBlock) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if ((TO_BER in inputSchema.idBlock) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    const encodedId = inputSchema.idBlock.toBER(false);
    if (encodedId.byteLength === 0) {
        return {
            verified: false,
            result: { error: "Error encoding idBlock for ASN.1 schema" },
        };
    }
    const decodedOffset = inputSchema.idBlock.fromBER(encodedId, 0, encodedId.byteLength);
    if (decodedOffset === -1) {
        return {
            verified: false,
            result: { error: "Error decoding idBlock for ASN.1 schema" },
        };
    }
    if (inputSchema.idBlock.hasOwnProperty(TAG_CLASS) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if (inputSchema.idBlock.tagClass !== inputData.idBlock.tagClass) {
        return {
            verified: false,
            result: root,
        };
    }
    if (inputSchema.idBlock.hasOwnProperty(TAG_NUMBER) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if (inputSchema.idBlock.tagNumber !== inputData.idBlock.tagNumber) {
        return {
            verified: false,
            result: root,
        };
    }
    if (inputSchema.idBlock.hasOwnProperty(IS_CONSTRUCTED) === false) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if (inputSchema.idBlock.isConstructed !== inputData.idBlock.isConstructed) {
        return {
            verified: false,
            result: root,
        };
    }
    if (!(IS_HEX_ONLY in inputSchema.idBlock)) {
        return {
            verified: false,
            result: { error: "Wrong ASN.1 schema" },
        };
    }
    if (inputSchema.idBlock.isHexOnly !== inputData.idBlock.isHexOnly) {
        return {
            verified: false,
            result: root,
        };
    }
    if (inputSchema.idBlock.isHexOnly) {
        if ((VALUE_HEX_VIEW in inputSchema.idBlock) === false) {
            return {
                verified: false,
                result: { error: "Wrong ASN.1 schema" },
            };
        }
        const schemaView = inputSchema.idBlock.valueHexView;
        const asn1View = inputData.idBlock.valueHexView;
        if (schemaView.length !== asn1View.length) {
            return {
                verified: false,
                result: root,
            };
        }
        for (let i = 0; i < schemaView.length; i++) {
            if (schemaView[i] !== asn1View[1]) {
                return {
                    verified: false,
                    result: root,
                };
            }
        }
    }
    if (inputSchema.name) {
        inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
        if (inputSchema.name)
            root[inputSchema.name] = inputData;
    }
    if (inputSchema instanceof typeStore.Constructed) {
        let admission = 0;
        let result = {
            verified: false,
            result: { error: "Unknown error" },
        };
        let maxLength = inputSchema.valueBlock.value.length;
        if (maxLength > 0) {
            if (inputSchema.valueBlock.value[0] instanceof Repeated) {
                maxLength = inputData.valueBlock.value.length;
            }
        }
        if (maxLength === 0) {
            return {
                verified: true,
                result: root,
            };
        }
        if ((inputData.valueBlock.value.length === 0)
            && (inputSchema.valueBlock.value.length !== 0)) {
            let _optional = true;
            for (let i = 0; i < inputSchema.valueBlock.value.length; i++)
                _optional = _optional && (inputSchema.valueBlock.value[i].optional || false);
            if (_optional) {
                return {
                    verified: true,
                    result: root,
                };
            }
            if (inputSchema.name) {
                inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                if (inputSchema.name)
                    delete root[inputSchema.name];
            }
            root.error = "Inconsistent object length";
            return {
                verified: false,
                result: root,
            };
        }
        for (let i = 0; i < maxLength; i++) {
            if ((i - admission) >= inputData.valueBlock.value.length) {
                if (inputSchema.valueBlock.value[i].optional === false) {
                    const _result = {
                        verified: false,
                        result: root,
                    };
                    root.error = "Inconsistent length between ASN.1 data and schema";
                    if (inputSchema.name) {
                        inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                        if (inputSchema.name) {
                            delete root[inputSchema.name];
                            _result.name = inputSchema.name;
                        }
                    }
                    return _result;
                }
            }
            else {
                if (inputSchema.valueBlock.value[0] instanceof Repeated) {
                    result = compareSchema(root, inputData.valueBlock.value[i], inputSchema.valueBlock.value[0].value);
                    if (result.verified === false) {
                        if (inputSchema.valueBlock.value[0].optional)
                            admission++;
                        else {
                            if (inputSchema.name) {
                                inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                                if (inputSchema.name)
                                    delete root[inputSchema.name];
                            }
                            return result;
                        }
                    }
                    if ((NAME in inputSchema.valueBlock.value[0]) && (inputSchema.valueBlock.value[0].name.length > 0)) {
                        let arrayRoot = {};
                        if ((LOCAL in inputSchema.valueBlock.value[0]) && (inputSchema.valueBlock.value[0].local))
                            arrayRoot = inputData;
                        else
                            arrayRoot = root;
                        if (typeof arrayRoot[inputSchema.valueBlock.value[0].name] === "undefined")
                            arrayRoot[inputSchema.valueBlock.value[0].name] = [];
                        arrayRoot[inputSchema.valueBlock.value[0].name].push(inputData.valueBlock.value[i]);
                    }
                }
                else {
                    result = compareSchema(root, inputData.valueBlock.value[i - admission], inputSchema.valueBlock.value[i]);
                    if (result.verified === false) {
                        if (inputSchema.valueBlock.value[i].optional)
                            admission++;
                        else {
                            if (inputSchema.name) {
                                inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                                if (inputSchema.name)
                                    delete root[inputSchema.name];
                            }
                            return result;
                        }
                    }
                }
            }
        }
        if (result.verified === false) {
            const _result = {
                verified: false,
                result: root,
            };
            if (inputSchema.name) {
                inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                if (inputSchema.name) {
                    delete root[inputSchema.name];
                    _result.name = inputSchema.name;
                }
            }
            return _result;
        }
        return {
            verified: true,
            result: root,
        };
    }
    if (inputSchema.primitiveSchema
        && (VALUE_HEX_VIEW in inputData.valueBlock)) {
        const asn1 = localFromBER(inputData.valueBlock.valueHexView);
        if (asn1.offset === -1) {
            const _result = {
                verified: false,
                result: asn1.result,
            };
            if (inputSchema.name) {
                inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING$1);
                if (inputSchema.name) {
                    delete root[inputSchema.name];
                    _result.name = inputSchema.name;
                }
            }
            return _result;
        }
        return compareSchema(root, asn1.result, inputSchema.primitiveSchema);
    }
    return {
        verified: true,
        result: root,
    };
}

const EMPTY_BUFFER = new ArrayBuffer(0);
const EMPTY_STRING = "";

class ArgumentError extends TypeError {
    constructor() {
        super(...arguments);
        this.name = ArgumentError.NAME;
    }
    static isType(value, type) {
        if (typeof type === "string") {
            if (type === "Array" && Array.isArray(value)) {
                return true;
            }
            else if (type === "ArrayBuffer" && value instanceof ArrayBuffer) {
                return true;
            }
            else if (type === "ArrayBufferView" && ArrayBuffer.isView(value)) {
                return true;
            }
            else if (typeof value === type) {
                return true;
            }
        }
        else if (value instanceof type) {
            return true;
        }
        return false;
    }
    static assert(value, name, ...types) {
        for (const type of types) {
            if (this.isType(value, type)) {
                return;
            }
        }
        const typeNames = types.map(o => o instanceof Function && "name" in o ? o.name : `${o}`);
        throw new ArgumentError(`Parameter '${name}' is not of type ${typeNames.length > 1 ? `(${typeNames.join(" or ")})` : typeNames[0]}`);
    }
}
ArgumentError.NAME = "ArgumentError";

class ParameterError extends TypeError {
    static assert(...args) {
        let target = null;
        let params;
        let fields;
        if (typeof args[0] === "string") {
            target = args[0];
            params = args[1];
            fields = args.slice(2);
        }
        else {
            params = args[0];
            fields = args.slice(1);
        }
        ArgumentError.assert(params, "parameters", "object");
        for (const field of fields) {
            const value = params[field];
            if (value === undefined || value === null) {
                throw new ParameterError(field, target);
            }
        }
    }
    static assertEmpty(value, name, target) {
        if (value === undefined || value === null) {
            throw new ParameterError(name, target);
        }
    }
    constructor(field, target = null, message) {
        super();
        this.name = ParameterError.NAME;
        this.field = field;
        if (target) {
            this.target = target;
        }
        if (message) {
            this.message = message;
        }
        else {
            this.message = `Absent mandatory parameter '${field}' ${target ? ` in '${target}'` : EMPTY_STRING}`;
        }
    }
}
ParameterError.NAME = "ParameterError";

class AsnError extends Error {
    static assertSchema(asn1, target) {
        if (!asn1.verified) {
            throw new Error(`Object's schema was not verified against input data for ${target}`);
        }
    }
    static assert(asn, target) {
        if (asn.offset === -1) {
            throw new AsnError(`Error during parsing of ASN.1 data. Data is not correct for '${target}'.`);
        }
    }
    constructor(message) {
        super(message);
        this.name = "AsnError";
    }
}

class PkiObject {
    static blockName() {
        return this.CLASS_NAME;
    }
    static fromBER(raw) {
        const asn1 = fromBER(raw);
        AsnError.assert(asn1, this.name);
        try {
            return new this({ schema: asn1.result });
        }
        catch (e) {
            throw new AsnError(`Cannot create '${this.CLASS_NAME}' from ASN.1 object`);
        }
    }
    static defaultValues(memberName) {
        throw new Error(`Invalid member name for ${this.CLASS_NAME} class: ${memberName}`);
    }
    static schema(parameters = {}) {
        throw new Error(`Method '${this.CLASS_NAME}.schema' should be overridden`);
    }
    get className() {
        return this.constructor.CLASS_NAME;
    }
    toString(encoding = "hex") {
        let schema;
        try {
            schema = this.toSchema();
        }
        catch {
            schema = this.toSchema(true);
        }
        return Convert.ToString(schema.toBER(), encoding);
    }
}
PkiObject.CLASS_NAME = "PkiObject";

function stringPrep(inputString) {
    let isSpace = false;
    let cutResult = EMPTY_STRING;
    const result = inputString.trim();
    for (let i = 0; i < result.length; i++) {
        if (result.charCodeAt(i) === 32) {
            if (isSpace === false)
                isSpace = true;
        }
        else {
            if (isSpace) {
                cutResult += " ";
                isSpace = false;
            }
            cutResult += result[i];
        }
    }
    return cutResult.toLowerCase();
}

const TYPE$5 = "type";
const VALUE$6 = "value";
class AttributeTypeAndValue extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.type = getParametersValue(parameters, TYPE$5, AttributeTypeAndValue.defaultValues(TYPE$5));
        this.value = getParametersValue(parameters, VALUE$6, AttributeTypeAndValue.defaultValues(VALUE$6));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TYPE$5:
                return EMPTY_STRING;
            case VALUE$6:
                return {};
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.type || EMPTY_STRING) }),
                new Any({ name: (names.value || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            TYPE$5,
            "typeValue"
        ]);
        const asn1 = compareSchema(schema, schema, AttributeTypeAndValue.schema({
            names: {
                type: TYPE$5,
                value: "typeValue"
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.type = asn1.result.type.valueBlock.toString();
        this.value = asn1.result.typeValue;
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.type }),
                this.value
            ]
        }));
    }
    toJSON() {
        const _object = {
            type: this.type
        };
        if (Object.keys(this.value).length !== 0) {
            _object.value = (this.value).toJSON();
        }
        else {
            _object.value = this.value;
        }
        return _object;
    }
    isEqual(compareTo) {
        const stringBlockNames = [
            Utf8String.blockName(),
            BmpString.blockName(),
            UniversalString.blockName(),
            NumericString.blockName(),
            PrintableString.blockName(),
            TeletexString.blockName(),
            VideotexString.blockName(),
            IA5String.blockName(),
            GraphicString.blockName(),
            VisibleString.blockName(),
            GeneralString.blockName(),
            CharacterString.blockName()
        ];
        if (compareTo instanceof ArrayBuffer) {
            return BufferSourceConverter.isEqual(this.value.valueBeforeDecodeView, compareTo);
        }
        if (compareTo.constructor.blockName() === AttributeTypeAndValue.blockName()) {
            if (this.type !== compareTo.type)
                return false;
            const isStringPair = [false, false];
            const thisName = this.value.constructor.blockName();
            for (const name of stringBlockNames) {
                if (thisName === name) {
                    isStringPair[0] = true;
                }
                if (compareTo.value.constructor.blockName() === name) {
                    isStringPair[1] = true;
                }
            }
            if (isStringPair[0] !== isStringPair[1]) {
                return false;
            }
            const isString = (isStringPair[0] && isStringPair[1]);
            if (isString) {
                const value1 = stringPrep(this.value.valueBlock.value);
                const value2 = stringPrep(compareTo.value.valueBlock.value);
                if (value1.localeCompare(value2) !== 0)
                    return false;
            }
            else {
                if (!BufferSourceConverter.isEqual(this.value.valueBeforeDecodeView, compareTo.value.valueBeforeDecodeView))
                    return false;
            }
            return true;
        }
        return false;
    }
}
AttributeTypeAndValue.CLASS_NAME = "AttributeTypeAndValue";

const TYPE_AND_VALUES = "typesAndValues";
const VALUE_BEFORE_DECODE = "valueBeforeDecode";
const RDN = "RDN";
class RelativeDistinguishedNames extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.typesAndValues = getParametersValue(parameters, TYPE_AND_VALUES, RelativeDistinguishedNames.defaultValues(TYPE_AND_VALUES));
        this.valueBeforeDecode = getParametersValue(parameters, VALUE_BEFORE_DECODE, RelativeDistinguishedNames.defaultValues(VALUE_BEFORE_DECODE));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TYPE_AND_VALUES:
                return [];
            case VALUE_BEFORE_DECODE:
                return EMPTY_BUFFER;
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case TYPE_AND_VALUES:
                return (memberValue.length === 0);
            case VALUE_BEFORE_DECODE:
                return (memberValue.byteLength === 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.repeatedSequence || EMPTY_STRING),
                    value: new Set({
                        value: [
                            new Repeated({
                                name: (names.repeatedSet || EMPTY_STRING),
                                value: AttributeTypeAndValue.schema(names.typeAndValue || {})
                            })
                        ]
                    })
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            RDN,
            TYPE_AND_VALUES
        ]);
        const asn1 = compareSchema(schema, schema, RelativeDistinguishedNames.schema({
            names: {
                blockName: RDN,
                repeatedSet: TYPE_AND_VALUES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (TYPE_AND_VALUES in asn1.result) {
            this.typesAndValues = Array.from(asn1.result.typesAndValues, element => new AttributeTypeAndValue({ schema: element }));
        }
        this.valueBeforeDecode = asn1.result.RDN.valueBeforeDecodeView.slice().buffer;
    }
    toSchema() {
        if (this.valueBeforeDecode.byteLength === 0) {
            return (new Sequence({
                value: [new Set({
                        value: Array.from(this.typesAndValues, o => o.toSchema())
                    })]
            }));
        }
        const asn1 = fromBER(this.valueBeforeDecode);
        AsnError.assert(asn1, "RelativeDistinguishedNames");
        if (!(asn1.result instanceof Sequence)) {
            throw new Error("ASN.1 result should be SEQUENCE");
        }
        return asn1.result;
    }
    toJSON() {
        return {
            typesAndValues: Array.from(this.typesAndValues, o => o.toJSON())
        };
    }
    isEqual(compareTo) {
        if (compareTo instanceof RelativeDistinguishedNames) {
            if (this.typesAndValues.length !== compareTo.typesAndValues.length)
                return false;
            for (const [index, typeAndValue] of this.typesAndValues.entries()) {
                if (typeAndValue.isEqual(compareTo.typesAndValues[index]) === false)
                    return false;
            }
            return true;
        }
        if (compareTo instanceof ArrayBuffer) {
            return isEqualBuffer(this.valueBeforeDecode, compareTo);
        }
        return false;
    }
}
RelativeDistinguishedNames.CLASS_NAME = "RelativeDistinguishedNames";

const TYPE$4 = "type";
const VALUE$5 = "value";
function builtInStandardAttributes(parameters = {}, optional = false) {
    const names = getParametersValue(parameters, "names", {});
    return (new Sequence({
        optional,
        value: [
            new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 2,
                    tagNumber: 1
                },
                name: (names.country_name || EMPTY_STRING),
                value: [
                    new Choice({
                        value: [
                            new NumericString(),
                            new PrintableString()
                        ]
                    })
                ]
            }),
            new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 2,
                    tagNumber: 2
                },
                name: (names.administration_domain_name || EMPTY_STRING),
                value: [
                    new Choice({
                        value: [
                            new NumericString(),
                            new PrintableString()
                        ]
                    })
                ]
            }),
            new Primitive({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                name: (names.network_address || EMPTY_STRING),
                isHexOnly: true
            }),
            new Primitive({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                name: (names.terminal_identifier || EMPTY_STRING),
                isHexOnly: true
            }),
            new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                name: (names.private_domain_name || EMPTY_STRING),
                value: [
                    new Choice({
                        value: [
                            new NumericString(),
                            new PrintableString()
                        ]
                    })
                ]
            }),
            new Primitive({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 3
                },
                name: (names.organization_name || EMPTY_STRING),
                isHexOnly: true
            }),
            new Primitive({
                optional: true,
                name: (names.numeric_user_identifier || EMPTY_STRING),
                idBlock: {
                    tagClass: 3,
                    tagNumber: 4
                },
                isHexOnly: true
            }),
            new Constructed({
                optional: true,
                name: (names.personal_name || EMPTY_STRING),
                idBlock: {
                    tagClass: 3,
                    tagNumber: 5
                },
                value: [
                    new Primitive({
                        idBlock: {
                            tagClass: 3,
                            tagNumber: 0
                        },
                        isHexOnly: true
                    }),
                    new Primitive({
                        optional: true,
                        idBlock: {
                            tagClass: 3,
                            tagNumber: 1
                        },
                        isHexOnly: true
                    }),
                    new Primitive({
                        optional: true,
                        idBlock: {
                            tagClass: 3,
                            tagNumber: 2
                        },
                        isHexOnly: true
                    }),
                    new Primitive({
                        optional: true,
                        idBlock: {
                            tagClass: 3,
                            tagNumber: 3
                        },
                        isHexOnly: true
                    })
                ]
            }),
            new Constructed({
                optional: true,
                name: (names.organizational_unit_names || EMPTY_STRING),
                idBlock: {
                    tagClass: 3,
                    tagNumber: 6
                },
                value: [
                    new Repeated({
                        value: new PrintableString()
                    })
                ]
            })
        ]
    }));
}
function builtInDomainDefinedAttributes(optional = false) {
    return (new Sequence({
        optional,
        value: [
            new PrintableString(),
            new PrintableString()
        ]
    }));
}
function extensionAttributes(optional = false) {
    return (new Set({
        optional,
        value: [
            new Primitive({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                isHexOnly: true
            }),
            new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: [new Any()]
            })
        ]
    }));
}
class GeneralName extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.type = getParametersValue(parameters, TYPE$4, GeneralName.defaultValues(TYPE$4));
        this.value = getParametersValue(parameters, VALUE$5, GeneralName.defaultValues(VALUE$5));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TYPE$4:
                return 9;
            case VALUE$5:
                return {};
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case TYPE$4:
                return (memberValue === GeneralName.defaultValues(memberName));
            case VALUE$5:
                return (Object.keys(memberValue).length === 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Choice({
            value: [
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    name: (names.blockName || EMPTY_STRING),
                    value: [
                        new ObjectIdentifier(),
                        new Constructed({
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 0
                            },
                            value: [new Any()]
                        })
                    ]
                }),
                new Primitive({
                    name: (names.blockName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                }),
                new Primitive({
                    name: (names.blockName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    }
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 3
                    },
                    name: (names.blockName || EMPTY_STRING),
                    value: [
                        builtInStandardAttributes((names.builtInStandardAttributes || {}), false),
                        builtInDomainDefinedAttributes(true),
                        extensionAttributes(true)
                    ]
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 4
                    },
                    name: (names.blockName || EMPTY_STRING),
                    value: [RelativeDistinguishedNames.schema(names.directoryName || {})]
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 5
                    
                    name: (names.blockName *  copyright
value
                        new Constructed({
                            optional: true,
                            idBlock: {

                                tagNumber: 0
                            },
                            value: [
                                new Choice({
                                    value: [
                                        new TeletexString(),
                                        new PrintableString(),
                                        new UniversalString(),
                                        new Utf8String(),
                                        new BmpString()
                                    ]
                                })
                            ]
                        }),
                        new Constructed({
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 1
                            },
                            value: [
                                new Choice({
                                    value: [
                                        new TeletexString(),
                                        new PrintableString(),
                                        new UniversalString(),
                                        new Utf8String(),
                                        new BmpString()
                                    ]
                                })
                            ]
                        })
                    ]
                }),
                new Primitive({
                    name: (names.blockName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 6
                    }
                }),
                new Primitive({
                    name: (names.blockName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 7
                    }
                }),
                new Primitive({
                    name: (names.blockName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 8
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            "blockName",
            "otherName",
            "rfc822Name",
            "dNSName",
            "x400Address",
            "directoryName",
            "ediPartyName",
            "uniformResourceIdentifier",
            "iPAddress",
            "registeredID"
        ]);
        const asn1 = compareSchema(schema, schema, GeneralName.schema({
            names: {
                blockName: "blockName",
                otherName: "otherName",
                rfc822Name: "rfc822Name",
                dNSName: "dNSName",
                x400Address: "x400Address",
                directoryName: {
                    names: {
                        blockName: "directoryName"
                    }
                },
                ediPartyName: "ediPartyName",
                uniformResourceIdentifier: "uniformResourceIdentifier",
                iPAddress: "iPAddress",
                registeredID: "registeredID"
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.type = asn1.result.blockName.idBlock.tagNumber;
        switch (this.type) {
            case 0:
                this.value = asn1.result.blockName;
                break;
            case 1:
            case 2:
            case 6:
                {
                    const value = asn1.result.blockName;
                    value.idBlock.tagClass = 1;
                    value.idBlock.tagNumber = 22;
                    const valueBER = value.toBER(false);
                    const asnValue = fromBER(valueBER);
                    AsnError.assert(asnValue, "GeneralName value");
                    this.value = asnValue.result.valueBlock.value;
                }
                break;
            case 3:
                this.value = asn1.result.blockName;
                break;
            case 4:
                this.value = new RelativeDistinguishedNames({ schema: asn1.result.directoryName });
                break;
            case 5:
                this.value = asn1.result.ediPartyName;
                break;
            case 7:
                this.value = new OctetString({ valueHex: asn1.result.blockName.valueBlock.valueHex });
                break;
            case 8:
                {
                    const value = asn1.result.blockName;
                    value.idBlock.tagClass = 1;
                    value.idBlock.tagNumber = 6;
                    const valueBER = value.toBER(false);
                    const asnValue = fromBER(valueBER);
                    AsnError.assert(asnValue, "GeneralName registeredID");
                    this.value = asnValue.result.valueBlock.toString();
                }
                break;
        }
    }
    toSchema() {
        switch (this.type) {
            case 0:
            case 3:
            case 5:
                return new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: this.type
                    },
                    value: [
                        this.value
                    ]
                });
            case 1:
            case 2:
            case 6:
                {
                    const value = new IA5String({ value: this.value });
                    value.idBlock.tagClass = 3;
                    value.idBlock.tagNumber = this.type;
                    return value;
                }
            case 4:
                return new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 4
                    },
                    value: [this.value.toSchema()]
                });
            case 7:
                {
                    const value = this.value;
                    value.idBlock.tagClass = 3;
                    value.idBlock.tagNumber = this.type;
                    return value;
                }
            case 8:
                {
                    const value = new ObjectIdentifier({ value: this.value });
                    value.idBlock.tagClass = 3;
                    value.idBlock.tagNumber = this.type;
                    return value;
                }
            default:
                return GeneralName.schema();
        }
    }
    toJSON() {
        const _object = {
            type: this.type,
            value: EMPTY_STRING
        };
        if ((typeof this.value) === "string")
            _object.value = this.value;
        else {
            try {
                _object.value = this.value.toJSON();
            }
            catch {
            }
        }
        return _object;
    }
}
GeneralName.CLASS_NAME = "GeneralName";

const ACCESS_METHOD = "accessMethod";
const ACCESS_LOCATION = "accessLocation";
const CLEAR_PROPS$1v = [
    ACCESS_METHOD,
    ACCESS_LOCATION,
];
class AccessDescription extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.accessMethod = getParametersValue(parameters, ACCESS_METHOD, AccessDescription.defaultValues(ACCESS_METHOD));
        this.accessLocation = getParametersValue(parameters, ACCESS_LOCATION, AccessDescription.defaultValues(ACCESS_LOCATION));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ACCESS_METHOD:
                return EMPTY_STRING;
            case ACCESS_LOCATION:
                return new GeneralName();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.accessMethod || EMPTY_STRING) }),
                GeneralName.schema(names.accessLocation || {})
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1v);
        const asn1 = compareSchema(schema, schema, AccessDescription.schema({
            names: {
                accessMethod: ACCESS_METHOD,
                accessLocation: {
                    names: {
                        blockName: ACCESS_LOCATION
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.accessMethod = asn1.result.accessMethod.valueBlock.toString();
        this.accessLocation = new GeneralName({ schema: asn1.result.accessLocation });
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.accessMethod }),
                this.accessLocation.toSchema()
            ]
        }));
    }
    toJSON() {
        return {
            accessMethod: this.accessMethod,
            accessLocation: this.accessLocation.toJSON()
        };
    }
}
AccessDescription.CLASS_NAME = "AccessDescription";

const SECONDS = "seconds";
const MILLIS = "millis";
const MICROS = "micros";
class Accuracy extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (SECONDS in parameters) {
            this.seconds = getParametersValue(parameters, SECONDS, Accuracy.defaultValues(SECONDS));
        }
        if (MILLIS in parameters) {
            this.millis = getParametersValue(parameters, MILLIS, Accuracy.defaultValues(MILLIS));
        }
        if (MICROS in parameters) {
            this.micros = getParametersValue(parameters, MICROS, Accuracy.defaultValues(MICROS));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case SECONDS:
            case MILLIS:
            case MICROS:
                return 0;
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case SECONDS:
            case MILLIS:
            case MICROS:
                return (memberValue === Accuracy.defaultValues(memberName));
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            optional: true,
            value: [
                new Integer({
                    optional: true,
                    name: (names.seconds || EMPTY_STRING)
                }),
                new Primitive({
                    name: (names.millis || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    }
                }),
                new Primitive({
                    name: (names.micros || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            SECONDS,
            MILLIS,
            MICROS,
        ]);
        const asn1 = compareSchema(schema, schema, Accuracy.schema({
            names: {
                seconds: SECONDS,
                millis: MILLIS,
                micros: MICROS,
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if ("seconds" in asn1.result) {
            this.seconds = asn1.result.seconds.valueBlock.valueDec;
        }
        if ("millis" in asn1.result) {
            const intMillis = new Integer({ valueHex: asn1.result.millis.valueBlock.valueHex });
            this.millis = intMillis.valueBlock.valueDec;
        }
        if ("micros" in asn1.result) {
            const intMicros = new Integer({ valueHex: asn1.result.micros.valueBlock.valueHex });
            this.micros = intMicros.valueBlock.valueDec;
        }
    }
    toSchema() {
        const outputArray = [];
        if (this.seconds !== undefined)
            outputArray.push(new Integer({ value: this.seconds }));
        if (this.millis !== undefined) {
            const intMillis = new Integer({ value: this.millis });
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                valueHex: intMillis.valueBlock.valueHexView
            }));
        }
        if (this.micros !== undefined) {
            const intMicros = new Integer({ value: this.micros });
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                valueHex: intMicros.valueBlock.valueHexView
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const _object = {};
        if (this.seconds !== undefined)
            _object.seconds = this.seconds;
        if (this.millis !== undefined)
            _object.millis = this.millis;
        if (this.micros !== undefined)
            _object.micros = this.micros;
        return _object;
    }
}
Accuracy.CLASS_NAME = "Accuracy";

const ALGORITHM_ID = "algorithmId";
const ALGORITHM_PARAMS = "algorithmParams";
const ALGORITHM$2 = "algorithm";
const PARAMS = "params";
const CLEAR_PROPS$1u = [
    ALGORITHM$2,
    PARAMS
];
class AlgorithmIdentifier extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.algorithmId = getParametersValue(parameters, ALGORITHM_ID, AlgorithmIdentifier.defaultValues(ALGORITHM_ID));
        if (ALGORITHM_PARAMS in parameters) {
            this.algorithmParams = getParametersValue(parameters, ALGORITHM_PARAMS, AlgorithmIdentifier.defaultValues(ALGORITHM_PARAMS));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ALGORITHM_ID:
                return EMPTY_STRING;
            case ALGORITHM_PARAMS:
                return new Any();
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case ALGORITHM_ID:
                return (memberValue === EMPTY_STRING);
            case ALGORITHM_PARAMS:
                return (memberValue instanceof Any);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            optional: (names.optional || false),
            value: [
                new ObjectIdentifier({ name: (names.algorithmIdentifier || EMPTY_STRING) }),
                new Any({ name: (names.algorithmParams || EMPTY_STRING), optional: true })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1u);
        const asn1 = compareSchema(schema, schema, AlgorithmIdentifier.schema({
            names: {
                algorithmIdentifier: ALGORITHM$2,
                algorithmParams: PARAMS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.algorithmId = asn1.result.algorithm.valueBlock.toString();
        if (PARAMS in asn1.result) {
            this.algorithmParams = asn1.result.params;
        }
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(new ObjectIdentifier({ value: this.algorithmId }));
        if (this.algorithmParams && !(this.algorithmParams instanceof Any)) {
            outputArray.push(this.algorithmParams);
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {
            algorithmId: this.algorithmId
        };
        if (this.algorithmParams && !(this.algorithmParams instanceof Any)) {
            object.algorithmParams = this.algorithmParams.toJSON();
        }
        return object;
    }
    isEqual(algorithmIdentifier) {
        if (!(algorithmIdentifier instanceof AlgorithmIdentifier)) {
            return false;
        }
        if (this.algorithmId !== algorithmIdentifier.algorithmId) {
            return false;
        }
        if (this.algorithmParams) {
            if (algorithmIdentifier.algorithmParams) {
                return JSON.stringify(this.algorithmParams) === JSON.stringify(algorithmIdentifier.algorithmParams);
            }
            return false;
        }
        if (algorithmIdentifier.algorithmParams) {
            return false;
        }
        return true;
    }
}
AlgorithmIdentifier.CLASS_NAME = "AlgorithmIdentifier";

const ALT_NAMES = "altNames";
const CLEAR_PROPS$1t = [
    ALT_NAMES
];
class AltName extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.altNames = getParametersValue(parameters, ALT_NAMES, AltName.defaultValues(ALT_NAMES));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ALT_NAMES:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.altNames || EMPTY_STRING),
                    value: GeneralName.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1t);
        const asn1 = compareSchema(schema, schema, AltName.schema({
            names: {
                altNames: ALT_NAMES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (ALT_NAMES in asn1.result) {
            this.altNames = Array.from(asn1.result.altNames, element => new GeneralName({ schema: element }));
        }
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.altNames, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            altNames: Array.from(this.altNames, o => o.toJSON())
        };
    }
}
AltName.CLASS_NAME = "AltName";

const TYPE$3 = "type";
const VALUES$1 = "values";
const CLEAR_PROPS$1s = [
    TYPE$3,
    VALUES$1
];
class Attribute extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.type = getParametersValue(parameters, TYPE$3, Attribute.defaultValues(TYPE$3));
        this.values = getParametersValue(parameters, VALUES$1, Attribute.defaultValues(VALUES$1));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TYPE$3:
                return EMPTY_STRING;
            case VALUES$1:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case TYPE$3:
                return (memberValue === EMPTY_STRING);
            case VALUES$1:
                return (memberValue.length === 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.type || EMPTY_STRING) }),
                new Set({
                    name: (names.setName || EMPTY_STRING),
                    value: [
                        new Repeated({
                            name: (names.values || EMPTY_STRING),
                            value: new Any()
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1s);
        const asn1 = compareSchema(schema, schema, Attribute.schema({
            names: {
                type: TYPE$3,
                values: VALUES$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.type = asn1.result.type.valueBlock.toString();
        this.values = asn1.result.values;
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.type }),
                new Set({
                    value: this.values
                })
            ]
        }));
    }
    toJSON() {
        return {
            type: this.type,
            values: Array.from(this.values, o => o.toJSON())
        };
    }
}
Attribute.CLASS_NAME = "Attribute";

const NOT_BEFORE_TIME = "notBeforeTime";
const NOT_AFTER_TIME = "notAfterTime";
const CLEAR_PROPS$1r = [
    NOT_BEFORE_TIME,
    NOT_AFTER_TIME,
];
class AttCertValidityPeriod extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.notBeforeTime = getParametersValue(parameters, NOT_BEFORE_TIME, AttCertValidityPeriod.defaultValues(NOT_BEFORE_TIME));
        this.notAfterTime = getParametersValue(parameters, NOT_AFTER_TIME, AttCertValidityPeriod.defaultValues(NOT_AFTER_TIME));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case NOT_BEFORE_TIME:
            case NOT_AFTER_TIME:
                return new Date(0, 0, 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new GeneralizedTime({ name: (names.notBeforeTime || EMPTY_STRING) }),
                new GeneralizedTime({ name: (names.notAfterTime || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1r);
        const asn1 = compareSchema(schema, schema, AttCertValidityPeriod.schema({
            names: {
                notBeforeTime: NOT_BEFORE_TIME,
                notAfterTime: NOT_AFTER_TIME
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.notBeforeTime = asn1.result.notBeforeTime.toDate();
        this.notAfterTime = asn1.result.notAfterTime.toDate();
    }
    toSchema() {
        return (new Sequence({
            value: [
                new GeneralizedTime({ valueDate: this.notBeforeTime }),
                new GeneralizedTime({ valueDate: this.notAfterTime }),
            ]
        }));
    }
    toJSON() {
        return {
            notBeforeTime: this.notBeforeTime,
            notAfterTime: this.notAfterTime
        };
    }
}
AttCertValidityPeriod.CLASS_NAME = "AttCertValidityPeriod";

const NAMES = "names";
const GENERAL_NAMES = "generalNames";
class GeneralNames extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.names = getParametersValue(parameters, NAMES, GeneralNames.defaultValues(NAMES));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case "names":
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}, optional = false) {
        const names = getParametersValue(parameters, NAMES, {});
        return (new Sequence({
            optional,
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.generalNames || EMPTY_STRING),
                    value: GeneralName.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            NAMES,
            GENERAL_NAMES
        ]);
        const asn1 = compareSchema(schema, schema, GeneralNames.schema({
            names: {
                blockName: NAMES,
                generalNames: GENERAL_NAMES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.names = Array.from(asn1.result.generalNames, element => new GeneralName({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.names, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            names: Array.from(this.names, o => o.toJSON())
        };
    }
}
GeneralNames.CLASS_NAME = "GeneralNames";

const id_SubjectDirectoryAttributes = "2.5.29.9";
const id_SubjectKeyIdentifier = "2.5.29.14";
const id_KeyUsage = "2.5.29.15";
const id_PrivateKeyUsagePeriod = "2.5.29.16";
const id_SubjectAltName = "2.5.29.17";
const id_IssuerAltName = "2.5.29.18";
const id_BasicConstraints = "2.5.29.19";
const id_CRLNumber = "2.5.29.20";
const id_BaseCRLNumber = "2.5.29.27";
const id_CRLReason = "2.5.29.21";
const id_InvalidityDate = "2.5.29.24";
const id_IssuingDistributionPoint = "2.5.29.28";
const id_CertificateIssuer = "2.5.29.29";
const id_NameConstraints = "2.5.29.30";
const id_CRLDistributionPoints = "2.5.29.31";
const id_FreshestCRL = "2.5.29.46";
const id_CertificatePolicies = "2.5.29.32";
const id_AnyPolicy = "2.5.29.32.0";
const id_MicrosoftAppPolicies = "1.3.6.1.4.1.311.21.10";
const id_PolicyMappings = "2.5.29.33";
const id_AuthorityKeyIdentifier = "2.5.29.35";
const id_PolicyConstraints = "2.5.29.36";
const id_ExtKeyUsage = "2.5.29.37";
const id_InhibitAnyPolicy = "2.5.29.54";
const id_AuthorityInfoAccess = "1.3.6.1.5.5.7.1.1";
const id_SubjectInfoAccess = "1.3.6.1.5.5.7.1.11";
const id_SignedCertificateTimestampList = "1.3.6.1.4.1.11129.2.4.2";
const id_MicrosoftCertTemplateV1 = "1.3.6.1.4.1.311.20.2";
const id_MicrosoftPrevCaCertHash = "1.3.6.1.4.1.311.21.2";
const id_MicrosoftCertTemplateV2 = "1.3.6.1.4.1.311.21.7";
const id_MicrosoftCaVersion = "1.3.6.1.4.1.311.21.1";
const id_QCStatements = "1.3.6.1.5.5.7.1.3";
const id_ContentType_Data = "1.2.840.113549.1.7.1";
const id_ContentType_SignedData = "1.2.840.113549.1.7.2";
const id_ContentType_EnvelopedData = "1.2.840.113549.1.7.3";
const id_ContentType_EncryptedData = "1.2.840.113549.1.7.6";
const id_eContentType_TSTInfo = "1.2.840.113549.1.9.16.1.4";
const id_CertBag_X509Certificate = "1.2.840.113549.1.9.22.1";
const id_CertBag_SDSICertificate = "1.2.840.113549.1.9.22.2";
const id_CertBag_AttributeCertificate = "1.2.840.113549.1.9.22.3";
const id_CRLBag_X509CRL = "1.2.840.113549.1.9.23.1";
const id_pkix = "1.3.6.1.5.5.7";
const id_ad = `${id_pkix}.48`;
const id_PKIX_OCSP_Basic = `${id_ad}.1.1`;
const id_ad_caIssuers = `${id_ad}.2`;
const id_ad_ocsp = `${id_ad}.1`;
const id_sha1 = "1.3.14.3.2.26";
const id_sha256 = "2.16.840.1.101.3.4.2.1";
const id_sha384 = "2.16.840.1.101.3.4.2.2";
const id_sha512 = "2.16.840.1.101.3.4.2.3";

const KEY_IDENTIFIER$1 = "keyIdentifier";
const AUTHORITY_CERT_ISSUER = "authorityCertIssuer";
const AUTHORITY_CERT_SERIAL_NUMBER = "authorityCertSerialNumber";
const CLEAR_PROPS$1q = [
    KEY_IDENTIFIER$1,
    AUTHORITY_CERT_ISSUER,
    AUTHORITY_CERT_SERIAL_NUMBER,
];
class AuthorityKeyIdentifier extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (KEY_IDENTIFIER$1 in parameters) {
            this.keyIdentifier = getParametersValue(parameters, KEY_IDENTIFIER$1, AuthorityKeyIdentifier.defaultValues(KEY_IDENTIFIER$1));
        }
        if (AUTHORITY_CERT_ISSUER in parameters) {
            this.authorityCertIssuer = getParametersValue(parameters, AUTHORITY_CERT_ISSUER, AuthorityKeyIdentifier.defaultValues(AUTHORITY_CERT_ISSUER));
        }
        if (AUTHORITY_CERT_SERIAL_NUMBER in parameters) {
            this.authorityCertSerialNumber = getParametersValue(parameters, AUTHORITY_CERT_SERIAL_NUMBER, AuthorityKeyIdentifier.defaultValues(AUTHORITY_CERT_SERIAL_NUMBER));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case KEY_IDENTIFIER$1:
                return new OctetString();
            case AUTHORITY_CERT_ISSUER:
                return [];
            case AUTHORITY_CERT_SERIAL_NUMBER:
                return new Integer();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Primitive({
                    name: (names.keyIdentifier || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    }
                }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: [
                        new Repeated({
                            name: (names.authorityCertIssuer || EMPTY_STRING),
                            value: GeneralName.schema()
                        })
                    ]
                }),
                new Primitive({
                    name: (names.authorityCertSerialNumber || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1q);
        const asn1 = compareSchema(schema, schema, AuthorityKeyIdentifier.schema({
            names: {
                keyIdentifier: KEY_IDENTIFIER$1,
                authorityCertIssuer: AUTHORITY_CERT_ISSUER,
                authorityCertSerialNumber: AUTHORITY_CERT_SERIAL_NUMBER
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (KEY_IDENTIFIER$1 in asn1.result)
            this.keyIdentifier = new OctetString({ valueHex: asn1.result.keyIdentifier.valueBlock.valueHex });
        if (AUTHORITY_CERT_ISSUER in asn1.result)
            this.authorityCertIssuer = Array.from(asn1.result.authorityCertIssuer, o => new GeneralName({ schema: o }));
        if (AUTHORITY_CERT_SERIAL_NUMBER in asn1.result)
            this.authorityCertSerialNumber = new Integer({ valueHex: asn1.result.authorityCertSerialNumber.valueBlock.valueHex });
    }
    toSchema() {
        const outputArray = [];
        if (this.keyIdentifier) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                valueHex: this.keyIdentifier.valueBlock.valueHexView
            }));
        }
        if (this.authorityCertIssuer) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: Array.from(this.authorityCertIssuer, o => o.toSchema())
            }));
        }
        if (this.authorityCertSerialNumber) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                valueHex: this.authorityCertSerialNumber.valueBlock.valueHexView
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {};
        if (this.keyIdentifier) {
            object.keyIdentifier = this.keyIdentifier.toJSON();
        }
        if (this.authorityCertIssuer) {
            object.authorityCertIssuer = Array.from(this.authorityCertIssuer, o => o.toJSON());
        }
        if (this.authorityCertSerialNumber) {
            object.authorityCertSerialNumber = this.authorityCertSerialNumber.toJSON();
        }
        return object;
    }
}
AuthorityKeyIdentifier.CLASS_NAME = "AuthorityKeyIdentifier";

const PATH_LENGTH_CONSTRAINT = "pathLenConstraint";
const CA = "cA";
class BasicConstraints extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.cA = getParametersValue(parameters, CA, false);
        if (PATH_LENGTH_CONSTRAINT in parameters) {
            this.pathLenConstraint = getParametersValue(parameters, PATH_LENGTH_CONSTRAINT, 0);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case CA:
                return false;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
         rb_range_size,)java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
new(
            name: (names )
             range_it_remove )
                new(java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29

        :cA|)
                }),
                 )java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
optionaljava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
                    name names.pathLenConstraint| EMPTY_STRING
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            CA,
            PATH_LENGTH_CONSTRAINT
        ]);
        const asn1 = compareSchema(schema, schema, BasicConstraints.schema({
            names: {
                cA: CA,
                pathLenConstraint: PATH_LENGTH_CONSTRAINT
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (CA in asn1.result) {
            this.cA = asn1.result.cA.valueBlock.value;
        }
        if (PATH_LENGTH_CONSTRAINT in asn1.result) {
            if (asn1.result.pathLenConstraint.valueBlock.isHexOnly) {
                this.pathLenConstraint = asn1.result.pathLenConstraint;
            }
            else {
                this.pathLenConstraint = asn1.result.pathLenConstraint.valueBlock.valueDec;
            }
        }
    }
    toSchema() {
        const outputArray = [];
        if (this.cA !== BasicConstraints.defaultValues(CA))
            outputArray.push(new Boolean({ value: this.cA }));
        if (PATH_LENGTH_CONSTRAINT in this) {
            if (this.pathLenConstraint instanceof Integer) {
                outputArray.push(this.pathLenConstraint);
            }
            else {
                outputArray.push(new Integer({ value: this.pathLenConstraint }));
            }
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {};
        if (this.cA !== BasicConstraints.defaultValues(CA)) {
            object.cA = this.cA;
        }
        if (PATH_LENGTH_CONSTRAINT in this) {
            if (this.pathLenConstraint instanceof Integer) {
                object.pathLenConstraint = this.pathLenConstraint.toJSON();
            }
            else {
                object.pathLenConstraint = this.pathLenConstraint;
            }
        }
        return object;
    }
}
BasicConstraints.CLASS_NAME = "BasicConstraints";

const CERTIFICATE_INDEX = "certificateIndex";
const KEY_INDEX = "keyIndex";
class CAVersion extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.certificateIndex = getParametersValue(parameters, CERTIFICATE_INDEX, CAVersion.defaultValues(CERTIFICATE_INDEX));
        this.keyIndex = getParametersValue(parameters, KEY_INDEX, CAVersion.defaultValues(KEY_INDEX));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case CERTIFICATE_INDEX:
            case KEY_INDEX:
                return 0;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema() {
        return (new Integer());
    }
    fromSchema(schema) {
        if (schema.constructor.blockName() !== Integer.blockName()) {
            throw new Error("Object's schema was not verified against input data for CAVersion");
        }
        let value = schema.valueBlock.valueHex.slice(0);
        const valueView = new Uint8Array(value);
        switch (true) {
            case (value.byteLength < 4):
                {
                    const tempValue = new ArrayBuffer(4);
                    const tempValueView = new Uint8Array(tempValue);
                    tempValueView.set(valueView, 4 - value.byteLength);
                    value = tempValue.slice(0);
                }
                break;
            case (value.byteLength > 4):
                {
                    const tempValue = new ArrayBuffer(4);
                    const tempValueView = new Uint8Array(tempValue);
                    tempValueView.set(valueView.slice(0, 4));
                    value = tempValue.slice(0);
                }
                break;
        }
        const keyIndexBuffer = value.slice(0, 2);
        const keyIndexView8 = new Uint8Array(keyIndexBuffer);
        let temp = keyIndexView8[0];
        keyIndexView8[0] = keyIndexView8[1];
        keyIndexView8[1] = temp;
        const keyIndexView16 = new Uint16Array(keyIndexBuffer);
        this.keyIndex = keyIndexView16[0];
        const certificateIndexBuffer = value.slice(2);
        const certificateIndexView8 = new Uint8Array(certificateIndexBuffer);
        temp = certificateIndexView8[0];
        certificateIndexView8[0] = certificateIndexView8[1];
        certificateIndexView8[1] = temp;
        const certificateIndexView16 = new Uint16Array(certificateIndexBuffer);
        this.certificateIndex = certificateIndexView16[0];
    }
    toSchema() {
        const certificateIndexBuffer = new ArrayBuffer(2);
        const certificateIndexView = new Uint16Array(certificateIndexBuffer);
        certificateIndexView[0] = this.certificateIndex;
        const certificateIndexView8 = new Uint8Array(certificateIndexBuffer);
        let temp = certificateIndexView8[0];
        certificateIndexView8[0] = certificateIndexView8[1];
        certificateIndexView8[1] = temp;
        const keyIndexBuffer = new ArrayBuffer(2);
        const keyIndexView = new Uint16Array(keyIndexBuffer);
        keyIndexView[0] = this.keyIndex;
        const keyIndexView8 = new Uint8Array(keyIndexBuffer);
        temp = keyIndexView8[0];
        keyIndexView8[0] = keyIndexView8[1];
        keyIndexView8[1] = temp;
        return (new Integer({
            valueHex: utilConcatBuf(keyIndexBuffer, certificateIndexBuffer)
        }));
    }
    toJSON() {
        return {
            certificateIndex: this.certificateIndex,
            keyIndex: this.keyIndex
        };
    }
}
CAVersion.CLASS_NAME = "CAVersion";

const POLICY_QUALIFIER_ID = "policyQualifierId";
const QUALIFIER = "qualifier";
const CLEAR_PROPS$1p = [
    POLICY_QUALIFIER_ID,
    QUALIFIER
];
class PolicyQualifierInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.policyQualifierId = getParametersValue(parameters, POLICY_QUALIFIER_ID, PolicyQualifierInfo.defaultValues(POLICY_QUALIFIER_ID));
        this.qualifier = getParametersValue(parameters, QUALIFIER, PolicyQualifierInfo.defaultValues(QUALIFIER));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case POLICY_QUALIFIER_ID:
                return EMPTY_STRING;
            case QUALIFIER:
                return new Any();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.policyQualifierId || EMPTY_STRING) }),
                new Any({ name: (names.qualifier || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1p);
        const asn1 = compareSchema(schema, schema, PolicyQualifierInfo.schema({
            names: {
                policyQualifierId: POLICY_QUALIFIER_ID,
                qualifier: QUALIFIER
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.policyQualifierId = asn1.result.policyQualifierId.valueBlock.toString();
        this.qualifier = asn1.result.qualifier;
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.policyQualifierId }),
                this.qualifier
            ]
        }));
    }
    toJSON() {
        return {
            policyQualifierId: this.policyQualifierId,
            qualifier: this.qualifier.toJSON()
        };
    }
}
PolicyQualifierInfo.CLASS_NAME = "PolicyQualifierInfo";

const POLICY_IDENTIFIER = "policyIdentifier";
const POLICY_QUALIFIERS = "policyQualifiers";
const CLEAR_PROPS$1o = [
    POLICY_IDENTIFIER,
    POLICY_QUALIFIERS
];
class PolicyInformation extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.policyIdentifier = getParametersValue(parameters, POLICY_IDENTIFIER, PolicyInformation.defaultValues(POLICY_IDENTIFIER));
        if (POLICY_QUALIFIERS in parameters) {
            this.policyQualifiers = getParametersValue(parameters, POLICY_QUALIFIERS, PolicyInformation.defaultValues(POLICY_QUALIFIERS));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case POLICY_IDENTIFIER:
                return EMPTY_STRING;
            case POLICY_QUALIFIERS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.policyIdentifier || EMPTY_STRING) }),
                new Sequence({
                    optional: true,
                    value: [
                        new Repeated({
                            name: (names.policyQualifiers || EMPTY_STRING),
                            value: PolicyQualifierInfo.schema()
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1o);
        const asn1 = compareSchema(schema, schema, PolicyInformation.schema({
            names: {
                policyIdentifier: POLICY_IDENTIFIER,
                policyQualifiers: POLICY_QUALIFIERS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.policyIdentifier = asn1.result.policyIdentifier.valueBlock.toString();
        if (POLICY_QUALIFIERS in asn1.result) {
            this.policyQualifiers = Array.from(asn1.result.policyQualifiers, element => new PolicyQualifierInfo({ schema: element }));
        }
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(new ObjectIdentifier({ value: this.policyIdentifier }));
        if (this.policyQualifiers) {
            outputArray.push(new Sequence({
                value: Array.from(this.policyQualifiers, o => o.toSchema())
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {
            policyIdentifier: this.policyIdentifier
        };
        if (this.policyQualifiers)
            res.policyQualifiers = Array.from(this.policyQualifiers, o => o.toJSON());
        return res;
    }
}
PolicyInformation.CLASS_NAME = "PolicyInformation";

const CERTIFICATE_POLICIES = "certificatePolicies";
const CLEAR_PROPS$1n = [
    CERTIFICATE_POLICIES,
];
class CertificatePolicies extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.certificatePolicies = getParametersValue(parameters, CERTIFICATE_POLICIES, CertificatePolicies.defaultValues(CERTIFICATE_POLICIES));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case CERTIFICATE_POLICIES:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.certificatePolicies || EMPTY_STRING),
                    value: PolicyInformation.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1n);
        const asn1 = compareSchema(schema, schema, CertificatePolicies.schema({
            names: {
                certificatePolicies: CERTIFICATE_POLICIES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.certificatePolicies = Array.from(asn1.result.certificatePolicies, element => new PolicyInformation({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.certificatePolicies, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            certificatePolicies: Array.from(this.certificatePolicies, o => o.toJSON())
        };
    }
}
CertificatePolicies.CLASS_NAME = "CertificatePolicies";

const TEMPLATE_ID = "templateID";
const TEMPLATE_MAJOR_VERSION = "templateMajorVersion";
const TEMPLATE_MINOR_VERSION = "templateMinorVersion";
const CLEAR_PROPS$1m = [
    TEMPLATE_ID,
    TEMPLATE_MAJOR_VERSION,
    TEMPLATE_MINOR_VERSION
];
class CertificateTemplate extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.templateID = getParametersValue(parameters, TEMPLATE_ID, CertificateTemplate.defaultValues(TEMPLATE_ID));
        if (TEMPLATE_MAJOR_VERSION in parameters) {
            this.templateMajorVersion = getParametersValue(parameters, TEMPLATE_MAJOR_VERSION, CertificateTemplate.defaultValues(TEMPLATE_MAJOR_VERSION));
        }
        if (TEMPLATE_MINOR_VERSION in parameters) {
            this.templateMinorVersion = getParametersValue(parameters, TEMPLATE_MINOR_VERSION, CertificateTemplate.defaultValues(TEMPLATE_MINOR_VERSION));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TEMPLATE_ID:
                return EMPTY_STRING;
            case TEMPLATE_MAJOR_VERSION:
            case TEMPLATE_MINOR_VERSION:
                return 0;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.templateID || EMPTY_STRING) }),
                new Integer({
                    name: (names.templateMajorVersion || EMPTY_STRING),
                    optional: true
                }),
                new Integer({
                    name: (names.templateMinorVersion || EMPTY_STRING),
                    optional: true
                }),
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1m);
        const asn1 = compareSchema(schema, schema, CertificateTemplate.schema({
            names: {
                templateID: TEMPLATE_ID,
                templateMajorVersion: TEMPLATE_MAJOR_VERSION,
                templateMinorVersion: TEMPLATE_MINOR_VERSION
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.templateID = asn1.result.templateID.valueBlock.toString();
        if (TEMPLATE_MAJOR_VERSION in asn1.result) {
            this.templateMajorVersion = asn1.result.templateMajorVersion.valueBlock.valueDec;
        }
        if (TEMPLATE_MINOR_VERSION in asn1.result) {
            this.templateMinorVersion = asn1.result.templateMinorVersion.valueBlock.valueDec;
        }
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(new ObjectIdentifier({ value: this.templateID }));
        if (TEMPLATE_MAJOR_VERSION in this) {
            outputArray.push(new Integer({ value: this.templateMajorVersion }));
        }
        if (TEMPLATE_MINOR_VERSION in this) {
            outputArray.push(new Integer({ value: this.templateMinorVersion }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {
            templateID: this.templateID
        };
        if (TEMPLATE_MAJOR_VERSION in this)
            res.templateMajorVersion = this.templateMajorVersion;
        if (TEMPLATE_MINOR_VERSION in this)
            res.templateMinorVersion = this.templateMinorVersion;
        return res;
    }
}

const DISTRIBUTION_POINT$1 = "distributionPoint";
const DISTRIBUTION_POINT_NAMES$1 = "distributionPointNames";
const REASONS = "reasons";
const CRL_ISSUER = "cRLIssuer";
const CRL_ISSUER_NAMES = "cRLIssuerNames";
const CLEAR_PROPS$1l = [
    DISTRIBUTION_POINT$1,
    DISTRIBUTION_POINT_NAMES$1,
    REASONS,
    CRL_ISSUER,
    CRL_ISSUER_NAMES,
];
class DistributionPoint extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (DISTRIBUTION_POINT$1 in parameters) {
            this.distributionPoint = getParametersValue(parameters, DISTRIBUTION_POINT$1, DistributionPoint.defaultValues(DISTRIBUTION_POINT$1));
        }
        if (REASONS in parameters) {
            this.reasons = getParametersValue(parameters, REASONS, DistributionPoint.defaultValues(REASONS));
        }
        if (CRL_ISSUER in parameters) {
            this.cRLIssuer = getParametersValue(parameters, CRL_ISSUER, DistributionPoint.defaultValues(CRL_ISSUER));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case DISTRIBUTION_POINT$1:
                return [];
            case REASONS:
                return new BitString();
            case CRL_ISSUER:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [
                        new Choice({
                            value: [
                                new Constructed({
                                    name: (names.distributionPoint || EMPTY_STRING),
                                    optional: true,
                                    idBlock: {
                                        tagClass: 3,
                                        tagNumber: 0
                                    },
                                    value: [
                                        new Repeated({
                                            name: (names.distributionPointNames || EMPTY_STRING),
                                            value: GeneralName.schema()
                                        })
                                    ]
                                }),
                                new Constructed({
                                    name: (names.distributionPoint || EMPTY_STRING),
                                    optional: true,
                                    idBlock: {
                                        tagClass: 3,
                                        tagNumber: 1
                                    },
                                    value: RelativeDistinguishedNames.schema().valueBlock.value
                                })
                            ]
                        })
                    ]
                }),
                new Primitive({
                    name: (names.reasons || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                }),
                new Constructed({
                    name: (names.cRLIssuer || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    },
                    value: [
                        new Repeated({
                            name: (names.cRLIssuerNames || EMPTY_STRING),
                            value: GeneralName.schema()
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1l);
        const asn1 = compareSchema(schema, schema, DistributionPoint.schema({
            names: {
                distributionPoint: DISTRIBUTION_POINT$1,
                distributionPointNames: DISTRIBUTION_POINT_NAMES$1,
                reasons: REASONS,
                cRLIssuer: CRL_ISSUER,
                cRLIssuerNames: CRL_ISSUER_NAMES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (DISTRIBUTION_POINT$1 in asn1.result) {
            if (asn1.result.distributionPoint.idBlock.tagNumber === 0) {
                this.distributionPoint = Array.from(asn1.result.distributionPointNames, element => new GeneralName({ schema: element }));
            }
            if (asn1.result.distributionPoint.idBlock.tagNumber === 1) {
                this.distributionPoint = new RelativeDistinguishedNames({
                    schema: new Sequence({
                        value: asn1.result.distributionPoint.valueBlock.value
                    })
                });
            }
        }
        if (REASONS in asn1.result) {
            this.reasons = new BitString({ valueHex: asn1.result.reasons.valueBlock.valueHex });
        }
        if (CRL_ISSUER in asn1.result) {
            this.cRLIssuer = Array.from(asn1.result.cRLIssuerNames, element => new GeneralName({ schema: element }));
        }
    }
    toSchema() {
        const outputArray = [];
        if (this.distributionPoint) {
            let internalValue;
            if (this.distributionPoint instanceof Array) {
                internalValue = new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: Array.from(this.distributionPoint, o => o.toSchema())
                });
            }
            else {
                internalValue = new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: [this.distributionPoint.toSchema()]
                });
            }
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: [internalValue]
            }));
        }
        if (this.reasons) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                valueHex: this.reasons.valueBlock.valueHexView
            }));
        }
        if (this.cRLIssuer) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                value: Array.from(this.cRLIssuer, o => o.toSchema())
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {};
        if (this.distributionPoint) {
            if (this.distributionPoint instanceof Array) {
                object.distributionPoint = Array.from(this.distributionPoint, o => o.toJSON());
            }
            else {
                object.distributionPoint = this.distributionPoint.toJSON();
            }
        }
        if (this.reasons) {
            object.reasons = this.reasons.toJSON();
        }
        if (this.cRLIssuer) {
            object.cRLIssuer = Array.from(this.cRLIssuer, o => o.toJSON());
        }
        return object;
    }
}
DistributionPoint.CLASS_NAME = "DistributionPoint";

const DISTRIBUTION_POINTS = "distributionPoints";
const CLEAR_PROPS$1k = [
    DISTRIBUTION_POINTS
];
class CRLDistributionPoints extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.distributionPoints = getParametersValue(parameters, DISTRIBUTION_POINTS, CRLDistributionPoints.defaultValues(DISTRIBUTION_POINTS));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case DISTRIBUTION_POINTS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.distributionPoints || EMPTY_STRING),
                    value: DistributionPoint.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1k);
        const asn1 = compareSchema(schema, schema, CRLDistributionPoints.schema({
            names: {
                distributionPoints: DISTRIBUTION_POINTS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.distributionPoints = Array.from(asn1.result.distributionPoints, element => new DistributionPoint({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.distributionPoints, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            distributionPoints: Array.from(this.distributionPoints, o => o.toJSON())
        };
    }
}
CRLDistributionPoints.CLASS_NAME = "CRLDistributionPoints";

const KEY_PURPOSES = "keyPurposes";
const CLEAR_PROPS$1j = [
    KEY_PURPOSES,
];
class ExtKeyUsage extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.keyPurposes = getParametersValue(parameters, KEY_PURPOSES, ExtKeyUsage.defaultValues(KEY_PURPOSES));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case KEY_PURPOSES:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.keyPurposes || EMPTY_STRING),
                    value: new ObjectIdentifier()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1j);
        const asn1 = compareSchema(schema, schema, ExtKeyUsage.schema({
            names: {
                keyPurposes: KEY_PURPOSES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.keyPurposes = Array.from(asn1.result.keyPurposes, (element) => element.valueBlock.toString());
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.keyPurposes, element => new ObjectIdentifier({ value: element }))
        }));
    }
    toJSON() {
        return {
            keyPurposes: Array.from(this.keyPurposes)
        };
    }
}
ExtKeyUsage.CLASS_NAME = "ExtKeyUsage";

const ACCESS_DESCRIPTIONS = "accessDescriptions";
class InfoAccess extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.accessDescriptions = getParametersValue(parameters, ACCESS_DESCRIPTIONS, InfoAccess.defaultValues(ACCESS_DESCRIPTIONS));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ACCESS_DESCRIPTIONS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.accessDescriptions || EMPTY_STRING),
                    value: AccessDescription.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, [
            ACCESS_DESCRIPTIONS
        ]);
        const asn1 = compareSchema(schema, schema, InfoAccess.schema({
            names: {
                accessDescriptions: ACCESS_DESCRIPTIONS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.accessDescriptions = Array.from(asn1.result.accessDescriptions, element => new AccessDescription({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.accessDescriptions, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            accessDescriptions: Array.from(this.accessDescriptions, o => o.toJSON())
        };
    }
}
InfoAccess.CLASS_NAME = "InfoAccess";

const DISTRIBUTION_POINT = "distributionPoint";
const DISTRIBUTION_POINT_NAMES = "distributionPointNames";
const ONLY_CONTAINS_USER_CERTS = "onlyContainsUserCerts";
const ONLY_CONTAINS_CA_CERTS = "onlyContainsCACerts";
const ONLY_SOME_REASON = "onlySomeReasons";
const INDIRECT_CRL = "indirectCRL";
const ONLY_CONTAINS_ATTRIBUTE_CERTS = "onlyContainsAttributeCerts";
const CLEAR_PROPS$1i = [
    DISTRIBUTION_POINT,
    DISTRIBUTION_POINT_NAMES,
    ONLY_CONTAINS_USER_CERTS,
    ONLY_CONTAINS_CA_CERTS,
    ONLY_SOME_REASON,
    INDIRECT_CRL,
    ONLY_CONTAINS_ATTRIBUTE_CERTS,
];
class IssuingDistributionPoint extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (DISTRIBUTION_POINT in parameters) {
            this.distributionPoint = getParametersValue(parameters, DISTRIBUTION_POINT, IssuingDistributionPoint.defaultValues(DISTRIBUTION_POINT));
        }
        this.onlyContainsUserCerts = getParametersValue(parameters, ONLY_CONTAINS_USER_CERTS, IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_USER_CERTS));
        this.onlyContainsCACerts = getParametersValue(parameters, ONLY_CONTAINS_CA_CERTS, IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_CA_CERTS));
        if (ONLY_SOME_REASON in parameters) {
            this.onlySomeReasons = getParametersValue(parameters, ONLY_SOME_REASON, IssuingDistributionPoint.defaultValues(ONLY_SOME_REASON));
        }
        this.indirectCRL = getParametersValue(parameters, INDIRECT_CRL, IssuingDistributionPoint.defaultValues(INDIRECT_CRL));
        this.onlyContainsAttributeCerts = getParametersValue(parameters, ONLY_CONTAINS_ATTRIBUTE_CERTS, IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_ATTRIBUTE_CERTS));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case DISTRIBUTION_POINT:
                return [];
            case ONLY_CONTAINS_USER_CERTS:
                return false;
            case ONLY_CONTAINS_CA_CERTS:
                return false;
            case ONLY_SOME_REASON:
                return 0;
            case INDIRECT_CRL:
                return false;
            case ONLY_CONTAINS_ATTRIBUTE_CERTS:
                return false;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [
                        new Choice({
                            value: [
                                new Constructed({
                                    name: (names.distributionPoint || EMPTY_STRING),
                                    idBlock: {
                                        tagClass: 3,
                                        tagNumber: 0
                                    },
                                    value: [
                                        new Repeated({
                                            name: (names.distributionPointNames || EMPTY_STRING),
                                            value: GeneralName.schema()
                                        })
                                    ]
                                }),
                                new Constructed({
                                    name: (names.distributionPoint || EMPTY_STRING),
                                    idBlock: {
                                        tagClass: 3,
                                        tagNumber: 1
                                    },
                                    value: RelativeDistinguishedNames.schema().valueBlock.value
                                })
                            ]
                        })
                    ]
                }),
                new Primitive({
                    name: (names.onlyContainsUserCerts || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                }),
                new Primitive({
                    name: (names.onlyContainsCACerts || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    }
                }),
                new Primitive({
                    name: (names.onlySomeReasons || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 3
                    }
                }),
                new Primitive({
                    name: (names.indirectCRL || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 4
                    }
                }),
                new Primitive({
                    name: (names.onlyContainsAttributeCerts || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 5
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1i);
        const asn1 = compareSchema(schema, schema, IssuingDistributionPoint.schema({
            names: {
                distributionPoint: DISTRIBUTION_POINT,
                distributionPointNames: DISTRIBUTION_POINT_NAMES,
                onlyContainsUserCerts: ONLY_CONTAINS_USER_CERTS,
                onlyContainsCACerts: ONLY_CONTAINS_CA_CERTS,
                onlySomeReasons: ONLY_SOME_REASON,
                indirectCRL: INDIRECT_CRL,
                onlyContainsAttributeCerts: ONLY_CONTAINS_ATTRIBUTE_CERTS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (DISTRIBUTION_POINT in asn1.result) {
            switch (true) {
                case (asn1.result.distributionPoint.idBlock.tagNumber === 0):
                    this.distributionPoint = Array.from(asn1.result.distributionPointNames, element => new GeneralName({ schema: element }));
                    break;
                case (asn1.result.distributionPoint.idBlock.tagNumber === 1):
                    {
                        this.distributionPoint = new RelativeDistinguishedNames({
                            schema: new Sequence({
                                value: asn1.result.distributionPoint.valueBlock.value
                            })
                        });
                    }
                    break;
                default:
                    throw new Error("Unknown tagNumber for distributionPoint: {$asn1.result.distributionPoint.idBlock.tagNumber}");
            }
        }
        if (ONLY_CONTAINS_USER_CERTS in asn1.result) {
            const view = new Uint8Array(asn1.result.onlyContainsUserCerts.valueBlock.valueHex);
            this.onlyContainsUserCerts = (view[0] !== 0x00);
        }
        if (ONLY_CONTAINS_CA_CERTS in asn1.result) {
            const view = new Uint8Array(asn1.result.onlyContainsCACerts.valueBlock.valueHex);
            this.onlyContainsCACerts = (view[0] !== 0x00);
        }
        if (ONLY_SOME_REASON in asn1.result) {
            const view = new Uint8Array(asn1.result.onlySomeReasons.valueBlock.valueHex);
            this.onlySomeReasons = view[0];
        }
        if (INDIRECT_CRL in asn1.result) {
            const view = new Uint8Array(asn1.result.indirectCRL.valueBlock.valueHex);
            this.indirectCRL = (view[0] !== 0x00);
        }
        if (ONLY_CONTAINS_ATTRIBUTE_CERTS in asn1.result) {
            const view = new Uint8Array(asn1.result.onlyContainsAttributeCerts.valueBlock.valueHex);
            this.onlyContainsAttributeCerts = (view[0] !== 0x00);
        }
    }
    toSchema() {
        const outputArray = [];
        if (this.distributionPoint) {
            let value;
            if (this.distributionPoint instanceof Array) {
                value = new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: Array.from(this.distributionPoint, o => o.toSchema())
                });
            }
            else {
                value = this.distributionPoint.toSchema();
                value.idBlock.tagClass = 3;
                value.idBlock.tagNumber = 1;
            }
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: [value]
            }));
        }
        if (this.onlyContainsUserCerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_USER_CERTS)) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                valueHex: (new Uint8Array([0xFF])).buffer
            }));
        }
        if (this.onlyContainsCACerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_CA_CERTS)) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                valueHex: (new Uint8Array([0xFF])).buffer
            }));
        }
        if (this.onlySomeReasons !== undefined) {
            const buffer = new ArrayBuffer(1);
            const view = new Uint8Array(buffer);
            view[0] = this.onlySomeReasons;
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 3
                },
                valueHex: buffer
            }));
        }
        if (this.indirectCRL !== IssuingDistributionPoint.defaultValues(INDIRECT_CRL)) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 4
                },
                valueHex: (new Uint8Array([0xFF])).buffer
            }));
        }
        if (this.onlyContainsAttributeCerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_ATTRIBUTE_CERTS)) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 5
                },
                valueHex: (new Uint8Array([0xFF])).buffer
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const obj = {};
        if (this.distributionPoint) {
            if (this.distributionPoint instanceof Array) {
                obj.distributionPoint = Array.from(this.distributionPoint, o => o.toJSON());
            }
            else {
                obj.distributionPoint = this.distributionPoint.toJSON();
            }
        }
        if (this.onlyContainsUserCerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_USER_CERTS)) {
            obj.onlyContainsUserCerts = this.onlyContainsUserCerts;
        }
        if (this.onlyContainsCACerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_CA_CERTS)) {
            obj.onlyContainsCACerts = this.onlyContainsCACerts;
        }
        if (ONLY_SOME_REASON in this) {
            obj.onlySomeReasons = this.onlySomeReasons;
        }
        if (this.indirectCRL !== IssuingDistributionPoint.defaultValues(INDIRECT_CRL)) {
            obj.indirectCRL = this.indirectCRL;
        }
        if (this.onlyContainsAttributeCerts !== IssuingDistributionPoint.defaultValues(ONLY_CONTAINS_ATTRIBUTE_CERTS)) {
            obj.onlyContainsAttributeCerts = this.onlyContainsAttributeCerts;
        }
        return obj;
    }
}
IssuingDistributionPoint.CLASS_NAME = "IssuingDistributionPoint";

const BASE = "base";
const MINIMUM = "minimum";
const MAXIMUM = "maximum";
const CLEAR_PROPS$1h = [
    BASE,
    MINIMUM,
    MAXIMUM
];
class GeneralSubtree extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.base = getParametersValue(parameters, BASE, GeneralSubtree.defaultValues(BASE));
        this.minimum = getParametersValue(parameters, MINIMUM, GeneralSubtree.defaultValues(MINIMUM));
        if (MAXIMUM in parameters) {
            this.maximum = getParametersValue(parameters, MAXIMUM, GeneralSubtree.defaultValues(MAXIMUM));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case BASE:
                return new GeneralName();
            case MINIMUM:
                return 0;
            case MAXIMUM:
                return 0;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                GeneralName.schema(names.base || {}),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [new Integer({ name: (names.minimum || EMPTY_STRING) })]
                }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: [new Integer({ name: (names.maximum || EMPTY_STRING) })]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1h);
        const asn1 = compareSchema(schema, schema, GeneralSubtree.schema({
            names: {
                base: {
                    names: {
                        blockName: BASE
                    }
                },
                minimum: MINIMUM,
                maximum: MAXIMUM
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.base = new GeneralName({ schema: asn1.result.base });
        if (MINIMUM in asn1.result) {
            if (asn1.result.minimum.valueBlock.isHexOnly)
                this.minimum = asn1.result.minimum;
            else
                this.minimum = asn1.result.minimum.valueBlock.valueDec;
        }
        if (MAXIMUM in asn1.result) {
            if (asn1.result.maximum.valueBlock.isHexOnly)
                this.maximum = asn1.result.maximum;
            else
                this.maximum = asn1.result.maximum.valueBlock.valueDec;
        }
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(this.base.toSchema());
        if (this.minimum !== 0) {
            let valueMinimum = 0;
            if (this.minimum instanceof Integer) {
                valueMinimum = this.minimum;
            }
            else {
                valueMinimum = new Integer({ value: this.minimum });
            }
            outputArray.push(new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: [valueMinimum]
            }));
        }
        if (MAXIMUM in this) {
            let valueMaximum = 0;
            if (this.maximum instanceof Integer) {
                valueMaximum = this.maximum;
            }
            else {
                valueMaximum = new Integer({ value: this.maximum });
            }
            outputArray.push(new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: [valueMaximum]
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {
            base: this.base.toJSON()
        };
        if (this.minimum !== 0) {
            if (typeof this.minimum === "number") {
                res.minimum = this.minimum;
            }
            else {
                res.minimum = this.minimum.toJSON();
            }
        }
        if (this.maximum !== undefined) {
            if (typeof this.maximum === "number") {
                res.maximum = this.maximum;
            }
            else {
                res.maximum = this.maximum.toJSON();
            }
        }
        return res;
    }
}
GeneralSubtree.CLASS_NAME = "GeneralSubtree";

const PERMITTED_SUBTREES = "permittedSubtrees";
const EXCLUDED_SUBTREES = "excludedSubtrees";
const CLEAR_PROPS$1g = [
    PERMITTED_SUBTREES,
    EXCLUDED_SUBTREES
];
class NameConstraints extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (PERMITTED_SUBTREES in parameters) {
            this.permittedSubtrees = getParametersValue(parameters, PERMITTED_SUBTREES, NameConstraints.defaultValues(PERMITTED_SUBTREES));
        }
        if (EXCLUDED_SUBTREES in parameters) {
            this.excludedSubtrees = getParametersValue(parameters, EXCLUDED_SUBTREES, NameConstraints.defaultValues(EXCLUDED_SUBTREES));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case PERMITTED_SUBTREES:
            case EXCLUDED_SUBTREES:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [
                        new Repeated({
                            name: (names.permittedSubtrees || EMPTY_STRING),
                            value: GeneralSubtree.schema()
                        })
                    ]
                }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: [
                        new Repeated({
                            name: (names.excludedSubtrees || EMPTY_STRING),
                            value: GeneralSubtree.schema()
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1g);
        const asn1 = compareSchema(schema, schema, NameConstraints.schema({
            names: {
                permittedSubtrees: PERMITTED_SUBTREES,
                excludedSubtrees: EXCLUDED_SUBTREES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (PERMITTED_SUBTREES in asn1.result)
            this.permittedSubtrees = Array.from(asn1.result.permittedSubtrees, element => new GeneralSubtree({ schema: element }));
        if (EXCLUDED_SUBTREES in asn1.result)
            this.excludedSubtrees = Array.from(asn1.result.excludedSubtrees, element => new GeneralSubtree({ schema: element }));
    }
    toSchema() {
        const outputArray = [];
        if (this.permittedSubtrees) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: Array.from(this.permittedSubtrees, o => o.toSchema())
            }));
        }
        if (this.excludedSubtrees) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: Array.from(this.excludedSubtrees, o => o.toSchema())
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {};
        if (this.permittedSubtrees) {
            object.permittedSubtrees = Array.from(this.permittedSubtrees, o => o.toJSON());
        }
        if (this.excludedSubtrees) {
            object.excludedSubtrees = Array.from(this.excludedSubtrees, o => o.toJSON());
        }
        return object;
    }
}
NameConstraints.CLASS_NAME = "NameConstraints";

const REQUIRE_EXPLICIT_POLICY = "requireExplicitPolicy";
const INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping";
const CLEAR_PROPS$1f = [
    REQUIRE_EXPLICIT_POLICY,
    INHIBIT_POLICY_MAPPING,
];
class PolicyConstraints extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (REQUIRE_EXPLICIT_POLICY in parameters) {
            this.requireExplicitPolicy = getParametersValue(parameters, REQUIRE_EXPLICIT_POLICY, PolicyConstraints.defaultValues(REQUIRE_EXPLICIT_POLICY));
        }
        if (INHIBIT_POLICY_MAPPING in parameters) {
            this.inhibitPolicyMapping = getParametersValue(parameters, INHIBIT_POLICY_MAPPING, PolicyConstraints.defaultValues(INHIBIT_POLICY_MAPPING));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case REQUIRE_EXPLICIT_POLICY:
                return 0;
            case INHIBIT_POLICY_MAPPING:
                return 0;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Primitive({
                    name: (names.requireExplicitPolicy || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    }
                }),
                new Primitive({
                    name: (names.inhibitPolicyMapping || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1f);
        const asn1 = compareSchema(schema, schema, PolicyConstraints.schema({
            names: {
                requireExplicitPolicy: REQUIRE_EXPLICIT_POLICY,
                inhibitPolicyMapping: INHIBIT_POLICY_MAPPING
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (REQUIRE_EXPLICIT_POLICY in asn1.result) {
            const field1 = asn1.result.requireExplicitPolicy;
            field1.idBlock.tagClass = 1;
            field1.idBlock.tagNumber = 2;
            const ber1 = field1.toBER(false);
            const int1 = fromBER(ber1);
            AsnError.assert(int1, "Integer");
            this.requireExplicitPolicy = int1.result.valueBlock.valueDec;
        }
        if (INHIBIT_POLICY_MAPPING in asn1.result) {
            const field2 = asn1.result.inhibitPolicyMapping;
            field2.idBlock.tagClass = 1;
            field2.idBlock.tagNumber = 2;
            const ber2 = field2.toBER(false);
            const int2 = fromBER(ber2);
            AsnError.assert(int2, "Integer");
            this.inhibitPolicyMapping = int2.result.valueBlock.valueDec;
        }
    }
    toSchema() {
        const outputArray = [];
        if (REQUIRE_EXPLICIT_POLICY in this) {
            const int1 = new Integer({ value: this.requireExplicitPolicy });
            int1.idBlock.tagClass = 3;
            int1.idBlock.tagNumber = 0;
            outputArray.push(int1);
        }
        if (INHIBIT_POLICY_MAPPING in this) {
            const int2 = new Integer({ value: this.inhibitPolicyMapping });
            int2.idBlock.tagClass = 3;
            int2.idBlock.tagNumber = 1;
            outputArray.push(int2);
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {};
        if (REQUIRE_EXPLICIT_POLICY in this) {
            res.requireExplicitPolicy = this.requireExplicitPolicy;
        }
        if (INHIBIT_POLICY_MAPPING in this) {
            res.inhibitPolicyMapping = this.inhibitPolicyMapping;
        }
        return res;
    }
}
PolicyConstraints.CLASS_NAME = "PolicyConstraints";

const ISSUER_DOMAIN_POLICY = "issuerDomainPolicy";
const SUBJECT_DOMAIN_POLICY = "subjectDomainPolicy";
const CLEAR_PROPS$1e = [
    ISSUER_DOMAIN_POLICY,
    SUBJECT_DOMAIN_POLICY
];
class PolicyMapping extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.issuerDomainPolicy = getParametersValue(parameters, ISSUER_DOMAIN_POLICY, PolicyMapping.defaultValues(ISSUER_DOMAIN_POLICY));
        this.subjectDomainPolicy = getParametersValue(parameters, SUBJECT_DOMAIN_POLICY, PolicyMapping.defaultValues(SUBJECT_DOMAIN_POLICY));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ISSUER_DOMAIN_POLICY:
                return EMPTY_STRING;
            case SUBJECT_DOMAIN_POLICY:
                return EMPTY_STRING;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.issuerDomainPolicy || EMPTY_STRING) }),
                new ObjectIdentifier({ name: (names.subjectDomainPolicy || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1e);
        const asn1 = compareSchema(schema, schema, PolicyMapping.schema({
            names: {
                issuerDomainPolicy: ISSUER_DOMAIN_POLICY,
                subjectDomainPolicy: SUBJECT_DOMAIN_POLICY
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.issuerDomainPolicy = asn1.result.issuerDomainPolicy.valueBlock.toString();
        this.subjectDomainPolicy = asn1.result.subjectDomainPolicy.valueBlock.toString();
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.issuerDomainPolicy }),
                new ObjectIdentifier({ value: this.subjectDomainPolicy })
            ]
        }));
    }
    toJSON() {
        return {
            issuerDomainPolicy: this.issuerDomainPolicy,
            subjectDomainPolicy: this.subjectDomainPolicy
        };
    }
}
PolicyMapping.CLASS_NAME = "PolicyMapping";

const MAPPINGS = "mappings";
const CLEAR_PROPS$1d = [
    MAPPINGS,
];
class PolicyMappings extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.mappings = getParametersValue(parameters, MAPPINGS, PolicyMappings.defaultValues(MAPPINGS));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case MAPPINGS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.mappings || EMPTY_STRING),
                    value: PolicyMapping.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1d);
        const asn1 = compareSchema(schema, schema, PolicyMappings.schema({
            names: {
                mappings: MAPPINGS
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.mappings = Array.from(asn1.result.mappings, element => new PolicyMapping({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.mappings, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            mappings: Array.from(this.mappings, o => o.toJSON())
        };
    }
}
PolicyMappings.CLASS_NAME = "PolicyMappings";

const NOT_BEFORE$1 = "notBefore";
const NOT_AFTER$1 = "notAfter";
const CLEAR_PROPS$1c = [
    NOT_BEFORE$1,
    NOT_AFTER$1
];
class PrivateKeyUsagePeriod extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (NOT_BEFORE$1 in parameters) {
            this.notBefore = getParametersValue(parameters, NOT_BEFORE$1, PrivateKeyUsagePeriod.defaultValues(NOT_BEFORE$1));
        }
        if (NOT_AFTER$1 in parameters) {
            this.notAfter = getParametersValue(parameters, NOT_AFTER$1, PrivateKeyUsagePeriod.defaultValues(NOT_AFTER$1));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case NOT_BEFORE$1:
                return new Date();
            case NOT_AFTER$1:
                return new Date();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Primitive({
                    name: (names.notBefore || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    }
                }),
                new Primitive({
                    name: (names.notAfter || EMPTY_STRING),
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1c);
        const asn1 = compareSchema(schema, schema, PrivateKeyUsagePeriod.schema({
            names: {
                notBefore: NOT_BEFORE$1,
                notAfter: NOT_AFTER$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (NOT_BEFORE$1 in asn1.result) {
            const localNotBefore = new GeneralizedTime();
            localNotBefore.fromBuffer(asn1.result.notBefore.valueBlock.valueHex);
            this.notBefore = localNotBefore.toDate();
        }
        if (NOT_AFTER$1 in asn1.result) {
            const localNotAfter = new GeneralizedTime({ valueHex: asn1.result.notAfter.valueBlock.valueHex });
            localNotAfter.fromBuffer(asn1.result.notAfter.valueBlock.valueHex);
            this.notAfter = localNotAfter.toDate();
        }
    }
    toSchema() {
        const outputArray = [];
        if (NOT_BEFORE$1 in this) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                valueHex: (new GeneralizedTime({ valueDate: this.notBefore })).valueBlock.valueHexView
            }));
        }
        if (NOT_AFTER$1 in this) {
            outputArray.push(new Primitive({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                valueHex: (new GeneralizedTime({ valueDate: this.notAfter })).valueBlock.valueHexView
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {};
        if (this.notBefore) {
            res.notBefore = this.notBefore;
        }
        if (this.notAfter) {
            res.notAfter = this.notAfter;
        }
        return res;
    }
}
PrivateKeyUsagePeriod.CLASS_NAME = "PrivateKeyUsagePeriod";

const ID = "id";
const TYPE$2 = "type";
const VALUES = "values";
const QC_STATEMENT_CLEAR_PROPS = [
    ID,
    TYPE$2
];
const QC_STATEMENTS_CLEAR_PROPS = [
    VALUES
];
class QCStatement extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.id = getParametersValue(parameters, ID, QCStatement.defaultValues(ID));
        if (TYPE$2 in parameters) {
            this.type = getParametersValue(parameters, TYPE$2, QCStatement.defaultValues(TYPE$2));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ID:
                return EMPTY_STRING;
            case TYPE$2:
                return new Null();
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case ID:
                return (memberValue === EMPTY_STRING);
            case TYPE$2:
                return (memberValue instanceof Null);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.id || EMPTY_STRING) }),
                new Any({
                    name: (names.type || EMPTY_STRING),
                    optional: true
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, QC_STATEMENT_CLEAR_PROPS);
        const asn1 = compareSchema(schema, schema, QCStatement.schema({
            names: {
                id: ID,
                type: TYPE$2
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.id = asn1.result.id.valueBlock.toString();
        if (TYPE$2 in asn1.result)
            this.type = asn1.result.type;
    }
    toSchema() {
        const value = [
            new ObjectIdentifier({ value: this.id })
        ];
        if (TYPE$2 in this)
            value.push(this.type);
        return (new Sequence({
            value,
        }));
    }
    toJSON() {
        const object = {
            id: this.id
        };
        if (this.type) {
            object.type = this.type.toJSON();
        }
        return object;
    }
}
QCStatement.CLASS_NAME = "QCStatement";
class QCStatements extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.values = getParametersValue(parameters, VALUES, QCStatements.defaultValues(VALUES));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VALUES:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case VALUES:
                return (memberValue.length === 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.values || EMPTY_STRING),
                    value: QCStatement.schema(names.value || {})
                }),
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, QC_STATEMENTS_CLEAR_PROPS);
        const asn1 = compareSchema(schema, schema, QCStatements.schema({
            names: {
                values: VALUES
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.values = Array.from(asn1.result.values, element => new QCStatement({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.values, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            values: Array.from(this.values, o => o.toJSON())
        };
    }
}
QCStatements.CLASS_NAME = "QCStatements";

class ByteStream {
    constructor(parameters = {}) {
        if ("view" in parameters) {
            this.fromUint8Array(parameters.view);
        }
        else if ("buffer" in parameters) {
            this.fromArrayBuffer(parameters.buffer);
        }
        else if ("string" in parameters) {
            this.fromString(parameters.string);
        }
        else if ("hexstring" in parameters) {
            this.fromHexString(parameters.hexstring);
        }
        else {
            if ("length" in parameters && parameters.length > 0) {
                this.length = parameters.length;
                if (parameters.stub) {
                    for (let i = 0; i < this._view.length; i++) {
                        this._view[i] = parameters.stub;
                    }
                }
            }
            else {
                this.length = 0;
            }
        }
    }
    set buffer(value) {
        this._buffer = value;
        this._view = new Uint8Array(this._buffer);
    }
    get buffer() {
        return this._buffer;
    }
    set view(value) {
        this._buffer = new ArrayBuffer(value.length);
        this._view = new Uint8Array(this._buffer);
        this._view.set(value);
    }
    get view() {
        return this._view;
    }
    get length() {
        return this.view.byteLength;
    }
    set length(value) {
        this._buffer = new ArrayBuffer(value);
        this._view = new Uint8Array(this._buffer);
    }
    clear() {
        this._buffer = new ArrayBuffer(0);
        this._view = new Uint8Array(this._buffer);
    }
    fromArrayBuffer(array) {
        this._buffer = array;
        this._view = new Uint8Array(this._buffer);
    }
    fromUint8Array(array) {
        this.fromArrayBuffer(new Uint8Array(array).buffer);
    }
    fromString(string) {
        const stringLength = string.length;
        this.length = stringLength;
        for (let i = 0; i < stringLength; i++)
            this.view[i] = string.charCodeAt(i);
    }
    toString(start = 0, length = (this.view.length - start)) {
        let result = "";
        if ((start >= this.view.length) || (start < 0)) {
            start = 0;
        }
        if ((length >= this.view.length) || (length < 0)) {
            length = this.view.length - start;
        }
        for (let i = start; i < (start + length); i++)
            result += String.fromCharCode(this.view[i]);
        return result;
    }
    fromHexString(hexString) {
        const stringLength = hexString.length;
        this.buffer = new ArrayBuffer(stringLength >> 1);
        this.view = new Uint8Array(this.buffer);
        const hexMap = new Map();
        hexMap.set("0", 0x00);
        hexMap.set("1", 0x01);
        hexMap.set("2", 0x02);
        hexMap.set("3", 0x03);
        hexMap.set("4", 0x04);
        hexMap.set("5", 0x05);
        hexMap.set("6", 0x06);
        hexMap.set("7", 0x07);
        hexMap.set("8", 0x08);
        hexMap.set("9", 0x09);
        hexMap.set("A", 0x0A);
        hexMap.set("a", 0x0A);
        hexMap.set("B", 0x0B);
        hexMap.set("b", 0x0B);
        hexMap.set("C", 0x0C);
        hexMap.set("c", 0x0C);
        hexMap.set("D", 0x0D);
        hexMap.set("d", 0x0D);
        hexMap.set("E", 0x0E);
        hexMap.set("e", 0x0E);
        hexMap.set("F", 0x0F);
        hexMap.set("f", 0x0F);
        let j = 0;
        let temp = 0x00;
        for (let i = 0; i < stringLength; i++) {
            if (!(i % 2)) {
                temp = hexMap.get(hexString.charAt(i)) << 4;
            }
            else {
                temp |= hexMap.get(hexString.charAt(i));
                this.view[j] = temp;
                j++;
            }
        }
    }
    toHexString(start = 0, length = (this.view.length - start)) {
        let result = "";
        if ((start >= this.view.length) || (start < 0)) {
            start = 0;
        }
        if ((length >= this.view.length) || (length < 0)) {
            length = this.view.length - start;
        }
        for (let i = start; i < (start + length); i++) {
            const str = this.view[i].toString(16).toUpperCase();
            result = result + ((str.length == 1) ? "0" : "") + str;
        }
        return result;
    }
    copy(start = 0, length = (this.length - start)) {
        if (!start && !this.length) {
            return new ByteStream();
        }
        if ((start < 0) || (start > (this.length - 1))) {
            throw new Error(`Wrong start position: ${start}`);
        }
        const stream = new ByteStream({
            buffer: this._buffer.slice(start, start + length)
        });
        return stream;
    }
    slice(start = 0, end = this.length) {
        if (!start && !this.length) {
            return new ByteStream();
        }
        if ((start < 0) || (start > (this.length - 1))) {
            throw new Error(`Wrong start position: ${start}`);
        }
        const stream = new ByteStream({
            buffer: this._buffer.slice(start, end),
        });
        return stream;
    }
    realloc(size) {
        const buffer = new ArrayBuffer(size);
        const view = new Uint8Array(buffer);
        if (size > this._view.length)
            view.set(this._view);
        else {
            view.set(new Uint8Array(this._buffer, 0, size));
        }
        this._buffer = buffer;
        this._view = new Uint8Array(this._buffer);
    }
    append(stream) {
        const initialSize = this.length;
        const streamViewLength = stream.length;
        const subarrayView = stream._view.subarray();
        this.realloc(initialSize + streamViewLength);
        this._view.set(subarrayView, initialSize);
    }
    insert(stream, start = 0, length = (this.length - start)) {
        if (start > (this.length - 1))
            return false;
        if (length > (this.length - start)) {
            length = this.length - start;
        }
        if (length > stream.length) {
            length = stream.length;
        }
        if (length == stream.length)
            this._view.set(stream._view, start);
        else {
            this._view.set(stream._view.subarray(0, length), start);
        }
        return true;
    }
    isEqual(stream) {
        if (this.length != stream.length)
            return false;
        for (let i = 0; i < stream.length; i++) {
            if (this.view[i] != stream.view[i])
                return false;
        }
        return true;
    }
    isEqualView(view) {
        if (view.length != this.view.length)
            return false;
        for (let i = 0; i < view.length; i++) {
            if (this.view[i] != view[i])
                return false;
        }
        return true;
    }
    findPattern(pattern, start_, length_, backward_) {
        const { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        const patternLength = pattern.length;
        if (patternLength > length) {
            return (-1);
        }
        const patternArray = [];
        for (let i = 0; i < patternLength; i++)
            patternArray.push(pattern.view[i]);
        for (let i = 0; i <= (length - patternLength); i++) {
            let equal = true;
            const equalStart = (backward) ? (start - patternLength - i) : (start + i);
            for (let j = 0; j < patternLength; j++) {
                if (this.view[j + equalStart] != patternArray[j]) {
                    equal = false;
                    break;
                }
            }
            if (equal) {
                return (backward) ? (start - patternLength - i) : (start + patternLength + i);
            }
        }
        return (-1);
    }
    findFirstIn(patterns, start_, length_, backward_) {
        const { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        const result = {
            id: (-1),
            position: (backward) ? 0 : (start + length),
            length: 0
        };
        for (let i = 0; i < patterns.length; i++) {
            const position = this.findPattern(patterns[i], start, length, backward);
            if (position != (-1)) {
                let valid = false;
                const patternLength = patterns[i].length;
                if (backward) {
                    if ((position - patternLength) >= (result.position - result.length))
                        valid = true;
                }
                else {
                    if ((position - patternLength) <= (result.position - result.length))
                        valid = true;
                }
                if (valid) {
                    result.position = position;
                    result.id = i;
                    result.length = patternLength;
                }
            }
        }
        return result;
    }
    findAllIn(patterns, start_, length_) {
        let { start, length } = this.prepareFindParameters(start_, length_);
        const result = [];
        let patternFound = {
            id: (-1),
            position: start
        };
        do {
            const position = patternFound.position;
            patternFound = this.findFirstIn(patterns, patternFound.position, length);
            if (patternFound.id == (-1)) {
                break;
            }
            length -= (patternFound.position - position);
            result.push({
                id: patternFound.id,
                position: patternFound.position
            });
        } while (true);
        return result;
    }
    findAllPatternIn(pattern, start_, length_) {
        const { start, length } = this.prepareFindParameters(start_, length_);
        const result = [];
        const patternLength = pattern.length;
        if (patternLength > length) {
            return (-1);
        }
        const patternArray = Array.from(pattern.view);
        for (let i = 0; i <= (length - patternLength); i++) {
            let equal = true;
            const equalStart = start + i;
            for (let j = 0; j < patternLength; j++) {
                if (this.view[j + equalStart] != patternArray[j]) {
                    equal = false;
                    break;
                }
            }
            if (equal) {
                result.push(start + patternLength + i);
                i += (patternLength - 1);
            }
        }
        return result;
    }
    findFirstNotIn(patterns, start_, length_, backward_) {
        let { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        const result = {
            left: {
                id: (-1),
                position: start
            },
            right: {
                id: (-1),
                position: 0
            },
            value: new ByteStream()
        };
        let currentLength = length;
        while (currentLength > 0) {
            result.right = this.findFirstIn(patterns, (backward) ? (start - length + currentLength) : (start + length - currentLength), currentLength, backward);
            if (result.right.id == (-1)) {
                length = currentLength;
                if (backward) {
                    start -= length;
                }
                else {
                    start = result.left.position;
                }
                result.value = new ByteStream({
                    buffer: this._buffer.slice(start, start + length),
                });
                break;
            }
            if (result.right.position != ((backward) ? (result.left.position - patterns[result.right.id].length) : (result.left.position + patterns[result.right.id].length))) {
                if (backward) {
                    start = result.right.position + patterns[result.right.id].length;
                    length = result.left.position - result.right.position - patterns[result.right.id].length;
                }
                else {
                    start = result.left.position;
                    length = result.right.position - result.left.position - patterns[result.right.id].length;
                }
                result.value = new ByteStream({
                    buffer: this._buffer.slice(start, start + length),
                });
                break;
            }
            result.left = result.right;
            currentLength -= patterns[result.right.id].length;
        }
        if (backward) {
            const temp = result.right;
            result.right = result.left;
            result.left = temp;
        }
        return result;
    }
    findAllNotIn(patterns, start_, length_) {
        let { start, length } = this.prepareFindParameters(start_, length_);
        const result = [];
        let patternFound = {
            left: {
                id: (-1),
                position: start
            },
            right: {
                id: (-1),
                position: start
            },
            value: new ByteStream()
        };
        do {
            const position = patternFound.right.position;
            patternFound = this.findFirstNotIn(patterns, patternFound.right.position, length);
            length -= (patternFound.right.position - position);
            result.push({
                left: {
                    id: patternFound.left.id,
                    position: patternFound.left.position
                },
                right: {
                    id: patternFound.right.id,
                    position: patternFound.right.position
                },
                value: patternFound.value
            });
        } while (patternFound.right.id != (-1));
        return result;
    }
    findFirstSequence(patterns, start_, length_, backward_) {
        let { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        const firstIn = this.skipNotPatterns(patterns, start, length, backward);
        if (firstIn == (-1)) {
            return {
                position: (-1),
                value: new ByteStream()
            };
        }
        const firstNotIn = this.skipPatterns(patterns, firstIn, length - ((backward) ? (start - firstIn) : (firstIn - start)), backward);
        if (backward) {
            start = firstNotIn;
            length = (firstIn - firstNotIn);
        }
        else {
            start = firstIn;
            length = (firstNotIn - firstIn);
        }
        const value = new ByteStream({
            buffer: this._buffer.slice(start, start + length),
        });
        return {
            position: firstNotIn,
            value
        };
    }
    findAllSequences(patterns, start_, length_) {
        let { start, length } = this.prepareFindParameters(start_, length_);
        const result = [];
        let patternFound = {
            position: start,
            value: new ByteStream()
        };
        do {
            const position = patternFound.position;
            patternFound = this.findFirstSequence(patterns, patternFound.position, length);
            if (patternFound.position != (-1)) {
                length -= (patternFound.position - position);
                result.push({
                    position: patternFound.position,
                    value: patternFound.value,
                });
            }
        } while (patternFound.position != (-1));
        return result;
    }
    findPairedPatterns(leftPattern, rightPattern, start_, length_) {
        const result = [];
        if (leftPattern.isEqual(rightPattern))
            return result;
        const { start, length } = this.prepareFindParameters(start_, length_);
        let currentPositionLeft = 0;
        const leftPatterns = this.findAllPatternIn(leftPattern, start, length);
        if (!Array.isArray(leftPatterns) || leftPatterns.length == 0) {
            return result;
        }
        const rightPatterns = this.findAllPatternIn(rightPattern, start, length);
        if (!Array.isArray(rightPatterns) || rightPatterns.length == 0) {
            return result;
        }
        while (currentPositionLeft < leftPatterns.length) {
            if (rightPatterns.length == 0) {
                break;
            }
            if (leftPatterns[0] == rightPatterns[0]) {
                result.push({
                    left: leftPatterns[0],
                    right: rightPatterns[0]
                });
                leftPatterns.splice(0, 1);
                rightPatterns.splice(0, 1);
                continue;
            }
            if (leftPatterns[currentPositionLeft] > rightPatterns[0]) {
                break;
            }
            while (leftPatterns[currentPositionLeft] < rightPatterns[0]) {
                currentPositionLeft++;
                if (currentPositionLeft >= leftPatterns.length) {
                    break;
                }
            }
            result.push({
                left: leftPatterns[currentPositionLeft - 1],
                right: rightPatterns[0]
            });
            leftPatterns.splice(currentPositionLeft - 1, 1);
            rightPatterns.splice(0, 1);
            currentPositionLeft = 0;
        }
        result.sort((a, b) => (a.left - b.left));
        return result;
    }
    findPairedArrays(inputLeftPatterns, inputRightPatterns, start_, length_) {
        const { start, length } = this.prepareFindParameters(start_, length_);
        const result = [];
        let currentPositionLeft = 0;
        const leftPatterns = this.findAllIn(inputLeftPatterns, start, length);
        if (leftPatterns.length == 0)
            return result;
        const rightPatterns = this.findAllIn(inputRightPatterns, start, length);
        if (rightPatterns.length == 0)
            return result;
        while (currentPositionLeft < leftPatterns.length) {
            if (rightPatterns.length == 0) {
                break;
            }
            if (leftPatterns[0].position == rightPatterns[0].position) {
                result.push({
                    left: leftPatterns[0],
                    right: rightPatterns[0]
                });
                leftPatterns.splice(0, 1);
                rightPatterns.splice(0, 1);
                continue;
            }
            if (leftPatterns[currentPositionLeft].position > rightPatterns[0].position) {
                break;
            }
            while (leftPatterns[currentPositionLeft].position < rightPatterns[0].position) {
                currentPositionLeft++;
                if (currentPositionLeft >= leftPatterns.length) {
                    break;
                }
            }
            result.push({
                left: leftPatterns[currentPositionLeft - 1],
                right: rightPatterns[0]
            });
            leftPatterns.splice(currentPositionLeft - 1, 1);
            rightPatterns.splice(0, 1);
            currentPositionLeft = 0;
        }
        result.sort((a, b) => (a.left.position - b.left.position));
        return result;
    }
    replacePattern(searchPattern, replacePattern, start_, length_, findAllResult = null) {
        let result = [];
        let i;
        const output = {
            status: (-1),
            searchPatternPositions: [],
            replacePatternPositions: []
        };
        const { start, length } = this.prepareFindParameters(start_, length_);
        if (findAllResult == null) {
            result = this.findAllIn([searchPattern], start, length);
            if (result.length == 0) {
                return output;
            }
        }
        else {
            result = findAllResult;
        }
        output.searchPatternPositions.push(...Array.from(result, element => element.position));
        const patternDifference = searchPattern.length - replacePattern.length;
        const changedBuffer = new ArrayBuffer(this.view.length - (result.length * patternDifference));
        const changedView = new Uint8Array(changedBuffer);
        changedView.set(new Uint8Array(this.buffer, 0, start));
        for (i = 0; i < result.length; i++) {
            const currentPosition = (i == 0) ? start : result[i - 1].position;
            changedView.set(new Uint8Array(this.buffer, currentPosition, result[i].position - searchPattern.length - currentPosition), currentPosition - i * patternDifference);
            changedView.set(replacePattern.view, result[i].position - searchPattern.length - i * patternDifference);
            output.replacePatternPositions.push(result[i].position - searchPattern.length - i * patternDifference);
        }
        i--;
        changedView.set(new Uint8Array(this.buffer, result[i].position, this.length - result[i].position), result[i].position - searchPattern.length + replacePattern.length - i * patternDifference);
        this.buffer = changedBuffer;
        this.view = new Uint8Array(this.buffer);
        output.status = 1;
        return output;
    }
    skipPatterns(patterns, start_, length_, backward_) {
        const { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        let result = start;
        for (let k = 0; k < patterns.length; k++) {
            const patternLength = patterns[k].length;
            const equalStart = (backward) ? (result - patternLength) : (result);
            let equal = true;
            for (let j = 0; j < patternLength; j++) {
                if (this.view[j + equalStart] != patterns[k].view[j]) {
                    equal = false;
                    break;
                }
            }
            if (equal) {
                k = (-1);
                if (backward) {
                    result -= patternLength;
                    if (result <= 0)
                        return result;
                }
                else {
                    result += patternLength;
                    if (result >= (start + length))
                        return result;
                }
            }
        }
        return result;
    }
    skipNotPatterns(patterns, start_, length_, backward_) {
        const { start, length, backward } = this.prepareFindParameters(start_, length_, backward_);
        let result = (-1);
        for (let i = 0; i < length; i++) {
            for (let k = 0; k < patterns.length; k++) {
                const patternLength = patterns[k].length;
                const equalStart = (backward) ? (start - i - patternLength) : (start + i);
                let equal = true;
                for (let j = 0; j < patternLength; j++) {
                    if (this.view[j + equalStart] != patterns[k].view[j]) {
                        equal = false;
                        break;
                    }
                }
                if (equal) {
                    result = (backward) ? (start - i) : (start + i);
                    break;
                }
            }
            if (result != (-1)) {
                break;
            }
        }
        return result;
    }
    prepareFindParameters(start = null, length = null, backward = false) {
        if (start === null) {
            start = (backward) ? this.length : 0;
        }
        if (start > this.length) {
            start = this.length;
        }
        if (backward) {
            if (length === null) {
                length = start;
            }
            if (length > start) {
                length = start;
            }
        }
        else {
            if (length === null) {
                length = this.length - start;
            }
            if (length > (this.length - start)) {
                length = this.length - start;
            }
        }
        return { start, length, backward };
    }
}

const pow2_24 = 16777216;
class SeqStream {
    constructor(parameters = {}) {
        this._stream = new ByteStream();
        this._length = 0;
        this._start = 0;
        this.backward = false;
        this.appendBlock = 0;
        this.prevLength = 0;
        this.prevStart = 0;
        if ("view" in parameters) {
            this.stream = new ByteStream({ view: parameters.view });
        }
        else if ("buffer" in parameters) {
            this.stream = new ByteStream({ buffer: parameters.buffer });
        }
        else if ("string" in parameters) {
            this.stream = new ByteStream({ string: parameters.string });
        }
        else if ("hexstring" in parameters) {
            this.stream = new ByteStream({ hexstring: parameters.hexstring });
        }
        else if ("stream" in parameters) {
            this.stream = parameters.stream.slice();
        }
        else {
            this.stream = new ByteStream();
        }
        if ("backward" in parameters && parameters.backward) {
            this.backward = parameters.backward;
            this._start = this.stream.length;
        }
        if ("length" in parameters && parameters.length > 0) {
            this._length = parameters.length;
        }
        if ("start" in parameters && parameters.start && parameters.start > 0) {
            this._start = parameters.start;
        }
        if ("appendBlock" in parameters && parameters.appendBlock && parameters.appendBlock > 0) {
            this.appendBlock = parameters.appendBlock;
        }
    }
    set stream(value) {
        this._stream = value;
        this.prevLength = this._length;
        this._length = value.length;
        this.prevStart = this._start;
        this._start = 0;
    }
    get stream() {
        return this._stream;
    }
    set length(value) {
        this.prevLength = this._length;
        this._length = value;
    }
    get length() {
        if (this.appendBlock) {
            return this.start;
        }
        return this._length;
    }
    set start(value) {
        if (value > this.stream.length)
            return;
        this.prevStart = this._start;
        this.prevLength = this._length;
        this._length -= (this.backward) ? (this._start - value) : (value - this._start);
        this._start = value;
    }
    get start() {
        return this._start;
    }
    get buffer() {
        return this._stream.buffer.slice(0, this._length);
    }
    resetPosition() {
        this._start = this.prevStart;
        this._length = this.prevLength;
    }
    findPattern(pattern, gap = null) {
        if ((gap == null) || (gap > this.length)) {
            gap = this.length;
        }
        const result = this.stream.findPattern(pattern, this.start, this.length, this.backward);
        if (result == (-1))
            return result;
        if (this.backward) {
            if (result < (this.start - pattern.length - gap)) {
                return (-1);
            }
        }
        else {
            if (result > (this.start + pattern.length + gap)) {
                return (-1);
            }
        }
        this.start = result;
        return result;
    }
    findFirstIn(patterns, gap = null) {
        if ((gap == null) || (gap > this.length)) {
            gap = this.length;
        }
        const result = this.stream.findFirstIn(patterns, this.start, this.length, this.backward);
        if (result.id == (-1))
            return result;
        if (this.backward) {
            if (result.position < (this.start - patterns[result.id].length - gap)) {
                return { Ijava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
                    :(1)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
                    position: (this.backward) ? 0 : (this.start + this.length)
                };
            }
        }
        else {
            if (result.position > (this.start + patterns[result.id].length + gap)) {
                return {
                    id: (-1),
                    position: (this.backward) ? 0 : (this.start + this.length)
                };
            }
        }
        this.start = result.position;
        return result;
    }
    findAllIn(patterns) {
        const start = (this.backward) ? (this.start - this.length) : this.start;
        return this.stream.findAllIn(patterns, start, this.length);
    }
    findFirstNotIn(patterns, gap = null) {
        if ((gap == null) || (gap > this._length)) {
            gap = this._length;
        }
        const result = this._stream.findFirstNotIn(patterns, this._start, this._length, this.backward);
        if ((result.left.id == (-1)) && (result.right.id == (-1))) {
            return result;
        }
        if (this.backward) {
            if (result.right.id != (-1)) {
                if (result.right.position < (this._start - patterns[result.right.id].length - gap)) {
                    return {
                        left: {
                            id: (-1),
                            position: this._start
                        },
                        right: {
                            id: (-1),
                            position: 0
                        },
                        value: new ByteStream()
                    };
                }
            }
        }
        else {
            if (result.left.id != (-1)) {
                if (result.left.position > (this._start + patterns[result.left.id].length + gap)) {
                    return {
                        left: {
                            id: (-1),
                            position: this._start
                        },
                        right: {
                            id: (-1),
                            position: 0
                        },
                        value: new ByteStream()
                    };
                }
            }
        }
        if (this.backward) {
            if (result.left.id == (-1)) {
                this.start = 0;
            }
            else {
                this.start = result.left.position;
            }
        }
        else {
            if (result.right.id == (-1)) {
                this.start = (this._start + this._length);
            }
            else {
                this.start = result.right.position;
            }
        }
        return result;
    }
    findAllNotIn(patterns) {
        const start = (this.backward) ? (this._start - this._length) : this._start;
        return this._stream.findAllNotIn(patterns, start, this._length);
    }
    findFirstSequence(patterns, length = null, gap = null) {
        if ((length == null) || (length > this._length)) {
            length = this._length;
        }
        if ((gap == null) || (gap > length)) {
            gap = length;
        }
        const result = this._stream.findFirstSequence(patterns, this._start, length, this.backward);
        if (result.value.length == 0) {
            return result;
        }
        if (this.backward) {
            if (result.position < (this._start - result.value.length - gap)) {
                return {
                    position: (-1),
                    value: new ByteStream()
                };
            }
        }
        else {
            if (result.position > (this._start + result.value.length + gap)) {
                return {
                    position: (-1),
                    value: new ByteStream()
                };
            }
        }
        this.start = result.position;
        return result;
    }
    findAllSequences(patterns) {
        const start = (this.backward) ? (this.start - this.length) : this.start;
        return this.stream.findAllSequences(patterns, start, this.length);
    }
    findPairedPatterns(leftPattern, rightPattern, gap = null) {
        if ((gap == null) || (gap > this.length)) {
            gap = this.length;
        }
        const start = (this.backward) ? (this.start - this.length) : this.start;
        const result = this.stream.findPairedPatterns(leftPattern, rightPattern, start, this.length);
        if (result.length) {
            if (this.backward) {
                if (result[0].right < (this.start - rightPattern.length - gap)) {
                    return [];
                }
            }
            else {
                if (result[0].left > (this.start + leftPattern.length + gap)) {
                    return [];
                }
            }
        }
        return result;
    }
    findPairedArrays(leftPatterns, rightPatterns, gap = null) {
        if ((gap == null) || (gap > this.length)) {
            gap = this.length;
        }
        const start = (this.backward) ? (this.start - this.length) : this.start;
        const result = this.stream.findPairedArrays(leftPatterns, rightPatterns, start, this.length);
        if (result.length) {
            if (this.backward) {
                if (result[0].right.position < (this.start - rightPatterns[result[0].right.id].length - gap)) {
                    return [];
                }
            }
            else {
                if (result[0].left.position > (this.start + leftPatterns[result[0].left.id].length + gap)) {
                    return [];
                }
            }
        }
        return result;
    }
    replacePattern(searchPattern, replacePattern) {
        const start = (this.backward) ? (this.start - this.length) : this.start;
        return this.stream.replacePattern(searchPattern, replacePattern, start, this.length);
    }
    skipPatterns(patterns) {
        const result = this.stream.skipPatterns(patterns, this.start, this.length, this.backward);
        this.start = result;
        return result;
    }
    skipNotPatterns(patterns) {
        const result = this.stream.skipNotPatterns(patterns, this.start, this.length, this.backward);
        if (result == (-1))
            return (-1);
        this.start = result;
        return result;
    }
    append(stream) {
        this.beforeAppend(stream.length);
        this._stream.view.set(stream.view, this._start);
        this._length += (stream.length * 2);
        this.start = (this._start + stream.length);
        this.prevLength -= (stream.length * 2);
    }
    appendView(view) {
        this.beforeAppend(view.length);
        this._stream.view.set(view, this._start);
        this._length += (view.length * 2);
        this.start = (this._start + view.length);
        this.prevLength -= (view.length * 2);
    }
    appendChar(char) {
        this.beforeAppend(1);
        this._stream.view[this._start] = char;
        this._length += 2;
        this.start = (this._start + 1);
        this.prevLength -= 2;
    }
    appendUint16(number) {
        this.beforeAppend(2);
        const value = new Uint16Array([number]);
        const view = new Uint8Array(value.buffer);
        this.stream.view[this._start] = view[1];
        this._stream.view[this._start + 1] = view[0];
        this._length += 4;
        this.start = this._start + 2;
        this.prevLength -= 4;
    }
    appendUint24(number) {
        this.beforeAppend(3);
        const value = new Uint32Array([number]);
        const view = new Uint8Array(value.buffer);
        this._stream.view[this._start] = view[2];
        this._stream.view[this._start + 1] = view[1];
        this._stream.view[this._start + 2] = view[0];
        this._length += 6;
        this.start = (this._start + 3);
        this.prevLength -= 6;
    }
    appendUint32(number) {
        this.beforeAppend(4);
        const value = new Uint32Array([number]);
        const view = new Uint8Array(value.buffer);
        this._stream.view[this._start] = view[3];
        this._stream.view[this._start + 1] = view[2];
        this._stream.view[this._start + 2] = view[1];
        this._stream.view[this._start + 3] = view[0];
        this._length += 8;
        this.start = (this._start + 4);
        this.prevLength -= 8;
    }
    appendInt16(number) {
        this.beforeAppend(2);
        const value = new Int16Array([number]);
        const view = new Uint8Array(value.buffer);
        this._stream.view[this._start] = view[1];
        this._stream.view[this._start + 1] = view[0];
        this._length += 4;
        this.start = (this._start + 2);
        this.prevLength -= 4;
    }
    appendInt32(number) {
        this.beforeAppend(4);
        const value = new Int32Array([number]);
        const view = new Uint8Array(value.buffer);
        this._stream.view[this._start] = view[3];
        this._stream.view[this._start + 1] = view[2];
        this._stream.view[this._start + 2] = view[1];
        this._stream.view[this._start + 3] = view[0];
        this._length += 8;
        this.start = (this._start + 4);
        this.prevLength -= 8;
    }
    getBlock(size, changeLength = true) {
        if (this._length <= 0) {
            return new Uint8Array(0);
        }
        if (this._length < size) {
            size = this._length;
        }
        let result;
        if (this.backward) {
            const view = this._stream.view.subarray(this._length - size, this._length);
            result = new Uint8Array(size);
            for (let i = 0; i < size; i++) {
                result[size - 1 - i] = view[i];
            }
        }
        else {
            result = this._stream.view.subarray(this._start, this._start + size);
        }
        if (changeLength) {
            this.start += ((this.backward) ? ((-1) * size) : size);
        }
        return result;
    }
    getUint16(changeLength = true) {
        const block = this.getBlock(2, changeLength);
        if (block.length < 2)
            return 0;
        return (block[0] << 8) | block[1];
    }
    getInt16(changeLength = true) {
        const num = this.getUint16(changeLength);
        const negative = 0x8000;
        if (num & negative) {
            return -(negative - (num ^ negative));
        }
        return num;
    }
    getUint24(changeLength = true) {
        const block = this.getBlock(4, changeLength);
        if (block.length < 3)
            return 0;
        return (block[0] << 16) |
            (block[1] << 8) |
            block[2];
    }
    getUint32(changeLength = true) {
        const block = this.getBlock(4, changeLength);
        if (block.length < 4)
            return 0;
        return (block[0] * pow2_24) +
            (block[1] << 16) +
            (block[2] << 8) +
            block[3];
    }
    getInt32(changeLength = true) {
        const num = this.getUint32(changeLength);
        const negative = 0x80000000;
        if (num & negative) {
            return -(negative - (num ^ negative));
        }
        return num;
    }
    beforeAppend(size) {
        if ((this._start + size) > this._stream.length) {
            if (size > this.appendBlock) {
                this.appendBlock = size + SeqStream.APPEND_BLOCK;
            }
            this._stream.realloc(this._stream.length + this.appendBlock);
        }
    }
}
SeqStream.APPEND_BLOCK = 1000;

// copied from utils
function isBytes(a) {
    return (a instanceof Uint8Array ||
        (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
}
function bytes(b, ...lengths) {
    if (!isBytes(b))
        throw new Error('Uint8Array expected');
    if (lengths.length > 0 && !lengths.includes(b.length))
        throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
}
function exists(instance, checkFinished = true) {
    if (instance.destroyed)
        throw new Error('Hash instance has been destroyed');
    if (checkFinished && instance.finished)
        throw new Error('Hash#digest() has already been called');
}
function output(out, instance) {
    bytes(out);
    const min = instance.outputLen;
    if (out.length < min) {
        throw new Error(`digestInto() expects output buffer of length at least ${min}`);
    }
}

/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
// node.js versions earlier than v19 don't declare it in global scope.
// For node.js, package.json#exports field mapping rewrites import
// from `crypto` to `cryptoNode`, which imports native module.
// Makes the utils un-importable in browsers without a bundler.
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
// Cast array to view
const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
// The rotate right (circular right shift) operation for uint32
const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
// The rotate left (circular left shift) operation for uint32
const rotl = (word, shift) => (word << shift) | ((word >>> (32 - shift)) >>> 0);
new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
/**
 * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
 */

function utf8ToBytes(str) {
    if (typeof str !== 'string')
        throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
    return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
}
/**
 * Normalizes (non-hex) string or Uint8Array to Uint8Array.
 * Warning: when Uint8Array is passed, it would NOT get copied.
 * Keep in mind for future mutable operations.
 */

function toBytes(data) {
    if (typeof data === 'string')
        data = utf8ToBytes(data);
    bytes(data);
    return data;
}
// For runtime check if class implements interface
class Hash {
    // Safe version that clones internal state
    clone() {
        return this._cloneInto();
    }
}
function wrapConstructor(hashCons) {
    const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
    const tmp = hashCons();
    hashC.outputLen = tmp.outputLen;
    hashC.blockLen = tmp.blockLen;
    hashC.create = () => hashCons();
    return hashC;
}

// Polyfill for Safari 14
function setBigUint64(view, byteOffset, value, isLE) {
    if (typeof view.setBigUint64 === 'function')
        return view.setBigUint64(byteOffset, value, isLE);
    const _32n = BigInt(32);
    const _u32_max = BigInt(0xffffffff);
    const wh = Number((value >> _32n) & _u32_max);
    const wl = Number(value & _u32_max);
    const h = isLE ? 4 : 0;
    const l = isLE ? 0 : 4;
    view.setUint32(byteOffset + h, wh, isLE);
    view.setUint32(byteOffset + l, wl, isLE);
}
// Choice: a ? b : c
const Chi = (a, b, c) => (a & b) ^ (~a & c);
// Majority function, true if any two inpust is true
const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
/**
 * Merkle-Damgard hash construction base class.
 * Could be used to create MD5, RIPEMD, SHA1, SHA2.
 */

class HashMD extends Hash {
    constructor(blockLen, outputLen, padOffset, isLE) {
        super();
        this.blockLen = blockLen;
        this.outputLen = outputLen;
        this.padOffset = padOffset;
        this.isLE = isLE;
        this.finished = false;
        this.length = 0;
        this.pos = 0;
        this.destroyed = false;
        this.buffer = new Uint8Array(blockLen);
        this.view = createView(this.buffer);
    }
    update(data) {
        exists(this);
        const { view, buffer, blockLen } = this;
        data = toBytes(data);
        const len = data.length;
        for (let pos = 0; pos < len;) {
            const take = Math.min(blockLen - this.pos, len - pos);
            // Fast path: we have at least one block in input, cast it to view and process
            if (take === blockLen) {
                const dataView = createView(data);
                for (; blockLen <= len - pos; pos += blockLen)
                    this.process(dataView, pos);
                continue;
            }
            buffer.set(data.subarray(pos, pos + take), this.pos);
            this.pos += take;
            pos += take;
            if (this.pos === blockLen) {
                this.process(view, 0);
                this.pos = 0;
            }
        }
        this.length += data.length;
        this.roundClean();
        return this;
    }
    digestInto(out) {
        exists(this);
        output(out, this);
        this.finished = true;
        // Padding
        // We can avoid allocation of buffer for padding completely if it
        // was previously not allocated here. But it won't change performance.
        const { buffer, view, blockLen, isLE } = this;
        let { pos } = this;
        // append the bit '1' to the message
        buffer[pos++] = 0b10000000;
        this.buffer.subarray(pos).fill(0);
        // we have less than padOffset left in buffer, so we cannot put length in
        // current block, need process it and pad again
        if (this.padOffset > blockLen - pos) {
            this.process(view, 0);
            pos = 0;
        }
        // Pad until full block byte with zeros
        for (let i = pos; i < blockLen; i++)
            buffer[i] = 0;
        // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
        // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
        // So we just write lowest 64 bits of that value.
        setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
        this.process(view, 0);
        const oview = createView(out);
        const len = this.outputLen;
        // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
        if (len % 4)
            throw new Error('_sha2: outputLen should be aligned to 32bit');
        const outLen = len / 4;
        const state = this.get();
        if (outLen > state.length)
            throw new Error('_sha2: outputLen bigger than state');
        for (let i = 0; i < outLen; i++)
            oview.setUint32(4 * i, state[i], isLE);
    }
    digest() {
        const { buffer, outputLen } = this;
        this.digestInto(buffer);
        const res = buffer.slice(0, outputLen);
        this.destroy();
        return res;
    }
    _cloneInto(to) {
        to || (to = new this.constructor());
        to.set(...this.get());
        const { blockLen, buffer, length, finished, destroyed, pos } = this;
        to.length = length;
        to.pos = pos;
        to.finished = finished;
        to.destroyed = destroyed;
        if (length % blockLen)
            to.buffer.set(buffer);
        return to;
    }
}

// SHA1 (RFC 3174) was cryptographically broken. It's still used. Don't use it for a new protocol.
// Initial state
const SHA1_IV = /* @__PURE__ */ new Uint32Array([
    0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0,
]);
// Temporary buffer, not used to store anything between runs
// Named this way because it matches specification.
const SHA1_W = /* @__PURE__ */ new Uint32Array(80);
let SHA1$1 = class SHA1 extends HashMD {
    constructor() {
        super(64, 20, 8, false);
        this.A = SHA1_IV[0] | 0;
        this.B = SHA1_IV[1] | 0;
        this.C = SHA1_IV[2] | 0;
        this.D = SHA1_IV[3] | 0;
        this.E = SHA1_IV[4] | 0;
    }
    get() {
        const { A, B, C, D, E } = this;
        return [A, B, C, D, E];
    }
    set(A, B, C, D, E) {
        this.A = A | 0;
        this.B = B | 0;
        this.C = C | 0;
        this.D = D | 0;
        this.E = E | 0;
    }
    process(view, offset) {
        for (let i = 0; i < 16; i++, offset += 4)
            SHA1_W[i] = view.getUint32(offset, false);
        for (let i = 16; i < 80; i++)
            SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);
        // Compression function main loop, 80 rounds
        let { A, B, C, D, E } = this;
        for (let i = 0; i < 80; i++) {
            let F, K;
            if (i < 20) {
                F = Chi(B, C, D);
                K = 0x5a827999;
            }
            else if (i < 40) {
                F = B ^ C ^ D;
                K = 0x6ed9eba1;
            }
            else if (i < 60) {
                F = Maj(B, C, D);
                K = 0x8f1bbcdc;
            }
            else {
                F = B ^ C ^ D;
                K = 0xca62c1d6;
            }
            const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0;
            E = D;
            D = C;
            C = rotl(B, 30);
            B = A;
            A = T;
        }
        // Add the compressed chunk to the current hash value
        A = (A + this.A) | 0;
        B = (B + this.B) | 0;
        C = (C + this.C) | 0;
        D = (D + this.D) | 0;
        E = (E + this.E) | 0;
        this.set(A, B, C, D, E);
    }
    roundClean() {
        SHA1_W.fill(0);
    }
    destroy() {
        this.set(0, 0, 0, 0, 0);
        this.buffer.fill(0);
    }
};
const sha1 = /* @__PURE__ */ wrapConstructor(() => new SHA1$1());

// SHA2-256 need to try 2^128 hashes to execute birthday attack.
// BTC network is doing 2^67 hashes/sec as per early 2023.
// Round constants:
// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
// prettier-ignore
const SHA256_K = /* @__PURE__ */ new Uint32Array([
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]);
// Initial state:
// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
// prettier-ignore
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
]);
// Temporary buffer, not used to store anything between runs
// Named this way because it matches specification.
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
let SHA256$1 = class SHA256 extends HashMD {
    constructor() {
        super(64, 32, 8, false);
        // We cannot use array here since array allows indexing by variable
        // which means optimizer/compiler cannot use registers.
        this.A = SHA256_IV[0] | 0;
        this.B = SHA256_IV[1] | 0;
        this.C = SHA256_IV[2] | 0;
        this.D = SHA256_IV[3] | 0;
        this.E = SHA256_IV[4] | 0;
        this.F = SHA256_IV[5] | 0;
        this.G = SHA256_IV[6] | 0;
        this.H = SHA256_IV[7] | 0;
    }
    get() {
        const { A, B, C, D, E, F, G, H } = this;
        return [A, B, C, D, E, F, G, H];
    }
    // prettier-ignore
    set(A, B, C, D, E, F, G, H) {
        this.A = A | 0;
        this.B = B | 0;
        this.C = C | 0;
        this.D = D | 0;
        this.E = E | 0;
        this.F = F | 0;
        this.G = G | 0;
        this.H = H | 0;
    }
    process(view, offset) {
        // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
        for (let i = 0; i < 16; i++, offset += 4)
            SHA256_W[i] = view.getUint32(offset, false);
        for (let i = 16; i < 64; i++) {
            const W15 = SHA256_W[i - 15];
            const W2 = SHA256_W[i - 2];
            const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
            const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
            SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
        }
        // Compression function main loop, 64 rounds
        let { A, B, C, D, E, F, G, H } = this;
        for (let i = 0; i < 64; i++) {
            const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
            const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
            const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
            const T2 = (sigma0 + Maj(A, B, C)) | 0;
            H = G;
            G = F;
            F = E;
            E = (D + T1) | 0;
            D = C;
            C = B;
            B = A;
            A = (T1 + T2) | 0;
        }
        // Add the compressed chunk to the current hash value
        A = (A + this.A) | 0;
        B = (B + this.B) | 0;
        C = (C + this.C) | 0;
        D = (D + this.D) | 0;
        E = (E + this.E) | 0;
        F = (F + this.F) | 0;
        G = (G + this.G) | 0;
        H = (H + this.H) | 0;
        this.set(A, B, C, D, E, F, G, H);
    }
    roundClean() {
        SHA256_W.fill(0);
    }
    destroy() {
        this.set(0, 0, 0, 0, 0, 0, 0, 0);
        this.buffer.fill(0);
    }
};
/**
 * SHA2-256 hash function
 * @param message - data that would be hashed
 */

const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256$1());

const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
const _32n = /* @__PURE__ */ BigInt(32);
// We are not using BigUint64Array, because they are extremely slow as per 2022
function fromBig(n, le = false) {
    if (le)
        return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
    return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
}
function split(lst, le = false) {
    let Ah = new Uint32Array(lst.length);
    let Al = new Uint32Array(lst.length);
    for (let i = 0; i < lst.length; i++) {
        const { h, l } = fromBig(lst[i], le);
        [Ah[i], Al[i]] = [h, l];
    }
    return [Ah, Al];
}
const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
// for Shift in [0, 32)
const shrSH = (h, _l, s) => h >>> s;
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
// Right rotate for Shift in [1, 32)
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
// Right rotate for shift===32 (just swaps l&h)
const rotr32H = (_h, l) => l;
const rotr32L = (h, _l) => h;
// Left rotate for Shift in [1, 32)
const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
// Left rotate for Shift in (32, 64), NOTE: 32 is special case.
const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
// JS uses 32-bit signed integers for bitwise operations which means we cannot
// simple take carry out of low bit sum by shift, we need to use division.
function add(Ah, Al, Bh, Bl) {
    const l = (Al >>> 0) + (Bl >>> 0);
    return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
}
// Addition with more than 2 elements
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
// prettier-ignore
const u64 = {
    fromBig, split, toBig,
    shrSH, shrSL,
    rotrSH, rotrSL, rotrBH, rotrBL,
    rotr32H, rotr32L,
    rotlSH, rotlSL, rotlBH, rotlBL,
    add, add3L, add3H, add4L, add4H, add5H, add5L,
};

// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
// prettier-ignore
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
    '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
    '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
    '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
    '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
    '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
    '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
    '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
    '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
    '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
    '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
    '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
    '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
    '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
    '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
    '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
    '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
    '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
    '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
    '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
    '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
].map(n => BigInt(n))))();
// Temporary buffer, not used to store anything between runs
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
let SHA512$1 = class SHA512 extends HashMD {
    constructor() {
        super(128, 64, 16, false);
        // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
        // Also looks cleaner and easier to verify with spec.
        // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
        // h -- high 32 bits, l -- low 32 bits
        this.Ah = 0x6a09e667 | 0;
        this.Al = 0xf3bcc908 | 0;
        this.Bh = 0xbb67ae85 | 0;
        this.Bl = 0x84caa73b | 0;
        this.Ch = 0x3c6ef372 | 0;
        this.Cl = 0xfe94f82b | 0;
        this.Dh = 0xa54ff53a | 0;
        this.Dl = 0x5f1d36f1 | 0;
        this.Eh = 0x510e527f | 0;
        this.El = 0xade682d1 | 0;
        this.Fh = 0x9b05688c | 0;
        this.Fl = 0x2b3e6c1f | 0;
        this.Gh = 0x1f83d9ab | 0;
        this.Gl = 0xfb41bd6b | 0;
        this.Hh = 0x5be0cd19 | 0;
        this.Hl = 0x137e2179 | 0;
    }
    // prettier-ignore
    get() {
        const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
        return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
    }
    // prettier-ignore
    set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
        this.Ah = Ah | 0;
        this.Al = Al | 0;
        this.Bh = Bh | 0;
        this.Bl = Bl | 0;
        this.Ch = Ch | 0;
        this.Cl = Cl | 0;
        this.Dh = Dh | 0;
        this.Dl = Dl | 0;
        this.Eh = Eh | 0;
        this.El = El | 0;
        this.Fh = Fh | 0;
        this.Fl = Fl | 0;
        this.Gh = Gh | 0;
        this.Gl = Gl | 0;
        this.Hh = Hh | 0;
        this.Hl = Hl | 0;
    }
    process(view, offset) {
        // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
        for (let i = 0; i < 16; i++, offset += 4) {
            SHA512_W_H[i] = view.getUint32(offset);
            SHA512_W_L[i] = view.getUint32((offset += 4));
        }
        for (let i = 16; i < 80; i++) {
            // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
            const W15h = SHA512_W_H[i - 15] | 0;
            const W15l = SHA512_W_L[i - 15] | 0;
            const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);
            const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);
            // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
            const W2h = SHA512_W_H[i - 2] | 0;
            const W2l = SHA512_W_L[i - 2] | 0;
            const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);
            const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);
            // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
            const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
            const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
            SHA512_W_H[i] = SUMh | 0;
            SHA512_W_L[i] = SUMl | 0;
        }
        let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
        // Compression function main loop, 80 rounds
        for (let i = 0; i < 80; i++) {
            // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
            const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);
            const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);
            //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
            const CHIh = (Eh & Fh) ^ (~Eh & Gh);
            const CHIl = (El & Fl) ^ (~El & Gl);
            // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
            // prettier-ignore
            const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
            const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
            const T1l = T1ll | 0;
            // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
            const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);
            const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);
            const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
            const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
            Hh = Gh | 0;
            Hl = Gl | 0;
            Gh = Fh | 0;
            Gl = Fl | 0;
            Fh = Eh | 0;
            Fl = El | 0;
            ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
            Dh = Ch | 0;
            Dl = Cl | 0;
            Ch = Bh | 0;
            Cl = Bl | 0;
            Bh = Ah | 0;
            Bl = Al | 0;
            const All = u64.add3L(T1l, sigma0l, MAJl);
            Ah = u64.add3H(All, T1h, sigma0h, MAJh);
            Al = All | 0;
        }
        // Add the compressed chunk to the current hash value
        ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
        ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
        ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
        ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
        ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
        ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
        ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
        ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
        this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
    }
    roundClean() {
        SHA512_W_H.fill(0);
        SHA512_W_L.fill(0);
    }
    destroy() {
        this.buffer.fill(0);
        this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    }
};
let SHA384$1 = class SHA384 extends SHA512$1 {
    constructor() {
        super();
        // h -- high 32 bits, l -- low 32 bits
        this.Ah = 0xcbbb9d5d | 0;
        this.Al = 0xc1059ed8 | 0;
        this.Bh = 0x629a292a | 0;
        this.Bl = 0x367cd507 | 0;
        this.Ch = 0x9159015a | 0;
        this.Cl = 0x3070dd17 | 0;
        this.Dh = 0x152fecd8 | 0;
        this.Dl = 0xf70e5939 | 0;
        this.Eh = 0x67332667 | 0;
        this.El = 0xffc00b31 | 0;
        this.Fh = 0x8eb44a87 | 0;
        this.Fl = 0x68581511 | 0;
        this.Gh = 0xdb0c2e0d | 0;
        this.Gl = 0x64f98fa7 | 0;
        this.Hh = 0x47b5481d | 0;
        this.Hl = 0xbefa4fa4 | 0;
        this.outputLen = 48;
    }
};
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512$1());
const sha384 = /* @__PURE__ */ wrapConstructor(() => new SHA384$1());

var _a;
class ECNamedCurves {
    static register(name, id, size) {
        this.namedCurves[name.toLowerCase()] = this.namedCurves[id] = { name, id, size };
    }
    static find(nameOrId) {
        return this.namedCurves[nameOrId.toLowerCase()] || null;
    }
}
_a = ECNamedCurves;
ECNamedCurves.namedCurves = {};
(() => {
    _a.register("P-256", "1.2.840.10045.3.1.7", 32);
    _a.register("P-384", "1.3.132.0.34", 48);
    _a.register("P-521", "1.3.132.0.35", 66);
    _a.register("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 32);
    _a.register("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 48);
    _a.register("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 64);
})();

const X = "x";
const Y = "y";
const NAMED_CURVE$1 = "namedCurve";
class ECPublicKey extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.x = getParametersValue(parameters, X, ECPublicKey.defaultValues(X));
        this.y = getParametersValue(parameters, Y, ECPublicKey.defaultValues(Y));
        this.namedCurve = getParametersValue(parameters, NAMED_CURVE$1, ECPublicKey.defaultValues(NAMED_CURVE$1));
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case X:
            case Y:
                return EMPTY_BUFFER;
            case NAMED_CURVE$1:
                return EMPTY_STRING;
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case X:
            case Y:
                return memberValue instanceof ArrayBuffer &&
                    (isEqualBuffer(memberValue, ECPublicKey.defaultValues(memberName)));
            case NAMED_CURVE$1:
                return typeof memberValue === "string" &&
                    memberValue === ECPublicKey.defaultValues(memberName);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema() {
        return new RawData();
    }
    fromSchema(schema1) {
        const view = BufferSourceConverter.toUint8Array(schema1);
        if (view[0] !== 0x04) {
            throw new Error("Object's schema was not verified against input data for ECPublicKey");
        }
        const namedCurve = ECNamedCurves.find(this.namedCurve);
        if (!namedCurve) {
            throw new Error(`Incorrect curve OID: ${this.namedCurve}`);
        }
        const coordinateLength = namedCurve.size;
        if (view.byteLength !== (coordinateLength * 2 + 1)) {
            throw new Error("Object's schema was not verified against input data for ECPublicKey");
        }
        this.namedCurve = namedCurve.name;
        this.x = view.slice(1, coordinateLength + 1).buffer;
        this.y = view.slice(1 + coordinateLength, coordinateLength * 2 + 1).buffer;
    }
    toSchema() {
        return new RawData({
            data: utilConcatBuf((new Uint8Array([0x04])).buffer, this.x, this.y)
        });
    }
    toJSON() {
        const namedCurve = ECNamedCurves.find(this.namedCurve);
        return {
            crv: namedCurve ? namedCurve.name : this.namedCurve,
            x: toBase64(arrayBufferToString(this.x), true, true, false),
            y: toBase64(arrayBufferToString(this.y), true, true, false)
        };
    }
    fromJSON(json) {
        ParameterError.assert("json", json, "crv", "x", "y");
        let coordinateLength = 0;
        const namedCurve = ECNamedCurves.find(json.crv);
        if (namedCurve) {
            this.namedCurve = namedCurve.id;
            coordinateLength = namedCurve.size;
        }
        const xConvertBuffer = stringToArrayBuffer(fromBase64(json.x, true));
        if (xConvertBuffer.byteLength < coordinateLength) {
            this.x = new ArrayBuffer(coordinateLength);
            const view = new Uint8Array(this.x);
            const convertBufferView = new Uint8Array(xConvertBuffer);
            view.set(convertBufferView, 1);
        }
        else {
            this.x = xConvertBuffer.slice(0, coordinateLength);
        }
        const yConvertBuffer = stringToArrayBuffer(fromBase64(json.y, true));
        if (yConvertBuffer.byteLength < coordinateLength) {
            this.y = new ArrayBuffer(coordinateLength);
            const view = new Uint8Array(this.y);
            const convertBufferView = new Uint8Array(yConvertBuffer);
            view.set(convertBufferView, 1);
        }
        else {
            this.y = yConvertBuffer.slice(0, coordinateLength);
        }
    }
}
ECPublicKey.CLASS_NAME = "ECPublicKey";

const MODULUS$1 = "modulus";
const PUBLIC_EXPONENT$1 = "publicExponent";
const CLEAR_PROPS$1b = [MODULUS$1, PUBLIC_EXPONENT$1];
class RSAPublicKey extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.modulus = getParametersValue(parameters, MODULUS$1, RSAPublicKey.defaultValues(MODULUS$1));
        this.publicExponent = getParametersValue(parameters, PUBLIC_EXPONENT$1, RSAPublicKey.defaultValues(PUBLIC_EXPONENT$1));
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case MODULUS$1:
                return new Integer();
            case PUBLIC_EXPONENT$1:
                return new Integer();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.modulus || EMPTY_STRING) }),
                new Integer({ name: (names.publicExponent || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1b);
        const asn1 = compareSchema(schema, schema, RSAPublicKey.schema({
            names: {
                modulus: MODULUS$1,
                publicExponent: PUBLIC_EXPONENT$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.modulus = asn1.result.modulus.convertFromDER(256);
        this.publicExponent = asn1.result.publicExponent;
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.modulus.convertToDER(),
                this.publicExponent
            ]
        }));
    }
    toJSON() {
        return {
            n: Convert.ToBase64Url(this.modulus.valueBlock.valueHexView),
            e: Convert.ToBase64Url(this.publicExponent.valueBlock.valueHexView),
        };
    }
    fromJSON(json) {
        ParameterError.assert("json", json, "n", "e");
        const array = stringToArrayBuffer(fromBase64(json.n, true));
        this.modulus = new Integer({ valueHex: array.slice(0, Math.pow(2, nearestPowerOf2(array.byteLength))) });
        this.publicExponent = new Integer({ valueHex: stringToArrayBuffer(fromBase64(json.e, true)).slice(0, 3) });
    }
}
RSAPublicKey.CLASS_NAME = "RSAPublicKey";

const ALGORITHM$1 = "algorithm";
const SUBJECT_PUBLIC_KEY = "subjectPublicKey";
const CLEAR_PROPS$1a = [ALGORITHM$1, SUBJECT_PUBLIC_KEY];
class PublicKeyInfo extends PkiObject {
    get parsedKey() {
        if (this._parsedKey === undefined) {
            switch (this.algorithm.algorithmId) {
                case "1.2.840.10045.2.1":
                    if ("algorithmParams" in this.algorithm) {
                        if (this.algorithm.algorithmParams.constructor.blockName() === ObjectIdentifier.blockName()) {
                            try {
                                this._parsedKey = new ECPublicKey({
                                    namedCurve: this.algorithm.algorithmParams.valueBlock.toString(),
                                    schema: this.subjectPublicKey.valueBlock.valueHexView
                                });
                            }
                            catch {
                            }
                        }
                    }
                    break;
                case "1.2.840.113549.1.1.1":
                    {
                        const publicKeyASN1 = fromBER(this.subjectPublicKey.valueBlock.valueHexView);
                        if (publicKeyASN1.offset !== -1) {
                            try {
                                this._parsedKey = new RSAPublicKey({ schema: publicKeyASN1.result });
                            }
                            catch {
                            }
                        }
                    }
                    break;
            }
            this._parsedKey || (this._parsedKey = null);
        }
        return this._parsedKey || undefined;
    }
    set parsedKey(value) {
        this._parsedKey = value;
    }
    constructor(parameters = {}) {
        super();
        this.algorithm = getParametersValue(parameters, ALGORITHM$1, PublicKeyInfo.defaultValues(ALGORITHM$1));
        this.subjectPublicKey = getParametersValue(parameters, SUBJECT_PUBLIC_KEY, PublicKeyInfo.defaultValues(SUBJECT_PUBLIC_KEY));
        const parsedKey = getParametersValue(parameters, "parsedKey", null);
        if (parsedKey) {
            this.parsedKey = parsedKey;
        }
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ALGORITHM$1:
                return new AlgorithmIdentifier();
            case SUBJECT_PUBLIC_KEY:
                return new BitString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                AlgorithmIdentifier.schema(names.algorithm || {}),
                new BitString({ name: (names.subjectPublicKey || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$1a);
        const asn1 = compareSchema(schema, schema, PublicKeyInfo.schema({
            names: {
                algorithm: {
                    names: {
                        blockName: ALGORITHM$1
                    }
                },
                subjectPublicKey: SUBJECT_PUBLIC_KEY
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.algorithm = new AlgorithmIdentifier({ schema: asn1.result.algorithm });
        this.subjectPublicKey = asn1.result.subjectPublicKey;
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.algorithm.toSchema(),
                this.subjectPublicKey
            ]
        }));
    }
    toJSON() {
        if (!this.parsedKey) {
            return {
                algorithm: this.algorithm.toJSON(),
                subjectPublicKey: this.subjectPublicKey.toJSON(),
            };
        }
        const jwk = {};
        switch (this.algorithm.algorithmId) {
            case "1.2.840.10045.2.1":
                jwk.kty = "EC";
                break;
            case "1.2.840.113549.1.1.1":
                jwk.kty = "RSA";
                break;
        }
        const publicKeyJWK = this.parsedKey.toJSON();
        Object.assign(jwk, publicKeyJWK);
        return jwk;
    }
    fromJSON(json) {
        if ("kty" in json) {
            switch (json.kty.toUpperCase()) {
                case "EC":
                    this.parsedKey = new ECPublicKey({ json });
                    this.algorithm = new AlgorithmIdentifier({
                        algorithmId: "1.2.840.10045.2.1",
                        algorithmParams: new ObjectIdentifier({ value: this.parsedKey.namedCurve })
                    });
                    break;
                case "RSA":
                    this.parsedKey = new RSAPublicKey({ json });
                    this.algorithm = new AlgorithmIdentifier({
                        algorithmId: "1.2.840.113549.1.1.1",
                        algorithmParams: new Null()
                    });
                    break;
                default:
                    throw new Error(`Invalid value for "kty" parameter: ${json.kty}`);
            }
            this.subjectPublicKey = new BitString({ valueHex: this.parsedKey.toSchema().toBER(false) });
        }
    }
    async importKey(publicKey, crypto = getCrypto(true)) {
        try {
            if (!publicKey) {
                throw new Error("Need to provide publicKey input parameter");
            }
            const exportedKey = await crypto.exportKey("spki", publicKey);
            const asn1 = fromBER(exportedKey);
            try {
                this.fromSchema(asn1.result);
            }
            catch {
                throw new Error("Error during initializing object from schema");
            }
        }
        catch (e) {
            const message = e instanceof Error ? e.message : `${e}`;
            throw new Error(`Error during exporting public key: ${message}`);
        }
    }
}
PublicKeyInfo.CLASS_NAME = "PublicKeyInfo";

const VERSION$l = "version";
const PRIVATE_KEY$1 = "privateKey";
const NAMED_CURVE = "namedCurve";
const PUBLIC_KEY$1 = "publicKey";
const CLEAR_PROPS$19 = [
    VERSION$l,
    PRIVATE_KEY$1,
    NAMED_CURVE,
    PUBLIC_KEY$1
];
class ECPrivateKey extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$l, ECPrivateKey.defaultValues(VERSION$l));
        this.privateKey = getParametersValue(parameters, PRIVATE_KEY$1, ECPrivateKey.defaultValues(PRIVATE_KEY$1));
        if (NAMED_CURVE in parameters) {
            this.namedCurve = getParametersValue(parameters, NAMED_CURVE, ECPrivateKey.defaultValues(NAMED_CURVE));
        }
        if (PUBLIC_KEY$1 in parameters) {
            this.publicKey = getParametersValue(parameters, PUBLIC_KEY$1, ECPrivateKey.defaultValues(PUBLIC_KEY$1));
        }
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$l:
                return 1;
            case PRIVATE_KEY$1:
                return new OctetString();
            case NAMED_CURVE:
                return EMPTY_STRING;
            case PUBLIC_KEY$1:
                return new ECPublicKey();
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case VERSION$l:
                return (memberValue === ECPrivateKey.defaultValues(memberName));
            case PRIVATE_KEY$1:
                return (memberValue.isEqual(ECPrivateKey.defaultValues(memberName)));
            case NAMED_CURVE:
                return (memberValue === EMPTY_STRING);
            case PUBLIC_KEY$1:
                return ((ECPublicKey.compareWithDefault(NAMED_CURVE, memberValue.namedCurve)) &&
                    (ECPublicKey.compareWithDefault("x", memberValue.x)) &&
                    (ECPublicKey.compareWithDefault("y", memberValue.y)));
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.version || EMPTY_STRING) }),
                new OctetString({ name: (names.privateKey || EMPTY_STRING) }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [
                        new ObjectIdentifier({ name: (names.namedCurve || EMPTY_STRING) })
                    ]
                }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: [
                        new BitString({ name: (names.publicKey || EMPTY_STRING) })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$19);
        const asn1 = compareSchema(schema, schema, ECPrivateKey.schema({
            names: {
                version: VERSION$l,
                privateKey: PRIVATE_KEY$1,
                namedCurve: NAMED_CURVE,
                publicKey: PUBLIC_KEY$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.version = asn1.result.version.valueBlock.valueDec;
        this.privateKey = asn1.result.privateKey;
        if (NAMED_CURVE in asn1.result) {
            this.namedCurve = asn1.result.namedCurve.valueBlock.toString();
        }
        if (PUBLIC_KEY$1 in asn1.result) {
            const publicKeyData = { schema: asn1.result.publicKey.valueBlock.valueHex };
            if// This code is governed by the BSD license found in the LICENSE file.
. =java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 59
            }
            this.publicKey = new ECPublicKey(publicKeyData);
        }
    }
    toSchema() {
        const outputArray = [
            new Integer({ value: this.version }),
            this.privateKey
        ];
        if (this.namedCurve) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: [
                    new ObjectIdentifier({ value: this.namedCurve })
                ]
            }));
        }
        if (this.publicKey) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: [
                    new BitString({ valueHex: this.publicKey.toSchema().toBER(false) })
                ]
            }));
        }
        return new Sequence({
            value: outputArray
        });
    }
    toJSON() {
        if (!this.namedCurve || ECPrivateKey.compareWithDefault(NAMED_CURVE, this.namedCurve)) {
            throw new Error("Not enough information for making JSON: absent \"namedCurve\" value");
        }
        const curve = ECNamedCurves.find(this.namedCurve);
        const privateKeyJSON = {
            crv: curve ? curve.name : this.namedCurve,
            d: Convert.ToBase64Url(this.privateKey.valueBlock.valueHexView),
        };
        if (this.publicKey) {
            const publicKeyJSON = this.publicKey.toJSON();
            privateKeyJSON.x = publicKeyJSON.x;
            privateKeyJSON.y = publicKeyJSON.y;
        }
        return privateKeyJSON;
    }
    fromJSON(json) {
        ParameterError.assert("json", json, "crv", "d");
        let coordinateLength = 0;
        const curve = ECNamedCurves.find(json.crv);
        if (curve) {
            this.namedCurve = curve.id;
            coordinateLength = curve.size;
        }
        const convertBuffer = Convert.FromBase64Url(json.d);
        if (convertBuffer.byteLength < coordinateLength) {
            const buffer = new ArrayBuffer(coordinateLength);
            const view = new Uint8Array(buffer);
            const convertBufferView = new Uint8Array(convertBuffer);
            view.set(convertBufferView, 1);
            this.privateKey = new OctetString({ valueHex: buffer });
        }
        else {
            this.privateKey = new OctetString({ valueHex: convertBuffer.slice(0, coordinateLength) });
        }
        if (json.x && json.y) {
            this.publicKey = new ECPublicKey({ json });
        }
    }
}
ECPrivateKey.CLASS_NAME = "ECPrivateKey";

const PRIME = "prime";
const EXPONENT = "exponent";
const COEFFICIENT$1 = "coefficient";
const CLEAR_PROPS$18 = [
    PRIME,
    EXPONENT,
    COEFFICIENT$1,
];
class OtherPrimeInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.prime = getParametersValue(parameters, PRIME, OtherPrimeInfo.defaultValues(PRIME));
        this.exponent = getParametersValue(parameters, EXPONENT, OtherPrimeInfo.defaultValues(EXPONENT));
        this.coefficient = getParametersValue(parameters, COEFFICIENT$1, OtherPrimeInfo.defaultValues(COEFFICIENT$1));
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case PRIME:
                return new Integer();
            case EXPONENT:
                return new Integer();
            case COEFFICIENT$1:
                return new Integer();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.prime || EMPTY_STRING) }),
                new Integer({ name: (names.exponent || EMPTY_STRING) }),
                new Integer({ name: (names.coefficient || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$18);
        const asn1 = compareSchema(schema, schema, OtherPrimeInfo.schema({
            names: {
                prime: PRIME,
                exponent: EXPONENT,
                coefficient: COEFFICIENT$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.prime = asn1.result.prime.convertFromDER();
        this.exponent = asn1.result.exponent.convertFromDER();
        this.coefficient = asn1.result.coefficient.convertFromDER();
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.prime.convertToDER(),
                this.exponent.convertToDER(),
                this.coefficient.convertToDER()
            ]
        }));
    }
    toJSON() {
        return {
            r: Convert.ToBase64Url(this.prime.valueBlock.valueHexView),
            d: Convert.ToBase64Url(this.exponent.valueBlock.valueHexView),
            t: Convert.ToBase64Url(this.coefficient.valueBlock.valueHexView),
        };
    }
    fromJSON(json) {
        ParameterError.assert("json", json, "r", "d", "r");
        this.prime = new Integer({ valueHex: Convert.FromBase64Url(json.r) });
        this.exponent = new Integer({ valueHex: Convert.FromBase64Url(json.d) });
        this.coefficient = new Integer({ valueHex: Convert.FromBase64Url(json.t) });
    }
}
OtherPrimeInfo.CLASS_NAME = "OtherPrimeInfo";

const VERSION$k = "version";
const MODULUS = "modulus";
const PUBLIC_EXPONENT = "publicExponent";
const PRIVATE_EXPONENT = "privateExponent";
const PRIME1 = "prime1";
const PRIME2 = "prime2";
const EXPONENT1 = "exponent1";
const EXPONENT2 = "exponent2";
const COEFFICIENT = "coefficient";
const OTHER_PRIME_INFOS = "otherPrimeInfos";
const CLEAR_PROPS$17 = [
    VERSION$k,
    MODULUS,
    PUBLIC_EXPONENT,
    PRIVATE_EXPONENT,
    PRIME1,
    PRIME2,
    EXPONENT1,
    EXPONENT2,
    COEFFICIENT,
    OTHER_PRIME_INFOS
];
class RSAPrivateKey extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$k, RSAPrivateKey.defaultValues(VERSION$k));
        this.modulus = getParametersValue(parameters, MODULUS, RSAPrivateKey.defaultValues(MODULUS));
        this.publicExponent = getParametersValue(parameters, PUBLIC_EXPONENT, RSAPrivateKey.defaultValues(PUBLIC_EXPONENT));
        this.privateExponent = getParametersValue(parameters, PRIVATE_EXPONENT, RSAPrivateKey.defaultValues(PRIVATE_EXPONENT));
        this.prime1 = getParametersValue(parameters, PRIME1, RSAPrivateKey.defaultValues(PRIME1));
        this.prime2 = getParametersValue(parameters, PRIME2, RSAPrivateKey.defaultValues(PRIME2));
        this.exponent1 = getParametersValue(parameters, EXPONENT1, RSAPrivateKey.defaultValues(EXPONENT1));
        this.exponent2 = getParametersValue(parameters, EXPONENT2, RSAPrivateKey.defaultValues(EXPONENT2));
        this.coefficient = getParametersValue(parameters, COEFFICIENT, RSAPrivateKey.defaultValues(COEFFICIENT));
        if (OTHER_PRIME_INFOS in parameters) {
            this.otherPrimeInfos = getParametersValue(parameters, OTHER_PRIME_INFOS, RSAPrivateKey.defaultValues(OTHER_PRIME_INFOS));
        }
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$k:
                return 0;
            case MODULUS:
                return new Integer();
            case PUBLIC_EXPONENT:
                return new Integer();
            case PRIVATE_EXPONENT:
                return new Integer();
            case PRIME1:
                return new Integer();
            case PRIME2:
                return new Integer();
            case EXPONENT1:
                return new Integer();
            case EXPONENT2:
                return new Integer();
            case COEFFICIENT:
                return new Integer();
            case OTHER_PRIME_INFOS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.version || EMPTY_STRING) }),
                new Integer({ name: (names.modulus || EMPTY_STRING) }),
                new Integer({ name: (names.publicExponent || EMPTY_STRING) }),
                new Integer({ name: (names.privateExponent || EMPTY_STRING) }),
                new Integer({ name: (names.prime1 || EMPTY_STRING) }),
                new Integer({ name: (names.prime2 || EMPTY_STRING) }),
                new Integer({ name: (names.exponent1 || EMPTY_STRING) }),
                new Integer({ name: (names.exponent2 || EMPTY_STRING) }),
                new Integer({ name: (names.coefficient || EMPTY_STRING) }),
                new Sequence({
                    optional: true,
                    value: [
                        new Repeated({
                            name: (names.otherPrimeInfosName || EMPTY_STRING),
                            value: OtherPrimeInfo.schema(names.otherPrimeInfo || {})
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$17);
        const asn1 = compareSchema(schema, schema, RSAPrivateKey.schema({
            names: {
                version: VERSION$k,
                modulus: MODULUS,
                publicExponent: PUBLIC_EXPONENT,
                privateExponent: PRIVATE_EXPONENT,
                prime1: PRIME1,
                prime2: PRIME2,
                exponent1: EXPONENT1,
                exponent2: EXPONENT2,
                coefficient: COEFFICIENT,
                otherPrimeInfo: {
                    names: {
                        blockName: OTHER_PRIME_INFOS
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.version = asn1.result.version.valueBlock.valueDec;
        this.modulus = asn1.result.modulus.convertFromDER(256);
        this.publicExponent = asn1.result.publicExponent;
        this.privateExponent = asn1.result.privateExponent.convertFromDER(256);
        this.prime1 = asn1.result.prime1.convertFromDER(128);
        this.prime2 = asn1.result.prime2.convertFromDER(128);
        this.exponent1 = asn1.result.exponent1.convertFromDER(128);
        this.exponent2 = asn1.result.exponent2.convertFromDER(128);
        this.coefficient = asn1.result.coefficient.convertFromDER(128);
        if (OTHER_PRIME_INFOS in asn1.result)
            this.otherPrimeInfos = Array.from(asn1.result.otherPrimeInfos, element => new OtherPrimeInfo({ schema: element }));
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(new Integer({ value: this.version }));
        outputArray.push(this.modulus.convertToDER());
        outputArray.push(this.publicExponent);
        outputArray.push(this.privateExponent.convertToDER());
        outputArray.push(this.prime1.convertToDER());
        outputArray.push(this.prime2.convertToDER());
        outputArray.push(this.exponent1.convertToDER());
        outputArray.push(this.exponent2.convertToDER());
        outputArray.push(this.coefficient.convertToDER());
        if (this.otherPrimeInfos) {
            outputArray.push(new Sequence({
                value: Array.from(this.otherPrimeInfos, o => o.toSchema())
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const jwk = {
            n: Convert.ToBase64Url(this.modulus.valueBlock.valueHexView),
            e: Convert.ToBase64Url(this.publicExponent.valueBlock.valueHexView),
            d: Convert.ToBase64Url(this.privateExponent.valueBlock.valueHexView),
            p: Convert.ToBase64Url(this.prime1.valueBlock.valueHexView),
            q: Convert.ToBase64Url(this.prime2.valueBlock.valueHexView),
            dp: Convert.ToBase64Url(this.exponent1.valueBlock.valueHexView),
            dq: Convert.ToBase64Url(this.exponent2.valueBlock.valueHexView),
            qi: Convert.ToBase64Url(this.coefficient.valueBlock.valueHexView),
        };
        if (this.otherPrimeInfos) {
            jwk.oth = Array.from(this.otherPrimeInfos, o => o.toJSON());
        }
        return jwk;
    }
    fromJSON(json) {
        ParameterError.assert("json", json, "n", "e", "d", "p", "q", "dp", "dq", "qi");
        this.modulus = new Integer({ valueHex: Convert.FromBase64Url(json.n) });
        this.publicExponent = new Integer({ valueHex: Convert.FromBase64Url(json.e) });
        this.privateExponent = new Integer({ valueHex: Convert.FromBase64Url(json.d) });
        this.prime1 = new Integer({ valueHex: Convert.FromBase64Url(json.p) });
        this.prime2 = new Integer({ valueHex: Convert.FromBase64Url(json.q) });
        this.exponent1 = new Integer({ valueHex: Convert.FromBase64Url(json.dp) });
        this.exponent2 = new Integer({ valueHex: Convert.FromBase64Url(json.dq) });
        this.coefficient = new Integer({ valueHex: Convert.FromBase64Url(json.qi) });
        if (json.oth) {
            this.otherPrimeInfos = Array.from(json.oth, (element) => new OtherPrimeInfo({ json: element }));
        }
    }
}
RSAPrivateKey.CLASS_NAME = "RSAPrivateKey";

const VERSION$j = "version";
const PRIVATE_KEY_ALGORITHM = "privateKeyAlgorithm";
const PRIVATE_KEY = "privateKey";
const ATTRIBUTES$5 = "attributes";
const PARSED_KEY = "parsedKey";
const CLEAR_PROPS$16 = [
    VERSION$j,
    PRIVATE_KEY_ALGORITHM,
    PRIVATE_KEY,
    ATTRIBUTES$5
];
class PrivateKeyInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$j, PrivateKeyInfo.defaultValues(VERSION$j));
        this.privateKeyAlgorithm = getParametersValue(parameters, PRIVATE_KEY_ALGORITHM, PrivateKeyInfo.defaultValues(PRIVATE_KEY_ALGORITHM));
        this.privateKey = getParametersValue(parameters, PRIVATE_KEY, PrivateKeyInfo.defaultValues(PRIVATE_KEY));
        if (ATTRIBUTES$5 in parameters) {
            this.attributes = getParametersValue(parameters, ATTRIBUTES$5, PrivateKeyInfo.defaultValues(ATTRIBUTES$5));
        }
        if (PARSED_KEY in parameters) {
            this.parsedKey = getParametersValue(parameters, PARSED_KEY, PrivateKeyInfo.defaultValues(PARSED_KEY));
        }
        if (parameters.json) {
            this.fromJSON(parameters.json);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$j:
                return 0;
            case PRIVATE_KEY_ALGORITHM:
                return new AlgorithmIdentifier();
            case PRIVATE_KEY:
                return new OctetString();
            case ATTRIBUTES$5:
                return [];
            case PARSED_KEY:
                return {};
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.version || EMPTY_STRING) }),
                AlgorithmIdentifier.schema(names.privateKeyAlgorithm || {}),
                new OctetString({ name: (names.privateKey || EMPTY_STRING) }),
                new Constructed({
                    optional: true,
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [
                        new Repeated({
                            name: (names.attributes || EMPTY_STRING),
                            value: Attribute.schema()
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$16);
        const asn1 = compareSchema(schema, schema, PrivateKeyInfo.schema({
            names: {
                version: VERSION$j,
                privateKeyAlgorithm: {
                    names: {
                        blockName: PRIVATE_KEY_ALGORITHM
                    }
                },
                privateKey: PRIVATE_KEY,
                attributes: ATTRIBUTES$5
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.version = asn1.result.version.valueBlock.valueDec;
        this.privateKeyAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.privateKeyAlgorithm });
        this.privateKey = asn1.result.privateKey;
        if (ATTRIBUTES$5 in asn1.result)
            this.attributes = Array.from(asn1.result.attributes, element => new Attribute({ schema: element }));
        switch (this.privateKeyAlgorithm.algorithmId) {
            case "1.2.840.113549.1.1.1":
                {
                    const privateKeyASN1 = fromBER(this.privateKey.valueBlock.valueHexView);
                    if (privateKeyASN1.offset !== -1)
                        this.parsedKey = new RSAPrivateKey({ schema: privateKeyASN1.result });
                }
                break;
            case "1.2.840.10045.2.1":
                if ("algorithmParams" in this.privateKeyAlgorithm) {
                    if (this.privateKeyAlgorithm.algorithmParams instanceof ObjectIdentifier) {
                        const privateKeyASN1 = fromBER(this.privateKey.valueBlock.valueHexView);
                        if (privateKeyASN1.offset !== -1) {
                            this.parsedKey = new ECPrivateKey({
                                namedCurve: this.privateKeyAlgorithm.algorithmParams.valueBlock.toString(),
                                schema: privateKeyASN1.result
                            });
                        }
                    }
                }
                break;
        }
    }
    toSchema() {
        const outputArray = [
            new Integer({ value: this.version }),
            this.privateKeyAlgorithm.toSchema(),
            this.privateKey
        ];
        if (this.attributes) {
            outputArray.push(new Constructed({
                optional: true,
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: Array.from(this.attributes, o => o.toSchema())
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        if (!this.parsedKey) {
            const object = {
                version: this.version,
                privateKeyAlgorithm: this.privateKeyAlgorithm.toJSON(),
                privateKey: this.privateKey.toJSON(),
            };
            if (this.attributes) {
                object.attributes = Array.from(this.attributes, o => o.toJSON());
            }
            return object;
        }
        const jwk = {};
        switch (this.privateKeyAlgorithm.algorithmId) {
            case "1.2.840.10045.2.1":
                jwk.kty = "EC";
                break;
            case "1.2.840.113549.1.1.1":
                jwk.kty = "RSA";
                break;
        }
        const publicKeyJWK = this.parsedKey.toJSON();
        Object.assign(jwk, publicKeyJWK);
        return jwk;
    }
    fromJSON(json) {
        if ("kty" in json) {
            switch (json.kty.toUpperCase()) {
                case "EC":
                    this.parsedKey = new ECPrivateKey({ json });
                    this.privateKeyAlgorithm = new AlgorithmIdentifier({
                        algorithmId: "1.2.840.10045.2.1",
                        algorithmParams: new ObjectIdentifier({ value: this.parsedKey.namedCurve })
                    });
                    break;
                case "RSA":
                    this.parsedKey = new RSAPrivateKey({ json });
                    this.privateKeyAlgorithm = new AlgorithmIdentifier({
                        algorithmId: "1.2.840.113549.1.1.1",
                        algorithmParams: new Null()
                    });
                    break;
                default:
                    throw new Error(`Invalid value for "kty" parameter: ${json.kty}`);
            }
            this.privateKey = new OctetString({ valueHex: this.parsedKey.toSchema().toBER(false) });
        }
    }
}
PrivateKeyInfo.CLASS_NAME = "PrivateKeyInfo";

const CONTENT_TYPE$1 = "contentType";
const CONTENT_ENCRYPTION_ALGORITHM = "contentEncryptionAlgorithm";
const ENCRYPTED_CONTENT = "encryptedContent";
const CLEAR_PROPS$15 = [
    CONTENT_TYPE$1,
    CONTENT_ENCRYPTION_ALGORITHM,
    ENCRYPTED_CONTENT,
];
const PIECE_SIZE = 1024;
class EncryptedContentInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.contentType = getParametersValue(parameters, CONTENT_TYPE$1, EncryptedContentInfo.defaultValues(CONTENT_TYPE$1));
        this.contentEncryptionAlgorithm = getParametersValue(parameters, CONTENT_ENCRYPTION_ALGORITHM, EncryptedContentInfo.defaultValues(CONTENT_ENCRYPTION_ALGORITHM));
        if (ENCRYPTED_CONTENT in parameters && parameters.encryptedContent) {
            this.encryptedContent = parameters.encryptedContent;
            if ((this.encryptedContent.idBlock.tagClass === 1) &&
                (this.encryptedContent.idBlock.tagNumber === 4)) {
                if (this.encryptedContent.idBlock.isConstructed === false && !parameters.disableSplit) {
                    const constrString = new OctetString({
                        idBlock: { isConstructed: true },
                        isConstructed: true
                    });
                    let offset = 0;
                    const valueHex = this.encryptedContent.valueBlock.valueHexView.slice().buffer;
                    let length = valueHex.byteLength;
                    while (length > 0) {
                        const pieceView = new Uint8Array(valueHex, offset, ((offset + PIECE_SIZE) > valueHex.byteLength) ? (valueHex.byteLength - offset) : PIECE_SIZE);
                        const _array = new ArrayBuffer(pieceView.length);
                        const _view = new Uint8Array(_array);
                        for (let i = 0; i < _view.length; i++)
                            _view[i] = pieceView[i];
                        constrString.valueBlock.value.push(new OctetString({ valueHex: _array }));
                        length -= pieceView.length;
                        offset += pieceView.length;
                    }
                    this.encryptedContent = constrString;
                }
            }
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case CONTENT_TYPE$1:
                return EMPTY_STRING;
            case CONTENT_ENCRYPTION_ALGORITHM:
                return new AlgorithmIdentifier();
            case ENCRYPTED_CONTENT:
                return new OctetString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case CONTENT_TYPE$1:
                return (memberValue === EMPTY_STRING);
            case CONTENT_ENCRYPTION_ALGORITHM:
                return ((memberValue.algorithmId === EMPTY_STRING) && (("algorithmParams" in memberValue) === false));
            case ENCRYPTED_CONTENT:
                return (memberValue.isEqual(EncryptedContentInfo.defaultValues(ENCRYPTED_CONTENT)));
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.contentType || EMPTY_STRING) }),
                AlgorithmIdentifier.schema(names.contentEncryptionAlgorithm || {}),
                new Choice({
                    value: [
                        new Constructed({
                            name: (names.encryptedContent || EMPTY_STRING),
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 0
                            },
                            value: [
                                new Repeated({
                                    value: new OctetString()
                                })
                            ]
                        }),
                        new Primitive({
                            name: (names.encryptedContent || EMPTY_STRING),
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 0
                            }
                        })
                    ]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$15);
        const asn1 = compareSchema(schema, schema, EncryptedContentInfo.schema({
            names: {
                contentType: CONTENT_TYPE$1,
                contentEncryptionAlgorithm: {
                    names: {
                        blockName: CONTENT_ENCRYPTION_ALGORITHM
                    }
                },
                encryptedContent: ENCRYPTED_CONTENT
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.contentType = asn1.result.contentType.valueBlock.toString();
        this.contentEncryptionAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.contentEncryptionAlgorithm });
        if (ENCRYPTED_CONTENT in asn1.result) {
            this.encryptedContent = asn1.result.encryptedContent;
            this.encryptedContent.idBlock.tagClass = 1;
            this.encryptedContent.idBlock.tagNumber = 4;
        }
    }
    toSchema() {
        const sequenceLengthBlock = {
            isIndefiniteForm: false
        };
        const outputArray = [];
        outputArray.push(new ObjectIdentifier({ value: this.contentType }));
        outputArray.push(this.contentEncryptionAlgorithm.toSchema());
        if (this.encryptedContent) {
            sequenceLengthBlock.isIndefiniteForm = this.encryptedContent.idBlock.isConstructed;
            const encryptedValue = this.encryptedContent;
            encryptedValue.idBlock.tagClass = 3;
            encryptedValue.idBlock.tagNumber = 0;
            encryptedValue.lenBlock.isIndefiniteForm = this.encryptedContent.idBlock.isConstructed;
            outputArray.push(encryptedValue);
        }
        return (new Sequence({
            lenBlock: sequenceLengthBlock,
            value: outputArray
        }));
    }
    toJSON() {
        const res = {
            contentType: this.contentType,
            contentEncryptionAlgorithm: this.contentEncryptionAlgorithm.toJSON()
        };
        if (this.encryptedContent) {
            res.encryptedContent = this.encryptedContent.toJSON();
        }
        return res;
    }
    getEncryptedContent() {
        if (!this.encryptedContent) {
            throw new Error("Parameter 'encryptedContent' is undefined");
        }
        return OctetString.prototype.getValue.call(this.encryptedContent);
    }
}
EncryptedContentInfo.CLASS_NAME = "EncryptedContentInfo";

const HASH_ALGORITHM$4 = "hashAlgorithm";
const MASK_GEN_ALGORITHM$1 = "maskGenAlgorithm";
const SALT_LENGTH = "saltLength";
const TRAILER_FIELD = "trailerField";
const CLEAR_PROPS$14 = [
    HASH_ALGORITHM$4,
    MASK_GEN_ALGORITHM$1,
    SALT_LENGTH,
    TRAILER_FIELD
];
class RSASSAPSSParams extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.hashAlgorithm = getParametersValue(parameters, HASH_ALGORITHM$4, RSASSAPSSParams.defaultValues(HASH_ALGORITHM$4));
        this.maskGenAlgorithm = getParametersValue(parameters, MASK_GEN_ALGORITHM$1, RSASSAPSSParams.defaultValues(MASK_GEN_ALGORITHM$1));
        this.saltLength = getParametersValue(parameters, SALT_LENGTH, RSASSAPSSParams.defaultValues(SALT_LENGTH));
        this.trailerField = getParametersValue(parameters, TRAILER_FIELD, RSASSAPSSParams.defaultValues(TRAILER_FIELD));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case HASH_ALGORITHM$4:
                return new AlgorithmIdentifier({
                    algorithmId: "1.3.14.3.2.26",
                    algorithmParams: new Null()
                });
            case MASK_GEN_ALGORITHM$1:
                return new AlgorithmIdentifier({
                    algorithmId: "1.2.840.113549.1.1.8",
                    algorithmParams: (new AlgorithmIdentifier({
                        algorithmId: "1.3.14.3.2.26",
                        algorithmParams: new Null()
                    })).toSchema()
                });
            case SALT_LENGTH:
                return 20;
            case TRAILER_FIELD:
                return 1;
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    optional: true,
                    value: [AlgorithmIdentifier.schema(names.hashAlgorithm || {})]
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    optional: true,
                    value: [AlgorithmIdentifier.schema(names.maskGenAlgorithm || {})]
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    },
                    optional: true,
                    value: [new Integer({ name: (names.saltLength || EMPTY_STRING) })]
                }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 3
                    },
                    optional: true,
                    value: [new Integer({ name: (names.trailerField || EMPTY_STRING) })]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$14);
        const asn1 = compareSchema(schema, schema, RSASSAPSSParams.schema({
            names: {
                hashAlgorithm: {
                    names: {
                        blockName: HASH_ALGORITHM$4
                    }
                },
                maskGenAlgorithm: {
                    names: {
                        blockName: MASK_GEN_ALGORITHM$1
                    }
                },
                saltLength: SALT_LENGTH,
                trailerField: TRAILER_FIELD
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (HASH_ALGORITHM$4 in asn1.result)
            this.hashAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.hashAlgorithm });
        if (MASK_GEN_ALGORITHM$1 in asn1.result)
            this.maskGenAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.maskGenAlgorithm });
        if (SALT_LENGTH in asn1.result)
            this.saltLength = asn1.result.saltLength.valueBlock.valueDec;
        if (TRAILER_FIELD in asn1.result)
            this.trailerField = asn1.result.trailerField.valueBlock.valueDec;
    }
    toSchema() {
        const outputArray = [];
        if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues(HASH_ALGORITHM$4))) {
            outputArray.push(new Constructed({
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
                   3
                    tagNumber: 0
                },
                value: [this.hashAlgorithm.toSchema()]

        }Thisjava.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 59
        if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParamsthe optionaljava.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 71
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: [this.maskGenAlgorithm.toSchema()]
            }));
        }
        if (this.saltLength !== RSASSAPSSParams.defaultValues(SALT_LENGTH)) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                value: [new Integer({ value: this.saltLength })]
            }));
        }
        if (this.trailerField !== RSASSAPSSParams.defaultValues(TRAILER_FIELD)) {
            outputArray.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 3
                },
                value: [new Integer({ value: this.trailerField })]
            }));
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {};
        if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues(HASH_ALGORITHM$4))) {
            res.hashAlgorithm = this.hashAlgorithm.toJSON();
        }
        if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParams.defaultValues(MASK_GEN_ALGORITHM$1))) {
            res.maskGenAlgorithm = this.maskGenAlgorithm.toJSON();
        }
        if (this.saltLength !== RSASSAPSSParams.defaultValues(SALT_LENGTH)) {
            res.saltLength = this.saltLength;
        }
        if (this.trailerField !== RSASSAPSSParams.defaultValues(TRAILER_FIELD)) {
            res.trailerField = this.trailerField;
        }
        return res;
    }
}
RSASSAPSSParams.CLASS_NAME = "RSASSAPSSParams";

const SALT = "salt";
const ITERATION_COUNT = "iterationCount";
const KEY_LENGTH = "keyLength";
const PRF = "prf";
const CLEAR_PROPS$13 = [
    SALT,
    ITERATION_COUNT,
    KEY_LENGTH,
    PRF
];
class PBKDF2Params extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.salt = getParametersValue(parameters, SALT, PBKDF2Params.defaultValues(SALT));
        this.iterationCount = getParametersValue(parameters, ITERATION_COUNT, PBKDF2Params.defaultValues(ITERATION_COUNT));
        if (KEY_LENGTH in parameters) {
            this.keyLength = getParametersValue(parameters, KEY_LENGTH, PBKDF2Params.defaultValues(KEY_LENGTH));
        }
        if (PRF in parameters) {
            this.prf = getParametersValue(parameters, PRF, PBKDF2Params.defaultValues(PRF));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case SALT:
                return {};
            case ITERATION_COUNT:
                return (-1);
            case KEY_LENGTH:
                return 0;
            case PRF:
                return new AlgorithmIdentifier({
                    algorithmId: "1.3.14.3.2.26",
                    algorithmParams: new Null()
                });
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Choice({
                    value: [
                        new OctetString({ name: (names.saltPrimitive || EMPTY_STRING) }),
                        AlgorithmIdentifier.schema(names.saltConstructed || {})
                    ]
                }),
                new Integer({ name: (names.iterationCount || EMPTY_STRING) }),
                new Integer({
                    name: (names.keyLength || EMPTY_STRING),
                    optional: true
                }),
                AlgorithmIdentifier.schema(names.prf || {
                    names: {
                        optional: true
                    }
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$13);
        const asn1 = compareSchema(schema, schema, PBKDF2Params.schema({
            names: {
                saltPrimitive: SALT,
                saltConstructed: {
                    names: {
                        blockName: SALT
                    }
                },
                iterationCount: ITERATION_COUNT,
                keyLength: KEY_LENGTH,
                prf: {
                    names: {
                        blockName: PRF,
                        optional: true
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.salt = asn1.result.salt;
        this.iterationCount = asn1.result.iterationCount.valueBlock.valueDec;
        if (KEY_LENGTH in asn1.result)
            this.keyLength = asn1.result.keyLength.valueBlock.valueDec;
        if (PRF in asn1.result)
            this.prf = new AlgorithmIdentifier({ schema: asn1.result.prf });
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(this.salt);
        outputArray.push(new Integer({ value: this.iterationCount }));
        if (KEY_LENGTH in this) {
            if (PBKDF2Params.defaultValues(KEY_LENGTH) !== this.keyLength)
                outputArray.push(new Integer({ value: this.keyLength }));
        }
        if (this.prf) {
            if (PBKDF2Params.defaultValues(PRF).isEqual(this.prf) === false)
                outputArray.push(this.prf.toSchema());
        }
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const res = {
            salt: this.salt.toJSON(),
            iterationCount: this.iterationCount
        };
        if (KEY_LENGTH in this) {
            if (PBKDF2Params.defaultValues(KEY_LENGTH) !== this.keyLength)
                res.keyLength = this.keyLength;
        }
        if (this.prf) {
            if (PBKDF2Params.defaultValues(PRF).isEqual(this.prf) === false)
                res.prf = this.prf.toJSON();
        }
        return res;
    }
}
PBKDF2Params.CLASS_NAME = "PBKDF2Params";

const KEY_DERIVATION_FUNC = "keyDerivationFunc";
const ENCRYPTION_SCHEME = "encryptionScheme";
const CLEAR_PROPS$12 = [
    KEY_DERIVATION_FUNC,
    ENCRYPTION_SCHEME
];
class PBES2Params extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.keyDerivationFunc = getParametersValue(parameters, KEY_DERIVATION_FUNC, PBES2Params.defaultValues(KEY_DERIVATION_FUNC));
        this.encryptionScheme = getParametersValue(parameters, ENCRYPTION_SCHEME, PBES2Params.defaultValues(ENCRYPTION_SCHEME));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case KEY_DERIVATION_FUNC:
                return new AlgorithmIdentifier();
            case ENCRYPTION_SCHEME:
                return new AlgorithmIdentifier();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                AlgorithmIdentifier.schema(names.keyDerivationFunc || {}),
                AlgorithmIdentifier.schema(names.encryptionScheme || {})
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$12);
        const asn1 = compareSchema(schema, schema, PBES2Params.schema({
            names: {
                keyDerivationFunc: {
                    names: {
                        blockName: KEY_DERIVATION_FUNC
                    }
                },
                encryptionScheme: {
                    names: {
                        blockName: ENCRYPTION_SCHEME
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.keyDerivationFunc = new AlgorithmIdentifier({ schema: asn1.result.keyDerivationFunc });
        this.encryptionScheme = new AlgorithmIdentifier({ schema: asn1.result.encryptionScheme });
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.keyDerivationFunc.toSchema(),
                this.encryptionScheme.toSchema()
            ]
        }));
    }
    toJSON() {
        return {
            keyDerivationFunc: this.keyDerivationFunc.toJSON(),
            encryptionScheme: this.encryptionScheme.toJSON()
        };
    }
}
PBES2Params.CLASS_NAME = "PBES2Params";

class AbstractCryptoEngine {
    constructor(parameters) {
        this.crypto = parameters.crypto;
        this.subtle = "webkitSubtle" in parameters.crypto
            ? parameters.crypto.webkitSubtle
            : parameters.crypto.subtle;
        this.name = getParametersValue(parameters, "name", EMPTY_STRING);
    }
    async encrypt(...args) {
        return this.subtle.encrypt(...args);
    }
    async decrypt(...args) {
        return this.subtle.decrypt(...args);
    }
    sign(...args) {
        return this.subtle.sign(...args);
    }
    async verify(...args) {
        return this.subtle.verify(...args);
    }
    async digest(...args) {
        return this.subtle.digest(...args);
    }
    async generateKey(...args) {
        return this.subtle.generateKey(...args);
    }
    async deriveKey(...args) {
        return this.subtle.deriveKey(...args);
    }
    async deriveBits(...args) {
        return this.subtle.deriveBits(...args);
    }
    async wrapKey(...args) {
        return this.subtle.wrapKey(...args);
    }
    async unwrapKey(...args) {
        return this.subtle.unwrapKey(...args);
    }
    exportKey(...args) {
        return this.subtle.exportKey(...args);
    }
    importKey(...args) {
        return this.subtle.importKey(...args);
    }
    getRandomValues(array) {
        if (array === null) {
            throw new Error("Argument \"array\" must not be null");
        }
        return this.crypto.getRandomValues(array);
    }
}

async function makePKCS12B2Key(hashAlgorithm, keyLength, password, salt, iterationCount) {
    let u;
    let v;
    let md;
    switch (hashAlgorithm.toUpperCase()) {
        case "SHA-1":
            u = 20;
            v = 64;
            md = sha1;
            break;
        case "SHA-256":
            u = 32;
            v = 64;
            md = sha256;
            break;
        case "SHA-384":
            u = 48;
            v = 128;
            md = sha384;
            break;
        case "SHA-512":
            u = 64;
            v = 128;
            md = sha512;
            break;
        default:
            throw new Error("Unsupported hashing algorithm");
    }
    const originalPassword = new Uint8Array(password);
    let decodedPassword = new TextDecoder().decode(password);
    const encodedPassword = new TextEncoder().encode(decodedPassword);
    if (encodedPassword.some((byte, i) => byte !== originalPassword[i])) {
        decodedPassword = String.fromCharCode(...originalPassword);
    }
    const passwordTransformed = new Uint8Array(decodedPassword.length * 2 + 2);
    const passwordView = new DataView(passwordTransformed.buffer);
    for (let i = 0; i < decodedPassword.length; i++) {
        passwordView.setUint16(i * 2, decodedPassword.charCodeAt(i), false);
    }
    passwordView.setUint16(decodedPassword.length * 2, 0, false);
    const D = new Uint8Array(v).fill(3);
    const saltView = new Uint8Array(salt);
    const S = new Uint8Array(v * Math.ceil(saltView.length / v)).map((_, i) => saltView[i % saltView.length]);
    const P = new Uint8Array(v * Math.ceil(passwordTransformed.length / v)).map((_, i) => passwordTransformed[i % passwordTransformed.length]);
    let I = new Uint8Array(S.length + P.length);
    I.set(S);
    I.set(P, S.length);
    const c = Math.ceil((keyLength >> 3) / u);
    const result = [];
    for (let i = 0; i < c; i++) {
        let A = new Uint8Array(D.length + I.length);
        A.set(D);
        A.set(I, D.length);
        for (let j = 0; j < iterationCount; j++) {
            A = md(A);
        }
        const B = new Uint8Array(v).map((_, i) => A[i % A.length]);
        const k = Math.ceil(saltView.length / v) + Math.ceil(passwordTransformed.length / v);
        const iRound = [];
        for (let j = 0; j < k; j++) {
            const chunk = Array.from(I.slice(j * v, (j + 1) * v));
            let x = 0x1ff;
            for (let l = B.length - 1; l >= 0; l--) {
                x >>= 8;
                x += B[l] + (chunk[l] || 0);
                chunk[l] = x & 0xff;
            }
            iRound.push(...chunk);
        }
        I = new Uint8Array(iRound);
        result.push(...A);
    }
    return new Uint8Array(result.slice(0, keyLength >> 3)).buffer;
}
function prepareAlgorithm(data) {
    const res = typeof data === "string"
        ? { name: data }
        : data;
    if ("hash" in res) {
        return {
            ...res,
            hash: prepareAlgorithm(res.hash)
        };
    }
    return res;
}
class CryptoEngine extends AbstractCryptoEngine {
    async importKey(format, keyData, algorithm, extractable, keyUsages) {
        var _a, _b, _c, _d, _e, _f;
        let jwk = {};
        const alg = prepareAlgorithm(algorithm);
        switch (format.toLowerCase()) {
            case "raw":
                return this.subtle.importKey("raw", keyData, algorithm, extractable, keyUsages);
            case "spki":
                {
                    const asn1 = fromBER(BufferSourceConverter.toArrayBuffer(keyData));
                    AsnError.assert(asn1, "keyData");
                    const publicKeyInfo = new PublicKeyInfo();
                    try {
                        publicKeyInfo.fromSchema(asn1.result);
                    }
                    catch {
                        throw new ArgumentError("Incorrect keyData");
                    }
                    switch (alg.name.toUpperCase()) {
                        case "RSA-PSS":
                            {
                                if (!alg.hash) {
                                    throw new ParameterError("hash", "algorithm.hash", "Incorrect hash algorithm: Hash algorithm is missed");
                                }
                                switch (alg.hash.name.toUpperCase()) {
                                    case "SHA-1":
                                        jwk.alg = "PS1";
                                        break;
                                    case "SHA-256":
                                        jwk.alg = "PS256";
                                        break;
                                    case "SHA-384":
                                        jwk.alg = "PS384";
                                        break;
                                    case "SHA-512":
                                        jwk.alg = "PS512";
                                        break;
                                    default:
                                        throw new Error(`Incorrect hash algorithm: ${alg.hash.name.toUpperCase()}`);
                                }
                            }
                        case "RSASSA-PKCS1-V1_5":
                            {
                                keyUsages = ["verify"];
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                if (publicKeyInfo.algorithm.algorithmId !== "1.2.840.113549.1.1.1")
                                    throw new Error(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`);
                                if (!jwk.alg) {
                                    if (!alg.hash) {
                                        throw new ParameterError("hash", "algorithm.hash", "Incorrect hash algorithm: Hash algorithm is missed");
                                    }
                                    switch (alg.hash.name.toUpperCase()) {
                                        case "SHA-1":
                                            jwk.alg = "RS1";
                                            break;
                                        case "SHA-256":
                                            jwk.alg = "RS256";
                                            break;
                                        case "SHA-384":
                                            jwk.alg = "RS384";
                                            break;
                                        case "SHA-512":
                                            jwk.alg = "RS512";
                                            break;
                                        default:
                                            throw new Error(`Incorrect hash algorithm: ${alg.hash.name.toUpperCase()}`);
                                    }
                                }
                                const publicKeyJSON = publicKeyInfo.toJSON();
                                Object.assign(jwk, publicKeyJSON);
                            }
                            break;
                        case "ECDSA":
                            keyUsages = ["verify"];
                        case "ECDH":
                            {
                                jwk = {
                                    kty: "EC",
                                    ext: extractable,
                                    key_ops: keyUsages
                                };
                                if (publicKeyInfo.algorithm.algorithmId !== "1.2.840.10045.2.1") {
                                    throw new Error(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`);
                                }
                                const publicKeyJSON = publicKeyInfo.toJSON();
                                Object.assign(jwk, publicKeyJSON);
                            }
                            break;
                        case "RSA-OAEP":
                            {
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                if (this.name.toLowerCase() === "safari")
                                    jwk.alg = "RSA-OAEP";
                                else {
                                    if (!alg.hash) {
                                        throw new ParameterError("hash", "algorithm.hash", "Incorrect hash algorithm: Hash algorithm is missed");
                                    }
                                    switch (alg.hash.name.toUpperCase()) {
                                        case "SHA-1":
                                            jwk.alg = "RSA-OAEP";
                                            break;
                                        case "SHA-256":
                                            jwk.alg = "RSA-OAEP-256";
                                            break;
                                        case "SHA-384":
                                            jwk.alg = "RSA-OAEP-384";
                                            break;
                                        case "SHA-512":
                                            jwk.alg = "RSA-OAEP-512";
                                            break;
                                        default:
                                            throw new Error(`Incorrect hash algorithm: ${alg.hash.name.toUpperCase()}`);
                                    }
                                }
                                const publicKeyJSON = publicKeyInfo.toJSON();
                                Object.assign(jwk, publicKeyJSON);
                            }
                            break;
                        case "RSAES-PKCS1-V1_5":
                            {
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                jwk.alg = "PS1";
                                const publicKeyJSON = publicKeyInfo.toJSON();
                                Object.assign(jwk, publicKeyJSON);
                            }
                            break;
                        default:
                            throw new Error(`Incorrect algorithm name: ${alg.name.toUpperCase()}`);
                    }
                }
                break;
            case "pkcs8":
                {
                    const privateKeyInfo = new PrivateKeyInfo();
                    const asn1 = fromBER(BufferSourceConverter.toArrayBuffer(keyData));
                    AsnError.assert(asn1, "keyData");
                    try {
                        privateKeyInfo.fromSchema(asn1.result);
                    }
                    catch {
                        throw new Error("Incorrect keyData");
                    }
                    if (!privateKeyInfo.parsedKey)
                        throw new Error("Incorrect keyData");
                    switch (alg.name.toUpperCase()) {
                        case "RSA-PSS":
                            {
                                switch ((_a = alg.hash) === null || _a === void 0 ? void 0 : _a.name.toUpperCase()) {
                                    case "SHA-1":
                                        jwk.alg = "PS1";
                                        break;
                                    case "SHA-256":
                                        jwk.alg = "PS256";
                                        break;
                                    case "SHA-384":
                                        jwk.alg = "PS384";
                                        break;
                                    case "SHA-512":
                                        jwk.alg = "PS512";
                                        break;
                                    default:
                                        throw new Error(`Incorrect hash algorithm: ${(_b = alg.hash) === null || _b === void 0 ? void 0 : _b.name.toUpperCase()}`);
                                }
                            }
                        case "RSASSA-PKCS1-V1_5":
                            {
                                keyUsages = ["sign"];
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                if (privateKeyInfo.privateKeyAlgorithm.algorithmId !== "1.2.840.113549.1.1.1")
                                    throw new Error(`Incorrect private key algorithm: ${privateKeyInfo.privateKeyAlgorithm.algorithmId}`);
                                if (("alg" in jwk) === false) {
                                    switch ((_c = alg.hash) === null || _c === void 0 ? void 0 : _c.name.toUpperCase()) {
                                        case "SHA-1":
                                            jwk.alg = "RS1";
                                            break;
                                        case "SHA-256":
                                            jwk.alg = "RS256";
                                            break;
                                        case "SHA-384":
                                            jwk.alg = "RS384";
                                            break;
                                        case "SHA-512":
                                            jwk.alg = "RS512";
                                            break;
                                        default:
                                            throw new Error(`Incorrect hash algorithm: ${(_d = alg.hash) === null || _d === void 0 ? void 0 : _d.name.toUpperCase()}`);
                                    }
                                }
                                const privateKeyJSON = privateKeyInfo.toJSON();
                                Object.assign(jwk, privateKeyJSON);
                            }
                            break;
                        case "ECDSA":
                            keyUsages = ["sign"];
                        case "ECDH":
                            {
                                jwk = {
                                    kty: "EC",
                                    ext: extractable,
                                    key_ops: keyUsages
                                };
                                if (privateKeyInfo.privateKeyAlgorithm.algorithmId !== "1.2.840.10045.2.1")
                                    throw new Error(`Incorrect algorithm: ${privateKeyInfo.privateKeyAlgorithm.algorithmId}`);
                                const privateKeyJSON = privateKeyInfo.toJSON();
                                Object.assign(jwk, privateKeyJSON);
                            }
                            break;
                        case "RSA-OAEP":
                            {
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                if (this.name.toLowerCase() === "safari")
                                    jwk.alg = "RSA-OAEP";
                                else {
                                    switch ((_e = alg.hash) === null || _e === void 0 ? void 0 : _e.name.toUpperCase()) {
                                        case "SHA-1":
                                            jwk.alg = "RSA-OAEP";
                                            break;
                                        case "SHA-256":
                                            jwk.alg = "RSA-OAEP-256";
                                            break;
                                        case "SHA-384":
                                            jwk.alg = "RSA-OAEP-384";
                                            break;
                                        case "SHA-512":
                                            jwk.alg = "RSA-OAEP-512";
                                            break;
                                        default:
                                            throw new Error(`Incorrect hash algorithm: ${(_f = alg.hash) === null || _f === void 0 ? void 0 : _f.name.toUpperCase()}`);
                                    }
                                }
                                const privateKeyJSON = privateKeyInfo.toJSON();
                                Object.assign(jwk, privateKeyJSON);
                            }
                            break;
                        case "RSAES-PKCS1-V1_5":
                            {
                                keyUsages = ["decrypt"];
                                jwk.kty = "RSA";
                                jwk.ext = extractable;
                                jwk.key_ops = keyUsages;
                                jwk.alg = "PS1";
                                const privateKeyJSON = privateKeyInfo.toJSON();
                                Object.assign(jwk, privateKeyJSON);
                            }
                            break;
                        default:
                            throw new Error(`Incorrect algorithm name: ${alg.name.toUpperCase()}`);
                    }
                }
                break;
            case "jwk":
                jwk = keyData;
                break;
            default:
                throw new Error(`Incorrect format: ${format}`);
        }
        if (this.name.toLowerCase() === "safari") {
            try {
                return this.subtle.importKey("jwk", stringToArrayBuffer(JSON.stringify(jwk)), algorithm, extractable, keyUsages);
            }
            catch {
                return this.subtle.importKey("jwk", jwk, algorithm, extractable, keyUsages);
            }
        }
        return this.subtle.importKey("jwk", jwk, algorithm, extractable, keyUsages);
    }
    async exportKey(format, key) {
        let jwk = await this.subtle.exportKey("jwk", key);
        if (this.name.toLowerCase() === "safari") {
            if (jwk instanceof ArrayBuffer) {
                jwk = JSON.parse(arrayBufferToString(jwk));
            }
        }
        switch (format.toLowerCase()) {
            case "raw":
                return this.subtle.exportKey("raw", key);
            case "spki": {
                const publicKeyInfo = new PublicKeyInfo();
                try {
                    publicKeyInfo.fromJSON(jwk);
                }
                catch {
                    throw new Error("Incorrect key data");
                }
                return publicKeyInfo.toSchema().toBER(false);
            }
            case "pkcs8": {
                const privateKeyInfo = new PrivateKeyInfo();
                try {
                    privateKeyInfo.fromJSON(jwk);
                }
                catch {
                    throw new Error("Incorrect key data");
                }
                return privateKeyInfo.toSchema().toBER(false);
            }
            case "jwk":
                return jwk;
            default:
                throw new Error(`Incorrect format: ${format}`);
        }
    }
    async convert(inputFormat, outputFormat, keyData, algorithm, extractable, keyUsages) {
        if (inputFormat.toLowerCase() === outputFormat.toLowerCase()) {
            return keyData;
        }
        const key = await this.importKey(inputFormat, keyData, algorithm, extractable, keyUsages);
        return this.exportKey(outputFormat, key);
    }
    getAlgorithmByOID(oid, safety = false, target) {
        switch (oid) {
            case "1.2.840.113549.1.1.1":
                return {
                    name: "RSAES-PKCS1-v1_5"
                };
            case "1.2.840.113549.1.1.5":
                return {
                    name: "RSASSA-PKCS1-v1_5",
                    hash: {
                        name: "SHA-1"
                    }
                };
            case "1.2.840.113549.1.1.11":
                return {
                    name: "RSASSA-PKCS1-v1_5",
                    hash: {
                        name: "SHA-256"
                    }
                };
            case "1.2.840.113549.1.1.12":
                return {
                    name: "RSASSA-PKCS1-v1_5",
                    hash: {
                        name: "SHA-384"
                    }
                };
            case "1.2.840.113549.1.1.13":
                return {
                    name: "RSASSA-PKCS1-v1_5",
                    hash: {
                        name: "SHA-512"
                    }
                };
            case "1.2.840.113549.1.1.10":
                return {
                    name: "RSA-PSS"
                };
            case "1.2.840.113549.1.1.7":
                return {
                    name: "RSA-OAEP"
                };
            case "1.2.840.10045.2.1":
            case "1.2.840.10045.4.1":
                return {
                    name: "ECDSA",
                    hash: {
                        name: "SHA-1"
                    }
                };
            case "1.2.840.10045.4.3.2":
                return {
                    name: "ECDSA",
                    hash: {
                        name: "SHA-256"
                    }
                };
            case "1.2.840.10045.4.3.3":
                return {
                    name: "ECDSA",
                    hash: {
                        name: "SHA-384"
                    }
                };
            case "1.2.840.10045.4.3.4":
                return {
                    name: "ECDSA",
                    hash: {
                        name: "SHA-512"
                    }
                };
            case "1.3.133.16.840.63.0.2":
                return {
                    name: "ECDH",
                    kdf: "SHA-1"
                };
            case "1.3.132.1.11.1":
                return {
                    name: "ECDH",
                    kdf: "SHA-256"
                };
            case "1.3.132.1.11.2":
                return {
                    name: "ECDH",
                    kdf: "SHA-384"
                };
            case "1.3.132.1.11.3":
                return {
                    name: "ECDH",
                    kdf: "SHA-512"
                };
            case "2.16.840.1.101.3.4.1.2":
                return {
                    name: "AES-CBC",
                    length: 128
                };
            case "2.16.840.1.101.3.4.1.22":
                return {
                    name: "AES-CBC",
                    length: 192
                };
            case "2.16.840.1.101.3.4.1.42":
                return {
                    name: "AES-CBC",
                    length: 256
                };
            case "2.16.840.1.101.3.4.1.6":
                return {
                    name: "AES-GCM",
                    length: 128
                };
            case "2.16.840.1.101.3.4.1.26":
                return {
                    name: "AES-GCM",
                    length: 192
                };
            case "2.16.840.1.101.3.4.1.46":
                return {
                    name: "AES-GCM",
                    length: 256
                };
            case "2.16.840.1.101.3.4.1.4":
                return {
                    name: "AES-CFB",
                    length: 128
                };
            case "2.16.840.1.101.3.4.1.24":
                return {
                    name: "AES-CFB",
                    length: 192
                };
            case "2.16.840.1.101.3.4.1.44":
                return {
                    name: "AES-CFB",
                    length: 256
                };
            case "2.16.840.1.101.3.4.1.5":
                return {
                    name: "AES-KW",
                    length: 128
                };
            case "2.16.840.1.101.3.4.1.25":
                return {
                    name: "AES-KW",
                    length: 192
                };
            case "2.16.840.1.101.3.4.1.45":
                return {
                    name: "AES-KW",
                    length: 256
                };
            case "1.2.840.113549.2.7":
                return {
name HMAC
                    hash: {
                        name: "SHA- isa 

                };
            case "1.2.840.113549.2.9":
                return {
                    name: "HMAC",
                    hash: {
                        name: "SHA-256"
                    }
                };
            case "1.2.840.113549.2.10":
                return {
                    name: "HMAC",
                    hash: {
                        name: "SHA-384"
                    }
                };
            case "1.2.840.113549.2.11":
                return {
                    name: "HMAC",
                    hash: {
                        name: "SHA-512"
                    }
                };
            case "1.2.840.113549.1.9.16.3.5":
                return {
                    name: "DH"
                };
            case "1.3.14.3.2.26":
                return {
                    name: "SHA-1"
                };
            case "2.16.840.1.101.3.4.2.1":
                return {
                    name: "SHA-256"
                };
            case "2.16.840.1.101.3.4.2.2":
                return {
                    name: "SHA-384"
                };
            case "2.16.840.1.101.3.4.2.3":
                return {
                    name: "SHA-512"
                };
            case "1.2.840.113549.1.5.12":
                return {
                    name: "PBKDF2"
                };
            case "1.2.840.10045.3.1.7":
                return {
                    name: "P-256"
                };
            case "1.3.132.0.34":
                return {
                    name: "P-384"
                };
            case "1.3.132.0.35":
                return {
                    name: "P-521"
                };
        }
        if (safety) {
            throw new Error(`Unsupported algorithm identifier ${target ? `for ${target} ` : EMPTY_STRING}: ${oid}`);
        }
        return {};
    }
    getOIDByAlgorithm(algorithm, safety = false, target) {
        let result = EMPTY_STRING;
        switch (algorithm.name.toUpperCase()) {
            case "RSAES-PKCS1-V1_5":
                result = "1.2.840.113549.1.1.1";
                break;
            case "RSASSA-PKCS1-V1_5":
                switch (algorithm.hash.name.toUpperCase()) {
                    case "SHA-1":
                        result = "1.2.840.113549.1.1.5";
                        break;
                    case "SHA-256":
                        result = "1.2.840.113549.1.1.11";
                        break;
                    case "SHA-384":
                        result = "1.2.840.113549.1.1.12";
                        break;
                    case "SHA-512":
                        result = "1.2.840.113549.1.1.13";
                        break;
                }
                break;
            case "RSA-PSS":
                result = "1.2.840.113549.1.1.10";
                break;
            case "RSA-OAEP":
                result = "1.2.840.113549.1.1.7";
                break;
            case "ECDSA":
                switch (algorithm.hash.name.toUpperCase()) {
                    case "SHA-1":
                        result = "1.2.840.10045.4.1";
                        break;
                    case "SHA-256":
                        result = "1.2.840.10045.4.3.2";
                        break;
                    case "SHA-384":
                        result = "1.2.840.10045.4.3.3";
                        break;
                    case "SHA-512":
                        result = "1.2.840.10045.4.3.4";
                        break;
                }
                break;
            case "ECDH":
                switch (algorithm.kdf.toUpperCase()) {
                    case "SHA-1":
                        result = "1.3.133.16.840.63.0.2";
                        break;
                    case "SHA-256":
                        result = "1.3.132.1.11.1";
                        break;
                    case "SHA-384":
                        result = "1.3.132.1.11.2";
                        break;
                    case "SHA-512":
                        result = "1.3.132.1.11.3";
                        break;
                }
                break;
            case "AES-CTR":
                break;
            case "AES-CBC":
                switch (algorithm.length) {
                    case 128:
                        result = "2.16.840.1.101.3.4.1.2";
                        break;
                    case 192:
                        result = "2.16.840.1.101.3.4.1.22";
                        break;
                    case 256:
                        result = "2.16.840.1.101.3.4.1.42";
                        break;
                }
                break;
            case "AES-CMAC":
                break;
            case "AES-GCM":
                switch (algorithm.length) {
                    case 128:
                        result = "2.16.840.1.101.3.4.1.6";
                        break;
                    case 192:
                        result = "2.16.840.1.101.3.4.1.26";
                        break;
                    case 256:
                        result = "2.16.840.1.101.3.4.1.46";
                        break;
                }
                break;
            case "AES-CFB":
                switch (algorithm.length) {
                    case 128:
                        result = "2.16.840.1.101.3.4.1.4";
                        break;
                    case 192:
                        result = "2.16.840.1.101.3.4.1.24";
                        break;
                    case 256:
                        result = "2.16.840.1.101.3.4.1.44";
                        break;
                }
                break;
            case "AES-KW":
                switch (algorithm.length) {
                    case 128:
                        result = "2.16.840.1.101.3.4.1.5";
                        break;
                    case 192:
                        result = "2.16.840.1.101.3.4.1.25";
                        break;
                    case 256:
                        result = "2.16.840.1.101.3.4.1.45";
                        break;
                }
                break;
            case "HMAC":
                switch (algorithm.hash.name.toUpperCase()) {
                    case "SHA-1":
                        result = "1.2.840.113549.2.7";
                        break;
                    case "SHA-256":
                        result = "1.2.840.113549.2.9";
                        break;
                    case "SHA-384":
                        result = "1.2.840.113549.2.10";
                        break;
                    case "SHA-512":
                        result = "1.2.840.113549.2.11";
                        break;
                }
                break;
            case "DH":
                result = "1.2.840.113549.1.9.16.3.5";
                break;
            case "SHA-1":
                result = "1.3.14.3.2.26";
                break;
            case "SHA-256":
                result = "2.16.840.1.101.3.4.2.1";
                break;
            case "SHA-384":
                result = "2.16.840.1.101.3.4.2.2";
                break;
            case "SHA-512":
                result = "2.16.840.1.101.3.4.2.3";
                break;
            case "CONCAT":
                break;
            case "HKDF":
                break;
            case "PBKDF2":
                result = "1.2.840.113549.1.5.12";
                break;
            case "P-256":
                result = "1.2.840.10045.3.1.7";
                break;
            case "P-384":
                result = "1.3.132.0.34";
                break;
            case "P-521":
                result = "1.3.132.0.35";
                break;
        }
        if (!result && safety) {
            throw new Error(`Unsupported algorithm ${target ? `for ${target} ` : EMPTY_STRING}: ${algorithm.name}`);
        }
        return result;
    }
    getAlgorithmParameters(algorithmName, operation) {
        let result = {
            algorithm: {},
            usages: []
        };
        switch (algorithmName.toUpperCase()) {
            case "RSAES-PKCS1-V1_5":
            case "RSASSA-PKCS1-V1_5":
                switch (operation.toLowerCase()) {
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "RSASSA-PKCS1-v1_5",
                                modulusLength: 2048,
                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    case "verify":
                    case "sign":
                    case "importkey":
                        result = {
                            algorithm: {
                                name: "RSASSA-PKCS1-v1_5",
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["verify"]
                        };
                        break;
                    case "exportkey":
                    default:
                        return {
                            algorithm: {
                                name: "RSASSA-PKCS1-v1_5"
                            },
                            usages: []
                        };
                }
                break;
            case "RSA-PSS":
                switch (operation.toLowerCase()) {
                    case "sign":
                    case "verify":
                        result = {
                            algorithm: {
                                name: "RSA-PSS",
                                hash: {
                                    name: "SHA-1"
                                },
                                saltLength: 20
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "RSA-PSS",
                                modulusLength: 2048,
                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
                                hash: {
                                    name: "SHA-1"
                                }
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    case "importkey":
                        result = {
                            algorithm: {
                                name: "RSA-PSS",
                                hash: {
                                    name: "SHA-1"
                                }
                            },
                            usages: ["verify"]
                        };
                        break;
                    case "exportkey":
                    default:
                        return {
                            algorithm: {
                                name: "RSA-PSS"
                            },
                            usages: []
                        };
                }
                break;
            case "RSA-OAEP":
                switch (operation.toLowerCase()) {
                    case "encrypt":
                    case "decrypt":
                        result = {
                            algorithm: {
                                name: "RSA-OAEP"
                            },
                            usages: ["encrypt", "decrypt"]
                        };
                        break;
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "RSA-OAEP",
                                modulusLength: 2048,
                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    case "importkey":
                        result = {
                            algorithm: {
                                name: "RSA-OAEP",
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["encrypt"]
                        };
                        break;
                    case "exportkey":
                    default:
                        return {
                            algorithm: {
                                name: "RSA-OAEP"
                            },
                            usages: []
                        };
                }
                break;
            case "ECDSA":
                switch (operation.toLowerCase()) {
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "ECDSA",
                                namedCurve: "P-256"
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    case "importkey":
                        result = {
                            algorithm: {
                                name: "ECDSA",
                                namedCurve: "P-256"
                            },
                            usages: ["verify"]
                        };
                        break;
                    case "verify":
                    case "sign":
                        result = {
                            algorithm: {
                                name: "ECDSA",
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["sign"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "ECDSA"
                            },
                            usages: []
                        };
                }
                break;
            case "ECDH":
                switch (operation.toLowerCase()) {
                    case "exportkey":
                    case "importkey":
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "ECDH",
                                namedCurve: "P-256"
                            },
                            usages: ["deriveKey", "deriveBits"]
                        };
                        break;
                    case "derivekey":
                    case "derivebits":
                        result = {
                            algorithm: {
                                name: "ECDH",
                                namedCurve: "P-256",
                                public: []
                            },
                            usages: ["encrypt", "decrypt"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "ECDH"
                            },
                            usages: []
                        };
                }
                break;
            case "AES-CTR":
                switch (operation.toLowerCase()) {
                    case "importkey":
                    case "exportkey":
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "AES-CTR",
                                length: 256
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    case "decrypt":
                    case "encrypt":
                        result = {
                            algorithm: {
                                name: "AES-CTR",
                                counter: new Uint8Array(16),
                                length: 10
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "AES-CTR"
                            },
                            usages: []
                        };
                }
                break;
            case "AES-CBC":
                switch (operation.toLowerCase()) {
                    case "importkey":
                    case "exportkey":
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "AES-CBC",
                                length: 256
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    case "decrypt":
                    case "encrypt":
                        result = {
                            algorithm: {
                                name: "AES-CBC",
                                iv: this.getRandomValues(new Uint8Array(16))
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "AES-CBC"
                            },
                            usages: []
                        };
                }
                break;
            case "AES-GCM":
                switch (operation.toLowerCase()) {
                    case "importkey":
                    case "exportkey":
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "AES-GCM",
                                length: 256
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    case "decrypt":
                    case "encrypt":
                        result = {
                            algorithm: {
                                name: "AES-GCM",
                                iv: this.getRandomValues(new Uint8Array(16))
                            },
                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "AES-GCM"
                            },
                            usages: []
                        };
                }
                break;
            case "AES-KW":
                switch (operation.toLowerCase()) {
                    case "importkey":
                    case "exportkey":
                    case "generatekey":
                    case "wrapkey":
                    case "unwrapkey":
                        result = {
                            algorithm: {
                                name: "AES-KW",
                                length: 256
                            },
                            usages: ["wrapKey", "unwrapKey"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "AES-KW"
                            },
                            usages: []
                        };
                }
                break;
            case "HMAC":
                switch (operation.toLowerCase()) {
                    case "sign":
                    case "verify":
                        result = {
                            algorithm: {
                                name: "HMAC"
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    case "importkey":
                    case "exportkey":
                    case "generatekey":
                        result = {
                            algorithm: {
                                name: "HMAC",
                                length: 32,
                                hash: {
                                    name: "SHA-256"
                                }
                            },
                            usages: ["sign", "verify"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "HMAC"
                            },
                            usages: []
                        };
                }
                break;
            case "HKDF":
                switch (operation.toLowerCase()) {
                    case "derivekey":
                        result = {
                            algorithm: {
                                name: "HKDF",
                                hash: "SHA-256",
                                salt: new Uint8Array([]),
                                info: new Uint8Array([])
                            },
                            usages: ["encrypt", "decrypt"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "HKDF"
                            },
                            usages: []
                        };
                }
                break;
            case "PBKDF2":
                switch (operation.toLowerCase()) {
                    case "derivekey":
                        result = {
                            algorithm: {
                                name: "PBKDF2",
                                hash: { name: "SHA-256" },
                                salt: new Uint8Array([]),
                                iterations: 10000
                            },
                            usages: ["encrypt", "decrypt"]
                        };
                        break;
                    default:
                        return {
                            algorithm: {
                                name: "PBKDF2"
                            },
                            usages: []
                        };
                }
                break;
        }
        return result;
    }
    getHashAlgorithm(signatureAlgorithm) {
        let result = EMPTY_STRING;
        switch (signatureAlgorithm.algorithmId) {
            case "1.2.840.10045.4.1":
            case "1.2.840.113549.1.1.5":
                result = "SHA-1";
                break;
            case "1.2.840.10045.4.3.2":
            case "1.2.840.113549.1.1.11":
                result = "SHA-256";
                break;
            case "1.2.840.10045.4.3.3":
            case "1.2.840.113549.1.1.12":
                result = "SHA-384";
                break;
            case "1.2.840.10045.4.3.4":
            case "1.2.840.113549.1.1.13":
                result = "SHA-512";
                break;
            case "1.2.840.113549.1.1.10":
                {
                    try {
                        const params = new RSASSAPSSParams({ schema: signatureAlgorithm.algorithmParams });
                        if (params.hashAlgorithm) {
                            const algorithm = this.getAlgorithmByOID(params.hashAlgorithm.algorithmId);
                            if ("name" in algorithm) {
                                result = algorithm.name;
                            }
                            else {
                                return EMPTY_STRING;
                            }
                        }
                        else
                            result = "SHA-1";
                    }
                    catch {
                    }
                }
                break;
        }
        return result;
    }
    async encryptEncryptedContentInfo(parameters) {
        ParameterError.assert(parameters, "password", "contentEncryptionAlgorithm", "hmacHashAlgorithm", "iterationCount", "contentToEncrypt", "contentToEncrypt", "contentType");
        const contentEncryptionOID = this.getOIDByAlgorithm(parameters.contentEncryptionAlgorithm, true, "contentEncryptionAlgorithm");
        const pbkdf2OID = this.getOIDByAlgorithm({
            name: "PBKDF2"
        }, true, "PBKDF2");
        const hmacOID = this.getOIDByAlgorithm({
            name: "HMAC",
            hash: {
                name: parameters.hmacHashAlgorithm
            }
        }, true, "hmacHashAlgorithm");
        const ivBuffer = new ArrayBuffer(16);
        const ivView = new Uint8Array(ivBuffer);
        this.getRandomValues(ivView);
        const saltBuffer = new ArrayBuffer(64);
        const saltView = new Uint8Array(saltBuffer);
        this.getRandomValues(saltView);
        const contentView = new Uint8Array(parameters.contentToEncrypt);
        const pbkdf2Params = new PBKDF2Params({
            salt: new OctetString({ valueHex: saltBuffer }),
            iterationCount: parameters.iterationCount,
            prf: new AlgorithmIdentifier({
                algorithmId: hmacOID,
                algorithmParams: new Null()
            })
        });
        const passwordView = new Uint8Array(parameters.password);
        const pbkdfKey = await this.importKey("raw", passwordView, "PBKDF2", false, ["deriveKey"]);
        const derivedKey = await this.deriveKey({
            name: "PBKDF2",
            hash: {
                name: parameters.hmacHashAlgorithm
            },
            salt: saltView,
            iterations: parameters.iterationCount
        }, pbkdfKey, parameters.contentEncryptionAlgorithm, false, ["encrypt"]);
        const encryptedData = await this.encrypt({
            name: parameters.contentEncryptionAlgorithm.name,
            iv: ivView
        }, derivedKey, contentView);
        const pbes2Parameters = new PBES2Params({
            keyDerivationFunc: new AlgorithmIdentifier({
                algorithmId: pbkdf2OID,
                algorithmParams: pbkdf2Params.toSchema()
            }),
            encryptionScheme: new AlgorithmIdentifier({
                algorithmId: contentEncryptionOID,
                algorithmParams: new OctetString({ valueHex: ivBuffer })
            })
        });
        return new EncryptedContentInfo({
            contentType: parameters.contentType,
            contentEncryptionAlgorithm: new AlgorithmIdentifier({
                algorithmId: "1.2.840.113549.1.5.13",
                algorithmParams: pbes2Parameters.toSchema()
            }),
            encryptedContent: new OctetString({ valueHex: encryptedData })
        });
    }
    async decryptEncryptedContentInfo(parameters) {
        ParameterError.assert(parameters, "password", "encryptedContentInfo");
        if (parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId !== "1.2.840.113549.1.5.13")
            throw new Error(`Unknown "contentEncryptionAlgorithm": ${parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`);
        let pbes2Parameters;
        try {
            pbes2Parameters = new PBES2Params({ schema: parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmParams });
        }
        catch {
            throw new Error("Incorrectly encoded \"pbes2Parameters\"");
        }
        let pbkdf2Params;
        try {
            pbkdf2Params = new PBKDF2Params({ schema: pbes2Parameters.keyDerivationFunc.algorithmParams });
        }
        catch {
            throw new Error("Incorrectly encoded \"pbkdf2Params\"");
        }
        const contentEncryptionAlgorithm = this.getAlgorithmByOID(pbes2Parameters.encryptionScheme.algorithmId, true);
        const ivBuffer = pbes2Parameters.encryptionScheme.algorithmParams.valueBlock.valueHex;
        const ivView = new Uint8Array(ivBuffer);
        const saltBuffer = pbkdf2Params.salt.valueBlock.valueHex;
        const saltView = new Uint8Array(saltBuffer);
        const iterationCount = pbkdf2Params.iterationCount;
        let hmacHashAlgorithm = "SHA-1";
        if (pbkdf2Params.prf) {
            const algorithm = this.getAlgorithmByOID(pbkdf2Params.prf.algorithmId, true);
            hmacHashAlgorithm = algorithm.hash.name;
        }
        const pbkdfKey = await this.importKey("raw", parameters.password, "PBKDF2", false, ["deriveKey"]);
        const result = await this.deriveKey({
            name: "PBKDF2",
            hash: {
                name: hmacHashAlgorithm
            },
            salt: saltView,
            iterations: iterationCount
        }, pbkdfKey, contentEncryptionAlgorithm, false, ["decrypt"]);
        const dataBuffer = parameters.encryptedContentInfo.getEncryptedContent();
        return this.decrypt({
            name: contentEncryptionAlgorithm.name,
            iv: ivView
        }, result, dataBuffer);
    }
    async stampDataWithPassword(parameters) {
        if ((parameters instanceof Object) === false)
            throw new Error("Parameters must have type \"Object\"");
        ParameterError.assert(parameters, "password", "hashAlgorithm", "iterationCount", "salt", "contentToStamp");
        let length;
        switch (parameters.hashAlgorithm.toLowerCase()) {
            case "sha-1":
                length = 160;
                break;
            case "sha-256":
                length = 256;
                break;
            case "sha-384":
                length = 384;
                break;
            case "sha-512":
                length = 512;
                break;
            default:
                throw new Error(`Incorrect "parameters.hashAlgorithm" parameter: ${parameters.hashAlgorithm}`);
        }
        const hmacAlgorithm = {
            name: "HMAC",
            length,
            hash: {
                name: parameters.hashAlgorithm
            }
        };
        const pkcsKey = await makePKCS12B2Key(parameters.hashAlgorithm, length, parameters.password, parameters.salt, parameters.iterationCount);
        const hmacKey = await this.importKey("raw", new Uint8Array(pkcsKey), hmacAlgorithm, false, ["sign"]);
        return this.sign(hmacAlgorithm, hmacKey, new Uint8Array(parameters.contentToStamp));
    }
    async verifyDataStampedWithPassword(parameters) {
        ParameterError.assert(parameters, "password", "hashAlgorithm", "salt", "iterationCount", "contentToVerify", "signatureToVerify");
        let length = 0;
        switch (parameters.hashAlgorithm.toLowerCase()) {
            case "sha-1":
                length = 160;
                break;
            case "sha-256":
                length = 256;
                break;
            case "sha-384":
                length = 384;
                break;
            case "sha-512":
                length = 512;
                break;
            default:
                throw new Error(`Incorrect "parameters.hashAlgorithm" parameter: ${parameters.hashAlgorithm}`);
        }
        const hmacAlgorithm = {
            name: "HMAC",
            length,
            hash: {
                name: parameters.hashAlgorithm
            }
        };
        const pkcsKey = await makePKCS12B2Key(parameters.hashAlgorithm, length, parameters.password, parameters.salt, parameters.iterationCount);
        const hmacKey = await this.importKey("raw", new Uint8Array(pkcsKey), hmacAlgorithm, false, ["verify"]);
        return this.verify(hmacAlgorithm, hmacKey, new Uint8Array(parameters.signatureToVerify), new Uint8Array(parameters.contentToVerify));
    }
    async getSignatureParameters(privateKey, hashAlgorithm = "SHA-1") {
        this.getOIDByAlgorithm({ name: hashAlgorithm }, true, "hashAlgorithm");
        const signatureAlgorithm = new AlgorithmIdentifier();
        const parameters = this.getAlgorithmParameters(privateKey.algorithm.name, "sign");
        if (!Object.keys(parameters.algorithm).length) {
            throw new Error("Parameter 'algorithm' is empty");
        }
        const algorithm = parameters.algorithm;
        if ("hash" in privateKey.algorithm && privateKey.algorithm.hash && privateKey.algorithm.hash.name) {
            algorithm.hash.name = privateKey.algorithm.hash.name;
        }
        else {
            algorithm.hash.name = hashAlgorithm;
        }
        switch (privateKey.algorithm.name.toUpperCase()) {
            case "RSASSA-PKCS1-V1_5":
            case "ECDSA":
                signatureAlgorithm.algorithmId = this.getOIDByAlgorithm(algorithm, true);
                break;
            case "RSA-PSS":
                {
                    switch (algorithm.hash.name.toUpperCase()) {
                        case "SHA-256":
                            algorithm.saltLength = 32;
                            break;
                        case "SHA-384":
                            algorithm.saltLength = 48;
                            break;
                        case "SHA-512":
                            algorithm.saltLength = 64;
                            break;
                    }
                    const paramsObject = {};
                    if (algorithm.hash.name.toUpperCase() !== "SHA-1") {
                        const hashAlgorithmOID = this.getOIDByAlgorithm({ name: algorithm.hash.name }, true, "hashAlgorithm");
                        paramsObject.hashAlgorithm = new AlgorithmIdentifier({
                            algorithmId: hashAlgorithmOID,
                            algorithmParams: new Null()
                        });
                        paramsObject.maskGenAlgorithm = new AlgorithmIdentifier({
                            algorithmId: "1.2.840.113549.1.1.8",
                            algorithmParams: paramsObject.hashAlgorithm.toSchema()
                        });
                    }
                    if (algorithm.saltLength !== 20)
                        paramsObject.saltLength = algorithm.saltLength;
                    const pssParameters = new RSASSAPSSParams(paramsObject);
                    signatureAlgorithm.algorithmId = "1.2.840.113549.1.1.10";
                    signatureAlgorithm.algorithmParams = pssParameters.toSchema();
                }
                break;
            default:
                throw new Error(`Unsupported signature algorithm: ${privateKey.algorithm.name}`);
        }
        return {
            signatureAlgorithm,
            parameters
        };
    }
    async signWithPrivateKey(data, privateKey, parameters) {
        const signature = await this.sign(parameters.algorithm, privateKey, data);
        if (parameters.algorithm.name === "ECDSA") {
            return createCMSECDSASignature(signature);
        }
        return signature;
    }
    fillPublicKeyParameters(publicKeyInfo, signatureAlgorithm) {
        const parameters = {};
        const shaAlgorithm = this.getHashAlgorithm(signatureAlgorithm);
        if (shaAlgorithm === EMPTY_STRING)
            throw new Error(`Unsupported signature algorithm: ${signatureAlgorithm.algorithmId}`);
        let algorithmId;
        if (signatureAlgorithm.algorithmId === "1.2.840.113549.1.1.10")
            algorithmId = signatureAlgorithm.algorithmId;
        else
            algorithmId = publicKeyInfo.algorithm.algorithmId;
        const algorithmObject = this.getAlgorithmByOID(algorithmId, true);
        parameters.algorithm = this.getAlgorithmParameters(algorithmObject.name, "importKey");
        if ("hash" in parameters.algorithm.algorithm)
            parameters.algorithm.algorithm.hash.name = shaAlgorithm;
        if (algorithmObject.name === "ECDSA") {
            const publicKeyAlgorithm = publicKeyInfo.algorithm;
            if (!publicKeyAlgorithm.algorithmParams) {
                throw new Error("Algorithm parameters for ECDSA public key are missed");
            }
            const publicKeyAlgorithmParams = publicKeyAlgorithm.algorithmParams;
            if ("idBlock" in publicKeyAlgorithm.algorithmParams) {
                if (!((publicKeyAlgorithmParams.idBlock.tagClass === 1) && (publicKeyAlgorithmParams.idBlock.tagNumber === 6))) {
                    throw new Error("Incorrect type for ECDSA public key parameters");
                }
            }
            const curveObject = this.getAlgorithmByOID(publicKeyAlgorithmParams.valueBlock.toString(), true);
            parameters.algorithm.algorithm.namedCurve = curveObject.name;
        }
        return parameters;
    }
    async getPublicKey(publicKeyInfo, signatureAlgorithm, parameters) {
        if (!parameters) {
            parameters = this.fillPublicKeyParameters(publicKeyInfo, signatureAlgorithm);
        }
        const publicKeyInfoBuffer = publicKeyInfo.toSchema().toBER(false);
        return this.importKey("spki", publicKeyInfoBuffer, parameters.algorithm.algorithm, true, parameters.algorithm.usages);
    }
    async verifyWithPublicKey(data, signature, publicKeyInfo, signatureAlgorithm, shaAlgorithm) {
        let publicKey;
        if (!shaAlgorithm) {
            shaAlgorithm = this.getHashAlgorithm(signatureAlgorithm);
            if (!shaAlgorithm)
                throw new Error(`Unsupported signature algorithm: ${signatureAlgorithm.algorithmId}`);
            publicKey = await this.getPublicKey(publicKeyInfo, signatureAlgorithm);
        }
        else {
            const parameters = {};
            let algorithmId;
            if (signatureAlgorithm.algorithmId === "1.2.840.113549.1.1.10")
                algorithmId = signatureAlgorithm.algorithmId;
            else
                algorithmId = publicKeyInfo.algorithm.algorithmId;
            const algorithmObject = this.getAlgorithmByOID(algorithmId, true);
            parameters.algorithm = this.getAlgorithmParameters(algorithmObject.name, "importKey");
            if ("hash" in parameters.algorithm.algorithm)
                parameters.algorithm.algorithm.hash.name = shaAlgorithm;
            if (algorithmObject.name === "ECDSA") {
                let algorithmParamsChecked = false;
                if (("algorithmParams" in publicKeyInfo.algorithm) === true) {
                    if ("idBlock" in publicKeyInfo.algorithm.algorithmParams) {
                        if ((publicKeyInfo.algorithm.algorithmParams.idBlock.tagClass === 1) && (publicKeyInfo.algorithm.algorithmParams.idBlock.tagNumber === 6))
                            algorithmParamsChecked = true;
                    }
                }
                if (algorithmParamsChecked === false) {
                    throw new Error("Incorrect type for ECDSA public key parameters");
                }
                const curveObject = this.getAlgorithmByOID(publicKeyInfo.algorithm.algorithmParams.valueBlock.toString(), true);
                parameters.algorithm.algorithm.namedCurve = curveObject.name;
            }
            publicKey = await this.getPublicKey(publicKeyInfo, null, parameters);
        }
        const algorithm = this.getAlgorithmParameters(publicKey.algorithm.name, "verify");
        if ("hash" in algorithm.algorithm)
            algorithm.algorithm.hash.name = shaAlgorithm;
        let signatureValue = signature.valueBlock.valueHexView;
        if (publicKey.algorithm.name === "ECDSA") {
            const namedCurve = ECNamedCurves.find(publicKey.algorithm.namedCurve);
            if (!namedCurve) {
                throw new Error("Unsupported named curve in use");
            }
            const asn1 = fromBER(signatureValue);
            AsnError.assert(asn1, "Signature value");
            signatureValue = createECDSASignatureFromCMS(asn1.result, namedCurve.size);
        }
        if (publicKey.algorithm.name === "RSA-PSS") {
            const pssParameters = new RSASSAPSSParams({ schema: signatureAlgorithm.algorithmParams });
            if ("saltLength" in pssParameters)
                algorithm.algorithm.saltLength = pssParameters.saltLength;
            else
                algorithm.algorithm.saltLength = 20;
            let hashAlgo = "SHA-1";
            if ("hashAlgorithm" in pssParameters) {
                const hashAlgorithm = this.getAlgorithmByOID(pssParameters.hashAlgorithm.algorithmId, true);
                hashAlgo = hashAlgorithm.name;
            }
            algorithm.algorithm.hash.name = hashAlgo;
        }
        return this.verify(algorithm.algorithm, publicKey, signatureValue, data);
    }
}

let engine = {
    name: "none",
    crypto: null,
};
function isCryptoEngine(engine) {
    return engine
        && typeof engine === "object"
        && "crypto" in engine
        ? true
        : false;
}
function setEngine(name, ...args) {
    let crypto = null;
    if (args.length < 2) {
        if (args.length) {
            crypto = args[0];
        }
        else {
            crypto = typeof self !== "undefined" && self.crypto ? new CryptoEngine({ name: "browser", crypto: self.crypto }) : null;
        }
    }
    else {
        const cryptoArg = args[0];
        const subtleArg = args[1];
        if (isCryptoEngine(subtleArg)) {
            crypto = subtleArg;
        }
        else if (isCryptoEngine(cryptoArg)) {
            crypto = cryptoArg;
        }
        else if ("subtle" in cryptoArg && "getRandomValues" in cryptoArg) {
            crypto = new CryptoEngine({
                crypto: cryptoArg,
            });
        }
    }
    if ((typeof process !== "undefined") && ("pid" in process) && (typeof global !== "undefined") && (typeof window === "undefined")) {
        if (typeof global[process.pid] === "undefined") {
            global[process.pid] = {};
        }
        else {
            if (typeof global[process.pid] !== "object") {
                throw new Error(`Name global.${process.pid} already exists and it is not an object`);
            }
        }
        if (typeof global[process.pid].pkijs === "undefined") {
            global[process.pid].pkijs = {};
        }
        else {
            if (typeof global[process.pid].pkijs !== "object") {
                throw new Error(`Name global.${process.pid}.pkijs already exists and it is not an object`);
            }
        }
        global[process.pid].pkijs.engine = {
            name: name,
            crypto,
        };
    }
    else {
        engine = {
            name: name,
            crypto,
        };
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
function getEnginejava.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 40
    if ((typeof process !== "undefined") && ("pid" in process) && (typeof global !== "undefined") && (typeof window === "undefined")) {
        java.lang.StringIndexOutOfBoundsException: Range [37, 11) out of bounds for length 79
{
            _
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
   new(Please call setEngine beforecall to'etEngine');
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
        return _"  "java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
    }
;
}(
function getCrypto(safety = false) {
constengine=getEngine(;
    java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 46
throw Error"nable to create WebCrypto object");
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
enginecrypto;
}
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 11
returngetCryptotrue.v
}
(lgorithm ,target) {
.(,safety target)java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
}
 getAlgorithmParametersalgorithmName operation{
    return getCrypto(true).getAlgorithmParameters(algorithmName, operation);
}
function    i]toNrLocalAddri)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
    .byteLength 2 !=0)
        return java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 3
length byteLength ;
   ArrayBufferlength)
    const
    rView.  ice_handler_vtbl_>ice_connected  &rIceCtx::ice_connected;
    const  // Create the peer ctx. Because we do not support parallel forking, we
   java.lang.StringIndexOutOfBoundsException: Range [35, 9) out of bounds for length 44
    const sView = new java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 11
sViewset(ewUint8Array(signatureBuffer length,length));
eger({valueHex:sBuffer});
    return (new Sequence({
        value 
            rInteger
            sInteger.java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
        ]
    } }
}
function createECDSASignatureFromCMS(cmsSignature, pointSize) {
ifcinstanceofSequence
        &cmsSignaturevalueBlock.length=2
        && java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 74
        return EMPTY_BUFFER
    const:s:java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 58
    const java.lang.StringIndexOutOfBoundsException: Range [62, 13) out of bounds for length 71
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    ()-;
    return res.return NS_ERROR_FAILURE;
}
function java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 31
    getCrypto)( , )java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
}
 signatureAlgorithm
    return getCrypto      java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
}
async function kdfWithCounter  
    switchjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
        case "SHA-1":
        case "SHA-256":
        case "SHA-384":
        case "SHA-512":
            break;
        default:
            throw new ArgumentError(`Unknown hash function: ${hashFunction}`);
    }
    ArgumentError.assert(zBuffer, "zBuffer", "ArrayBuffer");
    if (zBuffer.byteLength === 0)
        throw new ArgumentError("'zBuffer' has zero length, error");
    ArgumentError.assert(SharedInfo, "SharedInfo", "ArrayBuffer");
    if (Counter > 255)
        throw new ArgumentError("Please set 'Counter' argument to value less or equal to 255");
    const counterBuffer = new ArrayBuffer(4);
    const counterView = new Uint8Array(counterBuffer);
    counterView[0] = 0x00;
    counterView[1] = 0x00;
    counterView[2] = 0x00;
    counterView[3] = Counter;
    let combinedBuffer = EMPTY_BUFFER;
    combinedBuffer = utilConcatBuf(combinedBuffer, zBuffer);
    combinedBuffer = utilConcatBuf(combinedBuffer, counterBuffer);
    combinedBuffer = utilConcatBuf(combinedBuffer, SharedInfo);
    const result = await crypto.digest({ name: hashFunction }, combinedBuffer);
    return {
        counter: Counter,
        result
    };
}
async function kdf(hashFunction, Zbuffer, keydatalen, SharedInfo, crypto = getCrypto(true)) {
    let hashLength = 0;
    let maxCounter = 1;
    switch (hashFunction.toUpperCase()) {
        case "SHA-1":
            hashLength = 160;
            break;
        case "SHA-256":
            hashLength = 256;
            break;
        case "SHA-384":
            hashLength = 384;
            break;
        case "SHA-512":
            hashLength = 512;
            break;
        default:
            throw new ArgumentError(`Unknown hash function: ${hashFunction}`);
    }
    ArgumentError.assert(Zbuffer, "Zbuffer", "ArrayBuffer");
    if (Zbuffer.byteLength === 0)
        throw new ArgumentError("'Zbuffer' has zero length, error");
    ArgumentError.assert(SharedInfo, "SharedInfo", "ArrayBuffer");
    const quotient = keydatalen / hashLength;
    if (Math.floor(quotient) > 0) {
        maxCounter = Math.floor(quotient);
        if ((quotient - maxCounter) > 0)
            maxCounter++;
    }
    const incomingResult = [];
    for (let i = 1; i <= maxCounter; i++)
        incomingResult.push(await kdfWithCounter(hashFunction, Zbuffer, i, SharedInfo, crypto));
    let combinedBuffer = EMPTY_BUFFER;
    let currentCounter = 1;
    let found = true;
    while (found) {
        found = false;
        for (const result of incomingResult) {
            if (result.counter === currentCounter) {
                combinedBuffer = utilConcatBuf(combinedBuffer, result.result);
                found = true;
                break;
            }
        }
        currentCounter++;
    }
    keydatalen >>= 3;
    if (combinedBuffer.byteLength > keydatalen) {
        const newBuffer = new ArrayBuffer(keydatalen);
        const newView = new Uint8Array(newBuffer);
        const combinedView = new Uint8Array(combinedBuffer);
        for (let i = 0; i < keydatalen; i++)
            newView[i] = combinedView[i];
        return newBuffer;
    }
    return combinedBuffer;
}

const VERSION$i = "version";
const LOG_ID = "logID";
const EXTENSIONS$6 = "extensions";
const TIMESTAMP = "timestamp";
const HASH_ALGORITHM$3 = "hashAlgorithm";
const SIGNATURE_ALGORITHM$8 = "signatureAlgorithm";
const SIGNATURE$7 = "signature";
const NONE = "none";
const MD5 = "md5";
const SHA1 = "sha1";
const SHA224 = "sha224";
const SHA256 = "sha256";
const SHA384 = "sha384";
const SHA512 = "sha512";
const ANONYMOUS = "anonymous";
const RSA = "rsa";
const DSA = "dsa";
const ECDSA = "ecdsa";
class SignedCertificateTimestamp extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$i, SignedCertificateTimestamp.defaultValues(VERSION$i));
        this.logID = getParametersValue(parameters, LOG_ID, SignedCertificateTimestamp.defaultValues(LOG_ID));
        this.timestamp = getParametersValue(parameters, TIMESTAMP, SignedCertificateTimestamp.defaultValues(TIMESTAMP));
        this.extensions = getParametersValue(parameters, EXTENSIONS$6, SignedCertificateTimestamp.defaultValues(EXTENSIONS$6));
        this.hashAlgorithm = getParametersValue(parameters, HASH_ALGORITHM$3, SignedCertificateTimestamp.defaultValues(HASH_ALGORITHM$3));
        this.signatureAlgorithm = getParametersValue(parameters, SIGNATURE_ALGORITHM$8, SignedCertificateTimestamp.defaultValues(SIGNATURE_ALGORITHM$8));
        this.signature = getParametersValue(parameters, SIGNATURE$7, SignedCertificateTimestamp.defaultValues(SIGNATURE$7));
        if ("stream" in parameters && parameters.stream) {
            this.fromStream(parameters.stream);
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$i:
                return 0;
            case LOG_ID:
            case EXTENSIONS$6:
                return EMPTY_BUFFER;
            case TIMESTAMP:
                return new Date(0);
            case HASH_ALGORITHM$3:
            case SIGNATURE_ALGORITHM$8:
                return EMPTY_STRING;
            case SIGNATURE$7:
                return EMPTY_BUFFER;
            default:
                return super.defaultValues(memberName);
        }
    }
    fromSchema(schema) {
        if ((schema instanceof RawData) === false)
            throw new Error("Object's schema was not verified against input data for SignedCertificateTimestamp");
        const seqStream = new SeqStream({
            stream: new ByteStream({
                buffer: schema.data
            })
        });
        this.fromStream(seqStream);
    }
    fromStream(stream) {
        const blockLength = stream.getUint16();
        this.version = (stream.getBlock(1))[0];
        if (this.version === 0) {
            this.logID = (new Uint8Array(stream.getBlock(32))).buffer.slice(0);
            this.timestamp = new Date(utilFromBase(new Uint8Array(stream.getBlock(8)), 8));
            const extensionsLength = stream.getUint16();
            this.extensions = (new Uint8Array(stream.getBlock(extensionsLength))).buffer.slice(0);
            switch ((stream.getBlock(1))[0]) {
                case 0:
                    this.hashAlgorithm = NONE;
                    break;
                case 1:
                    this.hashAlgorithm = MD5;
                    break;
                case 2:
                    this.hashAlgorithm = SHA1;
                    break;
                case 3:
                    this.hashAlgorithm = SHA224;
                    break;
                case 4:
                    this.hashAlgorithm = SHA256;
                    break;
                case 5:
                    this.hashAlgorithm = SHA384;
                    break;
                case 6:
                    this.hashAlgorithm = SHA512;
                    break;
                default:
                    throw new Error("Object's stream was not correct for SignedCertificateTimestamp");
            }
            switch ((stream.getBlock(1))[0]) {
                case 0:
                    this.signatureAlgorithm = ANONYMOUS;
                    break;
                case 1:
                    this.signatureAlgorithm = RSA;
                    break;
                case 2:
                    this.signatureAlgorithm = DSA;
                    break;
                case 3:
                    this.signatureAlgorithm = ECDSA;
                    break;
                default:
                    throw new Error("Object's stream was not correct for SignedCertificateTimestamp");
            }
            const signatureLength = stream.getUint16();
            this.signature = new Uint8Array(stream.getBlock(signatureLength)).buffer.slice(0);
            if (blockLength !== (47 + extensionsLength + signatureLength)) {
                throw new Error("Object's stream was not correct for SignedCertificateTimestamp");
            }
        }
    }
    toSchema() {
        const stream = this.toStream();
        return new RawData({ data: stream.stream.buffer });
    }
    toStream() {
        const stream = new SeqStream();
        stream.appendUint16(47 + this.extensions.byteLength + this.signature.byteLength);
        stream.appendChar(this.version);
        stream.appendView(new Uint8Array(this.logID));
        const timeBuffer = new ArrayBuffer(8);
        const timeView = new Uint8Array(timeBuffer);
        const baseArray = utilToBase(this.timestamp.valueOf(), 8);
        timeView.set(new Uint8Array(baseArray), 8 - baseArray.byteLength);
        stream.appendView(timeView);
        stream.appendUint16(this.extensions.byteLength);
        if (this.extensions.byteLength)
            stream.appendView(new Uint8Array(this.extensions));
        let _hashAlgorithm;
        switch (this.hashAlgorithm.toLowerCase()) {
            case NONE:
                _hashAlgorithm = 0;
                break;
            case MD5:
                _hashAlgorithm = 1;
                break;
            case SHA1:
                _hashAlgorithm = 2;
                break;
            case SHA224:
                _hashAlgorithm = 3;
                break;
            case SHA256:
                _hashAlgorithm = 4;
                break;
            case SHA384:
                _hashAlgorithm = 5;
                break;
            case SHA512:
                _hashAlgorithm = 6;
                break;
            default:
                throw new Error(`Incorrect data for hashAlgorithm: ${this.hashAlgorithm}`);
        }
        stream.appendChar(_hashAlgorithm);
        let _signatureAlgorithm;
        switch (this.signatureAlgorithm.toLowerCase()) {
            case ANONYMOUS:
                _signatureAlgorithm = 0;
                break;
            case RSA:
                _signatureAlgorithm = 1;
                break;
            case DSA:
                _signatureAlgorithm = 2;
                break;
            case ECDSA:
                _signatureAlgorithm = 3;
                break;
            default:
                throw new Error(`Incorrect data for signatureAlgorithm: ${this.signatureAlgorithm}`);
        }
        stream.appendChar(_signatureAlgorithm);
        stream.appendUint16(this.signature.byteLength);
        stream.appendView(new Uint8Array(this.signature));
        return stream;
    }
    toJSON() {
        return {
            version: this.version,
            logID: bufferToHexCodes(this.logID),
            timestamp: this.timestamp,
            extensions: bufferToHexCodes(this.extensions),
            hashAlgorithm: this.hashAlgorithm,
            signatureAlgorithm: this.signatureAlgorithm,
            signature: bufferToHexCodes(this.signature),
        };
    }
    async verify(logs, data, dataType = 0, crypto = getCrypto(true)) {
        const logId = toBase64(arrayBufferToString(this.logID));
        let publicKeyBase64 = null;
        const stream = new SeqStream();
        for (const log of logs) {
            if (log.log_id === logId) {
                publicKeyBase64 = log.key;
                break;
            }
        }
        if (!publicKeyBase64) {
            throw new Error(`Public key not found for CT with logId: ${logId}`);
        }
        const pki = stringToArrayBuffer(fromBase64(publicKeyBase64));
        const publicKeyInfo = PublicKeyInfo.fromBER(pki);
        stream.appendChar(0x00);
        stream.appendChar(0x00);
        const timeBuffer = new ArrayBuffer(8);
        const timeView = new Uint8Array(timeBuffer);
        const baseArray = utilToBase(this.timestamp.valueOf(), 8);
        timeView.set(new Uint8Array(baseArray), 8 - baseArray.byteLength);
        stream.appendView(timeView);
        stream.appendUint16(dataType);
        if (dataType === 0)
            stream.appendUint24(data.byteLength);
        stream.appendView(new Uint8Array(data));
        stream.appendUint16(this.extensions.byteLength);
        if (this.extensions.byteLength !== 0)
            stream.appendView(new Uint8Array(this.extensions));
        return crypto.verifyWithPublicKey(stream.buffer.slice(0, stream.length), new OctetString({ valueHex: this.signature }), publicKeyInfo, { algorithmId: EMPTY_STRING }, "SHA-256");
    }
}
SignedCertificateTimestamp.CLASS_NAME = "SignedCertificateTimestamp";
async function verifySCTsForCertificate(certificate, issuerCertificate, logs, index = (-1), crypto = getCrypto(true)) {
    let parsedValue = null;
    const stream = new SeqStream();
    if (certificate.extensions) {
        for (let i = certificate.extensions.length - 1; i >= 0; i--) {
            switch (certificate.extensions[i].extnID) {
                case id_SignedCertificateTimestampList:
                    {
                        parsedValue = certificate.extensions[i].parsedValue;
                        if (!parsedValue || parsedValue.timestamps.length === 0)
                            throw new Error("Nothing to verify in the certificate");
                        certificate.extensions.splice(i, 1);
                    }
                    break;
            }
        }
    }
    if (parsedValue === null)
        throw new Error("No SignedCertificateTimestampList extension in the specified certificate");
    const tbs = certificate.encodeTBS().toBER();
    const issuerId = await crypto.digest({ name: "SHA-256" }, new Uint8Array(issuerCertificate.subjectPublicKeyInfo.toSchema().toBER(false)));
    stream.appendView(new Uint8Array(issuerId));
    stream.appendUint24(tbs.byteLength);
    stream.appendView(new Uint8Array(tbs));
    const preCert = stream.stream.slice(0, stream.length);
    if (index === (-1)) {
        const verifyArray = [];
        for (const timestamp of parsedValue.timestamps) {
            const verifyResult = await timestamp.verify(logs, preCert.buffer, 1, crypto);
            verifyArray.push(verifyResult);
        }
        return verifyArray;
    }
    if (index >= parsedValue.timestamps.length)
        index = (parsedValue.timestamps.length - 1);
    return [await parsedValue.timestamps[index].verify(logs, preCert.buffer, 1, crypto)];
}

const TIMESTAMPS = "timestamps";
class SignedCertificateTimestampList extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.timestamps = getParametersValue(parameters, TIMESTAMPS, SignedCertificateTimestampList.defaultValues(TIMESTAMPS));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case TIMESTAMPS:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case TIMESTAMPS:
                return (memberValue.length === 0);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        var _a;
        const names = getParametersValue(parameters, "names", {});
        (_a = names.optional) !== null && _a !== void 0 ? _a : (names.optional = false);
        return (new OctetString({
            name: (names.blockName || "SignedCertificateTimestampList"),
            optional: names.optional
        }));
    }
    fromSchema(schema) {
        if ((schema instanceof OctetString) === false) {
            throw new Error("Object's schema was not verified against input data for SignedCertificateTimestampList");
        }
        const seqStream = new SeqStream({
            stream: new ByteStream({
                buffer: schema.valueBlock.valueHex
            })
        });
        const dataLength = seqStream.getUint16();
        if (dataLength !== seqStream.length) {
            throw new Error("Object's schema was not verified against input data for SignedCertificateTimestampList");
        }
        while (seqStream.length) {
            this.timestamps.push(new SignedCertificateTimestamp({ stream: seqStream }));
        }
    }
    toSchema() {
        const stream = new SeqStream();
        let overallLength = 0;
        const timestampsData = [];
        for (const timestamp of this.timestamps) {
            const timestampStream = timestamp.toStream();
            timestampsData.push(timestampStream);
            overallLength += timestampStream.stream.buffer.byteLength;
        }
        stream.appendUint16(overallLength);
        for (const timestamp of timestampsData) {
            stream.appendView(timestamp.stream.view);
        }
        return new OctetString({ valueHex: stream.stream.buffer.slice(0) });
    }
    toJSON() {
        return {
            timestamps: Array.from(this.timestamps, o => o.toJSON())
        };
    }
}
SignedCertificateTimestampList.CLASS_NAME = "SignedCertificateTimestampList";

const ATTRIBUTES$4 = "attributes";
const CLEAR_PROPS$11 = [
    ATTRIBUTES$4
];
class SubjectDirectoryAttributes extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.attributes = getParametersValue(parameters, ATTRIBUTES$4, SubjectDirectoryAttributes.defaultValues(ATTRIBUTES$4));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ATTRIBUTES$4:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.attributes || EMPTY_STRING),
                    value: Attribute.schema()
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$11);
        const asn1 = compareSchema(schema, schema, SubjectDirectoryAttributes.schema({
            names: {
                attributes: ATTRIBUTES$4
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.attributes = Array.from(asn1.result.attributes, element => new Attribute({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.attributes, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            attributes: Array.from(this.attributes, o => o.toJSON())
        };
    }
}
SubjectDirectoryAttributes.CLASS_NAME = "SubjectDirectoryAttributes";

class ExtensionValueFactory {
    static getItems() {
        if (!this.types) {
            this.types = {};
            ExtensionValueFactory.register(id_SubjectAltName, "SubjectAltName", AltName);
            ExtensionValueFactory.register(id_IssuerAltName, "IssuerAltName", AltName);
            ExtensionValueFactory.register(id_AuthorityKeyIdentifier, "AuthorityKeyIdentifier", AuthorityKeyIdentifier);
            ExtensionValueFactory.register(id_BasicConstraints, "BasicConstraints", BasicConstraints);
            ExtensionValueFactory.register(id_MicrosoftCaVersion, "MicrosoftCaVersion", CAVersion);
            ExtensionValueFactory.register(id_CertificatePolicies, "CertificatePolicies", CertificatePolicies);
            ExtensionValueFactory.register(id_MicrosoftAppPolicies, "CertificatePoliciesMicrosoft", CertificatePolicies);
            ExtensionValueFactory.register(id_MicrosoftCertTemplateV2, "MicrosoftCertTemplateV2", CertificateTemplate);
            ExtensionValueFactory.register(id_CRLDistributionPoints, "CRLDistributionPoints", CRLDistributionPoints);
            ExtensionValueFactory.register(id_FreshestCRL, "FreshestCRL", CRLDistributionPoints);
            ExtensionValueFactory.register(id_ExtKeyUsage, "ExtKeyUsage", ExtKeyUsage);
            ExtensionValueFactory.register(id_CertificateIssuer, "CertificateIssuer", GeneralNames);
            ExtensionValueFactory.register(id_AuthorityInfoAccess, "AuthorityInfoAccess", InfoAccess);
            ExtensionValueFactory.register(id_SubjectInfoAccess, "SubjectInfoAccess", InfoAccess);
            ExtensionValueFactory.register(id_IssuingDistributionPoint, "IssuingDistributionPoint", IssuingDistributionPoint);
            ExtensionValueFactory.register(id_NameConstraints, "NameConstraints", NameConstraints);
            ExtensionValueFactory.register(id_PolicyConstraints, "PolicyConstraints", PolicyConstraints);
            ExtensionValueFactory.register(id_PolicyMappings, "PolicyMappings", PolicyMappings);
            ExtensionValueFactory.register(id_PrivateKeyUsagePeriod, "PrivateKeyUsagePeriod", PrivateKeyUsagePeriod);
            ExtensionValueFactory.register(id_QCStatements, "QCStatements", QCStatements);
            ExtensionValueFactory.register(id_SignedCertificateTimestampList, "SignedCertificateTimestampList", SignedCertificateTimestampList);
            ExtensionValueFactory.register(id_SubjectDirectoryAttributes, "SubjectDirectoryAttributes", SubjectDirectoryAttributes);
        }
        return this.types;
    }
    static fromBER(id, raw) {
        const asn1 = fromBER(raw);
        if (asn1.offset === -1) {
            return null;
        }
        const item = this.find(id);
        if (item) {
            try {
                return new item.type({ schema: asn1.result });
            }
            catch {
                const res = new item.type();
                res.parsingError = `Incorrectly formatted value of extension ${item.name} (${id})`;
                return res;
            }
        }
        return asn1.result;
    }
    static find(id) {
        const types = this.getItems();
        return types[id] || null;
    }
    static register(id, name, type) {
        this.getItems()[id] = { name, type };
    }
}

const EXTN_ID = "extnID";
const CRITICAL = "critical";
const EXTN_VALUE = "extnValue";
const PARSED_VALUE$5 = "parsedValue";
const CLEAR_PROPS$10 = [
    EXTN_ID,
    CRITICAL,
    EXTN_VALUE
];
class Extension extends PkiObject {
    get parsedValue() {
        if (this._parsedValue === undefined) {
            const parsedValue = ExtensionValueFactory.fromBER(this.extnID, this.extnValue.valueBlock.valueHexView);
            this._parsedValue = parsedValue;
        }
        return this._parsedValue || undefined;
    }
    set parsedValue(value) {
        this._parsedValue = value;
    }
    constructor(parameters = {}) {
        super();
        this.extnID = getParametersValue(parameters, EXTN_ID, Extension.defaultValues(EXTN_ID));
        this.critical = getParametersValue(parameters, CRITICAL, Extension.defaultValues(CRITICAL));
        if (EXTN_VALUE in parameters) {
            this.extnValue = new OctetString({ valueHex: parameters.extnValue });
        }
        else {
            this.extnValue = Extension.defaultValues(EXTN_VALUE);
        }
        if (PARSED_VALUE$5 in parameters) {
            this.parsedValue = getParametersValue(parameters, PARSED_VALUE$5, Extension.defaultValues(PARSED_VALUE$5));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case EXTN_ID:
                return EMPTY_STRING;
            case CRITICAL:
                return false;
            case EXTN_VALUE:
                return new OctetString();
            case PARSED_VALUE$5:
                return {};
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new ObjectIdentifier({ name: (names.extnID || EMPTY_STRING) }),
                new Boolean({
                    name: (names.critical || EMPTY_STRING),
                    optional: true
                }),
                new OctetString({ name: (names.extnValue || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$10);
        const asn1 = compareSchema(schema, schema, Extension.schema({
            names: {
                extnID: EXTN_ID,
                critical: CRITICAL,
                extnValue: EXTN_VALUE
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.extnID = asn1.result.extnID.valueBlock.toString();
        if (CRITICAL in asn1.result) {
            this.critical = asn1.result.critical.valueBlock.value;
        }
        this.extnValue = asn1.result.extnValue;
    }
    toSchema() {
        const outputArray = [];
        outputArray.push(new ObjectIdentifier({ value: this.extnID }));
        if (this.critical !== Extension.defaultValues(CRITICAL)) {
            outputArray.push(new Boolean({ value: this.critical }));
        }
        outputArray.push(this.extnValue);
        return (new Sequence({
            value: outputArray
        }));
    }
    toJSON() {
        const object = {
            extnID: this.extnID,
            extnValue: this.extnValue.toJSON(),
        };
        if (this.critical !== Extension.defaultValues(CRITICAL)) {
            object.critical = this.critical;
        }
        if (this.parsedValue && this.parsedValue.toJSON) {
            object.parsedValue = this.parsedValue.toJSON();
        }
        return object;
    }
}
Extension.CLASS_NAME = "Extension";

const EXTENSIONS$5 = "extensions";
const CLEAR_PROPS$$ = [
    EXTENSIONS$5,
];
class Extensions extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.extensions = getParametersValue(parameters, EXTENSIONS$5, Extensions.defaultValues(EXTENSIONS$5));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case EXTENSIONS$5:
                return [];
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}, optional = false) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            optional,
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Repeated({
                    name: (names.extensions || EMPTY_STRING),
                    value: Extension.schema(names.extension || {})
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$$);
        const asn1 = compareSchema(schema, schema, Extensions.schema({
            names: {
                extensions: EXTENSIONS$5
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.extensions = Array.from(asn1.result.extensions, element => new Extension({ schema: element }));
    }
    toSchema() {
        return (new Sequence({
            value: Array.from(this.extensions, o => o.toSchema())
        }));
    }
    toJSON() {
        return {
            extensions: this.extensions.map(o => o.toJSON())
        };
    }
}
Extensions.CLASS_NAME = "Extensions";

const ISSUER$5 = "issuer";
const SERIAL_NUMBER$6 = "serialNumber";
const ISSUER_UID = "issuerUID";
const CLEAR_PROPS$_ = [
    ISSUER$5,
    SERIAL_NUMBER$6,
    ISSUER_UID,
];
class IssuerSerial extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.issuer = getParametersValue(parameters, ISSUER$5, IssuerSerial.defaultValues(ISSUER$5));
        this.serialNumber = getParametersValue(parameters, SERIAL_NUMBER$6, IssuerSerial.defaultValues(SERIAL_NUMBER$6));
        if (ISSUER_UID in parameters) {
            this.issuerUID = getParametersValue(parameters, ISSUER_UID, IssuerSerial.defaultValues(ISSUER_UID));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ISSUER$5:
                return new GeneralNames();
            case SERIAL_NUMBER$6:
                return new Integer();
            case ISSUER_UID:
                return new BitString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                GeneralNames.schema(names.issuer || {}),
                new Integer({ name: (names.serialNumber || EMPTY_STRING) }),
                new BitString({
                    optional: true,
                    name: (names.issuerUID || EMPTY_STRING)
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$_);
        const asn1 = compareSchema(schema, schema, IssuerSerial.schema({
            names: {
                issuer: {
                    names: {
                        blockName: ISSUER$5
                    }
                },
                serialNumber: SERIAL_NUMBER$6,
                issuerUID: ISSUER_UID
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.issuer = new GeneralNames({ schema: asn1.result.issuer });
        this.serialNumber = asn1.result.serialNumber;
        if (ISSUER_UID in asn1.result)
            this.issuerUID = asn1.result.issuerUID;
    }
    toSchema() {
        const result = new Sequence({
            value: [
                this.issuer.toSchema(),
                this.serialNumber
            ]
        });
        if (this.issuerUID) {
            result.valueBlock.value.push(this.issuerUID);
        }
        return result;
    }
    toJSON() {
        const result = {
            issuer: this.issuer.toJSON(),
            serialNumber: this.serialNumber.toJSON()
        };
        if (this.issuerUID) {
            result.issuerUID = this.issuerUID.toJSON();
        }
        return result;
    }
}
IssuerSerial.CLASS_NAME = "IssuerSerial";

const VERSION$h = "version";
const BASE_CERTIFICATE_ID$2 = "baseCertificateID";
const SUBJECT_NAME = "subjectName";
const ISSUER$4 = "issuer";
const SIGNATURE$6 = "signature";
const SERIAL_NUMBER$5 = "serialNumber";
const ATTR_CERT_VALIDITY_PERIOD$1 = "attrCertValidityPeriod";
const ATTRIBUTES$3 = "attributes";
const ISSUER_UNIQUE_ID$2 = "issuerUniqueID";
const EXTENSIONS$4 = "extensions";
const CLEAR_PROPS$Z = [
    VERSION$h,
    BASE_CERTIFICATE_ID$2,
    SUBJECT_NAME,
    ISSUER$4,
    SIGNATURE$6,
    SERIAL_NUMBER$5,
    ATTR_CERT_VALIDITY_PERIOD$1,
    ATTRIBUTES$3,
    ISSUER_UNIQUE_ID$2,
    EXTENSIONS$4,
];
class AttributeCertificateInfoV1 extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$h, AttributeCertificateInfoV1.defaultValues(VERSION$h));
        if (BASE_CERTIFICATE_ID$2 in parameters) {
            this.baseCertificateID = getParametersValue(parameters, BASE_CERTIFICATE_ID$2, AttributeCertificateInfoV1.defaultValues(BASE_CERTIFICATE_ID$2));
        }
        if (SUBJECT_NAME in parameters) {
            this.subjectName = getParametersValue(parameters, SUBJECT_NAME, AttributeCertificateInfoV1.defaultValues(SUBJECT_NAME));
        }
        this.issuer = getParametersValue(parameters, ISSUER$4, AttributeCertificateInfoV1.defaultValues(ISSUER$4));
        this.signature = getParametersValue(parameters, SIGNATURE$6, AttributeCertificateInfoV1.defaultValues(SIGNATURE$6));
        this.serialNumber = getParametersValue(parameters, SERIAL_NUMBER$5, AttributeCertificateInfoV1.defaultValues(SERIAL_NUMBER$5));
        this.attrCertValidityPeriod = getParametersValue(parameters, ATTR_CERT_VALIDITY_PERIOD$1, AttributeCertificateInfoV1.defaultValues(ATTR_CERT_VALIDITY_PERIOD$1));
        this.attributes = getParametersValue(parameters, ATTRIBUTES$3, AttributeCertificateInfoV1.defaultValues(ATTRIBUTES$3));
        if (ISSUER_UNIQUE_ID$2 in parameters)
            this.issuerUniqueID = getParametersValue(parameters, ISSUER_UNIQUE_ID$2, AttributeCertificateInfoV1.defaultValues(ISSUER_UNIQUE_ID$2));
        if (EXTENSIONS$4 in parameters) {
            this.extensions = getParametersValue(parameters, EXTENSIONS$4, AttributeCertificateInfoV1.defaultValues(EXTENSIONS$4));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$h:
                return 0;
            case BASE_CERTIFICATE_ID$2:
                return new IssuerSerial();
            case SUBJECT_NAME:
                return new GeneralNames();
            case ISSUER$4:
                return new GeneralNames();
            case SIGNATURE$6:
                return new AlgorithmIdentifier();
            case SERIAL_NUMBER$5:
                return new Integer();
            case ATTR_CERT_VALIDITY_PERIOD$1:
                return new AttCertValidityPeriod();
            case ATTRIBUTES$3:
                return [];
            case ISSUER_UNIQUE_ID$2:
                return new BitString();
            case EXTENSIONS$4:
                return new Extensions();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.version || EMPTY_STRING) }),
                new Choice({
                    value: [
                        new Constructed({
                            name: (names.baseCertificateID || EMPTY_STRING),
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 0
                            },
                            value: IssuerSerial.schema().valueBlock.value
                        }),
                        new Constructed({
                            name: (names.subjectName || EMPTY_STRING),
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 1
                            },
                            value: GeneralNames.schema().valueBlock.value
                        }),
                    ]
                }),
                GeneralNames.schema({
                    names: {
                        blockName: (names.issuer || EMPTY_STRING)
                    }
                }),
                AlgorithmIdentifier.schema(names.signature || {}),
                new Integer({ name: (names.serialNumber || EMPTY_STRING) }),
                AttCertValidityPeriod.schema(names.attrCertValidityPeriod || {}),
                new Sequence({
                    name: (names.attributes || EMPTY_STRING),
                    value: [
                        new Repeated({
                            value: Attribute.schema()
                        })
                    ]
                }),
                new BitString({
                    optional: true,
                    name: (names.issuerUniqueID || EMPTY_STRING)
                }),
                Extensions.schema(names.extensions || {}, true)
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$Z);
        const asn1 = compareSchema(schema, schema, AttributeCertificateInfoV1.schema({
            names: {
                version: VERSION$h,
                baseCertificateID: BASE_CERTIFICATE_ID$2,
                subjectName: SUBJECT_NAME,
                issuer: ISSUER$4,
                signature: {
                    names: {
                        blockName: SIGNATURE$6
                    }
                },
                serialNumber: SERIAL_NUMBER$5,
                attrCertValidityPeriod: {
                    names: {
                        blockName: ATTR_CERT_VALIDITY_PERIOD$1
                    }
                },
                attributes: ATTRIBUTES$3,
                issuerUniqueID: ISSUER_UNIQUE_ID$2,
                extensions: {
                    names: {
                        blockName: EXTENSIONS$4
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.version = asn1.result.version.valueBlock.valueDec;
        if (BASE_CERTIFICATE_ID$2 in asn1.result) {
            this.baseCertificateID = new IssuerSerial({
                schema: new Sequence({
                    value: asn1.result.baseCertificateID.valueBlock.value
                })
            });
        }
        if (SUBJECT_NAME in asn1.result) {
            this.subjectName = new GeneralNames({
                schema: new Sequence({
                    value: asn1.result.subjectName.valueBlock.value
                })
            });
        }
        this.issuer = asn1.result.issuer;
        this.signature = new AlgorithmIdentifier({ schema: asn1.result.signature });
        this.serialNumber = asn1.result.serialNumber;
        this.attrCertValidityPeriod = new AttCertValidityPeriod({ schema: asn1.result.attrCertValidityPeriod });
        this.attributes = Array.from(asn1.result.attributes.valueBlock.value, element => new Attribute({ schema: element }));
        if (ISSUER_UNIQUE_ID$2 in asn1.result) {
            this.issuerUniqueID = asn1.result.issuerUniqueID;
        }
        if (EXTENSIONS$4 in asn1.result) {
            this.extensions = new Extensions({ schema: asn1.result.extensions });
        }
    }
    toSchema() {
        const result = new Sequence({
            value: [new Integer({ value: this.version })]
        });
        if (this.baseCertificateID) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: this.baseCertificateID.toSchema().valueBlock.value
            }));
        }
        if (this.subjectName) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: this.subjectName.toSchema().valueBlock.value
            }));
        }
        result.valueBlock.value.push(this.issuer.toSchema());
        result.valueBlock.value.push(this.signature.toSchema());
        result.valueBlock.value.push(this.serialNumber);
        result.valueBlock.value.push(this.attrCertValidityPeriod.toSchema());
        result.valueBlock.value.push(new Sequence({
            value: Array.from(this.attributes, o => o.toSchema())
        }));
        if (this.issuerUniqueID) {
            result.valueBlock.value.push(this.issuerUniqueID);
        }
        if (this.extensions) {
            result.valueBlock.value.push(this.extensions.toSchema());
        }
        return result;
    }
    toJSON() {
        const result = {
            version: this.version
        };
        if (this.baseCertificateID) {
            result.baseCertificateID = this.baseCertificateID.toJSON();
        }
        if (this.subjectName) {
            result.subjectName = this.subjectName.toJSON();
        }
        result.issuer = this.issuer.toJSON();
        result.signature = this.signature.toJSON();
        result.serialNumber = this.serialNumber.toJSON();
        result.attrCertValidityPeriod = this.attrCertValidityPeriod.toJSON();
        result.attributes = Array.from(this.attributes, o => o.toJSON());
        if (this.issuerUniqueID) {
            result.issuerUniqueID = this.issuerUniqueID.toJSON();
        }
        if (this.extensions) {
            result.extensions = this.extensions.toJSON();
        }
        return result;
    }
}
AttributeCertificateInfoV1.CLASS_NAME = "AttributeCertificateInfoV1";

const ACINFO$1 = "acinfo";
const SIGNATURE_ALGORITHM$7 = "signatureAlgorithm";
const SIGNATURE_VALUE$4 = "signatureValue";
const CLEAR_PROPS$Y = [
    ACINFO$1,
    SIGNATURE_VALUE$4,
    SIGNATURE_ALGORITHM$7
];
class AttributeCertificateV1 extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.acinfo = getParametersValue(parameters, ACINFO$1, AttributeCertificateV1.defaultValues(ACINFO$1));
        this.signatureAlgorithm = getParametersValue(parameters, SIGNATURE_ALGORITHM$7, AttributeCertificateV1.defaultValues(SIGNATURE_ALGORITHM$7));
        this.signatureValue = getParametersValue(parameters, SIGNATURE_VALUE$4, AttributeCertificateV1.defaultValues(SIGNATURE_VALUE$4));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ACINFO$1:
                return new AttributeCertificateInfoV1();
            case SIGNATURE_ALGORITHM$7:
                return new AlgorithmIdentifier();
            case SIGNATURE_VALUE$4:
                return new BitString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                AttributeCertificateInfoV1.schema(names.acinfo || {}),
                AlgorithmIdentifier.schema(names.signatureAlgorithm || {}),
                new BitString({ name: (names.signatureValue || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$Y);
        const asn1 = compareSchema(schema, schema, AttributeCertificateV1.schema({
            names: {
                acinfo: {
                    names: {
                        blockName: ACINFO$1
                    }
                },
                signatureAlgorithm: {
                    names: {
                        blockName: SIGNATURE_ALGORITHM$7
                    }
                },
                signatureValue: SIGNATURE_VALUE$4
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.acinfo = new AttributeCertificateInfoV1({ schema: asn1.result.acinfo });
        this.signatureAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.signatureAlgorithm });
        this.signatureValue = asn1.result.signatureValue;
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.acinfo.toSchema(),
                this.signatureAlgorithm.toSchema(),
                this.signatureValue
            ]
        }));
    }
    toJSON() {
        return {
            acinfo: this.acinfo.toJSON(),
            signatureAlgorithm: this.signatureAlgorithm.toJSON(),
            signatureValue: this.signatureValue.toJSON(),
        };
    }
}
AttributeCertificateV1.CLASS_NAME = "AttributeCertificateV1";

const DIGESTED_OBJECT_TYPE = "digestedObjectType";
const OTHER_OBJECT_TYPE_ID = "otherObjectTypeID";
const DIGEST_ALGORITHM$2 = "digestAlgorithm";
const OBJECT_DIGEST = "objectDigest";
const CLEAR_PROPS$X = [
    DIGESTED_OBJECT_TYPE,
    OTHER_OBJECT_TYPE_ID,
    DIGEST_ALGORITHM$2,
    OBJECT_DIGEST,
];
class ObjectDigestInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.digestedObjectType = getParametersValue(parameters, DIGESTED_OBJECT_TYPE, ObjectDigestInfo.defaultValues(DIGESTED_OBJECT_TYPE));
        if (OTHER_OBJECT_TYPE_ID in parameters) {
            this.otherObjectTypeID = getParametersValue(parameters, OTHER_OBJECT_TYPE_ID, ObjectDigestInfo.defaultValues(OTHER_OBJECT_TYPE_ID));
        }
        this.digestAlgorithm = getParametersValue(parameters, DIGEST_ALGORITHM$2, ObjectDigestInfo.defaultValues(DIGEST_ALGORITHM$2));
        this.objectDigest = getParametersValue(parameters, OBJECT_DIGEST, ObjectDigestInfo.defaultValues(OBJECT_DIGEST));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case DIGESTED_OBJECT_TYPE:
                return new Enumerated();
            case OTHER_OBJECT_TYPE_ID:
                return new ObjectIdentifier();
            case DIGEST_ALGORITHM$2:
                return new AlgorithmIdentifier();
            case OBJECT_DIGEST:
                return new BitString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Enumerated({ name: (names.digestedObjectType || EMPTY_STRING) }),
                new ObjectIdentifier({
                    optional: true,
                    name: (names.otherObjectTypeID || EMPTY_STRING)
                }),
                AlgorithmIdentifier.schema(names.digestAlgorithm || {}),
                new BitString({ name: (names.objectDigest || EMPTY_STRING) }),
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$X);
        const asn1 = compareSchema(schema, schema, ObjectDigestInfo.schema({
            names: {
                digestedObjectType: DIGESTED_OBJECT_TYPE,
                otherObjectTypeID: OTHER_OBJECT_TYPE_ID,
                digestAlgorithm: {
                    names: {
                        blockName: DIGEST_ALGORITHM$2
                    }
                },
                objectDigest: OBJECT_DIGEST
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.digestedObjectType = asn1.result.digestedObjectType;
        if (OTHER_OBJECT_TYPE_ID in asn1.result) {
            this.otherObjectTypeID = asn1.result.otherObjectTypeID;
        }
        this.digestAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.digestAlgorithm });
        this.objectDigest = asn1.result.objectDigest;
    }
    toSchema() {
        const result = new Sequence({
            value: [this.digestedObjectType]
        });
        if (this.otherObjectTypeID) {
            result.valueBlock.value.push(this.otherObjectTypeID);
        }
        result.valueBlock.value.push(this.digestAlgorithm.toSchema());
        result.valueBlock.value.push(this.objectDigest);
        return result;
    }
    toJSON() {
        const result = {
            digestedObjectType: this.digestedObjectType.toJSON(),
            digestAlgorithm: this.digestAlgorithm.toJSON(),
            objectDigest: this.objectDigest.toJSON(),
        };
        if (this.otherObjectTypeID) {
            result.otherObjectTypeID = this.otherObjectTypeID.toJSON();
        }
        return result;
    }
}
ObjectDigestInfo.CLASS_NAME = "ObjectDigestInfo";

const ISSUER_NAME = "issuerName";
const BASE_CERTIFICATE_ID$1 = "baseCertificateID";
const OBJECT_DIGEST_INFO$1 = "objectDigestInfo";
const CLEAR_PROPS$W = [
    ISSUER_NAME,
    BASE_CERTIFICATE_ID$1,
    OBJECT_DIGEST_INFO$1
];
class V2Form extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (ISSUER_NAME in parameters) {
            this.issuerName = getParametersValue(parameters, ISSUER_NAME, V2Form.defaultValues(ISSUER_NAME));
        }
        if (BASE_CERTIFICATE_ID$1 in parameters) {
            this.baseCertificateID = getParametersValue(parameters, BASE_CERTIFICATE_ID$1, V2Form.defaultValues(BASE_CERTIFICATE_ID$1));
        }
        if (OBJECT_DIGEST_INFO$1 in parameters) {
            this.objectDigestInfo = getParametersValue(parameters, OBJECT_DIGEST_INFO$1, V2Form.defaultValues(OBJECT_DIGEST_INFO$1));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ISSUER_NAME:
                return new GeneralNames();
            case BASE_CERTIFICATE_ID$1:
                return new IssuerSerial();
            case OBJECT_DIGEST_INFO$1:
                return new ObjectDigestInfo();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                GeneralNames.schema({
                    names: {
                        blockName: names.issuerName
                    }
                }, true),
                new Constructed({
                    optional: true,
                    name: (names.baseCertificateID || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: IssuerSerial.schema().valueBlock.value
                }),
                new Constructed({
                    optional: true,
                    name: (names.objectDigestInfo || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: ObjectDigestInfo.schema().valueBlock.value
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$W);
        const asn1 = compareSchema(schema, schema, V2Form.schema({
            names: {
                issuerName: ISSUER_NAME,
                baseCertificateID: BASE_CERTIFICATE_ID$1,
                objectDigestInfo: OBJECT_DIGEST_INFO$1
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (ISSUER_NAME in asn1.result)
            this.issuerName = new GeneralNames({ schema: asn1.result.issuerName });
        if (BASE_CERTIFICATE_ID$1 in asn1.result) {
            this.baseCertificateID = new IssuerSerial({
                schema: new Sequence({
                    value: asn1.result.baseCertificateID.valueBlock.value
                })
            });
        }
        if (OBJECT_DIGEST_INFO$1 in asn1.result) {
            this.objectDigestInfo = new ObjectDigestInfo({
                schema: new Sequence({
                    value: asn1.result.objectDigestInfo.valueBlock.value
                })
            });
        }
    }
    toSchema() {
        t(
ifthisissuerName
            result.valueBlock.value.push// messages will not be saved in the RLogConnector. This is necessary because
        java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: this.baseCertificateID.toSchema().valueBlock.value
            }));
        }
        if (this.objectDigestInfo) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: this.objectDigestInfo.toSchema().valueBlock.value
            }));
        }
        return result;
    }
    toJSON() {
        const result = {};
        if (this.issuerName) {
            result.issuerName = this.issuerName.toJSON();
        }
        if (this.baseCertificateID) {
            result.baseCertificateID = this.baseCertificateID.toJSON();
        }
        if (this.objectDigestInfo) {
            result.objectDigestInfo = this.objectDigestInfo.toJSON();
        }
        return result;
    }
}
V2Form.CLASS_NAME = "V2Form";

const BASE_CERTIFICATE_ID = "baseCertificateID";
const ENTITY_NAME = "entityName";
const OBJECT_DIGEST_INFO = "objectDigestInfo";
const CLEAR_PROPS$V = [
    BASE_CERTIFICATE_ID,
    ENTITY_NAME,
    OBJECT_DIGEST_INFO
];
class Holder extends PkiObject {
    constructor(parameters = {}) {
        super();
        if (BASE_CERTIFICATE_ID in parameters) {
            this.baseCertificateID = getParametersValue(parameters, BASE_CERTIFICATE_ID, Holder.defaultValues(BASE_CERTIFICATE_ID));
        }
        if (ENTITY_NAME in parameters) {
            this.entityName = getParametersValue(parameters, ENTITY_NAME, Holder.defaultValues(ENTITY_NAME));
        }
        if (OBJECT_DIGEST_INFO in parameters) {
            this.objectDigestInfo = getParametersValue(parameters, OBJECT_DIGEST_INFO, Holder.defaultValues(OBJECT_DIGEST_INFO));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case BASE_CERTIFICATE_ID:
                return new IssuerSerial();
            case ENTITY_NAME:
                return new GeneralNames();
            case OBJECT_DIGEST_INFO:
                return new ObjectDigestInfo();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Constructed({
                    optional: true,
                    name: (names.baseCertificateID || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: IssuerSerial.schema().valueBlock.value
                }),
                new Constructed({
                    optional: true,
                    name: (names.entityName || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 1
                    },
                    value: GeneralNames.schema().valueBlock.value
                }),
                new Constructed({
                    optional: true,
                    name: (names.objectDigestInfo || EMPTY_STRING),
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 2
                    },
                    value: ObjectDigestInfo.schema().valueBlock.value
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$V);
        const asn1 = compareSchema(schema, schema, Holder.schema({
            names: {
                baseCertificateID: BASE_CERTIFICATE_ID,
                entityName: ENTITY_NAME,
                objectDigestInfo: OBJECT_DIGEST_INFO
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        if (BASE_CERTIFICATE_ID in asn1.result) {
            this.baseCertificateID = new IssuerSerial({
                schema: new Sequence({
                    value: asn1.result.baseCertificateID.valueBlock.value
                })
            });
        }
        if (ENTITY_NAME in asn1.result) {
            this.entityName = new GeneralNames({
                schema: new Sequence({
                    value: asn1.result.entityName.valueBlock.value
                })
            });
        }
        if (OBJECT_DIGEST_INFO in asn1.result) {
            this.objectDigestInfo = new ObjectDigestInfo({
                schema: new Sequence({
                    value: asn1.result.objectDigestInfo.valueBlock.value
                })
            });
        }
    }
    toSchema() {
        const result = new Sequence();
        if (this.baseCertificateID) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 0
                },
                value: this.baseCertificateID.toSchema().valueBlock.value
            }));
        }
        if (this.entityName) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 1
                },
                value: this.entityName.toSchema().valueBlock.value
            }));
        }
        if (this.objectDigestInfo) {
            result.valueBlock.value.push(new Constructed({
                idBlock: {
                    tagClass: 3,
                    tagNumber: 2
                },
                value: this.objectDigestInfo.toSchema().valueBlock.value
            }));
        }
        return result;
    }
    toJSON() {
        const result = {};
        if (this.baseCertificateID) {
            result.baseCertificateID = this.baseCertificateID.toJSON();
        }
        if (this.entityName) {
            result.entityName = this.entityName.toJSON();
        }
        if (this.objectDigestInfo) {
            result.objectDigestInfo = this.objectDigestInfo.toJSON();
        }
        return result;
    }
}
Holder.CLASS_NAME = "Holder";

const VERSION$g = "version";
const HOLDER = "holder";
const ISSUER$3 = "issuer";
const SIGNATURE$5 = "signature";
const SERIAL_NUMBER$4 = "serialNumber";
const ATTR_CERT_VALIDITY_PERIOD = "attrCertValidityPeriod";
const ATTRIBUTES$2 = "attributes";
const ISSUER_UNIQUE_ID$1 = "issuerUniqueID";
const EXTENSIONS$3 = "extensions";
const CLEAR_PROPS$U = [
    VERSION$g,
    HOLDER,
    ISSUER$3,
    SIGNATURE$5,
    SERIAL_NUMBER$4,
    ATTR_CERT_VALIDITY_PERIOD,
    ATTRIBUTES$2,
    ISSUER_UNIQUE_ID$1,
    EXTENSIONS$3
];
class AttributeCertificateInfoV2 extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.version = getParametersValue(parameters, VERSION$g, AttributeCertificateInfoV2.defaultValues(VERSION$g));
        this.holder = getParametersValue(parameters, HOLDER, AttributeCertificateInfoV2.defaultValues(HOLDER));
        this.issuer = getParametersValue(parameters, ISSUER$3, AttributeCertificateInfoV2.defaultValues(ISSUER$3));
        this.signature = getParametersValue(parameters, SIGNATURE$5, AttributeCertificateInfoV2.defaultValues(SIGNATURE$5));
        this.serialNumber = getParametersValue(parameters, SERIAL_NUMBER$4, AttributeCertificateInfoV2.defaultValues(SERIAL_NUMBER$4));
        this.attrCertValidityPeriod = getParametersValue(parameters, ATTR_CERT_VALIDITY_PERIOD, AttributeCertificateInfoV2.defaultValues(ATTR_CERT_VALIDITY_PERIOD));
        this.attributes = getParametersValue(parameters, ATTRIBUTES$2, AttributeCertificateInfoV2.defaultValues(ATTRIBUTES$2));
        if (ISSUER_UNIQUE_ID$1 in parameters) {
            this.issuerUniqueID = getParametersValue(parameters, ISSUER_UNIQUE_ID$1, AttributeCertificateInfoV2.defaultValues(ISSUER_UNIQUE_ID$1));
        }
        if (EXTENSIONS$3 in parameters) {
            this.extensions = getParametersValue(parameters, EXTENSIONS$3, AttributeCertificateInfoV2.defaultValues(EXTENSIONS$3));
        }
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case VERSION$g:
                return 1;
            case HOLDER:
                return new Holder();
            case ISSUER$3:
                return {};
            case SIGNATURE$5:
                return new AlgorithmIdentifier();
            case SERIAL_NUMBER$4:
                return new Integer();
            case ATTR_CERT_VALIDITY_PERIOD:
                return new AttCertValidityPeriod();
            case ATTRIBUTES$2:
                return [];
            case ISSUER_UNIQUE_ID$1:
                return new BitString();
            case EXTENSIONS$3:
                return new Extensions();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                new Integer({ name: (names.version || EMPTY_STRING) }),
                Holder.schema(names.holder || {}),
                new Choice({
                    value: [
                        GeneralNames.schema({
                            names: {
                                blockName: (names.issuer || EMPTY_STRING)
                            }
                        }),
                        new Constructed({
                            name: (names.issuer || EMPTY_STRING),
                            idBlock: {
                                tagClass: 3,
                                tagNumber: 0
                            },
                            value: V2Form.schema().valueBlock.value
                        })
                    ]
                }),
                AlgorithmIdentifier.schema(names.signature || {}),
                new Integer({ name: (names.serialNumber || EMPTY_STRING) }),
                AttCertValidityPeriod.schema(names.attrCertValidityPeriod || {}),
                new Sequence({
                    name: (names.attributes || EMPTY_STRING),
                    value: [
                        new Repeated({
                            value: Attribute.schema()
                        })
                    ]
                }),
                new BitString({
                    optional: true,
                    name: (names.issuerUniqueID || EMPTY_STRING)
                }),
                Extensions.schema(names.extensions || {}, true)
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$U);
        const asn1 = compareSchema(schema, schema, AttributeCertificateInfoV2.schema({
            names: {
                version: VERSION$g,
                holder: {
                    names: {
                        blockName: HOLDER
                    }
                },
                issuer: ISSUER$3,
                signature: {
                    names: {
                        blockName: SIGNATURE$5
                    }
                },
                serialNumber: SERIAL_NUMBER$4,
                attrCertValidityPeriod: {
                    names: {
                        blockName: ATTR_CERT_VALIDITY_PERIOD
                    }
                },
                attributes: ATTRIBUTES$2,
                issuerUniqueID: ISSUER_UNIQUE_ID$1,
                extensions: {
                    names: {
                        blockName: EXTENSIONS$3
                    }
                }
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.version = asn1.result.version.valueBlock.valueDec;
        this.holder = new Holder({ schema: asn1.result.holder });
        switch (asn1.result.issuer.idBlock.tagClass) {
            case 3:
                this.issuer = new V2Form({
                    schema: new Sequence({
                        value: asn1.result.issuer.valueBlock.value
                    })
                });
                break;
            case 1:
            default:
                throw new Error("Incorrect value for 'issuer' in AttributeCertificateInfoV2");
        }
        this.signature = new AlgorithmIdentifier({ schema: asn1.result.signature });
        this.serialNumber = asn1.result.serialNumber;
        this.attrCertValidityPeriod = new AttCertValidityPeriod({ schema: asn1.result.attrCertValidityPeriod });
        this.attributes = Array.from(asn1.result.attributes.valueBlock.value, element => new Attribute({ schema: element }));
        if (ISSUER_UNIQUE_ID$1 in asn1.result) {
            this.issuerUniqueID = asn1.result.issuerUniqueID;
        }
        if (EXTENSIONS$3 in asn1.result) {
            this.extensions = new Extensions({ schema: asn1.result.extensions });
        }
    }
    toSchema() {
        const result = new Sequence({
            value: [
                new Integer({ value: this.version }),
                this.holder.toSchema(),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: this.issuer.toSchema().valueBlock.value
                }),
                this.signature.toSchema(),
                this.serialNumber,
                this.attrCertValidityPeriod.toSchema(),
                new Sequence({
                    value: Array.from(this.attributes, o => o.toSchema())
                })
            ]
        });
        if (this.issuerUniqueID) {
            result.valueBlock.value.push(this.issuerUniqueID);
        }
        if (this.extensions) {
            result.valueBlock.value.push(this.extensions.toSchema());
        }
        return result;
    }
    toJSON() {
        const result = {
            version: this.version,
            holder: this.holder.toJSON(),
            issuer: this.issuer.toJSON(),
            signature: this.signature.toJSON(),
            serialNumber: this.serialNumber.toJSON(),
            attrCertValidityPeriod: this.attrCertValidityPeriod.toJSON(),
            attributes: Array.from(this.attributes, o => o.toJSON())
        };
        if (this.issuerUniqueID) {
            result.issuerUniqueID = this.issuerUniqueID.toJSON();
        }
        if (this.extensions) {
            result.extensions = this.extensions.toJSON();
        }
        return result;
    }
}
AttributeCertificateInfoV2.CLASS_NAME = "AttributeCertificateInfoV2";

const ACINFO = "acinfo";
const SIGNATURE_ALGORITHM$6 = "signatureAlgorithm";
const SIGNATURE_VALUE$3 = "signatureValue";
const CLEAR_PROPS$T = [
    ACINFO,
    SIGNATURE_ALGORITHM$6,
    SIGNATURE_VALUE$3,
];
class AttributeCertificateV2 extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.acinfo = getParametersValue(parameters, ACINFO, AttributeCertificateV2.defaultValues(ACINFO));
        this.signatureAlgorithm = getParametersValue(parameters, SIGNATURE_ALGORITHM$6, AttributeCertificateV2.defaultValues(SIGNATURE_ALGORITHM$6));
        this.signatureValue = getParametersValue(parameters, SIGNATURE_VALUE$3, AttributeCertificateV2.defaultValues(SIGNATURE_VALUE$3));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case ACINFO:
                return new AttributeCertificateInfoV2();
            case SIGNATURE_ALGORITHM$6:
                return new AlgorithmIdentifier();
            case SIGNATURE_VALUE$3:
                return new BitString();
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        return (new Sequence({
            name: (names.blockName || EMPTY_STRING),
            value: [
                AttributeCertificateInfoV2.schema(names.acinfo || {}),
                AlgorithmIdentifier.schema(names.signatureAlgorithm || {}),
                new BitString({ name: (names.signatureValue || EMPTY_STRING) })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$T);
        const asn1 = compareSchema(schema, schema, AttributeCertificateV2.schema({
            names: {
                acinfo: {
                    names: {
                        blockName: ACINFO
                    }
                },
                signatureAlgorithm: {
                    names: {
                        blockName: SIGNATURE_ALGORITHM$6
                    }
                },
                signatureValue: SIGNATURE_VALUE$3
            }
        }));
        AsnError.assertSchema(asn1, this.className);
        this.acinfo = new AttributeCertificateInfoV2({ schema: asn1.result.acinfo });
        this.signatureAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.signatureAlgorithm });
        this.signatureValue = asn1.result.signatureValue;
    }
    toSchema() {
        return (new Sequence({
            value: [
                this.acinfo.toSchema(),
                this.signatureAlgorithm.toSchema(),
                this.signatureValue
            ]
        }));
    }
    toJSON() {
        return {
            acinfo: this.acinfo.toJSON(),
            signatureAlgorithm: this.signatureAlgorithm.toJSON(),
            signatureValue: this.signatureValue.toJSON(),
        };
    }
}
AttributeCertificateV2.CLASS_NAME = "AttributeCertificateV2";

const CONTENT_TYPE = "contentType";
const CONTENT = "content";
const CLEAR_PROPS$S = [CONTENT_TYPE, CONTENT];
class ContentInfo extends PkiObject {
    constructor(parameters = {}) {
        super();
        this.contentType = getParametersValue(parameters, CONTENT_TYPE, ContentInfo.defaultValues(CONTENT_TYPE));
        this.content = getParametersValue(parameters, CONTENT, ContentInfo.defaultValues(CONTENT));
        if (parameters.schema) {
            this.fromSchema(parameters.schema);
        }
    }
    static defaultValues(memberName) {
        switch (memberName) {
            case CONTENT_TYPE:
                return EMPTY_STRING;
            case CONTENT:
                return new Any();
            default:
                return super.defaultValues(memberName);
        }
    }
    static compareWithDefault(memberName, memberValue) {
        switch (memberName) {
            case CONTENT_TYPE:
                return (typeof memberValue === "string" &&
                    memberValue === this.defaultValues(CONTENT_TYPE));
            case CONTENT:
                return (memberValue instanceof Any);
            default:
                return super.defaultValues(memberName);
        }
    }
    static schema(parameters = {}) {
        const names = getParametersValue(parameters, "names", {});
        if (("optional" in names) === false) {
            names.optional = false;
        }
        return (new Sequence({
            name: (names.blockName || "ContentInfo"),
            optional: names.optional,
            value: [
                new ObjectIdentifier({ name: (names.contentType || CONTENT_TYPE) }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [new Any({ name: (names.content || CONTENT) })]
                })
            ]
        }));
    }
    fromSchema(schema) {
        clearProps(schema, CLEAR_PROPS$S);
        const asn1 = compareSchema(schema, schema, ContentInfo.schema());
        AsnError.assertSchema(asn1, this.className);
        this.contentType = asn1.result.contentType.valueBlock.toString();
        this.content = asn1.result.content;
    }
    toSchema() {
        return (new Sequence({
            value: [
                new ObjectIdentifier({ value: this.contentType }),
                new Constructed({
                    idBlock: {
                        tagClass: 3,
                        tagNumber: 0
                    },
                    value: [this.content]
                })
            ]
        }));
    }
    toJSON() {
        const object = {
            contentType: this.contentType
        };
        if (!(this.content instanceof Any)) {
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5 in Prozent
C=94 H=92 G=92

¤ Dauer der Verarbeitung: 1.111 Sekunden  (vorverarbeitet am  2026-10-11) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.