"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.compose = void 0;
const util_1 = require("./util");
/**
 * Combine two operations into one, such that the changes produced by the
 * by the single operation are the same as if the two operations were applied
 * in sequence.
 *
 * ```
 * apply(str, combine(op1, op2)) === apply(apply(str, op1), op2)
 * ```
 *
 * @param op1 First operation.
 * @param op2 Second operation.
 * @returns A combined operation.
 */
const compose = (op1, op2) => {
    const op3 = [];
    const len1 = op1.length;
    const len2 = op2.length;
    let off1 = 0;
    let i1 = 0;
    for (let i2 = 0; i2 < len2; i2++) {
        const comp2 = op2[i2];
        if (typeof comp2 === 'number') {
            if (comp2 > 0) {
                let length2 = comp2;
                while (length2 > 0) {
                    const comp1 = op1[i1];
                    const comp = i1 >= len1 ? length2 : (0, util_1.chunk)(comp1, off1, length2);
                    const compLength = (0, util_1.componentLength)(comp);
                    const isDelete = (0, util_1.isDeleteComponent)(comp);
                    const length1 = (0, util_1.componentLength)(comp1 || comp);
                    (0, util_1.append)(op3, comp);
                    off1 += compLength;
                    if (off1 >= length1) {
                        i1++;
                        off1 = 0;
                    }
                    if (!isDelete)
                        length2 -= compLength;
                }
            }
            else {
                const length2 = -comp2;
                let off2 = 0;
                while (off2 < length2) {
                    const remaining = length2 - off2;
                    const comp1 = op1[i1];
                    const comp = i1 >= len1 ? remaining : (0, util_1.chunk)(comp1, off1, remaining);
                    const compLength = (0, util_1.componentLength)(comp);
                    const isDelete = (0, util_1.isDeleteComponent)(comp);
                    const length1 = (0, util_1.componentLength)(comp1 || comp);
                    if (isDelete)
                        (0, util_1.append)(op3, comp);
                    else if (typeof comp === 'number')
                        (0, util_1.append)(op3, -compLength);
                    off1 += compLength;
                    if (off1 >= length1) {
                        i1++;
                        off1 = 0;
                    }
                    if (!isDelete)
                        off2 += compLength;
                }
            }
        }
        else if (comp2 instanceof Uint8Array) {
            (0, util_1.append)(op3, comp2);
        }
    }
    if (i1 < len1 && off1)
        (0, util_1.append)(op3, (0, util_1.chunk)(op1[i1++], off1, Number.POSITIVE_INFINITY));
    for (; i1 < len1; i1++)
        (0, util_1.append)(op3, op1[i1]);
    (0, util_1.trim)(op3);
    return op3;
};
exports.compose = compose;
//# sourceMappingURL=compose.js.map