(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sourcemapCodec = {}));
})(this, (function (exports) { 'use strict';

    const comma = ','.charCodeAt(0);
    const semicolon = ';'.charCodeAt(0);
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    const intToChar = new Uint8Array(64); // 64 possible chars.
    const charToInt = new Uint8Array(128); // z is 122 in ASCII
    for (let i = 0; i < chars.length; i++) {
        const c = chars.charCodeAt(i);
        intToChar[i] = c;
        charToInt[c] = i;
    }
    function decodeInteger(reader, relative) {
        let value = 0;
        let shift = 0;
        let integer = 0;
        do {
            const c = reader.next();
            integer = charToInt[c];
            value |= (integer & 31) << shift;
            shift += 5;
        } while (integer & 32);
        const shouldNegate = value & 1;
        value >>>= 1;
        if (shouldNegate) {
            value = -0x80000000 | -value;
        }
        return relative + value;
    }
    function encodeInteger(builder, num, relative) {
        let delta = num - relative;
        delta = delta < 0 ? (-delta << 1) | 1 : delta << 1;
        do {
            let clamped = delta & 0b011111;
            delta >>>= 5;
            if (delta > 0)
                clamped |= 0b100000;
            builder.write(intToChar[clamped]);
        } while (delta > 0);
        return num;
    }
    function hasMoreVlq(reader, max) {
        if (reader.pos >= max)
            return false;
        return reader.peek() !== comma;
    }

    const bufLength = 1024 * 16;
    // Provide a fallback for older environments.
    const td = typeof TextDecoder !== 'undefined'
        ? /* #__PURE__ */ new TextDecoder()
        : typeof Buffer !== 'undefined'
            ? {
                decode(buf) {
                    const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
                    return out.toString();
                },
            }
            : {
                decode(buf) {
                    let out = '';
                    for (let i = 0; i < buf.length; i++) {
                        out += String.fromCharCode(buf[i]);
                    }
                    return out;
                },
            };
    class StringWriter {
        constructor() {
            this.pos = 0;
            this.out = '';
            this.buffer = new Uint8Array(bufLength);
        }
        write(v) {
            const { buffer } = this;
            buffer[this.pos++] = v;
            if (this.pos === bufLength) {
                this.out += td.decode(buffer);
                this.pos = 0;
            }
        }
        flush() {
            const { buffer, out, pos } = this;
            return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
        }
    }
    class StringReader {
        constructor(buffer) {
            this.pos = 0;
            this.buffer = buffer;
        }
        next() {
            return this.buffer.charCodeAt(this.pos++);
        }
        peek() {
            return this.buffer.charCodeAt(this.pos);
        }
        indexOf(char) {
            const { buffer, pos } = this;
            const idx = buffer.indexOf(char, pos);
            return idx === -1 ? buffer.length : idx;
        }
    }

    const EMPTY = [];
    function decodeOriginalScopes(input) {
        const { length } = input;
        const reader = new StringReader(input);
        const scopes = [];
        const stack = [];
        let line = 0;
        for (; reader.pos < length; reader.pos++) {
            line = decodeInteger(reader, line);
            const column = decodeInteger(reader, 0);
            if (!hasMoreVlq(reader, length)) {
                const last = stack.pop();
                last[2] = line;
                last[3] = column;
                continue;
            }
            const kind = decodeInteger(reader, 0);
            const fields = decodeInteger(reader, 0);
            const hasName = fields & 0b0001;
            const scope = (hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]);
            let vars = EMPTY;
            if (hasMoreVlq(reader, length)) {
                vars = [];
                do {
                    const varsIndex = decodeInteger(reader, 0);
                    vars.push(varsIndex);
                } while (hasMoreVlq(reader, length));
            }
            scope.vars = vars;
            scopes.push(scope);
            stack.push(scope);
        }
        return scopes;
    }
    function encodeOriginalScopes(scopes) {
        const writer = new StringWriter();
        for (let i = 0; i < scopes.length;) {
            i = _encodeOriginalScopes(scopes, i, writer, [0]);
        }
        return writer.flush();
    }
    function _encodeOriginalScopes(scopes, index, writer, state) {
        const scope = scopes[index];
        const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
        if (index > 0)
            writer.write(comma);
        state[0] = encodeInteger(writer, startLine, state[0]);
        encodeInteger(writer, startColumn, 0);
        encodeInteger(writer, kind, 0);
        const fields = scope.length === 6 ? 0b0001 : 0;
        encodeInteger(writer, fields, 0);
        if (scope.length === 6)
            encodeInteger(writer, scope[5], 0);
        for (const v of vars) {
            encodeInteger(writer, v, 0);
        }
        for (index++; index < scopes.length;) {
            const next = scopes[index];
            const { 0: l, 1: c } = next;
            if (l > endLine || (l === endLine && c >= endColumn)) {
                break;
            }
            index = _encodeOriginalScopes(scopes, index, writer, state);
        }
        writer.write(comma);
        state[0] = encodeInteger(writer, endLine, state[0]);
        encodeInteger(writer, endColumn, 0);
        return index;
    }
    function decodeGeneratedRanges(input) {
        const { length } = input;
        const reader = new StringReader(input);
        const ranges = [];
        const stack = [];
        let genLine = 0;
        let definitionSourcesIndex = 0;
        let definitionScopeIndex = 0;
        let callsiteSourcesIndex = 0;
        let callsiteLine = 0;
        let callsiteColumn = 0;
        let bindingLine = 0;
        let bindingColumn = 0;
        do {
            const semi = reader.indexOf(';');
            let genColumn = 0;
            for (; reader.pos < semi; reader.pos++) {
                genColumn = decodeInteger(reader, genColumn);
                if (!hasMoreVlq(reader, semi)) {
                    const last = stack.pop();
                    last[2] = genLine;
                    last[3] = genColumn;
                    continue;
                }
                const fields = decodeInteger(reader, 0);
                const hasDefinition = fields & 0b0001;
                const hasCallsite = fields & 0b0010;
                const hasScope = fields & 0b0100;
                let callsite = null;
                let bindings = EMPTY;
                let range;
                if (hasDefinition) {
                    const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
                    definitionScopeIndex = decodeInteger(reader, definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0);
                    definitionSourcesIndex = defSourcesIndex;
                    range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];
                }
                else {
                    range = [genLine, genColumn, 0, 0];
                }
                range.isScope = !!hasScope;
                if (hasCallsite) {
                    const prevCsi = callsiteSourcesIndex;
                    const prevLine = callsiteLine;
                    callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
                    const sameSource = prevCsi === callsiteSourcesIndex;
                    callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
                    callsiteColumn = decodeInteger(reader, sameSource && prevLine === callsiteLine ? callsiteColumn : 0);
                    callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
                }
                range.callsite = callsite;
                if (hasMoreVlq(reader, semi)) {
                    bindings = [];
                    do {
                        bindingLine = genLine;
                        bindingColumn = genColumn;
                        const expressionsCount = decodeInteger(reader, 0);
                        let expressionRanges;
                        if (expressionsCount < -1) {
                            expressionRanges = [[decodeInteger(reader, 0)]];
                            for (let i = -1; i > expressionsCount; i--) {
                                const prevBl = bindingLine;
                                bindingLine = decodeInteger(reader, bindingLine);
                                bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
                                const expression = decodeInteger(reader, 0);
                                expressionRanges.push([expression, bindingLine, bindingColumn]);
                            }
                        }
                        else {
                            expressionRanges = [[expressionsCount]];
                        }
                        bindings.push(expressionRanges);
                    } while (hasMoreVlq(reader, semi));
                }
                range.bindings = bindings;
                ranges.push(range);
                stack.push(range);
            }
            genLine++;
            reader.pos = semi + 1;
        } while (reader.pos < length);
        return ranges;
    }
    function encodeGeneratedRanges(ranges) {
        if (ranges.length === 0)
            return '';
        const writer = new StringWriter();
        for (let i = 0; i < ranges.length;) {
            i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
        }
        return writer.flush();
    }
    function _encodeGeneratedRanges(ranges, index, writer, state) {
        const range = ranges[index];
        const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, isScope, callsite, bindings, } = range;
        if (state[0] < startLine) {
            catchupLine(writer, state[0], startLine);
            state[0] = startLine;
            state[1] = 0;
        }
        else if (index > 0) {
            writer.write(comma);
        }
        state[1] = encodeInteger(writer, range[1], state[1]);
        const fields = (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0);
        encodeInteger(writer, fields, 0);
        if (range.length === 6) {
            const { 4: sourcesIndex, 5: scopesIndex } = range;
            if (sourcesIndex !== state[2]) {
                state[3] = 0;
            }
            state[2] = encodeInteger(writer, sourcesIndex, state[2]);
            state[3] = encodeInteger(writer, scopesIndex, state[3]);
        }
        if (callsite) {
            const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;
            if (sourcesIndex !== state[4]) {
                state[5] = 0;
                state[6] = 0;
            }
            else if (callLine !== state[5]) {
                state[6] = 0;
            }
            state[4] = encodeInteger(writer, sourcesIndex, state[4]);
            state[5] = encodeInteger(writer, callLine, state[5]);
            state[6] = encodeInteger(writer, callColumn, state[6]);
        }
        if (bindings) {
            for (const binding of bindings) {
                if (binding.length > 1)
                    encodeInteger(writer, -binding.length, 0);
                const expression = binding[0][0];
                encodeInteger(writer, expression, 0);
                let bindingStartLine = startLine;
                let bindingStartColumn = startColumn;
                for (let i = 1; i < binding.length; i++) {
                    const expRange = binding[i];
                    bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);
                    bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);
                    encodeInteger(writer, expRange[0], 0);
                }
            }
        }
        for (index++; index < ranges.length;) {
            const next = ranges[index];
            const { 0: l, 1: c } = next;
            if (l > endLine || (l === endLine && c >= endColumn)) {
                break;
            }
            index = _encodeGeneratedRanges(ranges, index, writer, state);
        }
        if (state[0] < endLine) {
            catchupLine(writer, state[0], endLine);
            state[0] = endLine;
            state[1] = 0;
        }
        else {
            writer.write(comma);
        }
        state[1] = encodeInteger(writer, endColumn, state[1]);
        return index;
    }
    function catchupLine(writer, lastLine, line) {
        do {
            writer.write(semicolon);
        } while (++lastLine < line);
    }

    function decode(mappings) {
        const { length } = mappings;
        const reader = new StringReader(mappings);
        const decoded = [];
        let genColumn = 0;
        let sourcesIndex = 0;
        let sourceLine = 0;
        let sourceColumn = 0;
        let namesIndex = 0;
        do {
            const semi = reader.indexOf(';');
            const line = [];
            let sorted = true;
            let lastCol = 0;
            genColumn = 0;
            while (reader.pos < semi) {
                let seg;
                genColumn = decodeInteger(reader, genColumn);
                if (genColumn < lastCol)
                    sorted = false;
                lastCol = genColumn;
                if (hasMoreVlq(reader, semi)) {
                    sourcesIndex = decodeInteger(reader, sourcesIndex);
                    sourceLine = decodeInteger(reader, sourceLine);
                    sourceColumn = decodeInteger(reader, sourceColumn);
                    if (hasMoreVlq(reader, semi)) {
                        namesIndex = decodeInteger(reader, namesIndex);
                        seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
                    }
                    else {
                        seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
                    }
                }
                else {
                    seg = [genColumn];
                }
                line.push(seg);
                reader.pos++;
            }
            if (!sorted)
                sort(line);
            decoded.push(line);
            reader.pos = semi + 1;
        } while (reader.pos <= length);
        return decoded;
    }
    function sort(line) {
        line.sort(sortComparator);
    }
    function sortComparator(a, b) {
        return a[0] - b[0];
    }
    function encode(decoded) {
        const writer = new StringWriter();
        let sourcesIndex = 0;
        let sourceLine = 0;
        let sourceColumn = 0;
        let namesIndex = 0;
        for (let i = 0; i < decoded.length; i++) {
            const line = decoded[i];
            if (i > 0)
                writer.write(semicolon);
            if (line.length === 0)
                continue;
            let genColumn = 0;
            for (let j = 0; j < line.length; j++) {
                const segment = line[j];
                if (j > 0)
                    writer.write(comma);
                genColumn = encodeInteger(writer, segment[0], genColumn);
                if (segment.length === 1)
                    continue;
                sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
                sourceLine = encodeInteger(writer, segment[2], sourceLine);
                sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
                if (segment.length === 4)
                    continue;
                namesIndex = encodeInteger(writer, segment[4], namesIndex);
            }
        }
        return writer.flush();
    }

    exports.decode = decode;
    exports.decodeGeneratedRanges = decodeGeneratedRanges;
    exports.decodeOriginalScopes = decodeOriginalScopes;
    exports.encode = encode;
    exports.encodeGeneratedRanges = encodeGeneratedRanges;
    exports.encodeOriginalScopes = encodeOriginalScopes;

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

}));
//# sourceMappingURL=sourcemap-codec.umd.js.map
