// ignore-tidy-file-filelength
/**
 * @import * as stringdex from "./stringdex.d.ts"
 */

const EMPTY_UINT8 = new Uint8Array();

/**
 * @property {Uint8Array} keysAndCardinalities
 * @property {Uint8Array[]} containers
 */
class RoaringBitmap {
    /**
     * @param {Uint8Array|null} u8array
     * @param {number} [startingOffset]
    */
    constructor(u8array, startingOffset) {
        const start = startingOffset ? startingOffset : 0;
        let i = start;
        /** @type {Uint8Array} */
        this.keysAndCardinalities = EMPTY_UINT8;
        /** @type {(RoaringBitmapArray|RoaringBitmapBits|RoaringBitmapRun)[]} */
        this.containers = [];
        /** @type {number} */
        this.consumed_len_bytes = 0;
        if (u8array === null || u8array.length === i || u8array[i] === 0) {
            return this;
        } else if (u8array[i] > 0xf0) {
            // Special representation of tiny sets that are close together
            const lspecial = u8array[i] & 0x0f;
            this.keysAndCardinalities = new Uint8Array(lspecial * 4);
            let pspecial = i + 1;
            let key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8);
            let value = u8array[pspecial] | (u8array[pspecial + 1] << 8);
            let entry = (key << 16) | value;
            let container;
            container = new RoaringBitmapArray(1, new Uint8Array(4));
            container.array[0] = value & 0xFF;
            container.array[1] = (value >> 8) & 0xFF;
            this.containers.push(container);
            this.keysAndCardinalities[0] = key;
            this.keysAndCardinalities[1] = key >> 8;
            pspecial += 4;
            for (let ispecial = 1; ispecial < lspecial; ispecial += 1) {
                entry += u8array[pspecial] | (u8array[pspecial + 1] << 8);
                value = entry & 0xffff;
                key = entry >> 16;
                container = this.addToArrayAt(key);
                const cardinalityOld = container.cardinality;
                container.array[cardinalityOld * 2] = value & 0xFF;
                container.array[(cardinalityOld * 2) + 1] = (value >> 8) & 0xFF;
                container.cardinality = cardinalityOld + 1;
                pspecial += 2;
            }
            this.consumed_len_bytes = pspecial - i;
            return this;
        } else if (u8array[i] > 0xe0) {
            // Special representation of a node with multiple runs
            const run_count_m1 = (u8array[i] & 0x0f);
            const run_count = run_count_m1 + 1;
            this.keysAndCardinalities = new Uint8Array(run_count * 4);
            // the run keys and values
            let pspecial = i + 1;
            // the run lengths
            let pnspecial = pspecial + (run_count * 4);
            /** @type {number|null} */
            let previous_key = null;
            /** @type {RoaringBitmapRun|null} */
            let previous_container = null;
            for (let j = 0; j < run_count; j += 1) {
                const key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8);
                const value = u8array[pspecial] | (u8array[pspecial + 1] << 8);
                const run_length_m1 = j % 2 === 0 ?
                    (u8array[pnspecial] >> 4) :
                    (u8array[pnspecial] & 0x0f);
                if (j % 2 !== 0) {
                    pnspecial += 1;
                }
                pspecial += 4;
                if (key === previous_key && previous_container !== null) {
                    const new_container_array = new Uint8Array(
                        (previous_container.runcount + 1) * 4,
                    );
                    new_container_array.set(previous_container.array);
                    new_container_array[previous_container.runcount * 4] = value & 0xFF;
                    new_container_array[(previous_container.runcount * 4) + 1] =
                        (value >> 8) & 0xFF;
                    new_container_array[(previous_container.runcount * 4) + 2] =
                        run_length_m1;
                    previous_container.array = new_container_array;
                    previous_container.runcount += 1;
                    let cardinalitym1 =
                        this.keysAndCardinalities[(this.containers.length * 4) - 2] |
                        (this.keysAndCardinalities[(this.containers.length * 4) - 1] << 8);
                    cardinalitym1 += run_length_m1 + 1;
                    this.keysAndCardinalities[(this.containers.length * 4) - 2] =
                        cardinalitym1 & 0xFF;
                    this.keysAndCardinalities[(this.containers.length * 4) - 1] =
                        (cardinalitym1 >> 8) & 0xFF;
                } else {
                    previous_key = key;
                    previous_container = new RoaringBitmapRun(1, Uint8Array.of(
                        value & 0xFF,
                        (value >> 8) & 0xFF,
                        run_length_m1,
                        0,
                    ));
                    this.containers.push(previous_container);
                    this.keysAndCardinalities[(this.containers.length * 4) - 4] = key & 0xFF;
                    this.keysAndCardinalities[(this.containers.length * 4) - 3] = (key >> 8) & 0xFF;
                    this.keysAndCardinalities[(this.containers.length * 4) - 2] = run_length_m1;
                }
            }
            if (run_count % 2 !== 0) {
                pnspecial += 1;
            }
            this.consumed_len_bytes = pnspecial - i;
            return this;
        } else if (u8array[i] > 0xd0) {
            // Special representation of tiny sets that are close together
            const lspecial = u8array[i] & 0x0f;
            this.keysAndCardinalities = new Uint8Array(lspecial * 4);
            let pspecial = i + 1;
            let key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8);
            let value = u8array[pspecial] | (u8array[pspecial + 1] << 8);
            let entry = (key << 16) | value;
            let container;
            container = new RoaringBitmapArray(1, new Uint8Array(4));
            container.array[0] = value & 0xFF;
            container.array[1] = (value >> 8) & 0xFF;
            this.containers.push(container);
            this.keysAndCardinalities[0] = key;
            this.keysAndCardinalities[1] = key >> 8;
            pspecial += 4;
            for (let ispecial = 1; ispecial < lspecial; ispecial += 1) {
                entry += u8array[pspecial];
                value = entry & 0xffff;
                key = entry >> 16;
                container = this.addToArrayAt(key);
                const cardinalityOld = container.cardinality;
                container.array[cardinalityOld * 2] = value & 0xFF;
                container.array[(cardinalityOld * 2) + 1] = (value >> 8) & 0xFF;
                container.cardinality = cardinalityOld + 1;
                pspecial += 1;
            }
            this.consumed_len_bytes = pspecial - i;
            return this;
        } else if (u8array[i] > 0x80) {
            // Special representation of tiny sets that are runs
            const lspecial = u8array[i] & 0x3f;
            const lspecialm1 = lspecial - 1;
            this.keysAndCardinalities = new Uint8Array(4);
            i += 1;
            const key = u8array[i + 2] | (u8array[i + 3] << 8);
            const value = u8array[i] | (u8array[i + 1] << 8);
            const container = new RoaringBitmapRun(1, new Uint8Array(4));
            container.array[0] = value & 0xFF;
            container.array[1] = (value >> 8) & 0xFF;
            container.array[2] = lspecialm1 & 0xFF;
            container.array[3] = lspecialm1 >> 8;
            this.containers.push(container);
            this.keysAndCardinalities[0] = key & 0xFF;
            this.keysAndCardinalities[1] = (key >> 8) & 0xFF;
            this.keysAndCardinalities[2] = lspecialm1 & 0xFF;
            this.keysAndCardinalities[3] = lspecialm1 >> 8;
            this.consumed_len_bytes = 5;
            return this;
        } else if (u8array[i] < 0x3a) {
            // Special representation of tiny sets with arbitrary 32-bit integers
            const lspecial = u8array[i];
            this.keysAndCardinalities = new Uint8Array(lspecial * 4);
            let pspecial = i + 1;
            for (let ispecial = 0; ispecial < lspecial; ispecial += 1) {
                const key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8);
                const value = u8array[pspecial] | (u8array[pspecial + 1] << 8);
                const container = this.addToArrayAt(key);
                const cardinalityOld = container.cardinality;
                container.array[cardinalityOld * 2] = value & 0xFF;
                container.array[(cardinalityOld * 2) + 1] = (value >> 8) & 0xFF;
                container.cardinality = cardinalityOld + 1;
                pspecial += 4;
            }
            this.consumed_len_bytes = pspecial - i;
            return this;
        }
        // https://github.com/RoaringBitmap/RoaringFormatSpec
        //
        // Roaring bitmaps are used for flags that can be kept in their
        // compressed form, even when loaded into memory. This decoder
        // turns the containers into objects, but uses byte array
        // slices of the original format for the data payload.
        const has_runs = u8array[i] === 0x3b;
        if (u8array[i] !== 0x3a && u8array[i] !== 0x3b) {
            throw new Error("not a roaring bitmap: " + u8array[i]);
        }
        const size = has_runs ?
            ((u8array[i + 2] | (u8array[i + 3] << 8)) + 1) :
            ((u8array[i + 4] | (u8array[i + 5] << 8) |
             (u8array[i + 6] << 16) | (u8array[i + 7] << 24)));
        i += has_runs ? 4 : 8;
        let is_run;
        if (has_runs) {
            const is_run_len = (size + 7) >> 3;
            is_run = new Uint8Array(u8array.buffer, i + u8array.byteOffset, is_run_len);
            i += is_run_len;
        } else {
            is_run = EMPTY_UINT8;
        }
        this.keysAndCardinalities = u8array.subarray(i, i + (size * 4));
        i += size * 4;
        let offsets = null;
        if (!has_runs || size >= 4) {
            offsets = [];
            for (let j = 0; j < size; ++j) {
                offsets.push(u8array[i] | (u8array[i + 1] << 8) | (u8array[i + 2] << 16) |
                    (u8array[i + 3] << 24));
                i += 4;
            }
        }
        for (let j = 0; j < size; ++j) {
            if (offsets && offsets[j] !== i - start) {
                throw new Error(`corrupt bitmap ${j}: ${i - start} / ${offsets[j]}`);
            }
            const cardinality = (this.keysAndCardinalities[(j * 4) + 2] |
                (this.keysAndCardinalities[(j * 4) + 3] << 8)) + 1;
            if (is_run[j >> 3] & (1 << (j & 0x7))) {
                const runcount = (u8array[i] | (u8array[i + 1] << 8));
                i += 2;
                this.containers.push(new RoaringBitmapRun(
                    runcount,
                    new Uint8Array(u8array.buffer, i + u8array.byteOffset, runcount * 4),
                ));
                i += runcount * 4;
            } else if (cardinality >= 4096) {
                this.containers.push(new RoaringBitmapBits(new Uint8Array(
                    u8array.buffer,
                    i + u8array.byteOffset, 8192,
                )));
                i += 8192;
            } else {
                const end = cardinality * 2;
                this.containers.push(new RoaringBitmapArray(
                    cardinality,
                    new Uint8Array(u8array.buffer, i + u8array.byteOffset, end),
                ));
                i += end;
            }
        }
        this.consumed_len_bytes = i - start;
    }
    /**
     * @param {number} number
     * @returns {RoaringBitmap}
     */
    static makeSingleton(number) {
        const result = new RoaringBitmap(null, 0);
        result.keysAndCardinalities = Uint8Array.of(
            (number >> 16), (number >> 24),
            0, 0, // keysAndCardinalities stores the true cardinality minus 1
        );
        result.containers.push(new RoaringBitmapArray(
            1,
            Uint8Array.of(number, number >> 8),
        ));
        return result;
    }
    /** @returns {RoaringBitmap} */
    static everything() {
        if (EVERYTHING_BITMAP.isEmpty()) {
            let i = 0;
            const l = 1 << 16;
            const everything_range = new RoaringBitmapRun(1, Uint8Array.of(0, 0, 0xff, 0xff));
            EVERYTHING_BITMAP.keysAndCardinalities = new Uint8Array(l * 4);
            while (i < l) {
                EVERYTHING_BITMAP.containers.push(everything_range);
                // key
                EVERYTHING_BITMAP.keysAndCardinalities[(i * 4) + 0] = i;
                EVERYTHING_BITMAP.keysAndCardinalities[(i * 4) + 1] = i >> 8;
                // cardinality (minus one)
                EVERYTHING_BITMAP.keysAndCardinalities[(i * 4) + 2] = 0xff;
                EVERYTHING_BITMAP.keysAndCardinalities[(i * 4) + 3] = 0xff;
                i += 1;
            }
        }
        return EVERYTHING_BITMAP;
    }
    /** @returns {RoaringBitmap} */
    static empty() {
        return EMPTY_BITMAP;
    }
    /** @returns {boolean} */
    isEmpty() {
        return this.containers.length === 0;
    }
    /**
     * Helper function used when constructing bitmaps from lists.
     * Returns an array container with at least two free byte slots
     * and bumps `this.cardinalities`.
     * @param {number} key
     * @returns {RoaringBitmapArray}
     */
    addToArrayAt(key) {
        let mid = this.getContainerId(key);
        /** @type {RoaringBitmapArray|RoaringBitmapBits|RoaringBitmapRun} */
        let container;
        if (mid === -1) {
            container = new RoaringBitmapArray(0, new Uint8Array(2));
            mid = this.containers.length;
            this.containers.push(container);
            if (mid * 4 > this.keysAndCardinalities.length) {
                const keysAndContainers = new Uint8Array(mid * 8);
                keysAndContainers.set(this.keysAndCardinalities);
                this.keysAndCardinalities = keysAndContainers;
            }
            this.keysAndCardinalities[(mid * 4) + 0] = key;
            this.keysAndCardinalities[(mid * 4) + 1] = key >> 8;
        } else {
            container = this.containers[mid];
            const cardinalityOld =
                this.keysAndCardinalities[(mid * 4) + 2] |
                (this.keysAndCardinalities[(mid * 4) + 3] << 8);
            const cardinality = cardinalityOld + 1;
            this.keysAndCardinalities[(mid * 4) + 2] = cardinality;
            this.keysAndCardinalities[(mid * 4) + 3] = cardinality >> 8;
        }
        // the logic for handing this number is annoying, because keysAndCardinalities stores
        // the cardinality *minus one*, so that it can count up to 65536 with only two bytes
        // (because empty containers are never stored).
        //
        // So, if this is a new container, the stored cardinality contains `0 0`, which is
        // the proper value of the old cardinality (an imaginary empty container existed).
        // If this is adding to an existing container, then the above `else` branch bumps it
        // by one, leaving us with a proper value of `cardinality - 1`.
        const cardinalityOld =
            this.keysAndCardinalities[(mid * 4) + 2] |
            (this.keysAndCardinalities[(mid * 4) + 3] << 8);
        if (!(container instanceof RoaringBitmapArray) ||
            container.array.byteLength < ((cardinalityOld + 1) * 2)
        ) {
            const newBuf = new Uint8Array((cardinalityOld + 1) * 4);
            let idx = 0;
            for (const cvalue of container.values()) {
                newBuf[idx] = cvalue & 0xFF;
                newBuf[idx + 1] = (cvalue >> 8) & 0xFF;
                idx += 2;
            }
            if (container instanceof RoaringBitmapArray) {
                container.cardinality = cardinalityOld;
                container.array = newBuf;
                return container;
            }
            const newcontainer = new RoaringBitmapArray(cardinalityOld, newBuf);
            this.containers[mid] = newcontainer;
            return newcontainer;
        } else {
            return container;
        }
    }
    /**
     * @param {RoaringBitmap} that
     * @returns {RoaringBitmap}
     */
    union(that) {
        if (this.isEmpty()) {
            return that;
        }
        if (that.isEmpty()) {
            return this;
        }
        if (this === RoaringBitmap.everything() || that === RoaringBitmap.everything()) {
            return RoaringBitmap.everything();
        }
        let i = 0;
        const il = this.containers.length;
        let j = 0;
        const jl = that.containers.length;
        const result = new RoaringBitmap(null, 0);
        result.keysAndCardinalities = new Uint8Array((il + jl) * 4);
        while (i < il || j < jl) {
            const ik = i * 4;
            const jk = j * 4;
            const k = result.containers.length * 4;
            if (j >= jl || (i < il && (
                (this.keysAndCardinalities[ik + 1] < that.keysAndCardinalities[jk + 1]) ||
                (this.keysAndCardinalities[ik + 1] === that.keysAndCardinalities[jk + 1] &&
                    this.keysAndCardinalities[ik] < that.keysAndCardinalities[jk])
            ))) {
                result.keysAndCardinalities[k + 0] = this.keysAndCardinalities[ik + 0];
                result.keysAndCardinalities[k + 1] = this.keysAndCardinalities[ik + 1];
                result.keysAndCardinalities[k + 2] = this.keysAndCardinalities[ik + 2];
                result.keysAndCardinalities[k + 3] = this.keysAndCardinalities[ik + 3];
                result.containers.push(this.containers[i]);
                i += 1;
            } else if (i >= il || (j < jl && (
                (that.keysAndCardinalities[jk + 1] < this.keysAndCardinalities[ik + 1]) ||
                (that.keysAndCardinalities[jk + 1] === this.keysAndCardinalities[ik + 1] &&
                    that.keysAndCardinalities[jk] < this.keysAndCardinalities[ik])
            ))) {
                result.keysAndCardinalities[k + 0] = that.keysAndCardinalities[jk + 0];
                result.keysAndCardinalities[k + 1] = that.keysAndCardinalities[jk + 1];
                result.keysAndCardinalities[k + 2] = that.keysAndCardinalities[jk + 2];
                result.keysAndCardinalities[k + 3] = that.keysAndCardinalities[jk + 3];
                result.containers.push(that.containers[j]);
                j += 1;
            } else {
                // this key is not smaller than that key
                // that key is not smaller than this key
                // they must be equal
                const thisContainer = this.containers[i];
                const thatContainer = that.containers[j];
                let card = 0;
                if (thisContainer instanceof RoaringBitmapBits &&
                    thatContainer instanceof RoaringBitmapBits
                ) {
                    const resultArray = new Uint8Array(
                        thisContainer.array.length > thatContainer.array.length ?
                            thisContainer.array.length :
                            thatContainer.array.length,
                    );
                    let k = 0;
                    const kl = resultArray.length;
                    while (k < kl) {
                        const c = thisContainer.array[k] | thatContainer.array[k];
                        resultArray[k] = c;
                        card += bitCount(c);
                        k += 1;
                    }
                    result.containers.push(new RoaringBitmapBits(resultArray));
                } else {
                    const thisValues = thisContainer.values();
                    const thatValues = thatContainer.values();
                    let thisResult = thisValues.next();
                    let thatResult = thatValues.next();
                    /** @type {Array<number>} */
                    const resultValues = [];
                    while (!thatResult.done || !thisResult.done) {
                        // generator will definitely implement the iterator protocol correctly
                        /** @type {number} */
                        const thisValue = thisResult.value;
                        /** @type {number} */
                        const thatValue = thatResult.value;
                        if (thatResult.done || thisValue < thatValue) {
                            resultValues.push(thisValue);
                            thisResult = thisValues.next();
                        } else if (thisResult.done || thatValue < thisValue) {
                            resultValues.push(thatValue);
                            thatResult = thatValues.next();
                        } else {
                            // this value is not smaller than that value
                            // that value is not smaller than this value
                            // they must be equal
                            resultValues.push(thisValue);
                            thisResult = thisValues.next();
                            thatResult = thatValues.next();
                        }
                    }
                    const resultArray = new Uint8Array(resultValues.length * 2);
                    let k = 0;
                    for (const value of resultValues) {
                        // roaring bitmap is little endian
                        resultArray[k] = value & 0xFF;
                        resultArray[k + 1] = (value >> 8) & 0xFF;
                        k += 2;
                    }
                    result.containers.push(new RoaringBitmapArray(
                        resultValues.length,
                        resultArray,
                    ));
                    card = resultValues.length;
                }
                result.keysAndCardinalities[k + 0] = this.keysAndCardinalities[ik + 0];
                result.keysAndCardinalities[k + 1] = this.keysAndCardinalities[ik + 1];
                card -= 1;
                result.keysAndCardinalities[k + 2] = card;
                result.keysAndCardinalities[k + 3] = card >> 8;
                i += 1;
                j += 1;
            }
        }
        return result;
    }
    /**
     * @param {RoaringBitmap} that
     * @returns {RoaringBitmap}
     */
    intersection(that) {
        if (this.isEmpty() || that.isEmpty()) {
            return EMPTY_BITMAP;
        }
        if (this === RoaringBitmap.everything()) {
            return that;
        }
        if (that === RoaringBitmap.everything()) {
            return this;
        }
        let i = 0;
        const il = this.containers.length;
        let j = 0;
        const jl = that.containers.length;
        const result = new RoaringBitmap(null, 0);
        result.keysAndCardinalities = new Uint8Array((il > jl ? il : jl) * 4);
        while (i < il && j < jl) {
            const ik = i * 4;
            const jk = j * 4;
            const k = result.containers.length * 4;
            if (j >= jl || (i < il && (
                (this.keysAndCardinalities[ik + 1] < that.keysAndCardinalities[jk + 1]) ||
                (this.keysAndCardinalities[ik + 1] === that.keysAndCardinalities[jk + 1] &&
                    this.keysAndCardinalities[ik] < that.keysAndCardinalities[jk])
            ))) {
                i += 1;
            } else if (i >= il || (j < jl && (
                (that.keysAndCardinalities[jk + 1] < this.keysAndCardinalities[ik + 1]) ||
                (that.keysAndCardinalities[jk + 1] === this.keysAndCardinalities[ik + 1] &&
                    that.keysAndCardinalities[jk] < this.keysAndCardinalities[ik])
            ))) {
                j += 1;
            } else {
                // this key is not smaller than that key
                // that key is not smaller than this key
                // they must be equal
                const thisContainer = this.containers[i];
                const thatContainer = that.containers[j];
                let card = 0;
                if (thisContainer instanceof RoaringBitmapBits &&
                    thatContainer instanceof RoaringBitmapBits
                ) {
                    const resultArray = new Uint8Array(
                        thisContainer.array.length > thatContainer.array.length ?
                            thisContainer.array.length :
                            thatContainer.array.length,
                    );
                    let k = 0;
                    const kl = resultArray.length;
                    while (k < kl) {
                        const c = thisContainer.array[k] & thatContainer.array[k];
                        resultArray[k] = c;
                        card += bitCount(c);
                        k += 1;
                    }
                    if (card !== 0) {
                        result.containers.push(new RoaringBitmapBits(resultArray));
                    }
                } else {
                    const thisValues = thisContainer.values();
                    const thatValues = thatContainer.values();
                    let thisValue = thisValues.next();
                    let thatValue = thatValues.next();
                    const resultValues = [];
                    while (!thatValue.done && !thisValue.done) {
                        if (thisValue.value < thatValue.value) {
                            thisValue = thisValues.next();
                        } else if (thatValue.value < thisValue.value) {
                            thatValue = thatValues.next();
                        } else {
                            // this value is not smaller than that value
                            // that value is not smaller than this value
                            // they must be equal
                            resultValues.push(thisValue.value);
                            thisValue = thisValues.next();
                            thatValue = thatValues.next();
                        }
                    }
                    card = resultValues.length;
                    if (card !== 0) {
                        const resultArray = new Uint8Array(resultValues.length * 2);
                        let k = 0;
                        for (const value of resultValues) {
                            // roaring bitmap is little endian
                            resultArray[k] = value & 0xFF;
                            resultArray[k + 1] = (value >> 8) & 0xFF;
                            k += 2;
                        }
                        result.containers.push(new RoaringBitmapArray(
                            resultValues.length,
                            resultArray,
                        ));
                    }
                }
                if (card !== 0) {
                    result.keysAndCardinalities[k + 0] = this.keysAndCardinalities[ik + 0];
                    result.keysAndCardinalities[k + 1] = this.keysAndCardinalities[ik + 1];
                    card -= 1;
                    result.keysAndCardinalities[k + 2] = card;
                    result.keysAndCardinalities[k + 3] = card >> 8;
                }
                i += 1;
                j += 1;
            }
        }
        return result;
    }
    /** @param {number} keyvalue */
    contains(keyvalue) {
        const key = keyvalue >> 16;
        const value = keyvalue & 0xFFFF;
        const mid = this.getContainerId(key);
        return mid === -1 ? false : this.containers[mid].contains(value);
    }
    /**
     * @param {number} keyvalue
     * @returns {RoaringBitmap}
     */
    remove(keyvalue) {
        const key = keyvalue >> 16;
        const value = keyvalue & 0xFFFF;
        const mid = this.getContainerId(key);
        if (mid === -1) {
            return this;
        }
        const container = this.containers[mid];
        if (!container.contains(value)) {
            return this;
        }
        const newCardinality = (this.keysAndCardinalities[(mid * 4) + 2] |
            (this.keysAndCardinalities[(mid * 4) + 3] << 8));
        const l = this.containers.length;
        const m = l - (newCardinality === 0 ? 1 : 0);
        const result = new RoaringBitmap(null, 0);
        result.keysAndCardinalities = new Uint8Array(m * 4);
        let j = 0;
        for (let i = 0; i < l; i += 1) {
            if (i === mid) {
                if (newCardinality !== 0) {
                    result.keysAndCardinalities[(j * 4) + 0] = key;
                    result.keysAndCardinalities[(j * 4) + 1] = key >> 8;
                    const card = newCardinality - 1;
                    result.keysAndCardinalities[(j * 4) + 2] = card;
                    result.keysAndCardinalities[(j * 4) + 3] = card >> 8;
                    const newContainer = new RoaringBitmapArray(
                        newCardinality,
                        new Uint8Array(newCardinality * 2),
                    );
                    let newContainerSlot = 0;
                    for (const containerValue of container.values()) {
                        if (containerValue !== value) {
                            newContainer.array[newContainerSlot] = value & 0xFF;
                            newContainerSlot += 1;
                            newContainer.array[newContainerSlot] = value >> 8;
                            newContainerSlot += 1;
                        }
                    }
                    result.containers.push(newContainer);
                    j += 1;
                }
            } else {
                result.keysAndCardinalities[(j * 4) + 0] = this.keysAndCardinalities[(i * 4) + 0];
                result.keysAndCardinalities[(j * 4) + 1] = this.keysAndCardinalities[(i * 4) + 1];
                result.keysAndCardinalities[(j * 4) + 2] = this.keysAndCardinalities[(i * 4) + 2];
                result.keysAndCardinalities[(j * 4) + 3] = this.keysAndCardinalities[(i * 4) + 3];
                result.containers.push(this.containers[i]);
                j += 1;
            }
        }
        return result;
    }
    /**
     * @param {number} key
     * @returns {number}
     */
    getContainerId(key) {
        // Binary search algorithm copied from
        // https://en.wikipedia.org/wiki/Binary_search#Procedure
        //
        // Format is required by specification to be sorted.
        // Because keys are 16 bits and unique, length can't be
        // bigger than 2**16, and because we have 32 bits of safe int,
        // left + right can't overflow.
        let left = 0;
        let right = this.containers.length - 1;
        while (left <= right) {
            const mid = Math.floor((left + right) / 2);
            const x = this.keysAndCardinalities[(mid * 4)] |
                (this.keysAndCardinalities[(mid * 4) + 1] << 8);
            if (x < key) {
                left = mid + 1;
            } else if (x > key) {
                right = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
    * entries() {
        const l = this.containers.length;
        for (let i = 0; i < l; ++i) {
            const key = this.keysAndCardinalities[i * 4] |
                (this.keysAndCardinalities[(i * 4) + 1] << 8);
            for (const value of this.containers[i].values()) {
                yield (key << 16) | value;
            }
        }
    }
    /**
     * @returns {number|null}
     */
    first() {
        for (const entry of this.entries()) {
            return entry;
        }
        return null;
    }
    /**
     * @returns {number}
     */
    cardinality() {
        let result = 0;
        const l = this.containers.length;
        for (let i = 0; i < l; ++i) {
            const card = this.keysAndCardinalities[(i * 4) + 2] |
                (this.keysAndCardinalities[(i * 4) + 3] << 8);
            result += card + 1;
        }
        return result;
    }
}

class RoaringBitmapRun {
    /**
     * @param {number} runcount
     * @param {Uint8Array} array
     */
    constructor(runcount, array) {
        this.runcount = runcount;
        this.array = array;
    }
    /** @param {number} value */
    contains(value) {
        // Binary search algorithm copied from
        // https://en.wikipedia.org/wiki/Binary_search#Procedure
        //
        // Since runcount is stored as 16 bits, left + right
        // can't overflow.
        let left = 0;
        let right = this.runcount - 1;
        while (left <= right) {
            const mid = (left + right) >> 1;
            const i = mid * 4;
            const start = this.array[i] | (this.array[i + 1] << 8);
            const lenm1 = this.array[i + 2] | (this.array[i + 3] << 8);
            if ((start + lenm1) < value) {
                left = mid + 1;
            } else if (start > value) {
                right = mid - 1;
            } else {
                return true;
            }
        }
        return false;
    }
    * values() {
        let i = 0;
        while (i < this.runcount) {
            const start = this.array[i * 4] | (this.array[(i * 4) + 1] << 8);
            const lenm1 = this.array[(i * 4) + 2] | (this.array[(i * 4) + 3] << 8);
            let value = start;
            let j = 0;
            while (j <= lenm1) {
                yield value;
                value += 1;
                j += 1;
            }
            i += 1;
        }
    }
}
class RoaringBitmapArray {
    /**
     * @param {number} cardinality
     * @param {Uint8Array} array
     */
    constructor(cardinality, array) {
        this.cardinality = cardinality;
        this.array = array;
    }
    /** @param {number} value */
    contains(value) {
        // Binary search algorithm copied from
        // https://en.wikipedia.org/wiki/Binary_search#Procedure
        //
        // Since cardinality can't be higher than 4096, left + right
        // cannot overflow.
        let left = 0;
        let right = this.cardinality - 1;
        while (left <= right) {
            const mid = (left + right) >> 1;
            const i = mid * 2;
            const x = this.array[i] | (this.array[i + 1] << 8);
            if (x < value) {
                left = mid + 1;
            } else if (x > value) {
                right = mid - 1;
            } else {
                return true;
            }
        }
        return false;
    }
    /** @returns {Generator<number>} */
    * values() {
        let i = 0;
        const l = this.cardinality * 2;
        while (i < l) {
            yield this.array[i] | (this.array[i + 1] << 8);
            i += 2;
        }
    }
}
class RoaringBitmapBits {
    /**
     * @param {Uint8Array} array
     */
    constructor(array) {
        this.array = array;
    }
    /** @param {number} value */
    contains(value) {
        return !!(this.array[value >> 3] & (1 << (value & 7)));
    }
    * values() {
        let i = 0;
        const l = this.array.length << 3;
        while (i < l) {
            if (this.contains(i)) {
                yield i;
            }
            i += 1;
        }
    }
}

const EMPTY_BITMAP = new RoaringBitmap(null, 0);
EMPTY_BITMAP.consumed_len_bytes = 0;
const EMPTY_BITMAP1 = new RoaringBitmap(null, 0);
EMPTY_BITMAP1.consumed_len_bytes = 1;
const EVERYTHING_BITMAP = new RoaringBitmap(null, 0);

/**
 * A mapping from six byte nodeids to an arbitrary value.
 * We don't just use `Map` because that requires double hashing.
 * @template T
 * @property {Uint8Array} keys
 * @property {T[]} values
 * @property {number} size
 * @property {number} capacityClass
 */
class HashTable {
    /**
     * Construct an empty hash table.
     */
    constructor() {
        this.keys = EMPTY_UINT8;
        /** @type {(T|undefined)[]} */
        this.values = [];
        this.size = 0;
        this.capacityClass = 0;
    }
    /**
     * @returns {Generator<[Uint8Array, T]>}
     */
    * entries() {
        const keys = this.keys;
        const values = this.values;
        const l = this.values.length;
        for (let i = 0; i < l; i += 1) {
            const value = values[i];
            if (value !== undefined) {
                yield [keys.subarray(i * 5, (i + 1) * 5), value];
            }
        }
    }
    /**
     * Add a value to the hash table.
     * @param {Uint8Array} key
     * @param {T} value
     */
    set(key, value) {
        // 90 % load factor
        if (this.size * 10 >= this.values.length * 9) {
            const keys = this.keys;
            const values = this.values;
            const l = values.length;
            this.capacityClass += 1;
            const capacity = 1 << this.capacityClass;
            this.keys = new Uint8Array(capacity * 5);
            this.values = [];
            for (let i = 0; i < capacity; i += 1) {
                this.values.push(undefined);
            }
            this.size = 0;
            for (let i = 0; i < l; i += 1) {
                const oldValue = values[i];
                if (oldValue !== undefined) {
                    this.setNoGrow(keys, i * 5, oldValue);
                }
            }
        }
        this.setNoGrow(key, 0, value);
    }
    /**
     * @param {Uint8Array} key
     * @param {number} start
     * @param {T} value
     */
    setNoGrow(key, start, value) {
        const mask = ~(0xffffffff << this.capacityClass);
        const keys = this.keys;
        const values = this.values;
        const l = 1 << this.capacityClass;
        // because we know that our values are already hashed,
        // just chop off the first byte
        let slot = (
            (key[start + 1] << 24) |
            (key[start + 2] << 16) |
            (key[start + 3] << 8) |
            key[start + 4]
        ) & mask;
        for (let distance = 0; distance < l; ) {
            const j = slot * 5;
            const otherValue = values[slot];
            if (otherValue === undefined) {
                values[slot] = value;
                const keysStart = slot * 5;
                keys[keysStart + 0] = key[start + 0];
                keys[keysStart + 1] = key[start + 1];
                keys[keysStart + 2] = key[start + 2];
                keys[keysStart + 3] = key[start + 3];
                keys[keysStart + 4] = key[start + 4];
                this.size += 1;
                break;
            } else if (
                key[start + 0] === keys[j + 0] &&
                key[start + 1] === keys[j + 1] &&
                key[start + 2] === keys[j + 2] &&
                key[start + 3] === keys[j + 3] &&
                key[start + 4] === keys[j + 4]
            ) {
                values[slot] = value;
                break;
            } else {
                const otherPreferredSlot = (
                    (keys[j + 1] << 24) | (keys[j + 2] << 16) |
                    (keys[j + 3] << 8) | keys[j + 4]
                ) & mask;
                const otherDistance = otherPreferredSlot <= slot ?
                    slot - otherPreferredSlot :
                    (l - otherPreferredSlot) + slot;
                if (distance > otherDistance) {
                    // if the other key is closer to its preferred slot than this one,
                    // then insert our node in its place and swap
                    //
                    // https://cglab.ca/~abeinges/blah/robinhood-part-1/
                    const otherKey = keys.slice(j, j + 5);
                    values[slot] = value;
                    value = otherValue;
                    keys[j + 0] = key[start + 0];
                    keys[j + 1] = key[start + 1];
                    keys[j + 2] = key[start + 2];
                    keys[j + 3] = key[start + 3];
                    keys[j + 4] = key[start + 4];
                    key = otherKey;
                    start = 0;
                    distance = otherDistance;
                }
                distance += 1;
                slot = (slot + 1) & mask;
            }
        }
    }
    /**
     * Retrieve a value
     * @param {Uint8Array} key
     * @returns {T|undefined}
     */
    get(key) {
        if (key.length !== 5) {
            throw "invalid key";
        }
        return this.getWithOffsetKey(key, 0);
    }
    /**
     * Retrieve a value
     * @param {Uint8Array} key
     * @param {number} start
     * @returns {T|undefined}
     */
    getWithOffsetKey(key, start) {
        const mask = ~(0xffffffff << this.capacityClass);
        const keys = this.keys;
        const values = this.values;
        const l = 1 << this.capacityClass;
        // because we know that our values are already hashed,
        // just chop off the lower four bytes
        let slot = (
            (key[start + 1] << 24) |
            (key[start + 2] << 16) |
            (key[start + 3] << 8) |
            key[start + 4]
        ) & mask;
        for (let distance = 0; distance < l; distance += 1) {
            const j = slot * 5;
            const value = values[slot];
            if (value === undefined) {
                break;
            } else if (
                key[start + 0] === keys[j + 0] &&
                key[start + 1] === keys[j + 1] &&
                key[start + 2] === keys[j + 2] &&
                key[start + 3] === keys[j + 3] &&
                key[start + 4] === keys[j + 4]
            ) {
                return value;
            } else {
                const otherPreferredSlot = (
                    (keys[j + 1] << 24) | (keys[j + 2] << 16) |
                    (keys[j + 3] << 8) | keys[j + 4]
                ) & mask;
                const otherDistance = otherPreferredSlot <= slot ?
                    slot - otherPreferredSlot :
                    (l - otherPreferredSlot) + slot;
                if (distance > otherDistance) {
                    break;
                }
            }
            slot = (slot + 1) & mask;
        }
        return undefined;
    }
}

/*eslint-disable */
// ignore-tidy-linelength
/** <https://stackoverflow.com/questions/43122082/efficiently-count-the-number-of-bits-in-an-integer-in-javascript>
 * @param {number} n
 * @returns {number}
 */
function bitCount(n) {
    n = (~~n) - ((n >> 1) & 0x55555555);
    n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
    return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
/*eslint-enable */

/**
 * https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
 */
class Uint8ArraySearchPattern {
    /** @param {Uint8Array} needle */
    constructor(needle) {
        this.needle = needle;
        this.skipTable = [];
        const m = needle.length;
        for (let i = 0; i < 256; i += 1) {
            this.skipTable.push(m);
        }
        for (let i = 0; i < m - 1; i += 1) {
            this.skipTable[needle[i]] = m - 1 - i;
        }
    }
    /**
     * @param {Uint8Array} haystack
     * @returns {boolean}
     */
    matches(haystack) {
        const needle = this.needle;
        const skipTable = this.skipTable;
        const m = needle.length;
        const n = haystack.length;

        let skip = 0;
        search: while (n - skip >= m) {
            for (let i = m - 1; i >= 0; i -= 1) {
                if (haystack[skip + i] !== needle[i]) {
                    skip += skipTable[haystack[skip + m  - 1]];
                    continue search;
                }
            }
            return true;
        }
        return false;
    }
}

/**
 * @param {stringdex.Hooks} hooks
 * @returns {Promise<stringdex.Database>}
 */
function loadDatabase(hooks) {
    /** @type {stringdex.Callbacks} */
    const callbacks = {
        rr_: function(data) {
            const dataObj = JSON.parse(data);
            for (const colName of Object.keys(dataObj)) {
                if (Object.hasOwn(dataObj[colName], "N")) {
                    const counts = [];
                    const countsstring = dataObj[colName]["N"];
                    let i = 0;
                    const l = countsstring.length;
                    while (i < l) {
                        let n = 0;
                        let c = countsstring.charCodeAt(i);
                        while (c < 96) { // 96 = "`"
                            n = (n << 4) | (c & 0xF);
                            i += 1;
                            c = countsstring.charCodeAt(i);
                        }
                        n = (n << 4) | (c & 0xF);
                        counts.push(n);
                        i += 1;
                    }
                    registry.dataColumns.set(colName, new DataColumn(
                        counts,
                        makeUint8ArrayFromBase64(dataObj[colName]["H"]),
                        new RoaringBitmap(makeUint8ArrayFromBase64(dataObj[colName]["E"]), 0),
                        colName,
                        Object.hasOwn(dataObj[colName], "I") ?
                            makeSearchTreeFromBase64(dataObj[colName].I)[1] :
                            null,
                    ));
                }
            }
            const cb = registry.searchTreeRootCallback;
            if (cb) {
                cb(null, new Database(registry.searchTreeRoots, registry.dataColumns));
            }
        },
        err_rr_: function(err) {
            const cb = registry.searchTreeRootCallback;
            if (cb) {
                cb(err, null);
            }
        },
        rd_: function(dataString) {
            const l = dataString.length;
            const data = new Uint8Array(l);
            for (let i = 0; i < l; ++i) {
                data[i] = dataString.charCodeAt(i);
            }
            loadColumnFromBytes(data);
        },
        err_rd_: function(filename, err) {
            const nodeid = makeUint8ArrayFromHex(filename);
            const cb = registry.dataColumnLoadPromiseCallbacks.get(nodeid);
            if (cb) {
                cb(err, null);
            }
        },
        rb_: function(dataString64) {
            loadColumnFromBytes(makeUint8ArrayFromBase64(dataString64));
        },
        err_rb_: function(filename, err) {
            const nodeid = makeUint8ArrayFromHex(filename);
            const cb = registry.dataColumnLoadPromiseCallbacks.get(nodeid);
            if (cb) {
                cb(err, null);
            }
        },
        rn_: function(inputBase64) {
            const [nodeid, tree] = makeSearchTreeFromBase64(inputBase64);
            const cb = registry.searchTreeLoadPromiseCallbacks.get(nodeid);
            if (cb) {
                cb(null, tree);
                registry.searchTreeLoadPromiseCallbacks.set(nodeid, null);
            }
        },
        err_rn_: function(filename, err) {
            const nodeid = makeUint8ArrayFromHex(filename);
            const cb = registry.searchTreeLoadPromiseCallbacks.get(nodeid);
            if (cb) {
                cb(err, null);
            }
        },
    };

    /**
     * @type {{
     *      searchTreeRoots: Map<string, SearchTree>;
     *      searchTreeLoadPromiseCallbacks: HashTable<(function(any, SearchTree?): any)|null>;
     *      searchTreePromises: HashTable<Promise<SearchTree>>;
     *      dataColumnLoadPromiseCallbacks: HashTable<function(any, Uint8Array[]?): any>;
     *      dataColumns: Map<string, DataColumn>;
     *      dataColumnsBuckets: HashTable<Promise<Uint8Array[]>>;
     *      searchTreeLoadByNodeID: function(Uint8Array): Promise<SearchTree>;
     *      searchTreeRootCallback?: function(any, Database?): any;
     *      dataLoadByNameAndHash: function(string, Uint8Array): Promise<Uint8Array[]>;
     * }}
     */
    const registry = {
        searchTreeRoots: new Map(),
        searchTreeLoadPromiseCallbacks: new HashTable(),
        searchTreePromises: new HashTable(),
        dataColumnLoadPromiseCallbacks: new HashTable(),
        dataColumns: new Map(),
        dataColumnsBuckets: new HashTable(),
        searchTreeLoadByNodeID: function(nodeid) {
            /** @type {Promise<SearchTree>} */
            let newPromise;
            if ((nodeid[0] & 0x80) !== 0) {
                const isSuffixOnly = (nodeid[0] & 0x40) !== 0;
                const isRun = (nodeid[0] & 0x20) !== 0;
                const lengthOrData = nodeid[0] & 0x1F;
                const id = (nodeid[1] << 24) | (nodeid[2] << 16) | (nodeid[3] << 8) | nodeid[4];
                let bitmap;
                if (isRun) {
                    bitmap = new RoaringBitmap(null);
                    bitmap.containers.push(new RoaringBitmapRun(
                        1,
                        Uint8Array.of(
                            id & 0xFF,
                            (id >> 8) & 0xFF,
                            lengthOrData,
                            0,
                        ),
                    ));
                    bitmap.keysAndCardinalities = Uint8Array.of(
                        (id >> 16) & 0xff,
                        (id >> 24) & 0xff,
                        lengthOrData,
                        0,
                    );
                } else {
                    bitmap = RoaringBitmap.makeSingleton(id);
                }
                let tree;
                if (isSuffixOnly) {
                    tree = new SuffixSearchTree(
                        EMPTY_SEARCH_TREE_BRANCHES,
                        isRun ? 0 : (lengthOrData + 1),
                        bitmap,
                    );
                } else {
                    tree = new PrefixSearchTree(
                        EMPTY_SEARCH_TREE_BRANCHES,
                        EMPTY_SEARCH_TREE_BRANCHES,
                        isRun ? EMPTY_UINT8 : Uint8Array.of(LONG_ALPHABET.chars[lengthOrData]),
                        bitmap,
                        EMPTY_BITMAP,
                    );
                }
                newPromise = Promise.resolve(tree);
            } else {
                const existingPromise = registry.searchTreePromises.get(nodeid);
                if (existingPromise) {
                    return existingPromise;
                }
                const hashHex = makeHexFromUint8Array(nodeid);
                newPromise = new Promise((resolve, reject) => {
                    const cb = registry.searchTreeLoadPromiseCallbacks.get(nodeid);
                    if (cb) {
                        registry.searchTreeLoadPromiseCallbacks.set(nodeid, (err, data) => {
                            cb(err, data);
                            if (data) {
                                resolve(data);
                            } else {
                                reject(err);
                            }
                        });
                    } else {
                        registry.searchTreeLoadPromiseCallbacks.set(nodeid, (err, data) => {
                            if (data) {
                                resolve(data);
                            } else {
                                reject(err);
                            }
                        });
                        hooks.loadTreeByHash(hashHex);
                    }
                });
                registry.searchTreePromises.set(nodeid, newPromise);
            }
            return newPromise;
        },
        dataLoadByNameAndHash: function(name, hash) {
            const existingBucket = registry.dataColumnsBuckets.get(hash);
            if (existingBucket) {
                return existingBucket;
            }
            const hashHex = makeHexFromUint8Array(hash);
            /** @type {Promise<Uint8Array[]>} */
            const newBucket = new Promise((resolve, reject) => {
                const cb = registry.dataColumnLoadPromiseCallbacks.get(hash);
                if (cb) {
                    registry.dataColumnLoadPromiseCallbacks.set(hash, (err, data) => {
                        cb(err, data);
                        if (data) {
                            resolve(data);
                        } else {
                            reject(err);
                        }
                    });
                } else {
                    registry.dataColumnLoadPromiseCallbacks.set(hash, (err, data) => {
                        if (data) {
                            resolve(data);
                        } else {
                            reject(err);
                        }
                    });
                    hooks.loadDataByNameAndHash(name, hashHex);
                }
            });
            registry.dataColumnsBuckets.set(hash, newBucket);
            return newBucket;
        },
    };

    /**
     * The set of child subtrees.
     * @template ST
     * @type {{
     *    nodeids: Uint8Array,
     *    subtrees: Array<Promise<ST>|null>,
     * }}
     */
    class SearchTreeBranches {
        /**
         * Construct the subtree list with `length` nulls
         * @param {number} length
         * @param {Uint8Array} nodeids
         */
        constructor(length, nodeids) {
            this.nodeids = nodeids;
            this.subtrees = [];
            for (let i = 0; i < length; ++i) {
                this.subtrees.push(null);
            }
        }
        /**
         * @param {number} i
         * @returns {Uint8Array}
        */
        getNodeID(i) {
            return new Uint8Array(
                this.nodeids.buffer,
                this.nodeids.byteOffset + (i * 5),
                5,
            );
        }
        // https://github.com/microsoft/TypeScript/issues/17227
        /** @returns {Generator<[number, Promise<ST>|null]>} */
        entries() {
            throw new Error();
        }
        /**
         * @param {number} _k
         * @returns {number}
         */
        getIndex(_k) {
            throw new Error();
        }
        /**
         * @param {number} _i
         * @returns {number}
         */
        getKey(_i) {
            throw new Error();
        }
        /**
         * @returns {Uint8Array}
         */
        getKeys() {
            throw new Error();
        }
    }

    /**
     * A sorted array of search tree branches.
     *
     * @template ST
     * @extends SearchTreeBranches<ST>
     * @type {{
     *    keys: Uint8Array,
     *    nodeids: Uint8Array,
     *    subtrees: Array<Promise<ST>|null>,
     * }}
     */
    class SearchTreeBranchesArray extends SearchTreeBranches {
        /**
         * @param {Uint8Array} keys
         * @param {Uint8Array} nodeids
         */
        constructor(keys, nodeids) {
            super(keys.length, nodeids);
            this.keys = keys;
            let i = 1;
            while (i < this.keys.length) {
                if (this.keys[i - 1] >= this.keys[i]) {
                    throw new Error("HERE");
                }
                i += 1;
            }
        }
        /** @returns {Generator<[number, Promise<ST>|null]>} */
        * entries() {
            let i = 0;
            const l = this.keys.length;
            while (i < l) {
                yield [this.keys[i], this.subtrees[i]];
                i += 1;
            }
        }
        /**
         * @param {number} k
         * @returns {number}
         */
        getIndex(k) {
            // Since length can't be bigger than 256,
            // left + right can't overflow.
            let left = 0;
            let right = this.keys.length - 1;
            while (left <= right) {
                const mid = (left + right) >> 1;
                if (this.keys[mid] < k) {
                    left = mid + 1;
                } else if (this.keys[mid] > k) {
                    right = mid - 1;
                } else {
                    return mid;
                }
            }
            return -1;
        }
        /**
         * @param {number} i
         * @returns {number}
         */
        getKey(i) {
            return this.keys[i];
        }
        /**
         * @returns {Uint8Array}
         */
        getKeys() {
            return this.keys;
        }
    }

    const EMPTY_SEARCH_TREE_BRANCHES = new SearchTreeBranchesArray(
        EMPTY_UINT8,
        EMPTY_UINT8,
    );

    class Alphabet {
        constructor() {
            /** @type {number[]} */
            this.chars = [];
            /** @type {number} */
            this.len = 0;
            /** @type {number} */
            this.bytes = 0;
            /** @type {number} */
            this.flag = 0;
            /** @type {number} */
            this.bitwidth = 0;
        }
        /**
         * @param {number} c
         * @returns {boolean}
         */
        contains(c) {
            return this.chars.indexOf(c) !== -1;
        }
        /**
         * @param {number} c
         * @returns {number}
         */
        index(c) {
            return this.chars.indexOf(c);
        }
    }

    /** @type {Alphabet} */
    const VOWELONLY_ALPHABITMAP = Object.assign(
        new Alphabet(),
        {
            chars: [0x61, 0x65, 0x69, 0x6f, 0x75],
            len: 5,
            bytes: 0,
            flag: 0x80,
        },
    );

    /** @type {Alphabet} */
    const CONSONANTSONLY_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [],
            len: 21,
            bytes: 2,
            flag: 0xc0,
        },
    );
    for (let i = 0x61; i <= 0x7A; ++i) {
        if (i === 0x61 || i === 0x65 || i === 0x69 || i === 0x6f || i === 0x75) {
            // 21 bits, 26 letters, so skip aeiou
            continue;
        }
        CONSONANTSONLY_ALPHABET.chars.push(i);
    }

    /** @type {Alphabet} */
    const HEX_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [],
            len: 16,
            bytes: 2,
            flag: 0xfc,
        },
    );
    for (let i = 0x30; i <= 0x39; ++i) {
        HEX_ALPHABET.chars.push(i);
    }
    for (let i = 0x61; i <= 0x66; ++i) {
        HEX_ALPHABET.chars.push(i);
    }

    /** @type {Alphabet} */
    const SHORT_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [],
            len: 24,
            bytes: 3,
            flag: 0xfd,
        },
    );
    for (let i = 0x61; i <= 0x7A; ++i) {
        if (i === 0x76 || i === 0x71) {
            // 24 entries, 26 letters, so we skip q and v
            continue;
        }
        SHORT_ALPHABET.chars.push(i);
    }

    /** @type {Alphabet} */
    const LONG_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [0x31, 0x32, 0x33, 0x34, 0x35, 0x36],
            len: 32,
            bytes: 4,
            flag: 0xfe,
        },
    );
    for (let i = 0x61; i <= 0x7A; ++i) {
        LONG_ALPHABET.chars.push(i);
    }

    /** @type {Alphabet} */
    const ASCII_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [],
            len: 128,
            bytes: 16,
            flag: 0xf0,
            /**
             * @param {number} c
             * @returns {boolean}
             */
            contains(c) {
                return c <= 0x7f;
            },
            /**
             * @param {number} c
             * @returns {number}
             */
            index(c) {
                return c;
            },
        },
    );
    for (let i = 0x00; i <= 0x7f; ++i) {
        ASCII_ALPHABET.chars.push(i);
    }

    /** @type {Alphabet} */
    const RAWBYTE_ALPHABET = Object.assign(
        new Alphabet(),
        {
            chars: [],
            len: 256,
            bytes: 32,
            flag: 0xff,
            /**
             * @param {number} _c
             * @returns {boolean}
             */
            contains(_c) {
                return true;
            },
            /**
             * @param {number} c
             * @returns {number}
             */
            index(c) {
                return c;
            },
        },
    );
    for (let i = 0x00; i <= 0xff; ++i) {
        RAWBYTE_ALPHABET.chars.push(i);
    }

    /**
     * Parse an alphabet and buffer where the flag is right at the beginning.
     * @param {number} start
     * @param {Uint8Array} buf
     * @returns {{"alphabet": Alphabet, "consumed_len_bytes": number, "len": number}?}
     */
    Alphabet.parse = function(start, buf) {
        const flag = buf[start];
        const parsed = Alphabet.parseFlag(flag, start + 1, buf);
        if (!parsed) {
            return null;
        }
        parsed.consumed_len_bytes += 1;
        return parsed;
    };

    /**
     * Parse an alphabet and buffer where the flag is not at the beginning.
     * @param {number} flag
     * @param {number} i
     * @param {Uint8Array} buf
     * @returns {{"alphabet": Alphabet, "consumed_len_bytes": number, "len": number}?}
     */
    Alphabet.parseFlag = function(flag, i, buf) {
        if (flag <= 0x80) {
            return null;
        }
        const alphabet = flag === RAWBYTE_ALPHABET.flag ? RAWBYTE_ALPHABET : (
            flag === ASCII_ALPHABET.flag ? ASCII_ALPHABET : (
            flag === LONG_ALPHABET.flag ? LONG_ALPHABET : (
            flag === SHORT_ALPHABET.flag ? SHORT_ALPHABET : (
            flag === HEX_ALPHABET.flag ? HEX_ALPHABET : (
            flag >= CONSONANTSONLY_ALPHABET.flag ? CONSONANTSONLY_ALPHABET : VOWELONLY_ALPHABITMAP
        )))));
        let len = alphabet === CONSONANTSONLY_ALPHABET || alphabet === VOWELONLY_ALPHABITMAP ?
            bitCount(flag & 0x1f) : 0;
        for (let ix = 0; ix < alphabet.bytes; ++ix) {
            len += bitCount(buf[i]);
            i += 1;
        }
        return {alphabet, consumed_len_bytes: alphabet.bytes, len};
    };

    /**
     * @template ST
     * @extends SearchTreeBranches<ST>
     */
    class SearchTreeBranchesAlphaBitmap extends SearchTreeBranches {
        /**
         * @param {Alphabet} alphabet
         * @param {Uint8Array} buffer
         * @param {Uint8Array} nodeids
         */
        constructor(alphabet, buffer, nodeids) {
            let bitmap;
            if (alphabet === VOWELONLY_ALPHABITMAP) {
                bitmap = new Uint8Array(1);
                bitmap[0] = buffer[0] & 0x1f;
            } else if (alphabet === CONSONANTSONLY_ALPHABET) {
                bitmap = new Uint8Array(3);
                bitmap[0] = buffer[1];
                bitmap[1] = buffer[2];
                bitmap[2] = buffer[0] & 0x1f;
            } else {
                bitmap = buffer.subarray(1);
            }
            let cardinality = 0;
            for (let i = 0; i < bitmap.length; ++i) {
                cardinality += bitCount(bitmap[i]);
            }
            super(cardinality, nodeids);
            this.bitmap = bitmap;
            this.alphabet = alphabet;
        }
        /**
         * Yields [character, SearchTree] pairs.
         * @returns {Generator<[number, Promise<ST>|null]>}
         */
        * entries() {
            let i = 0;
            let j = 0;
            while (i < this.alphabet.len) {
                if (this.bitmap[i >> 3] & (1 << (i & 0x07))) {
                    yield [this.alphabet.chars[i], this.subtrees[j]];
                    j += 1;
                }
                i += 1;
            }
        }
        /**
         * Given a character, returns the numbered index of the search
         * tree, or -1 if there isn't one.
         * @param {number} c
         * @returns {number}
         */
        getIndex(c) {
            //return this.getKeys().indexOf(c);
            if (!this.alphabet.contains(c)) {
                return -1;
            }
            const k = this.alphabet.index(c);
            if (this.bitmap[k >> 3] & (1 << (k & 0x07))) {
                let result = bitCount(~(0xff << (k & 0x07)) & this.bitmap[k >> 3]);
                for (let ix = 0; ix < (k >> 3); ++ix) {
                    result += bitCount(this.bitmap[ix]);
                }
                return result;
            } else {
                return -1;
            }
        }
        /**
         * Given the numbered index of a search tree, returns the key.
         * This is the exact opposite of getIndex().
         * @param {number} branch_index
         * @returns {number}
         */
        getKey(branch_index) {
            return this.getKeys()[branch_index];
        }
        /**
         * Returns a list of one-byte keys.
         * @returns {Uint8Array}
         */
        getKeys() {
            let length = 0;
            for (let i = 0; i < this.bitmap.length; ++i) {
                length += bitCount(this.bitmap[i]);
            }
            const result = new Uint8Array(length);
            let result_index = 0;
            for (let ix = 0; ix < this.alphabet.len; ++ix) {
                if (this.bitmap[ix >> 3] & (1 << (ix & 0x07))) {
                    result[result_index] = this.alphabet.chars[ix];
                    result_index += 1;
                }
            }
            return result;
        }
    }

    /**
     * @typedef {PrefixSearchTree|SuffixSearchTree|InlineNeighborsTree} SearchTree
     * @typedef {PrefixTrie|SuffixTrie} Trie
     */

    /**
     * An interleaved [prefix] and [suffix tree],
     * used for name-based search.
     *
     * This data structure is used to drive prefix matches,
     * such as matching the query "link" to `LinkedList`,
     * and Lev-distance matches, such as matching the
     * query "hahsmap" to `HashMap`.
     *
     * [prefix tree]: https://en.wikipedia.org/wiki/Prefix_tree
     * [suffix tree]: https://en.wikipedia.org/wiki/Suffix_tree
     *
     * branches
     * : A sorted-array map of subtrees.
     *
     * data
     * : The substring represented by this node. The root node
     *   is always empty.
     *
     * leaves_suffix
     * : The IDs of every entry that matches. Levenshtein matches
     *   won't include these.
     *
     * leaves_whole
     * : The IDs of every entry that matches exactly. Levenshtein matches
     *   will include these.
     *
     * @type {{
     *     might_have_prefix_branches: SearchTreeBranches<SearchTree>,
     *     branches: SearchTreeBranches<SearchTree>,
     *     data: Uint8Array,
     *     leaves_suffix: RoaringBitmap,
     *     leaves_whole: RoaringBitmap,
     * }}
     */
    class PrefixSearchTree {
        /**
         * @param {SearchTreeBranches<SearchTree>} branches
         * @param {SearchTreeBranches<SearchTree>} might_have_prefix_branches
         * @param {Uint8Array} data
         * @param {RoaringBitmap} leaves_whole
         * @param {RoaringBitmap} leaves_suffix
         */
        constructor(
            branches,
            might_have_prefix_branches,
            data,
            leaves_whole,
            leaves_suffix,
        ) {
            this.might_have_prefix_branches = might_have_prefix_branches;
            this.branches = branches;
            this.data = data;
            this.leaves_suffix = leaves_suffix;
            this.leaves_whole = leaves_whole;
        }
        /**
         * Returns the Trie for the root node.
         *
         * A Trie pointer refers to a single node in a logical decompressed search tree
         * (the real search tree is compressed).
         *
         * @param {DataColumn} dataColumn
         * @param {Uint8ArraySearchPattern} searchPattern
         * @return {PrefixTrie}
         */
        trie(dataColumn, searchPattern) {
            return new PrefixTrie(this, 0, dataColumn, searchPattern);
        }

        /**
         * Return the trie representing `name`
         * @param {Uint8Array|string} name
         * @param {DataColumn} dataColumn
         * @returns {Promise<Trie?>}
         */
        async search(name, dataColumn) {
            if (typeof name === "string") {
                const utf8encoder = new TextEncoder();
                name = utf8encoder.encode(name);
            }
            const searchPattern = new Uint8ArraySearchPattern(name);
            /** @type {Trie} */
            let trie = this.trie(dataColumn, searchPattern);
            for (const datum of name) {
                // code point definitely exists
                /** @type {Promise<Trie>?} */
                const newTrie = trie.child(datum);
                if (newTrie) {
                    trie = await newTrie;
                } else {
                    return null;
                }
            }
            return trie;
        }

        /**
         * @param {Uint8Array|string} name
         * @param {DataColumn} dataColumn
         * @returns {AsyncGenerator<Trie>}
         */
        async* searchLev(name, dataColumn) {
            if (typeof name === "string") {
                const utf8encoder = new TextEncoder();
                name = utf8encoder.encode(name);
            }
            const w = name.length;
            if (w < 3) {
                const trie = await this.search(name, dataColumn);
                if (trie !== null) {
                    yield trie;
                }
                return;
            }
            const searchPattern = new Uint8ArraySearchPattern(name);
            const levParams = w >= 6 ?
                new Lev2TParametricDescription(w) :
                new Lev1TParametricDescription(w);
            /** @type {Array<[Promise<Trie>, number]>} */
            const stack = [[Promise.resolve(this.trie(dataColumn, searchPattern)), 0]];
            const n = levParams.n;
            while (stack.length !== 0) {
                // It's not empty
                /** @type {[Promise<Trie>, number]} */
                //@ts-expect-error
                const [triePromise, levState] = stack.pop();
                const trie = await triePromise;
                for (const byte of trie.keysExcludeSuffixOnly()) {
                    const levPos = levParams.getPosition(levState);
                    const vector = levParams.getVector(
                        name,
                        byte,
                        levPos,
                        Math.min(w, levPos + (2 * n) + 1),
                    );
                    const newLevState = levParams.transition(
                        levState,
                        levPos,
                        vector,
                    );
                    if (newLevState >= 0) {
                        const child = trie.child(byte);
                        if (child) {
                            stack.push([child, newLevState]);
                            if (levParams.isAccept(newLevState)) {
                                yield child;
                            }
                        }
                    }
                }
            }
        }

        /** @returns {RoaringBitmap} */
        getCurrentLeaves() {
            return this.leaves_whole.union(this.leaves_suffix);
        }
    }

    /**
     * A representation of a set of strings in the search index,
     * as a subset of the entire tree.
     */
    class PrefixTrie {
        /**
         * @param {PrefixSearchTree} tree
         * @param {number} offset
         * @param {DataColumn} dataColumn
         * @param {Uint8ArraySearchPattern} searchPattern
         */
        constructor(tree, offset, dataColumn, searchPattern) {
            this.tree = tree;
            this.offset = offset;
            this.dataColumn = dataColumn;
            this.searchPattern = searchPattern;
        }

        /**
         * All exact matches for the string represented by this node.
         * @returns {RoaringBitmap}
         */
        matches() {
            if (this.offset === this.tree.data.length) {
                return this.tree.leaves_whole;
            } else {
                return EMPTY_BITMAP;
            }
        }

        /**
         * All matches for strings that contain the string represented by this node.
         * @returns {AsyncGenerator<RoaringBitmap>}
         */
        async* substringMatches() {
            /** @type {Promise<SearchTree>[]} */
            let layer = [Promise.resolve(this.tree)];
            while (layer.length) {
                const current_layer = layer;
                layer = [];
                for await (const tree of current_layer) {
                    /** @type {number[]?} */
                    let rejected = null;
                    let leaves = tree.getCurrentLeaves();
                    for (const leaf of leaves.entries()) {
                        const haystack = await this.dataColumn.at(leaf);
                        if (haystack === undefined || !this.searchPattern.matches(haystack)) {
                            if (!rejected) {
                                rejected = [];
                            }
                            rejected.push(leaf);
                        }
                    }
                    if (rejected) {
                        if (leaves.cardinality() !== rejected.length) {
                            for (const rej of rejected) {
                                leaves = leaves.remove(rej);
                            }
                            yield leaves;
                        }
                    } else {
                        yield leaves;
                    }
                }
                /** @type {HashTable<[number, PrefixSearchTree|SuffixSearchTree][]>} */
                const subnodes = new HashTable();
                for await (const nodeEncoded of current_layer) {
                    const node = nodeEncoded instanceof InlineNeighborsTree ?
                        nodeEncoded.decode() :
                        nodeEncoded;
                    const branches = node.branches;
                    const l = branches.subtrees.length;
                    for (let i = 0; i < l; ++i) {
                        const subtree = branches.subtrees[i];
                        if (subtree) {
                            layer.push(subtree);
                        } else if (subtree === null) {
                            const byte = branches.getKey(i);
                            const newnode = branches.getNodeID(i);
                            if (!newnode) {
                                throw new Error(`malformed tree; no node for key ${byte}`);
                            } else {
                                let subnode_list = subnodes.get(newnode);
                                if (!subnode_list) {
                                    subnode_list = [[byte, node]];
                                    subnodes.set(newnode, subnode_list);
                                } else {
                                    subnode_list.push([byte, node]);
                                }
                            }
                        } else {
                            throw new Error(`malformed tree; index ${i} does not exist`);
                        }
                    }
                }
                for (const [newnode, subnode_list] of subnodes.entries()) {
                    const res = registry.searchTreeLoadByNodeID(newnode);
                    for (const [byte, node] of subnode_list) {
                        const branches = node.branches;
                        const i = branches.getIndex(byte);
                        branches.subtrees[i] = res;
                        if (node instanceof PrefixSearchTree) {
                            const might_have_prefix_branches = node.might_have_prefix_branches;
                            const mhpI = might_have_prefix_branches.getIndex(byte);
                            if (mhpI !== -1) {
                                might_have_prefix_branches.subtrees[mhpI] = res;
                            }
                        }
                    }
                    layer.push(res);
                }
            }
        }

        /**
         * All matches for strings that start with the string represented by this node.
         * @returns {AsyncGenerator<RoaringBitmap>}
         */
        async* prefixMatches() {
            /** @type {{node: Promise<SearchTree>, len: number}[]} */
            let layer = [{node: Promise.resolve(this.tree), len: 0}];
            // https://en.wikipedia.org/wiki/Heap_(data_structure)#Implementation_using_arrays
            /** @type {{bitmap: RoaringBitmap, length: number}[]} */
            const backlog = [];
            while (layer.length !== 0 || backlog.length !== 0) {
                const current_layer = layer;
                layer = [];
                let minLength = null;
                // push every entry in the current layer into the backlog,
                // a min-heap of result entries
                // we then yield the smallest ones (can't yield bigger ones
                // if we want to do them in order)
                for (const {node, len} of current_layer) {
                    const treeEncoded = await node;
                    const tree = treeEncoded instanceof InlineNeighborsTree ?
                        treeEncoded.decode() :
                        treeEncoded;
                    if (!(tree instanceof PrefixSearchTree)) {
                        continue;
                    }
                    const length = len + tree.data.length;
                    if (minLength === null || length < minLength) {
                        minLength = length;
                    }
                    let backlogSlot = backlog.length;
                    backlog.push({bitmap: tree.leaves_whole, length});
                    while (backlogSlot > 0 &&
                        backlog[backlogSlot].length < backlog[(backlogSlot - 1) >> 1].length
                    ) {
                        const parentSlot = (backlogSlot - 1) >> 1;
                        const parent = backlog[parentSlot];
                        backlog[parentSlot] = backlog[backlogSlot];
                        backlog[backlogSlot] = parent;
                        backlogSlot = parentSlot;
                    }
                }
                // yield nodes in length order, smallest one first
                // we know that, whatever the smallest item is
                // every child will be bigger than that
                while (backlog.length !== 0) {
                    const backlogEntry = backlog[0];
                    if (minLength !== null && backlogEntry.length > minLength) {
                        break;
                    }
                    if (!backlogEntry.bitmap.isEmpty()) {
                        yield backlogEntry.bitmap;
                    }
                    backlog[0] = backlog[backlog.length - 1];
                    backlog.length -= 1;
                    let backlogSlot = 0;
                    const backlogLength = backlog.length;
                    while (backlogSlot < backlogLength) {
                        const leftSlot = (backlogSlot << 1) + 1;
                        const rightSlot = (backlogSlot << 1) + 2;
                        let smallest = backlogSlot;
                        if (leftSlot < backlogLength &&
                            backlog[leftSlot].length < backlog[smallest].length
                        ) {
                            smallest = leftSlot;
                        }
                        if (rightSlot < backlogLength &&
                            backlog[rightSlot].length < backlog[smallest].length
                        ) {
                            smallest = rightSlot;
                        }
                        if (smallest === backlogSlot) {
                            break;
                        } else {
                            const tmp = backlog[backlogSlot];
                            backlog[backlogSlot] = backlog[smallest];
                            backlog[smallest] = tmp;
                            backlogSlot = smallest;
                        }
                    }
                }
                // if we still have more subtrees to walk, then keep going
                /** @type {HashTable<{byte: number, tree: PrefixSearchTree, len: number}[]>} */
                const subnodes = new HashTable();
                for await (const {node, len} of current_layer) {
                    const treeEncoded = await node;
                    const tree = treeEncoded instanceof InlineNeighborsTree ?
                        treeEncoded.decode() :
                        treeEncoded;
                    if (!(tree instanceof PrefixSearchTree)) {
                        continue;
                    }
                    const length = len + tree.data.length;
                    const mhp_branches = tree.might_have_prefix_branches;
                    const l = mhp_branches.subtrees.length;
                    for (let i = 0; i < l; ++i) {
                        const len = length + 1;
                        const subtree = mhp_branches.subtrees[i];
                        if (subtree) {
                            layer.push({node: subtree, len});
                        } else if (subtree === null) {
                            const byte = mhp_branches.getKey(i);
                            const newnode = mhp_branches.getNodeID(i);
                            if (!newnode) {
                                throw new Error(`malformed tree; no node for key ${byte}`);
                            } else {
                                let subnode_list = subnodes.get(newnode);
                                if (!subnode_list) {
                                    subnode_list = [{byte, tree, len}];
                                    subnodes.set(newnode, subnode_list);
                                } else {
                                    subnode_list.push({byte, tree, len});
                                }
                            }
                        }
                    }
                }
                for (const [newnode, subnode_list] of subnodes.entries()) {
                    const res = registry.searchTreeLoadByNodeID(newnode);
                    let len = Number.MAX_SAFE_INTEGER;
                    for (const {byte, tree, len: subtreelen} of subnode_list) {
                        if (subtreelen < len) {
                            len = subtreelen;
                        }
                        const mhp_branches = tree.might_have_prefix_branches;
                        const i = mhp_branches.getIndex(byte);
                        mhp_branches.subtrees[i] = res;
                        const branches = tree.branches;
                        const bi = branches.getIndex(byte);
                        branches.subtrees[bi] = res;
                    }
                    layer.push({node: res, len});
                }
            }
        }

        /**
         * Returns all keys that are children of this node.
         * @returns {Uint8Array}
         */
        keys() {
            const data = this.tree.data;
            if (this.offset === data.length) {
                return this.tree.branches.getKeys();
            } else {
                return Uint8Array.of(data[this.offset]);
            }
        }

        /**
         * Returns all nodes that are direct children of this node.
         * @returns {[number, Promise<Trie>][]}
         */
        children() {
            const data = this.tree.data;
            if (this.offset === data.length) {
                /** @type {[number, Promise<Trie>][]} */
                const nodes = [];
                let i = 0;
                for (const [k, v] of this.tree.branches.entries()) {
                    /** @type {Promise<SearchTree>} */
                    let node;
                    if (v) {
                        node = v;
                    } else {
                        const newnode = this.tree.branches.getNodeID(i);
                        if (!newnode) {
                            throw new Error(`malformed tree; no hash for key ${k}: ${newnode} \
                                ${this.tree.branches.nodeids} ${this.tree.branches.getKeys()}`);
                        }
                        node = registry.searchTreeLoadByNodeID(newnode);
                        this.tree.branches.subtrees[i] = node;
                        const mhpI = this.tree.might_have_prefix_branches.getIndex(k);
                        if (mhpI !== -1) {
                            this.tree.might_have_prefix_branches.subtrees[mhpI] = node;
                        }
                    }
                    nodes.push([k, node.then(node => {
                        return node.trie(this.dataColumn, this.searchPattern);
                    })]);
                    i += 1;
                }
                return nodes;
            } else {
                /** @type {number} */
                const codePoint = data[this.offset];
                const trie = new PrefixTrie(
                    this.tree,
                    this.offset + 1,
                    this.dataColumn,
                    this.searchPattern,
                );
                return [[codePoint, Promise.resolve(trie)]];
            }
        }

        /**
         * Returns all keys that are children of this node.
         * @returns {Uint8Array}
         */
        keysExcludeSuffixOnly() {
            const data = this.tree.data;
            if (this.offset === data.length) {
                return this.tree.might_have_prefix_branches.getKeys();
            } else {
                return Uint8Array.of(data[this.offset]);
            }
        }

        /**
         * Returns all nodes that are direct children of this node.
         * @returns {[number, Promise<Trie>][]}
         */
        childrenExcludeSuffixOnly() {
            const data = this.tree.data;
            if (this.offset === data.length) {
                /** @type {[number, Promise<Trie>][]} */
                const nodes = [];
                let i = 0;
                for (const [k, v] of this.tree.might_have_prefix_branches.entries()) {
                    /** @type {Promise<SearchTree>} */
                    let node;
                    if (v) {
                        node = v;
                    } else {
                        const newnode = this.tree.might_have_prefix_branches.getNodeID(i);
                        if (!newnode) {
                            throw new Error(`malformed tree; no node for key ${k}`);
                        }
                        node = registry.searchTreeLoadByNodeID(newnode);
                        this.tree.might_have_prefix_branches.subtrees[i] = node;
                        this.tree.branches.subtrees[this.tree.branches.getIndex(k)] = node;
                    }
                    nodes.push([k, node.then(node => {
                        return node.trie(this.dataColumn, this.searchPattern);
                    })]);
                    i += 1;
                }
                return nodes;
            } else {
                /** @type {number} */
                const codePoint = data[this.offset];
                const trie = new PrefixTrie(
                    this.tree,
                    this.offset + 1,
                    this.dataColumn,
                    this.searchPattern,
                );
                return [[codePoint, Promise.resolve(trie)]];
            }
        }

        /**
         * Returns a single node that is a direct child of this node.
         * @param {number} byte
         * @returns {Promise<Trie>?}
         */
        child(byte) {
            if (this.offset === this.tree.data.length) {
                const i = this.tree.branches.getIndex(byte);
                if (i !== -1) {
                    let branch = this.tree.branches.subtrees[i];
                    if (branch === null) {
                        const newnode = this.tree.branches.getNodeID(i);
                        if (!newnode) {
                            throw new Error(`malformed tree; no node for key ${byte}`);
                        }
                        branch = registry.searchTreeLoadByNodeID(newnode);
                        this.tree.branches.subtrees[i] = branch;
                        const mhpI = this.tree.might_have_prefix_branches.getIndex(byte);
                        if (mhpI !== -1) {
                            this.tree.might_have_prefix_branches.subtrees[mhpI] = branch;
                        }
                    }
                    return branch.then(branch => branch.trie(this.dataColumn, this.searchPattern));
                }
            } else if (this.tree.data[this.offset] === byte) {
                return Promise.resolve(new PrefixTrie(
                    this.tree,
                    this.offset + 1,
                    this.dataColumn,
                    this.searchPattern,
                ));
            }
            return null;
        }
    }
    /**
     * A [suffix tree], used for name-based search.
     *
     * This data structure is used to drive substring matches,
     * such as matching the query "inked" to `LinkedList`.
     *
     * [suffix tree]: https://en.wikipedia.org/wiki/Suffix_tree
     *
     * Suffix trees do not actually carry the intermediate data
     * between branches, so, in order to validate the results,
     * they must go through a filtering step at the end.
     * Suffix trees also cannot match lev and exact matches,
     * so those just return empty sets.
     *
     * branches
     * : A sorted-array map of subtrees.
     *
     * dataLen
     * : The length of the substring used by this node.
     *
     * leaves_suffix
     * : The IDs of every entry that matches. Levenshtein matches
     *   won't include these.
     *
     * @type {{
     *     branches: SearchTreeBranches<SearchTree>,
     *     dataLen: number,
     *     leaves_suffix: RoaringBitmap,
     * }}
     */
    class SuffixSearchTree {
        /**
         * @param {SearchTreeBranches<SearchTree>} branches
         * @param {number} dataLen
         * @param {RoaringBitmap} leaves_suffix
         */
        constructor(
            branches,
            dataLen,
            leaves_suffix,
        ) {
            this.branches = branches;
            this.dataLen = dataLen;
            this.leaves_suffix = leaves_suffix;
        }
        /**
         * Returns the Trie for the root node.
         *
         * A Trie pointer refers to a single node in a logical decompressed search tree
         * (the real search tree is compressed).
         *
         * @param {DataColumn} dataColumn
         * @param {Uint8ArraySearchPattern} searchPattern
         * @return {Trie}
         */
        trie(dataColumn, searchPattern) {
            return new SuffixTrie(this, 0, dataColumn, searchPattern);
        }

        /**
         * Return the trie representing `name`
         * @param {Uint8Array|string} name
         * @param {DataColumn} dataColumn
         * @returns {Promise<Trie?>}
         */
        async search(name, dataColumn) {
            if (typeof name === "string") {
                const utf8encoder = new TextEncoder();
                name = utf8encoder.encode(name);
            }
            const searchPattern = new Uint8ArraySearchPattern(name);
            let trie = this.trie(dataColumn, searchPattern);
            for (const datum of name) {
                // code point definitely exists
                const newTrie = trie.child(datum);
                if (newTrie) {
                    trie = await newTrie;
                } else {
                    return null;
                }
            }
            return trie;
        }

        /**
         * @param {Uint8Array|string} _name
         * @param {DataColumn} _dataColumn
         * @returns {AsyncGenerator<Trie>}
         */
        async* searchLev(_name, _dataColumn) {
            // this function only returns whole-string matches,
            // which pure-suffix nodes don't have, so is
            // intentionally blank
        }

        /** @returns {RoaringBitmap} */
        getCurrentLeaves() {
            return this.leaves_suffix;
        }
    }

    /**
     * A representation of a set of strings in the search index,
     * as a subset of the entire tree (suffix-only).
     */
    class SuffixTrie {
        /**
         * @param {SuffixSearchTree} tree
         * @param {number} offset
         * @param {DataColumn} dataColumn
         * @param {Uint8ArraySearchPattern} searchPattern
         */
        constructor(tree, offset, dataColumn, searchPattern) {
            this.tree = tree;
            this.offset = offset;
            this.dataColumn = dataColumn;
            this.searchPattern = searchPattern;
        }

        /**
         * All exact matches for the string represented by this node.
         * Since pure-suffix nodes have no exactly-matching children,
         * this function returns the empty bitmap.
         * @returns {RoaringBitmap}
         */
        matches() {
            return EMPTY_BITMAP;
        }

        /**
         * All matches for strings that contain the string represented by this node.
         * @returns {AsyncGenerator<RoaringBitmap>}
         */
        async* substringMatches() {
            /** @type {Promise<SearchTree>[]} */
            let layer = [Promise.resolve(this.tree)];
            while (layer.length) {
                const current_layer = layer;
                layer = [];
                for await (const tree of current_layer) {
                    /** @type {number[]?} */
                    let rejected = null;
                    let leaves = tree.getCurrentLeaves();
                    for (const leaf of leaves.entries()) {
                        const haystack = await this.dataColumn.at(leaf);
                        if (haystack === undefined || !this.searchPattern.matches(haystack)) {
                            if (!rejected) {
                                rejected = [];
                            }
                            rejected.push(leaf);
                        }
                    }
                    if (rejected) {
                        if (leaves.cardinality() !== rejected.length) {
                            for (const rej of rejected) {
                                leaves = leaves.remove(rej);
                            }
                            yield leaves;
                        }
                    } else {
                        yield leaves;
                    }
                }
                /** @type {HashTable<[number, PrefixSearchTree|SuffixSearchTree][]>} */
                const subnodes = new HashTable();
                for await (const nodeEncoded of current_layer) {
                    const node = nodeEncoded instanceof InlineNeighborsTree ?
                        nodeEncoded.decode() :
                        nodeEncoded;
                    const branches = node.branches;
                    const l = branches.subtrees.length;
                    for (let i = 0; i < l; ++i) {
                        const subtree = branches.subtrees[i];
                        if (subtree) {
                            layer.push(subtree);
                        } else if (subtree === null) {
                            const newnode = branches.getNodeID(i);
                            if (!newnode) {
                                throw new Error(`malformed tree; no node for index ${i}`);
                            } else {
                                let subnode_list = subnodes.get(newnode);
                                if (!subnode_list) {
                                    subnode_list = [[i, node]];
                                    subnodes.set(newnode, subnode_list);
                                } else {
                                    subnode_list.push([i, node]);
                                }
                            }
                        } else {
                            throw new Error(`malformed tree; index ${i} does not exist`);
                        }
                    }
                }
                for (const [newnode, subnode_list] of subnodes.entries()) {
                    const res = registry.searchTreeLoadByNodeID(newnode);
                    for (const [i, node] of subnode_list) {
                        const branches = node.branches;
                        branches.subtrees[i] = res;
                    }
                    layer.push(res);
                }
            }
        }

        /**
         * All matches for strings that start with the string represented by this node.
         * Since this is a pure-suffix node, there aren't any.
         * @returns {AsyncGenerator<RoaringBitmap>}
         */
        async* prefixMatches() {
            // this function only returns prefix matches,
            // which pure-suffix nodes don't have, so is
            // intentionally blank
        }

        /**
         * Returns all keys that are children of this node.
         * @returns {Uint8Array}
         */
        keysExcludeSuffixOnly() {
            return EMPTY_UINT8;
        }

        /**
         * Returns all nodes that are direct children of this node.
         * @returns {[number, Promise<Trie>][]}
         */
        childrenExcludeSuffixOnly() {
            return [];
        }

        /**
         * Returns a single node that is a direct child of this node.
         * @param {number} byte
         * @returns {Promise<Trie>?}
         */
        child(byte) {
            if (this.offset === this.tree.dataLen) {
                const i = this.tree.branches.getIndex(byte);
                if (i !== -1) {
                    /** @type {Promise<SearchTree>?} */
                    let branch = this.tree.branches.subtrees[i];
                    if (branch === null) {
                        const newnode = this.tree.branches.getNodeID(i);
                        if (!newnode) {
                            throw new Error(`malformed tree; no node for key ${byte}`);
                        }
                        branch = registry.searchTreeLoadByNodeID(newnode);
                        this.tree.branches.subtrees[i] = branch;
                    }
                    return branch.then(branch => branch.trie(this.dataColumn, this.searchPattern));
                }
            } else {
                return Promise.resolve(new SuffixTrie(
                    this.tree,
                    this.offset + 1,
                    this.dataColumn,
                    this.searchPattern,
                ));
            }
            return null;
        }
    }

    /**
     * Represents a subtree where all transitive leaves
     * have a shared 16bit prefix and there are no sub-branches.
     */
    class InlineNeighborsTree {
        /**
         * @param {Uint8Array} encoded
         * @param {number} start
         */
        constructor(
            encoded,
            start,
        ) {
            this.encoded = encoded;
            this.start = start;
        }
        /**
         * @return {PrefixSearchTree|SuffixSearchTree}
         */
        decode() {
            let i = this.start;
            const encoded = this.encoded;
            const has_branches = (encoded[i] & 0x04) !== 0;
            /** @type {boolean} */
            const is_suffixes_only = (encoded[i] & 0x01) !== 0;
            const leaves_count = (encoded[i] >> 4) & 0x07;
            const leaves_is_run = (encoded[i] >> 7) !== 0;
            i += 1;
            let branch_flag = 0;
            if (has_branches) {
                branch_flag = encoded[i];
                i += 1;
            }
            const dlen = encoded[i] & 0x3f;
            i += 1;
            /** @type {Uint8Array} */
            let data = EMPTY_UINT8;
            if (!is_suffixes_only && dlen !== 0) {
                data = encoded.subarray(i, i + dlen);
                i += dlen;
            }
            const branch_flag_alphabet = Alphabet.parseFlag(branch_flag, i, encoded);
            let branch_alphabitmap = EMPTY_UINT8;
            if (branch_flag_alphabet) {
                branch_alphabitmap = new Uint8Array(branch_flag_alphabet.consumed_len_bytes + 1);
                branch_alphabitmap[0] = branch_flag;
                branch_alphabitmap.set(
                    encoded.subarray(i, i + branch_flag_alphabet.consumed_len_bytes),
                    1,
                );
                i += branch_flag_alphabet.consumed_len_bytes;
            }
            const branch_count = branch_flag_alphabet ? branch_flag_alphabet.len : branch_flag;
            const leaf_value_upper = encoded[i] | (encoded[i + 1] << 8);
            i += 2;
            /** @type {Promise<SearchTree>[]} */
            const branch_nodes = [];
            for (let j = 0; j < branch_count; j += 1) {
                const branch_dlen = encoded[i] & 0x0f;
                const branch_leaves_count = (encoded[i] >> 4) & 0x07;
                const branch_leaves_is_run = (encoded[i] >> 7) !== 0;
                i += 1;
                /** @type {Uint8Array} */
                let branch_data = EMPTY_UINT8;
                if (!is_suffixes_only && branch_dlen !== 0) {
                    branch_data = encoded.subarray(i, i + branch_dlen);
                    i += branch_dlen;
                }
                const branch_leaves = new RoaringBitmap(null);
                branch_leaves.keysAndCardinalities = Uint8Array.of(
                    leaf_value_upper & 0xff,
                    (leaf_value_upper >> 8) & 0xff,
                    (branch_leaves_count - 1) & 0xff,
                    ((branch_leaves_count - 1) >> 8) & 0xff,
                );
                if (branch_leaves_is_run) {
                    branch_leaves.containers = [
                        new RoaringBitmapRun(
                            1,
                            Uint8Array.of(
                                encoded[i],
                                encoded[i + 1],
                                branch_leaves_count - 1,
                                0,
                            ),
                        ),
                    ];
                    i += 2;
                } else {
                    branch_leaves.containers = [
                        new RoaringBitmapArray(
                            branch_leaves_count,
                            encoded.subarray(i, i + (branch_leaves_count * 2)),
                        ),
                    ];
                    i += branch_leaves_count * 2;
                }
                branch_nodes.push(Promise.resolve(
                    is_suffixes_only ?
                        new SuffixSearchTree(
                            EMPTY_SEARCH_TREE_BRANCHES,
                            branch_dlen,
                            branch_leaves,
                        ) :
                        new PrefixSearchTree(
                            EMPTY_SEARCH_TREE_BRANCHES,
                            EMPTY_SEARCH_TREE_BRANCHES,
                            branch_data,
                            branch_leaves,
                            EMPTY_BITMAP,
                        ),
                ));
            }
            /** @type {SearchTreeBranches<SearchTree>} */
            const branches = branch_count === 0 ?
                EMPTY_SEARCH_TREE_BRANCHES :
                branch_flag_alphabet ?
                    new SearchTreeBranchesAlphaBitmap(
                        branch_flag_alphabet.alphabet,
                        branch_alphabitmap,
                        EMPTY_UINT8,
                    ) :
                    new SearchTreeBranchesArray(
                        encoded.subarray(i, i + branch_count),
                        EMPTY_UINT8,
                    );
            if (!branch_flag_alphabet) {
                i += branch_count;
            }
            branches.subtrees = branch_nodes;
            let leaves = EMPTY_BITMAP;
            if (leaves_count !== 0) {
                leaves = new RoaringBitmap(null);
                leaves.keysAndCardinalities = Uint8Array.of(
                    leaf_value_upper & 0xff,
                    (leaf_value_upper >> 8) & 0xff,
                    (leaves_count - 1) & 0xff,
                    ((leaves_count - 1) >> 8) & 0xff,
                );
                if (leaves_is_run) {
                    leaves.containers = [
                        new RoaringBitmapRun(
                            1,
                            Uint8Array.of(
                                encoded[i],
                                encoded[i + 1],
                                leaves_count - 1,
                                0,
                            ),
                        ),
                    ];
                    i += 2;
                } else {
                    leaves.containers = [
                        new RoaringBitmapArray(
                            leaves_count,
                            encoded.subarray(i, i + (leaves_count * 2)),
                        ),
                    ];
                    i += leaves_count * 2;
                }
            }
            return is_suffixes_only ?
                new SuffixSearchTree(
                    branches,
                    dlen,
                    leaves,
                ) :
                new PrefixSearchTree(
                    branches,
                    branches,
                    data,
                    leaves,
                    EMPTY_BITMAP,
                );
        }

        /**
         * Returns the Trie for the root node.
         *
         * A Trie pointer refers to a single node in a logical decompressed search tree
         * (the real search tree is compressed).
         *
         * @param {DataColumn} dataColumn
         * @param {Uint8ArraySearchPattern} searchPattern
         * @return {Trie}
         */
        trie(dataColumn, searchPattern) {
            const tree = this.decode();
            return tree instanceof SuffixSearchTree ?
                new SuffixTrie(tree, 0, dataColumn, searchPattern) :
                new PrefixTrie(tree, 0, dataColumn, searchPattern);
        }

        /**
         * Return the trie representing `name`
         * @param {Uint8Array|string} name
         * @param {DataColumn} dataColumn
         * @returns {Promise<Trie?>}
         */
        search(name, dataColumn) {
            return this.decode().search(name, dataColumn);
        }

        /**
         * @param {Uint8Array|string} name
         * @param {DataColumn} dataColumn
         * @returns {AsyncGenerator<Trie>}
         */
        searchLev(name, dataColumn) {
            return this.decode().searchLev(name, dataColumn);
        }

        /** @returns {RoaringBitmap} */
        getCurrentLeaves() {
            return this.decode().getCurrentLeaves();
        }
    }

    class DataColumn {
        /**
         * Construct the wrapper object for a data column.
         * @param {number[]} counts
         * @param {Uint8Array} hashes
         * @param {RoaringBitmap} emptyset
         * @param {string} name
         * @param {SearchTree?} searchTree
         */
        constructor(counts, hashes, emptyset, name, searchTree) {
            this.searchTree = searchTree;
            this.hashes = hashes;
            this.emptyset = emptyset;
            this.name = name;
            /** @type {{"hash": Uint8Array, "data": Uint8Array[]?, "end": number}[]} */
            this.buckets = [];
            this.bucket_keys = [];
            const l = counts.length;
            let k = 0;
            let totalLength = 0;
            for (let i = 0; i < l; ++i) {
                const count = counts[i];
                totalLength += count;
                const start = k;
                for (let j = 0; j < count; ++j) {
                    if (emptyset.contains(k)) {
                        j -= 1;
                    }
                    k += 1;
                }
                const end = k;
                const bucket = {hash: hashes.subarray(i * 5, (i + 1) * 5), data: null, end, count};
                this.buckets.push(bucket);
                this.bucket_keys.push(start);
            }
            this.length = totalLength;
        }
        /**
         * Check if a cell contains the empty string.
         * @param {number} id
         * @returns {boolean}
         */
        isEmpty(id) {
            return this.emptyset.contains(id);
        }
        /**
         * Look up a cell by row ID.
         * @param {number} id
         * @returns {Promise<Uint8Array>|Uint8Array|undefined}
         */
        at(id) {
            if (this.emptyset.contains(id)) {
                return EMPTY_UINT8;
            } else {
                let idx = -1;
                while (this.bucket_keys[idx + 1] <= id) {
                    idx += 1;
                }
                if (idx === -1 || idx >= this.bucket_keys.length) {
                    return undefined;
                } else {
                    const start = this.bucket_keys[idx];
                    const bucket = this.buckets[idx];
                    const data = this.buckets[idx].data;
                    if (data === null) {
                        return this.atAsyncFetch(id, start, bucket);
                    } else {
                        return data[id - start];
                    }
                }
            }
        }
        /**
         * Look up a cell by row ID.
         * @param {number} id
         * @param {number} start
         * @param {{hash: Uint8Array, data: Uint8Array[] | null, end: number}} bucket
         * @returns {Promise<Uint8Array>}
         */
        async atAsyncFetch(id, start, bucket) {
            const {hash, end} = bucket;
            const dataSansEmptysetOrig = await registry.dataLoadByNameAndHash(
                this.name,
                hash,
            );
            // After the `await` resolves, another task might fill
            // in the data. If so, we should use that.
            let data = bucket.data;
            if (data !== null) {
                return data[id - start];
            }
            const dataSansEmptyset = [...dataSansEmptysetOrig];
            /** @type {(Uint8Array[])|null} */
            let dataWithEmptyset = null;
            let pos = start;
            let insertCount = 0;
            while (pos < end) {
                if (this.emptyset.contains(pos)) {
                    if (dataWithEmptyset === null) {
                        dataWithEmptyset = dataSansEmptyset.splice(0, insertCount);
                    } else if (insertCount !== 0) {
                        dataWithEmptyset.push(
                            ...dataSansEmptyset.splice(0, insertCount),
                        );
                    }
                    insertCount = 0;
                    dataWithEmptyset.push(EMPTY_UINT8);
                } else {
                    insertCount += 1;
                }
                pos += 1;
            }
            data = dataWithEmptyset === null ?
                dataSansEmptyset :
                dataWithEmptyset.concat(dataSansEmptyset);
            bucket.data = data;
            return data[id - start];
        }
        /**
         * Search by exact substring
         * @param {Uint8Array|string} name
         * @returns {Promise<Trie?>}
         */
        async search(name) {
            return await (this.searchTree ? this.searchTree.search(name, this) : null);
        }
        /**
         * Search by whole, inexact match
         * @param {Uint8Array|string} name
         * @returns {AsyncGenerator<Trie>}
         */
        async *searchLev(name) {
            if (this.searchTree) {
                yield* this.searchTree.searchLev(name, this);
            }
        }
    }

    class Database {
        /**
         * The primary frontend for accessing data in this index.
         *
         * @param {Map<string, SearchTree>} searchTreeRoots
         * @param {Map<string, DataColumn>} dataColumns
         */
        constructor(searchTreeRoots, dataColumns) {
            this.searchTreeRoots = searchTreeRoots;
            this.dataColumns = dataColumns;
        }
        /**
         * Search a column by name, returning verbatim matched IDs.
         * @param {string} colname
         * @returns {SearchTree|undefined}
         */
        getIndex(colname) {
            return this.searchTreeRoots.get(colname);
        }
        /**
         * Look up a cell by column ID and row ID.
         * @param {string} colname
         * @returns {DataColumn|undefined}
         */
        getData(colname) {
            return this.dataColumns.get(colname);
        }
    }

    /**
     * Load a data column.
     * @param {Uint8Array} data
     */
    function loadColumnFromBytes(data) {
        const hashBuf = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0);
        const truncatedHash = hashBuf.subarray(3, 8);
        siphashOfBytes(data, 0, 0, 0, 0, hashBuf);
        const cb = registry.dataColumnLoadPromiseCallbacks.get(truncatedHash);
        if (cb) {
            const backrefs = [];
            const dataSansEmptyset = [];
            let i = 0;
            const l = data.length;
            while (i < l) {
                let c = data[i];
                if (c >= 48 && c <= 63) { // 48 = "0", 63 = "?"
                    dataSansEmptyset.push(backrefs[c - 48]);
                    i += 1;
                } else {
                    let n = 0;
                    while (c < 96) { // 96 = "`"
                        n = (n << 4) | (c & 0xF);
                        i += 1;
                        c = data[i];
                    }
                    n = (n << 4) | (c & 0xF);
                    i += 1;
                    const item = data.subarray(i, i + n);
                    dataSansEmptyset.push(item);
                    i += n;
                    backrefs.unshift(item);
                    if (backrefs.length > 16) {
                        backrefs.pop();
                    }
                }
            }
            cb(null, dataSansEmptyset);
        }
    }

    /**
     * @param {string} inputBase64
     * @returns {[Uint8Array, SearchTree]}
     */
    function makeSearchTreeFromBase64(inputBase64) {
        const input = makeUint8ArrayFromBase64(inputBase64);
        let i = 0;
        const l = input.length;
        /** @type {HashTable<SearchTree>} */
        const stash = new HashTable();
        const hash = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0);
        const truncatedHash = hash.subarray(3, 8);
        // used for handling compressed (that is, relative-offset) nodes
        /** @type {{hash: Uint8Array, used: boolean}[]} */
        const hash_history = [];
        /** @type {Uint8Array[]} */
        const data_history = [];
        let canonical = EMPTY_UINT8;
        /** @type {SearchTree} */
        let tree = new PrefixSearchTree(
            EMPTY_SEARCH_TREE_BRANCHES,
            EMPTY_SEARCH_TREE_BRANCHES,
            EMPTY_UINT8,
            EMPTY_BITMAP,
            EMPTY_BITMAP,
        );
        /**
         * @param {Uint8Array} input
         * @param {number} i
         * @param {number} compression_tag
         * @returns {{
         *     "might_have_prefix_branches": SearchTreeBranches<SearchTree>,
         *     "branches": SearchTreeBranches<SearchTree>,
         *     "branches_header": Uint8Array,
         *     "cpnodes": Uint8Array,
         *     "csnodes": Uint8Array,
         *     "branches_keys": Uint8Array,
         *     "consumed_len_bytes": number,
         * }}
         */
        function makeBranchesFromBinaryData(
            input,
            i,
            compression_tag,
        ) {
            const is_pure_suffixes_only_node = (compression_tag & 0x01) !== 0x00;
            const is_stack_compressed = (compression_tag & 0x02) !== 0;
            const is_long_compressed = (compression_tag & 0x04) !== 0;
            const all_children_are_compressed =
                (compression_tag & 0xF0) === 0xF0 && !is_long_compressed;
            const any_children_are_compressed =
                (compression_tag & 0xF0) !== 0x00 || is_long_compressed;
            const start_point = i;
            /**
             * @type {Alphabet|null}
             */
            let cpalphabet = null;
            /**
             * @type {Uint8Array}
             */
            let cpalphabitmap = EMPTY_UINT8;
            /**
             * @type {number}
             */
            let cplen;
            /**
             * @type {Alphabet|null}
             */
            let csalphabet = null;
            /**
             * @type {Uint8Array}
             */
            let csalphabitmap = EMPTY_UINT8;
            /**
             * @type {number}
             */
            let cslen;
            // might-have-prefix nodes
            if (is_pure_suffixes_only_node) {
                cplen = 0;
            } else {
                const parsed = Alphabet.parse(i, input);
                if (parsed) {
                    cpalphabitmap = input.subarray(i, i + parsed.consumed_len_bytes);
                    cpalphabet = parsed.alphabet;
                    cplen = parsed.len;
                    i += parsed.consumed_len_bytes;
                } else {
                    cplen = input[i];
                    i += 1;
                }
            }
            // suffix-only nodes
            const parsed = Alphabet.parse(i, input);
            if (parsed) {
                csalphabitmap = input.subarray(i, i + parsed.consumed_len_bytes);
                csalphabet = parsed.alphabet;
                cslen = parsed.len;
                i += parsed.consumed_len_bytes;
            } else {
                cslen = input[i];
                i += 1;
            }
            const branches_header = input.subarray(start_point, i);
            // now process the hashes, offsets, or stack
            let j = 0;
            /** @type {Uint8Array} */
            let cpnodes;
            if (any_children_are_compressed) {
                cpnodes = cplen === 0 ? EMPTY_UINT8 : new Uint8Array(cplen * 5);
                while (j < cplen) {
                    const is_compressed = all_children_are_compressed ||
                        ((0x10 << j) & compression_tag) !== 0;
                    if (is_compressed) {
                        let slot = hash_history.length - 1;
                        if (is_stack_compressed) {
                            while (hash_history[slot].used) {
                                slot -= 1;
                            }
                        } else {
                            slot -= input[i];
                            i += 1;
                        }
                        hash_history[slot].used = true;
                        cpnodes.set(
                            hash_history[slot].hash,
                            j * 5,
                        );
                    } else {
                        const joff = j * 5;
                        cpnodes[joff + 0] = input[i + 0];
                        cpnodes[joff + 1] = input[i + 1];
                        cpnodes[joff + 2] = input[i + 2];
                        cpnodes[joff + 3] = input[i + 3];
                        cpnodes[joff + 4] = input[i + 4];
                        i += 5;
                    }
                    j += 1;
                }
            } else {
                cpnodes = cplen === 0 ? EMPTY_UINT8 : input.subarray(i, i + (cplen * 5));
                i += cplen * 5;
            }
            j = 0;
            /** @type {Uint8Array} */
            let csnodes;
            if (any_children_are_compressed) {
                csnodes = cslen === 0 ? EMPTY_UINT8 : new Uint8Array(cslen * 5);
                while (j < cslen) {
                    const is_compressed = all_children_are_compressed ||
                        ((0x10 << (cplen + j)) & compression_tag) !== 0;
                    if (is_compressed) {
                        let slot = hash_history.length - 1;
                        if (is_stack_compressed) {
                            while (hash_history[slot].used) {
                                slot -= 1;
                            }
                        } else {
                            slot -= input[i];
                            i += 1;
                        }
                        hash_history[slot].used = true;
                        csnodes.set(
                            hash_history[slot].hash,
                            j * 5,
                        );
                    } else {
                        const joff = j * 5;
                        csnodes[joff + 0] = input[i + 0];
                        csnodes[joff + 1] = input[i + 1];
                        csnodes[joff + 2] = input[i + 2];
                        csnodes[joff + 3] = input[i + 3];
                        csnodes[joff + 4] = input[i + 4];
                        i += 5;
                    }
                    j += 1;
                }
            } else {
                csnodes = cslen === 0 ? EMPTY_UINT8 : input.subarray(i, i + (cslen * 5));
                i += cslen * 5;
            }
            const start_point_keys = i;
            let might_have_prefix_branches;
            if (cplen === 0) {
                might_have_prefix_branches = EMPTY_SEARCH_TREE_BRANCHES;
            } else if (cpalphabet) {
                might_have_prefix_branches = new SearchTreeBranchesAlphaBitmap(
                    cpalphabet,
                    cpalphabitmap,
                    cpnodes,
                );
            } else {
                might_have_prefix_branches = new SearchTreeBranchesArray(
                    new Uint8Array(input.buffer, i + input.byteOffset, cplen),
                    cpnodes,
                );
                i += cplen;
            }
            let branches;
            if (cslen === 0) {
                branches = might_have_prefix_branches;
            } else {
                if (csalphabet) {
                    branches = new SearchTreeBranchesAlphaBitmap(
                        csalphabet,
                        csalphabitmap,
                        csnodes,
                    );
                } else {
                    branches = new SearchTreeBranchesArray(
                        new Uint8Array(input.buffer, i + input.byteOffset, cslen),
                        csnodes,
                    );
                    i += cslen;
                }
                if (cplen !== 0) {
                    const hashes = new Uint8Array((cplen + cslen) * 5);
                    if (cplen + cslen > 32) {
                        const raw_bits = new Uint8Array(RAWBYTE_ALPHABET.bytes + 1);
                        raw_bits[0] = RAWBYTE_ALPHABET.flag;
                        const bits = raw_bits.subarray(1);
                        const mhp_keys = might_have_prefix_branches.getKeys();
                        const so_keys = branches.getKeys();
                        let mhp_i = 0;
                        let so_i = 0;
                        let j = 0;
                        while (mhp_i < cplen || so_i < cslen) {
                            if (so_i === cslen || mhp_keys[mhp_i] < so_keys[so_i]) {
                                const joff = j * 5;
                                const mhp_off = mhp_i * 5;
                                hashes[joff + 0] = cpnodes[mhp_off + 0];
                                hashes[joff + 1] = cpnodes[mhp_off + 1];
                                hashes[joff + 2] = cpnodes[mhp_off + 2];
                                hashes[joff + 3] = cpnodes[mhp_off + 3];
                                hashes[joff + 4] = cpnodes[mhp_off + 4];
                                const ix = mhp_keys[mhp_i];
                                bits[ix >> 3] |= 1 << (ix & 0x07);
                                mhp_i += 1;
                            } else {
                                const joff = j * 5;
                                const so_off = so_i * 5;
                                hashes[joff + 0] = csnodes[so_off + 0];
                                hashes[joff + 1] = csnodes[so_off + 1];
                                hashes[joff + 2] = csnodes[so_off + 2];
                                hashes[joff + 3] = csnodes[so_off + 3];
                                hashes[joff + 4] = csnodes[so_off + 4];
                                const ix = so_keys[so_i];
                                bits[ix >> 3] |= 1 << (ix & 0x07);
                                so_i += 1;
                            }
                            j += 1;
                        }
                        branches = new SearchTreeBranchesAlphaBitmap(
                            RAWBYTE_ALPHABET,
                            raw_bits,
                            hashes,
                        );
                    } else {
                        const merged_keys = new Uint8Array(cplen + cslen);
                        const mhp_keys = might_have_prefix_branches.getKeys();
                        const so_keys = branches.getKeys();
                        let mhp_i = 0;
                        let so_i = 0;
                        let j = 0;
                        while (mhp_i < cplen || so_i < cslen) {
                            if (so_i === cslen || mhp_keys[mhp_i] < so_keys[so_i]) {
                                const joff = j * 5;
                                const mhp_off = mhp_i * 5;
                                hashes[joff + 0] = cpnodes[mhp_off + 0];
                                hashes[joff + 1] = cpnodes[mhp_off + 1];
                                hashes[joff + 2] = cpnodes[mhp_off + 2];
                                hashes[joff + 3] = cpnodes[mhp_off + 3];
                                hashes[joff + 4] = cpnodes[mhp_off + 4];
                                merged_keys[j] = mhp_keys[mhp_i];
                                mhp_i += 1;
                            } else {
                                const joff = j * 5;
                                const so_off = so_i * 5;
                                hashes[joff + 0] = csnodes[so_off + 0];
                                hashes[joff + 1] = csnodes[so_off + 1];
                                hashes[joff + 2] = csnodes[so_off + 2];
                                hashes[joff + 3] = csnodes[so_off + 3];
                                hashes[joff + 4] = csnodes[so_off + 4];
                                merged_keys[j] = so_keys[so_i];
                                so_i += 1;
                            }
                            j += 1;
                        }
                        branches = new SearchTreeBranchesArray(
                            merged_keys,
                            hashes,
                        );
                    }
                }
            }
            const branches_keys = input.subarray(start_point_keys, i);
            return {
                consumed_len_bytes: i - start_point,
                cpnodes,
                csnodes,
                branches,
                might_have_prefix_branches,
                branches_header,
                branches_keys,
            };
        }
        while (i < l) {
            const start = i;
            let data;
            // compression_tag = 1 means pure-suffixes-only,
            // which is not considered "compressed" for the purposes of this loop
            // because that's the canonical, hashed version of the data
            let compression_tag = input[i];
            const is_pure_suffixes_only_node = (compression_tag & 0x01) !== 0;
            const is_long_compressed = (compression_tag & 0x04) !== 0;
            const is_data_compressed = (compression_tag & 0x08) !== 0;
            i += 1;
            if (is_long_compressed) {
                compression_tag |= input[i] << 8;
                i += 1;
            }
            /** @type {number} */
            let dlen;
            /** @type {number} */
            let no_leaves_flag;
            /** @type {number} */
            let no_branches_flag;
            if (is_data_compressed && is_pure_suffixes_only_node) {
                dlen = 0;
                no_leaves_flag = 0x80;
                no_branches_flag = 0;
            } else {
                dlen = input[i] & 0x3F;
                no_leaves_flag = input[i] & 0x80;
                no_branches_flag = input[i] & 0x40;
                i += 1;
            }
            if (no_leaves_flag !== 0 && no_branches_flag !== 0) {
                // node with packed leaves and common 16bit prefix
                const leaves_count = (compression_tag >> 4) & 0x07;
                const leaves_is_run = ((compression_tag >> 4) & 0x08) !== 0;
                const branch_flag = is_long_compressed ?
                    (compression_tag >> 8) & 0xff :
                    0;
                if (is_data_compressed) {
                    data = data_history[data_history.length - dlen - 1];
                    dlen = data.length;
                } else if (is_pure_suffixes_only_node) {
                    data = EMPTY_UINT8;
                } else {
                    data = dlen === 0 ?
                        EMPTY_UINT8 :
                        new Uint8Array(input.buffer, i + input.byteOffset, dlen);
                    i += dlen;
                }
                const branches_start = i;
                const branch_flag_alphabet = Alphabet.parseFlag(branch_flag, i, input);
                const branch_count = branch_flag_alphabet ? branch_flag_alphabet.len : branch_flag;
                if (branch_flag_alphabet) {
                    i += branch_flag_alphabet.consumed_len_bytes;
                }
                // leaf_value_upper
                i += 2;
                // branch_nodes
                for (let j = 0; j < branch_count; j += 1) {
                    const branch_dlen = input[i] & 0x0f;
                    const branch_leaves_count = (input[i] >> 4) & 0x0f;
                    const branch_leaves_is_run = (input[i] >> 7) !== 0;
                    i += 1;
                    if (!is_pure_suffixes_only_node) {
                        i += branch_dlen;
                    }
                    if (branch_leaves_is_run) {
                        i += 2;
                    } else {
                        i += branch_leaves_count * 2;
                    }
                }
                // branch keys
                if (!branch_flag_alphabet) {
                    i += branch_count;
                }
                // leaves
                if (leaves_is_run) {
                    i += 2;
                } else {
                    i += leaves_count * 2;
                }
                if (is_data_compressed) {
                    const clen = (
                        1 + // first compression header byte
                        (is_long_compressed ? 1 : 0) + // branch flag
                        1 + // data length and other flags
                        dlen + // data
                        (i - branches_start) // branches and leaves
                    );
                    const canonical = new Uint8Array(clen);
                    let ci = 0;
                    canonical[ci] = input[start] ^ 0x08;
                    ci += 1;
                    if (is_long_compressed) {
                        canonical[ci] = input[start + ci];
                        ci += 1;
                    }
                    canonical[ci] = dlen | 0xc0;
                    ci += 1;
                    for (let j = 0; j < dlen; j += 1) {
                        canonical[ci] = data[j];
                        ci += 1;
                    }
                    for (let j = branches_start; j < i; j += 1) {
                        canonical[ci] = input[j];
                        ci += 1;
                    }
                    tree = new InlineNeighborsTree(canonical, 0);
                    siphashOfBytes(canonical, 0, 0, 0, 0, hash);
                } else {
                    tree = new InlineNeighborsTree(input, start);
                    siphashOfBytes(new Uint8Array(
                        input.buffer,
                        start + input.byteOffset,
                        i - start,
                    ), 0, 0, 0, 0, hash);
                }
            } else if (compression_tag > 1) {
                // compressed node
                if (is_pure_suffixes_only_node) {
                    data = EMPTY_UINT8;
                } else if (is_data_compressed) {
                    data = data_history[data_history.length - dlen - 1];
                    dlen = data.length;
                } else {
                    data = dlen === 0 ?
                        EMPTY_UINT8 :
                        new Uint8Array(input.buffer, i + input.byteOffset, dlen);
                    i += dlen;
                }
                const {
                    cpnodes,
                    csnodes,
                    consumed_len_bytes: branches_consumed_len_bytes,
                    branches,
                    might_have_prefix_branches,
                    branches_header,
                    branches_keys,
                } = no_branches_flag !== 0 ?
                    {
                        cpnodes: EMPTY_UINT8,
                        csnodes: EMPTY_UINT8,
                        consumed_len_bytes: 0,
                        branches: EMPTY_SEARCH_TREE_BRANCHES,
                        might_have_prefix_branches: EMPTY_SEARCH_TREE_BRANCHES,
                        branches_header: EMPTY_UINT8,
                        branches_keys: EMPTY_UINT8,
                    } :
                    makeBranchesFromBinaryData(input, i, compression_tag);
                i += branches_consumed_len_bytes;
                let whole;
                let suffix;
                if (is_pure_suffixes_only_node) {
                    if (no_leaves_flag) {
                        whole = EMPTY_BITMAP;
                        suffix = EMPTY_BITMAP;
                    } else {
                        suffix = input[i] === 0 ?
                            EMPTY_BITMAP1 :
                            new RoaringBitmap(input, i);
                        i += suffix.consumed_len_bytes;
                    }
                    tree = new SuffixSearchTree(
                        branches,
                        dlen,
                        suffix,
                    );
                    const clen = (
                        // lengths of children and data
                        (is_data_compressed ? 1 : 2) +
                        // branches
                        branches_header.length +
                        csnodes.length +
                        branches_keys.length +
                        // leaves
                        suffix.consumed_len_bytes
                    );
                    if (canonical.length < clen) {
                        canonical = new Uint8Array(clen);
                    }
                    let ci = 0;
                    if (is_data_compressed) {
                        canonical[ci] = 0x09;
                        ci += 1;
                    } else {
                        canonical[ci] = 1;
                        ci += 1;
                        canonical[ci] = dlen | no_leaves_flag | no_branches_flag;
                        ci += 1;
                    }
                    canonical.set(branches_header, ci);
                    ci += branches_header.length;
                    canonical.set(csnodes, ci);
                    ci += csnodes.length;
                    canonical.set(branches_keys, ci);
                    ci += branches_keys.length;
                    const leavesOffset = i - suffix.consumed_len_bytes;
                    for (let j = leavesOffset; j < i; j += 1) {
                        canonical[ci + j - leavesOffset] = input[j];
                    }
                    siphashOfBytes(canonical.subarray(0, clen), 0, 0, 0, 0, hash);
                } else {
                    if (no_leaves_flag) {
                        whole = EMPTY_BITMAP;
                        suffix = EMPTY_BITMAP;
                    } else {
                        whole = input[i] === 0 ?
                            EMPTY_BITMAP1 :
                            new RoaringBitmap(input, i);
                        i += whole.consumed_len_bytes;
                        suffix = input[i] === 0 ?
                            EMPTY_BITMAP1 :
                            new RoaringBitmap(input, i);
                        i += suffix.consumed_len_bytes;
                    }
                    tree = new PrefixSearchTree(
                        branches,
                        might_have_prefix_branches,
                        data,
                        whole,
                        suffix,
                    );
                    const clen = (
                        2 + // lengths of children and data
                        dlen +
                        branches_header.length +
                        cpnodes.length + csnodes.length +
                        branches_keys.length +
                        whole.consumed_len_bytes +
                        suffix.consumed_len_bytes
                    );
                    if (canonical.length < clen) {
                        canonical = new Uint8Array(clen);
                    }
                    let ci = 0;
                    canonical[ci] = 0;
                    ci += 1;
                    canonical[ci] = dlen | no_leaves_flag | no_branches_flag;
                    ci += 1;
                    canonical.set(data, ci);
                    ci += data.length;
                    canonical.set(branches_header, ci);
                    ci += branches_header.length;
                    canonical.set(cpnodes, ci);
                    ci += cpnodes.length;
                    canonical.set(csnodes, ci);
                    ci += csnodes.length;
                    canonical.set(branches_keys, ci);
                    ci += branches_keys.length;
                    const leavesOffset = i - whole.consumed_len_bytes - suffix.consumed_len_bytes;
                    for (let j = leavesOffset; j < i; j += 1) {
                        canonical[ci + j - leavesOffset] = input[j];
                    }
                    siphashOfBytes(canonical.subarray(0, clen), 0, 0, 0, 0, hash);
                }
            } else {
                // uncompressed node
                if (dlen === 0 || is_pure_suffixes_only_node) {
                    data = EMPTY_UINT8;
                } else {
                    data = new Uint8Array(input.buffer, i + input.byteOffset, dlen);
                    i += dlen;
                }
                const {
                    consumed_len_bytes: branches_consumed_len_bytes,
                    branches,
                    might_have_prefix_branches,
                } = no_branches_flag !== 0 ?
                    {
                        consumed_len_bytes: 0,
                        branches: EMPTY_SEARCH_TREE_BRANCHES,
                        might_have_prefix_branches: EMPTY_SEARCH_TREE_BRANCHES,
                    } :
                    makeBranchesFromBinaryData(input, i, compression_tag);
                i += branches_consumed_len_bytes;
                let whole;
                let suffix;
                if (no_leaves_flag) {
                    whole = EMPTY_BITMAP;
                    suffix = EMPTY_BITMAP;
                } else if (is_pure_suffixes_only_node) {
                    whole = EMPTY_BITMAP;
                    suffix = input[i] === 0 ?
                        EMPTY_BITMAP1 :
                        new RoaringBitmap(input, i);
                    i += suffix.consumed_len_bytes;
                } else {
                    whole = input[i] === 0 ?
                        EMPTY_BITMAP1 :
                        new RoaringBitmap(input, i);
                    i += whole.consumed_len_bytes;
                    suffix = input[i] === 0 ?
                        EMPTY_BITMAP1 :
                        new RoaringBitmap(input, i);
                    i += suffix.consumed_len_bytes;
                }
                siphashOfBytes(new Uint8Array(
                    input.buffer,
                    start + input.byteOffset,
                    i - start,
                ), 0, 0, 0, 0, hash);
                tree = is_pure_suffixes_only_node ?
                    new SuffixSearchTree(
                        branches,
                        dlen,
                        suffix,
                    ) :
                    new PrefixSearchTree(
                        branches,
                        might_have_prefix_branches,
                        data,
                        whole,
                        suffix,
                    );
            }
            hash[3] &= 0x7f;
            hash_history.push({hash: truncatedHash.slice(), used: false});
            if (data.length !== 0) {
                data_history.push(data);
            }
            if (!(tree instanceof InlineNeighborsTree)) {
                const tree_branch_nodeids = tree.branches.nodeids;
                const tree_branch_subtrees = tree.branches.subtrees;
                let j = 0;
                const lb = tree.branches.subtrees.length;
                while (j < lb) {
                    // node id with a 1 in its most significant bit is inlined, and, so
                    // it won't be in the stash
                    if ((tree_branch_nodeids[j * 5] & 0x80) === 0) {
                        const subtree = stash.getWithOffsetKey(tree_branch_nodeids, j * 5);
                        if (subtree !== undefined) {
                            tree_branch_subtrees[j] = Promise.resolve(subtree);
                        }
                    }
                    j += 1;
                }
            }
            if (tree instanceof PrefixSearchTree) {
                const tree_mhp_branch_nodeids = tree.might_have_prefix_branches.nodeids;
                const tree_mhp_branch_subtrees = tree.might_have_prefix_branches.subtrees;
                let j = 0;
                const lb = tree.might_have_prefix_branches.subtrees.length;
                while (j < lb) {
                    // node id with a 1 in its most significant bit is inlined, and, so
                    // it won't be in the stash
                    if ((tree_mhp_branch_nodeids[j * 5] & 0x80) === 0) {
                        const subtree = stash.getWithOffsetKey(tree_mhp_branch_nodeids, j * 5);
                        if (subtree !== undefined) {
                            tree_mhp_branch_subtrees[j] = Promise.resolve(subtree);
                        }
                    }
                    j += 1;
                }
            }
            if (i !== l) {
                stash.set(truncatedHash, tree);
            }
        }
        return [truncatedHash, tree];
    }

    return new Promise((resolve, reject) => {
        registry.searchTreeRootCallback = (error, data) => {
            if (data) {
                resolve(data);
            } else {
                reject(error);
            }
        };
        hooks.loadRoot(callbacks);
    });
}

if (typeof window !== "undefined") {
    window.Stringdex = {
        loadDatabase,
    };
    window.RoaringBitmap = RoaringBitmap;
    if (window.StringdexOnload) {
        window.StringdexOnload.forEach(cb => cb(window.Stringdex));
    }
} else {
    /** @type {stringdex.Stringdex} */
    // eslint-disable-next-line no-undef
    module.exports.Stringdex = {
        loadDatabase,
    };
    /** @type {stringdex.RoaringBitmap} */
    // eslint-disable-next-line no-undef
    module.exports.RoaringBitmap = RoaringBitmap;
}

// eslint-disable-next-line max-len
// polyfill https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
/**
 * @type {function(string): Uint8Array} base64
 */
//@ts-expect-error
const makeUint8ArrayFromBase64 = Uint8Array.fromBase64 ? Uint8Array.fromBase64 : (string => {
    const bytes_as_string = atob(string);
    const l = bytes_as_string.length;
    const bytes = new Uint8Array(l);
    for (let i = 0; i < l; ++i) {
        bytes[i] = bytes_as_string.charCodeAt(i);
    }
    return bytes;
});
/**
 * @type {function(string): Uint8Array} base64
 */
//@ts-expect-error
const makeUint8ArrayFromHex = Uint8Array.fromHex ? Uint8Array.fromHex : (string => {
    /** @type {Object<string, number>} */
    const alpha = {
        "0": 0, "1": 1,
        "2": 2, "3": 3,
        "4": 4, "5": 5,
        "6": 6, "7": 7,
        "8": 8, "9": 9,
        "a": 10, "b": 11,
        "A": 10, "B": 11,
        "c": 12, "d": 13,
        "C": 12, "D": 13,
        "e": 14, "f": 15,
        "E": 14, "F": 15,
    };
    const l = string.length >> 1;
    const bytes = new Uint8Array(l);
    for (let i = 0; i < l; i += 1) {
        const top = string[i << 1];
        const bottom = string[(i << 1) + 1];
        bytes[i] = (alpha[top] << 4) | alpha[bottom];
    }
    return bytes;
});

/**
 * @type {function(Uint8Array): string} base64
 */
//@ts-expect-error
const makeHexFromUint8Array = Uint8Array.prototype.toHex ? (array => array.toHex()) : (array => {
    /** @type {string[]} */
    const alpha = [
        "0", "1",
        "2", "3",
        "4", "5",
        "6", "7",
        "8", "9",
        "a", "b",
        "c", "d",
        "e", "f",
    ];
    const l = array.length;
    const v = [];
    for (let i = 0; i < l; ++i) {
        v.push(alpha[array[i] >> 4]);
        v.push(alpha[array[i] & 0xf]);
    }
    return v.join("");
});

//////////////

/**
 * SipHash 1-3
 * @param {Uint8Array} input data to be hashed; all codepoints in string should be less than 256
 * @param {number} k0lo first word of key
 * @param {number} k0hi second word of key
 * @param {number} k1lo third word of key
 * @param {number} k1hi fourth word of key
 * @param {Uint8Array} output the data to write (clobber the first eight bytes)
 */
function siphashOfBytes(input, k0lo, k0hi, k1lo, k1hi, output) {
    // hash state
    // While siphash uses 64 bit state, js only has native support
    // for 32 bit numbers. BigInt, unfortunately, doesn't count.
    // It's too slow.
    let v0lo = k0lo ^ 0x70736575;
    let v0hi = k0hi ^ 0x736f6d65;
    let v1lo = k1lo ^ 0x6e646f6d;
    let v1hi = k1hi ^ 0x646f7261;
    let v2lo = k0lo ^ 0x6e657261;
    let v2hi = k0hi ^ 0x6c796765;
    let v3lo = k1lo ^ 0x79746573;
    let v3hi = k1hi ^ 0x74656462;
    const inputLength = input.length;
    let inputI = 0;
    // main hash loop
    const left = inputLength & 0x7;
    let milo = 0;
    let mihi = 0;
    while (inputI < inputLength - left) {
        u8ToU64le(inputI, inputI + 8);
        v3lo ^= milo;
        v3hi ^= mihi;
        siphashCompress();
        v0lo ^= milo;
        v0hi ^= mihi;
        inputI += 8;
    }
    u8ToU64le(inputI, inputI + left);
    // finish
    const blo = milo;
    const bhi = ((inputLength & 0xff) << 24) | mihi;
    v3lo ^= blo;
    v3hi ^= bhi;
    siphashCompress();
    v0lo ^= blo;
    v0hi ^= bhi;
    v2lo ^= 0xff;
    siphashCompress();
    siphashCompress();
    siphashCompress();
    output[7] = (v0lo ^ v1lo ^ v2lo ^ v3lo) & 0xff;
    output[6] = (v0lo ^ v1lo ^ v2lo ^ v3lo) >>> 8;
    output[5] = (v0lo ^ v1lo ^ v2lo ^ v3lo) >>> 16;
    output[4] = (v0lo ^ v1lo ^ v2lo ^ v3lo) >>> 24;
    output[3] = (v0hi ^ v1hi ^ v2hi ^ v3hi) & 0xff;
    output[2] = (v0hi ^ v1hi ^ v2hi ^ v3hi) >>> 8;
    output[1] = (v0hi ^ v1hi ^ v2hi ^ v3hi) >>> 16;
    output[0] = (v0hi ^ v1hi ^ v2hi ^ v3hi) >>> 24;
    /**
     * Convert eight bytes to a single 64-bit number
     * @param {number} offset
     * @param {number} length
     */
    function u8ToU64le(offset, length) {
        const n0 = offset < length ? input[offset] & 0xff : 0;
        const n1 = offset + 1 < length ? input[offset + 1] & 0xff : 0;
        const n2 = offset + 2 < length ? input[offset + 2] & 0xff : 0;
        const n3 = offset + 3 < length ? input[offset + 3] & 0xff : 0;
        const n4 = offset + 4 < length ? input[offset + 4] & 0xff : 0;
        const n5 = offset + 5 < length ? input[offset + 5] & 0xff : 0;
        const n6 = offset + 6 < length ? input[offset + 6] & 0xff : 0;
        const n7 = offset + 7 < length ? input[offset + 7] & 0xff : 0;
        milo = n0 | (n1 << 8) | (n2 << 16) | (n3 << 24);
        mihi = n4 | (n5 << 8) | (n6 << 16) | (n7 << 24);
    }
    function siphashCompress() {
        // v0 += v1;
        v0hi = (v0hi + v1hi + (((v0lo >>> 0) + (v1lo >>> 0) > 0xffffffff) ? 1 : 0)) | 0;
        v0lo = (v0lo + v1lo) | 0;
        // rotl(v1, 13)
        let v1lo_ = v1lo;
        let v1hi_ = v1hi;
        v1lo = (v1lo_ << 13) | (v1hi_ >>> 19);
        v1hi = (v1hi_ << 13) | (v1lo_ >>> 19);
        // v1 ^= v0
        v1lo ^= v0lo;
        v1hi ^= v0hi;
        // rotl(v0, 32)
        const v0lo_ = v0lo;
        const v0hi_ = v0hi;
        v0lo = v0hi_;
        v0hi = v0lo_;
        // v2 += v3
        v2hi = (v2hi + v3hi + (((v2lo >>> 0) + (v3lo >>> 0) > 0xffffffff) ? 1 : 0)) | 0;
        v2lo = (v2lo + v3lo) | 0;
        // rotl(v3, 16)
        let v3lo_ = v3lo;
        let v3hi_ = v3hi;
        v3lo = (v3lo_ << 16) | (v3hi_ >>> 16);
        v3hi = (v3hi_ << 16) | (v3lo_ >>> 16);
        // v3 ^= v2
        v3lo ^= v2lo;
        v3hi ^= v2hi;
        // v0 += v3
        v0hi = (v0hi + v3hi + (((v0lo >>> 0) + (v3lo >>> 0) > 0xffffffff) ? 1 : 0)) | 0;
        v0lo = (v0lo + v3lo) | 0;
        // rotl(v3, 21)
        v3lo_ = v3lo;
        v3hi_ = v3hi;
        v3lo = (v3lo_ << 21) | (v3hi_ >>> 11);
        v3hi = (v3hi_ << 21) | (v3lo_ >>> 11);
        // v3 ^= v0
        v3lo ^= v0lo;
        v3hi ^= v0hi;
        // v2 += v1
        v2hi = (v2hi + v1hi + (((v2lo >>> 0) + (v1lo >>> 0) > 0xffffffff) ? 1 : 0)) | 0;
        v2lo = (v2lo + v1lo) | 0;
        // rotl(v1, 17)
        v1lo_ = v1lo;
        v1hi_ = v1hi;
        v1lo = (v1lo_ << 17) | (v1hi_ >>> 15);
        v1hi = (v1hi_ << 17) | (v1lo_ >>> 15);
        // v1 ^= v2
        v1lo ^= v2lo;
        v1hi ^= v2hi;
        // rotl(v2, 32)
        const v2lo_ = v2lo;
        const v2hi_ = v2hi;
        v2lo = v2hi_;
        v2hi = v2lo_;
    }
}

//////////////


// Parts of this code are based on Lucene, which is licensed under the
// Apache/2.0 license.
// More information found here:
// https://fossies.org/linux/lucene/lucene/core/src/java/org/apache/lucene/util/automaton/
//   LevenshteinAutomata.java
class ParametricDescription {
    /**
     * @param {number} w
     * @param {number} n
     * @param {Int32Array} minErrors
     */
    constructor(w, n, minErrors) {
        this.w = w;
        this.n = n;
        this.minErrors = minErrors;
    }
    /**
     * @param {number} absState
     * @returns {boolean}
     */
    isAccept(absState) {
        const state = Math.floor(absState / (this.w + 1));
        const offset = absState % (this.w + 1);
        return this.w - offset + this.minErrors[state] <= this.n;
    }
    /**
     * @param {number} absState
     * @returns {number}
     */
    getPosition(absState) {
        return absState % (this.w + 1);
    }
    /**
     * @param {Uint8Array} name
     * @param {number} charCode
     * @param {number} pos
     * @param {number} end
     * @returns {number}
     */
    getVector(name, charCode, pos, end) {
        let vector = 0;
        for (let i = pos; i < end; i += 1) {
            vector = vector << 1;
            if (name[i] === charCode) {
                vector |= 1;
            }
        }
        return vector;
    }
    /**
     * @param {Int32Array} data
     * @param {number} index
     * @param {number} bitsPerValue
     * @returns {number}
     */
    unpack(data, index, bitsPerValue) {
        const bitLoc = (bitsPerValue * index);
        const dataLoc = bitLoc >> 5;
        const bitStart = bitLoc & 31;
        if (bitStart + bitsPerValue <= 32) {
            // not split
            return ((data[dataLoc] >> bitStart) & this.MASKS[bitsPerValue - 1]);
        } else {
            // split
            const part = 32 - bitStart;
            return ~~(((data[dataLoc] >> bitStart) & this.MASKS[part - 1]) +
                ((data[1 + dataLoc] & this.MASKS[bitsPerValue - part - 1]) << part));
        }
    }
}
ParametricDescription.prototype.MASKS = new Int32Array([
    0x1, 0x3, 0x7, 0xF,
    0x1F, 0x3F, 0x7F, 0xFF,
    0x1FF, 0x3F, 0x7FF, 0xFFF,
    0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
    0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
    0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
    0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
    0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
]);

// The following code was generated with the moman/finenight pkg
// This package is available under the MIT License, see NOTICE.txt
// for more details.
// This class is auto-generated, Please do not modify it directly.
// You should modify the https://gitlab.com/notriddle/createAutomata.py instead.
// The following code was generated with the moman/finenight pkg
// This package is available under the MIT License, see NOTICE.txt
// for more details.
// This class is auto-generated, Please do not modify it directly.
// You should modify https://gitlab.com/notriddle/moman-rustdoc instead.

class Lev2TParametricDescription extends ParametricDescription {
    /**
     * @param {number} absState
     * @param {number} position
     * @param {number} vector
     * @returns {number}
    */
    transition(absState, position, vector) {
        let state = Math.floor(absState / (this.w + 1));
        let offset = absState % (this.w + 1);

        if (position === this.w) {
            if (state < 3) {
                const loc = Math.imul(vector, 3) + state;
                offset += this.unpack(this.offsetIncrs0, loc, 1);
                state = this.unpack(this.toStates0, loc, 2) - 1;
            }
        } else if (position === this.w - 1) {
            if (state < 5) {
                const loc = Math.imul(vector, 5) + state;
                offset += this.unpack(this.offsetIncrs1, loc, 1);
                state = this.unpack(this.toStates1, loc, 3) - 1;
            }
        } else if (position === this.w - 2) {
            if (state < 13) {
                const loc = Math.imul(vector, 13) + state;
                offset += this.unpack(this.offsetIncrs2, loc, 2);
                state = this.unpack(this.toStates2, loc, 4) - 1;
            }
        } else if (position === this.w - 3) {
            if (state < 28) {
                const loc = Math.imul(vector, 28) + state;
                offset += this.unpack(this.offsetIncrs3, loc, 2);
                state = this.unpack(this.toStates3, loc, 5) - 1;
            }
        } else if (position === this.w - 4) {
            if (state < 45) {
                const loc = Math.imul(vector, 45) + state;
                offset += this.unpack(this.offsetIncrs4, loc, 3);
                state = this.unpack(this.toStates4, loc, 6) - 1;
            }
        } else {
            // eslint-disable-next-line no-lonely-if
            if (state < 45) {
                const loc = Math.imul(vector, 45) + state;
                offset += this.unpack(this.offsetIncrs5, loc, 3);
                state = this.unpack(this.toStates5, loc, 6) - 1;
            }
        }

        if (state === -1) {
            // null state
            return -1;
        } else {
            // translate back to abs
            return Math.imul(state, this.w + 1) + offset;
        }
    }

    // state map
    //   0 -> [(0, 0)]
    //   1 -> [(0, 1)]
    //   2 -> [(0, 2)]
    //   3 -> [(0, 1), (1, 1)]
    //   4 -> [(0, 2), (1, 2)]
    //   5 -> [(0, 1), (1, 1), (2, 1)]
    //   6 -> [(0, 2), (1, 2), (2, 2)]
    //   7 -> [(0, 1), (2, 1)]
    //   8 -> [(0, 1), (2, 2)]
    //   9 -> [(0, 2), (2, 1)]
    //   10 -> [(0, 2), (2, 2)]
    //   11 -> [t(0, 1), (0, 1), (1, 1), (2, 1)]
    //   12 -> [t(0, 2), (0, 2), (1, 2), (2, 2)]
    //   13 -> [(0, 2), (1, 2), (2, 2), (3, 2)]
    //   14 -> [(0, 1), (1, 1), (3, 2)]
    //   15 -> [(0, 1), (2, 2), (3, 2)]
    //   16 -> [(0, 1), (3, 2)]
    //   17 -> [(0, 1), t(1, 2), (2, 2), (3, 2)]
    //   18 -> [(0, 2), (1, 2), (3, 1)]
    //   19 -> [(0, 2), (1, 2), (3, 2)]
    //   20 -> [(0, 2), (1, 2), t(1, 2), (2, 2), (3, 2)]
    //   21 -> [(0, 2), (2, 1), (3, 1)]
    //   22 -> [(0, 2), (2, 2), (3, 2)]
    //   23 -> [(0, 2), (3, 1)]
    //   24 -> [(0, 2), (3, 2)]
    //   25 -> [(0, 2), t(1, 2), (1, 2), (2, 2), (3, 2)]
    //   26 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (3, 2)]
    //   27 -> [t(0, 2), (0, 2), (1, 2), (3, 1)]
    //   28 -> [(0, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
    //   29 -> [(0, 2), (1, 2), (2, 2), (4, 2)]
    //   30 -> [(0, 2), (1, 2), (2, 2), t(2, 2), (3, 2), (4, 2)]
    //   31 -> [(0, 2), (1, 2), (3, 2), (4, 2)]
    //   32 -> [(0, 2), (1, 2), (4, 2)]
    //   33 -> [(0, 2), (1, 2), t(1, 2), (2, 2), (3, 2), (4, 2)]
    //   34 -> [(0, 2), (1, 2), t(2, 2), (2, 2), (3, 2), (4, 2)]
    //   35 -> [(0, 2), (2, 1), (4, 2)]
    //   36 -> [(0, 2), (2, 2), (3, 2), (4, 2)]
    //   37 -> [(0, 2), (2, 2), (4, 2)]
    //   38 -> [(0, 2), (3, 2), (4, 2)]
    //   39 -> [(0, 2), (4, 2)]
    //   40 -> [(0, 2), t(1, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
    //   41 -> [(0, 2), t(2, 2), (2, 2), (3, 2), (4, 2)]
    //   42 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
    //   43 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (4, 2)]
    //   44 -> [t(0, 2), (0, 2), (1, 2), (2, 2), t(2, 2), (3, 2), (4, 2)]


    /** @param {number} w - length of word being checked */
    constructor(w) {
        super(w, 2, new Int32Array([
            0,1,2,0,1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,-2,-1,-1,-2,-1,-2,
            -1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
        ]));
    }
}

Lev2TParametricDescription.prototype.toStates0 = /*2 bits per value */ new Int32Array([
    0xe,
]);
Lev2TParametricDescription.prototype.offsetIncrs0 = /*1 bits per value */ new Int32Array([
    0x0,
]);

Lev2TParametricDescription.prototype.toStates1 = /*3 bits per value */ new Int32Array([
    0x1a688a2c,
]);
Lev2TParametricDescription.prototype.offsetIncrs1 = /*1 bits per value */ new Int32Array([
    0x3e0,
]);

Lev2TParametricDescription.prototype.toStates2 = /*4 bits per value */ new Int32Array([
    0x70707054,0xdc07035,0x3dd3a3a,0x2323213a,
    0x15435223,0x22545432,0x5435,
]);
Lev2TParametricDescription.prototype.offsetIncrs2 = /*2 bits per value */ new Int32Array([
    0x80000,0x55582088,0x55555555,0x55,
]);

Lev2TParametricDescription.prototype.toStates3 = /*5 bits per value */ new Int32Array([
    0x1c0380a4,0x700a570,0xca529c0,0x180a00,
    0xa80af180,0xc5498e60,0x5a546398,0x8c4300e8,
    0xac18c601,0xd8d43501,0x863500ad,0x51976d6a,
    0x8ca0180a,0xc3501ac2,0xb0c5be16,0x76dda8a5,
    0x18c4519,0xc41294a,0xe248d231,0x1086520c,
    0xce31ac42,0x13946358,0x2d0348c4,0x6732d494,
    0x1ad224a5,0xd635ad4b,0x520c4139,0xce24948,
    0x22110a52,0x58ce729d,0xc41394e3,0x941cc520,
    0x90e732d4,0x4729d224,0x39ce35ad,
]);
Lev2TParametricDescription.prototype.offsetIncrs3 = /*2 bits per value */ new Int32Array([
    0x80000,0xc0c830,0x300f3c30,0x2200fcff,
    0xcaa00a08,0x3c2200a8,0xa8fea00a,0x55555555,
    0x55555555,0x55555555,0x55555555,0x55555555,
    0x55555555,0x55555555,
]);

Lev2TParametricDescription.prototype.toStates4 = /*6 bits per value */ new Int32Array([
    0x801c0144,0x1453803,0x14700038,0xc0005145,
    0x1401,0x14,0x140000,0x0,
    0x510000,0x6301f007,0x301f00d1,0xa186178,
    0xc20ca0c3,0xc20c30,0xc30030c,0xc00c00cd,
    0xf0c00c30,0x4c054014,0xc30944c3,0x55150c34,
    0x8300550,0x430c0143,0x50c31,0xc30850c,
    0xc3143000,0x50053c50,0x5130d301,0x850d30c2,
    0x30a08608,0xc214414,0x43142145,0x21450031,
    0x1400c314,0x4c143145,0x32832803,0x28014d6c,
    0xcd34a0c3,0x1c50c76,0x1c314014,0x430c30c3,
    0x1431,0xc300500,0xca00d303,0xd36d0e40,
    0x90b0e400,0xcb2abb2c,0x70c20ca1,0x2c32ca2c,
    0xcd2c70cb,0x31c00c00,0x34c2c32c,0x5583280,
    0x558309b7,0x6cd6ca14,0x430850c7,0x51c51401,
    0x1430c714,0xc3087,0x71451450,0xca00d30,
    0xc26dc156,0xb9071560,0x1cb2abb2,0xc70c2144,
    0xb1c51ca1,0x1421c70c,0xc51c00c3,0x30811c51,
    0x24324308,0xc51031c2,0x70820820,0x5c33830d,
    0xc33850c3,0x30c30c30,0xc30c31c,0x451450c3,
    0x20c20c20,0xda0920d,0x5145914f,0x36596114,
    0x51965865,0xd9643653,0x365a6590,0x51964364,
    0x43081505,0x920b2032,0x2c718b28,0xd7242249,
    0x35cb28b0,0x2cb3872c,0x972c30d7,0xb0c32cb2,
    0x4e1c75c,0xc80c90c2,0x62ca2482,0x4504171c,
    0xd65d9610,0x33976585,0xd95cb5d,0x4b5ca5d7,
    0x73975c36,0x10308138,0xc2245105,0x41451031,
    0x14e24208,0xc35c3387,0x51453851,0x1c51c514,
    0xc70c30c3,0x20451450,0x14f1440c,0x4f0da092,
    0x4513d41,0x6533944d,0x1350e658,0xe1545055,
    0x64365a50,0x5519383,0x51030815,0x28920718,
    0x441c718b,0x714e2422,0x1c35cb28,0x4e1c7387,
    0xb28e1c51,0x5c70c32c,0xc204e1c7,0x81c61440,
    0x1c62ca24,0xd04503ce,0x85d63944,0x39338e65,
    0x8e154387,0x364b5ca3,0x38739738,
]);
Lev2TParametricDescription.prototype.offsetIncrs4 = /*3 bits per value */ new Int32Array([
    0x10000000,0xc00000,0x60061,0x400,
    0x0,0x80010008,0x249248a4,0x8229048,
    0x2092,0x6c3603,0xb61b6c30,0x6db6036d,
    0xdb6c0,0x361b0180,0x91b72000,0xdb11b71b,
    0x6db6236,0x1008200,0x12480012,0x24924906,
    0x48200049,0x80410002,0x24000900,0x4924a489,
    0x10822492,0x20800125,0x48360,0x9241b692,
    0x6da4924,0x40009268,0x241b010,0x291b4900,
    0x6d249249,0x49493423,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x2492,
]);

Lev2TParametricDescription.prototype.toStates5 = /*6 bits per value */ new Int32Array([
    0x801c0144,0x1453803,0x14700038,0xc0005145,
    0x1401,0x14,0x140000,0x0,
    0x510000,0x4e00e007,0xe0051,0x3451451c,
    0xd015000,0x30cd0000,0xc30c30c,0xc30c30d4,
    0x40c30c30,0x7c01c014,0xc03458c0,0x185e0c07,
    0x2830c286,0x830c3083,0xc30030,0x33430c,
    0x30c3003,0x70051030,0x16301f00,0x8301f00d,
    0x30a18617,0xc20ca0c,0x431420c3,0xb1450c51,
    0x14314315,0x4f143145,0x34c05401,0x4c30944c,
    0x55150c3,0x30830055,0x1430c014,0xc00050c3,
    0xc30850,0xc314300,0x150053c5,0x25130d30,
    0x5430d30c,0xc0354154,0x300d0c90,0x1cb2cd0c,
    0xc91cb0c3,0x72c30cb2,0x14f1cb2c,0xc34c0540,
    0x34c30944,0x82182214,0x851050c2,0x50851430,
    0x1400c50c,0x30c5085,0x50c51450,0x150053c,
    0xc25130d3,0x8850d30,0x1430a086,0x450c2144,
    0x51cb1c21,0x1c91c70c,0xc71c314b,0x34c1cb1,
    0x6c328328,0xc328014d,0x76cd34a0,0x1401c50c,
    0xc31c3140,0x31430c30,0x14,0x30c3005,
    0xa0ca00d3,0x535b0c,0x4d2830ca,0x514369b3,
    0xc500d01,0x5965965a,0x30d46546,0x6435030c,
    0x8034c659,0xdb439032,0x2c390034,0xcaaecb24,
    0x30832872,0xcb28b1c,0x4b1c32cb,0x70030033,
    0x30b0cb0c,0xe40ca00d,0x400d36d0,0xb2c90b0e,
    0xca1cb2ab,0xa2c70c20,0x6575d95c,0x4315b5ce,
    0x95c53831,0x28034c5d,0x9b705583,0xa1455830,
    0xc76cd6c,0x40143085,0x71451c51,0x871430c,
    0x450000c3,0xd3071451,0x1560ca00,0x560c26dc,
    0xb35b2851,0xc914369,0x1a14500d,0x46593945,
    0xcb2c939,0x94507503,0x328034c3,0x9b70558,
    0xe41c5583,0x72caaeca,0x1c308510,0xc7147287,
    0x50871c32,0x1470030c,0xd307147,0xc1560ca0,
    0x1560c26d,0xabb2b907,0x21441cb2,0x38a1c70c,
    0x8e657394,0x314b1c93,0x39438738,0x43083081,
    0x31c22432,0x820c510,0x830d7082,0x50c35c33,
    0xc30c338,0xc31c30c3,0x50c30c30,0xc204514,
    0x890c90c2,0x31440c70,0xa8208208,0xea0df0c3,
    0x8a231430,0xa28a28a2,0x28a28a1e,0x1861868a,
    0x48308308,0xc3682483,0x14516453,0x4d965845,
    0xd4659619,0x36590d94,0xd969964,0x546590d9,
    0x20c20541,0x920d20c,0x5914f0da,0x96114514,
    0x65865365,0xe89d3519,0x99e7a279,0x9e89e89e,
    0x81821827,0xb2032430,0x18b28920,0x422492c7,
    0xb28b0d72,0x3872c35c,0xc30d72cb,0x32cb2972,
    0x1c75cb0c,0xc90c204e,0xa2482c80,0x24b1c62c,
    0xc3a89089,0xb0ea2e42,0x9669a31c,0xa4966a28,
    0x59a8a269,0x8175e7a,0xb203243,0x718b2892,
    0x4114105c,0x17597658,0x74ce5d96,0x5c36572d,
    0xd92d7297,0xe1ce5d70,0xc90c204,0xca2482c8,
    0x4171c62,0x5d961045,0x976585d6,0x79669533,
    0x964965a2,0x659689e6,0x308175e7,0x24510510,
    0x451031c2,0xe2420841,0x5c338714,0x453851c3,
    0x51c51451,0xc30c31c,0x451450c7,0x41440c20,
    0xc708914,0x82105144,0xf1c58c90,0x1470ea0d,
    0x61861863,0x8a1e85e8,0x8687a8a2,0x3081861,
    0x24853c51,0x5053c368,0x1341144f,0x96194ce5,
    0x1544d439,0x94385514,0xe0d90d96,0x5415464,
    0x4f1440c2,0xf0da0921,0x4513d414,0x533944d0,
    0x350e6586,0x86082181,0xe89e981d,0x18277689,
    0x10308182,0x89207185,0x41c718b2,0x14e24224,
    0xc35cb287,0xe1c73871,0x28e1c514,0xc70c32cb,
    0x204e1c75,0x1c61440c,0xc62ca248,0x90891071,
    0x2e41c58c,0xa31c70ea,0xe86175e7,0xa269a475,
    0x5e7a57a8,0x51030817,0x28920718,0xf38718b,
    0xe5134114,0x39961758,0xe1ce4ce,0x728e3855,
    0x5ce0d92d,0xc204e1ce,0x81c61440,0x1c62ca24,
    0xd04503ce,0x85d63944,0x75338e65,0x5d86075e,
    0x89e69647,0x75e76576,
]);
Lev2TParametricDescription.prototype.offsetIncrs5 = /*3 bits per value */ new Int32Array([
    0x10000000,0xc00000,0x60061,0x400,
    0x0,0x60000008,0x6b003080,0xdb6ab6db,
    0x2db6,0x800400,0x49245240,0x11482412,
    0x104904,0x40020000,0x92292000,0xa4b25924,
    0x9649658,0xd80c000,0xdb0c001b,0x80db6d86,
    0x6db01b6d,0xc0600003,0x86000d86,0x6db6c36d,
    0xddadb6ed,0x300001b6,0x6c360,0xe37236e4,
    0x46db6236,0xdb6c,0x361b018,0xb91b7200,
    0x6dbb1b71,0x6db763,0x20100820,0x61248001,
    0x92492490,0x24820004,0x8041000,0x92400090,
    0x24924830,0x555b6a49,0x2080012,0x20004804,
    0x49252449,0x84112492,0x4000928,0x240201,
    0x92922490,0x58924924,0x49456,0x120d8082,
    0x6da4800,0x69249249,0x249a01b,0x6c04100,
    0x6d240009,0x92492483,0x24d5adb4,0x60208001,
    0x92000483,0x24925236,0x6846da49,0x10400092,
    0x241b0,0x49291b49,0x636d2492,0x92494935,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,0x49249249,
    0x92492492,0x24924924,0x49249249,0x92492492,
    0x24924924,0x49249249,0x92492492,0x24924924,
    0x49249249,0x92492492,0x24924924,
]);

class Lev1TParametricDescription extends ParametricDescription {
    /**
     * @param {number} absState
     * @param {number} position
     * @param {number} vector
     * @returns {number}
    */
    transition(absState, position, vector) {
        let state = Math.floor(absState / (this.w + 1));
        let offset = absState % (this.w + 1);

        if (position === this.w) {
            if (state < 2) {
                const loc = Math.imul(vector, 2) + state;
                offset += this.unpack(this.offsetIncrs0, loc, 1);
                state = this.unpack(this.toStates0, loc, 2) - 1;
            }
        } else if (position === this.w - 1) {
            if (state < 3) {
                const loc = Math.imul(vector, 3) + state;
                offset += this.unpack(this.offsetIncrs1, loc, 1);
                state = this.unpack(this.toStates1, loc, 2) - 1;
            }
        } else if (position === this.w - 2) {
            if (state < 6) {
                const loc = Math.imul(vector, 6) + state;
                offset += this.unpack(this.offsetIncrs2, loc, 2);
                state = this.unpack(this.toStates2, loc, 3) - 1;
            }
        } else {
            // eslint-disable-next-line no-lonely-if
            if (state < 6) {
                const loc = Math.imul(vector, 6) + state;
                offset += this.unpack(this.offsetIncrs3, loc, 2);
                state = this.unpack(this.toStates3, loc, 3) - 1;
            }
        }

        if (state === -1) {
            // null state
            return -1;
        } else {
            // translate back to abs
            return Math.imul(state, this.w + 1) + offset;
        }
    }

    // state map
    //   0 -> [(0, 0)]
    //   1 -> [(0, 1)]
    //   2 -> [(0, 1), (1, 1)]
    //   3 -> [(0, 1), (1, 1), (2, 1)]
    //   4 -> [(0, 1), (2, 1)]
    //   5 -> [t(0, 1), (0, 1), (1, 1), (2, 1)]


    /** @param {number} w - length of word being checked */
    constructor(w) {
        super(w, 1, new Int32Array([0,1,0,-1,-1,-1]));
    }
}

Lev1TParametricDescription.prototype.toStates0 = /*2 bits per value */ new Int32Array([
    0x2,
]);
Lev1TParametricDescription.prototype.offsetIncrs0 = /*1 bits per value */ new Int32Array([
    0x0,
]);

Lev1TParametricDescription.prototype.toStates1 = /*2 bits per value */ new Int32Array([
    0xa43,
]);
Lev1TParametricDescription.prototype.offsetIncrs1 = /*1 bits per value */ new Int32Array([
    0x38,
]);

Lev1TParametricDescription.prototype.toStates2 = /*3 bits per value */ new Int32Array([
    0x12180003,0xb45a4914,0x69,
]);
Lev1TParametricDescription.prototype.offsetIncrs2 = /*2 bits per value */ new Int32Array([
    0x558a0000,0x5555,
]);

Lev1TParametricDescription.prototype.toStates3 = /*3 bits per value */ new Int32Array([
    0x900c0003,0xa1904864,0x45a49169,0x5a6d196a,
    0x9634,
]);
Lev1TParametricDescription.prototype.offsetIncrs3 = /*2 bits per value */ new Int32Array([
    0xa0fc0000,0x5555ba08,0x55555555,
]);
